Source code for molfoundry.rule
from pathlib import Path
from typing import Optional, Callable, overload, Any
import requests
from ._engine import engine
from . import GraphType
from .post import summaryRaw
from .graphprinter import GraphPrinter
from .labeltype import LabelType
from .core import TSObject, coerce_type
from .exceptions import *
import molfoundry.dgstrat as dgstrat
_class_ref = TSObject.get_class_ref("Rule")
_ruleGMLString_func: Callable[[str, Optional[str], Optional[str]], "Rule"] = engine.eval("ruleGMLString")
# noinspection PyPep8Naming
[docs]
class Rule(TSObject):
# Injectable global state add function to prevent circular import
_add_rule: Callable[["Rule"], None]
# Injectable dgStrat util
_dg_strat: Callable[[Any], "dgstrat.DGStrat"]
def __init__(self) -> None:
super().__init__(_class_ref)
def __str__(self):
return f"'{self.name}'({self.id})"
def __repr__(self):
return f"'{self.name}'({self.id})"
def __rshift__(self, other) -> "dgstrat.DGStrat":
return dgstrat.DGStrat.makeSequence([Rule._dg_strat(self), Rule._dg_strat(other)])
[docs]
@staticmethod
def fromGMLString(gml: str, name: Optional[str] = None, invert=False, add=True) -> "Rule":
r = Rule.wrap(_ruleGMLString_func(gml, name, None))
if invert:
r = r.makeInverse()
if add:
Rule._add_rule(r)
return r
[docs]
@staticmethod
def fromGMLFile(f: str, name: Optional[str] = None, invert=False, add=True) -> "Rule":
return Rule.fromGMLString(Path(f).read_text('utf-8'), name, invert, add)
# noinspection PyShadowingBuiltins
[docs]
@staticmethod
def fromMolFoundry(id: str, name: Optional[str] = None, invert=False, add=True) -> "Rule":
response = requests.post("https://molfoundry.de/api/rules/download", json={
"rule_ids": [id]
}, headers={"Content-Type": "application/json"})
if response.status_code != 200:
raise LogicError("Failed to fetch rule from API")
body = response.json()
r = Rule.wrap(_ruleGMLString_func(body["rules"][0]["content"], name, id))
if invert:
r = r.makeInverse()
if add:
Rule._add_rule(r)
return r
[docs]
def getGMLString(self, withCoords: bool = False) -> str:
return self._ref.getGMLString(withCoords)
[docs]
def makeInverse(self) -> "Rule":
return Rule.wrap(self._ref.makeInverse())
@property
def id(self) -> int:
return int(self._ref.getId())
@property
def molFoundryId(self) -> str | None:
return coerce_type(self._ref.getMolFoundryId())
@property
def type(self) -> GraphType:
return GraphType.Electron if self._ref.getType() == "electron" else GraphType.Default
@property
def name(self) -> str:
return self._ref.getName()
@property
def labelType(self) -> LabelType:
if self._ref.getLabelType() == 'term':
return LabelType.Term
return LabelType.String
@property
def numLeftComponents(self) -> int:
return int(self._ref.numLeftComponents())
@property
def numRightComponents(self) -> int:
return int(self._ref.numRightComponents())
@overload
def print(self, printCombined: bool = False) -> None:
...
@overload
def print(self, first: GraphPrinter, second: Optional[GraphPrinter], printCombined: bool = False) -> None:
...
[docs]
def print(self, first: Optional[GraphPrinter] = None, second: Optional[GraphPrinter] = None, printCombined=False):
summaryRaw(f"""<div class="card mb-4" style="max-width: 1000px; margin: auto">
<div class="d-flex m-2">
<h5 class="card-title flex-grow-1 mb-0">{self.name}</h5>
{f"""<a href="https://molfoundry.de/rule/{self.molFoundryId}" target="_blank" class="btn btn-tiny btn-outline-secondary">MolFoundry</a>""" if self.molFoundryId is not None else ""}
</div>
{self._ref.getSVG(first._ref if first is not None else None)}
</div>""")