[Feature] Legacy API (#224)

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#224
This commit is contained in:
2025-11-19 20:45:16 +13:00
parent 89c194dcca
commit 67b1baa5b0
6 changed files with 737 additions and 64 deletions

View File

@ -1079,6 +1079,10 @@ class Rule(PolymorphicModel, EnviPathModel, AliasMixin, ScenarioMixin):
def apply(self, *args, **kwargs):
pass
@abc.abstractmethod
def get_rule_identifier(self) -> str:
pass
@staticmethod
def cls_for_type(rule_type: str):
if rule_type == "SimpleAmbitRule":
@ -1233,6 +1237,9 @@ class SimpleAmbitRule(SimpleRule):
def _url(self):
return "{}/simple-ambit-rule/{}".format(self.package.url, self.uuid)
def get_rule_identifier(self) -> str:
return "simple-rule"
def apply(self, smiles):
return FormatConverter.apply(smiles, self.smirks)
@ -1278,6 +1285,9 @@ class ParallelRule(Rule):
def _url(self):
return "{}/parallel-rule/{}".format(self.package.url, self.uuid)
def get_rule_identifier(self) -> str:
return "parallel-rule"
@cached_property
def srs(self) -> QuerySet:
return self.simple_rules.all()
@ -1309,6 +1319,57 @@ class ParallelRule(Rule):
return res
@staticmethod
@transaction.atomic
def create(
package: "Package",
simple_rules: List["SimpleRule"],
name: str = None,
description: str = None,
reactant_filter_smarts: str = None,
product_filter_smarts: str = None,
):
if len(simple_rules) == 0:
raise ValueError("At least one simple rule is required!")
for sr in simple_rules:
if sr.package != package:
raise ValueError(
f"Simple rule {sr.uuid} does not belong to package {package.uuid}!"
)
r = ParallelRule()
r.package = package
if name is not None:
name = nh3.clean(name, tags=s.ALLOWED_HTML_TAGS).strip()
if name is None or name == "":
name = f"Rule {Rule.objects.filter(package=package).count() + 1}"
r.name = name
if description is not None and description.strip() != "":
r.description = nh3.clean(description, tags=s.ALLOWED_HTML_TAGS).strip()
if reactant_filter_smarts is not None and reactant_filter_smarts.strip() != "":
if not FormatConverter.is_valid_smarts(reactant_filter_smarts.strip()):
raise ValueError(f'Reactant Filter SMARTS "{reactant_filter_smarts}" is invalid!')
else:
r.reactant_filter_smarts = reactant_filter_smarts.strip()
if product_filter_smarts is not None and product_filter_smarts.strip() != "":
if not FormatConverter.is_valid_smarts(product_filter_smarts.strip()):
raise ValueError(f'Product Filter SMARTS "{product_filter_smarts}" is invalid!')
else:
r.product_filter_smarts = product_filter_smarts.strip()
r.save()
for sr in simple_rules:
r.simple_rules.add(sr)
return r
class SequentialRule(Rule):
simple_rules = models.ManyToManyField(
@ -1318,6 +1379,9 @@ class SequentialRule(Rule):
def _url(self):
return "{}/sequential-rule/{}".format(self.compound.url, self.uuid)
def get_rule_identifier(self) -> str:
return "sequential-rule"
@property
def srs(self):
return self.simple_rules.all()