Updated parser functions to include identifiers.

This commit is contained in:
lwark
2025-06-11 13:18:01 -05:00
parent 592073c2a1
commit 90dc97683f
7 changed files with 254 additions and 25 deletions

View File

@@ -8,6 +8,7 @@ from dateutil.parser import parse
from pandas import DataFrame
from pydantic import BaseModel
from sqlalchemy import Column, INTEGER, String, JSON
from sqlalchemy.ext.associationproxy import AssociationProxy
from sqlalchemy.orm import DeclarativeMeta, declarative_base, Query, Session, InstrumentedAttribute, ColumnProperty
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.exc import ArgumentError
@@ -23,7 +24,7 @@ if 'pytest' in sys.modules:
# NOTE: For inheriting in LogMixin
Base: DeclarativeMeta = declarative_base()
logger = logging.getLogger(f"procedure.{__name__}")
logger = logging.getLogger(f"submissions.{__name__}")
class BaseClass(Base):
@@ -235,7 +236,7 @@ class BaseClass(Base):
def query_or_create(cls, **kwargs) -> Tuple[Any, bool]:
new = False
allowed = [k for k, v in cls.__dict__.items() if isinstance(v, InstrumentedAttribute)]
# and not isinstance(v.property, _RelationshipDeclared)]
# and not isinstance(v.property, _RelationshipDeclared)]
sanitized_kwargs = {k: v for k, v in kwargs.items() if k in allowed}
logger.debug(f"Sanitized kwargs: {sanitized_kwargs}")
instance = cls.query(**sanitized_kwargs)
@@ -389,7 +390,7 @@ class BaseClass(Base):
try:
template = env.get_template(temp_name)
except TemplateNotFound as e:
# logger.error(f"Couldn't find template {e}")
# logger.error(f"Couldn't find template {e}")
template = env.get_template("details.html")
return template
@@ -553,9 +554,23 @@ class BaseClass(Base):
output_date = datetime.combine(output_date, addition_time).strftime("%Y-%m-%d %H:%M:%S")
return output_date
def details_dict(self):
dicto = {k:v for k,v in self.__dict__.items() if not k.startswith("_")}
def details_dict(self, **kwargs):
relevant = {k: v for k, v in self.__class__.__dict__.items() if
isinstance(v, InstrumentedAttribute) or isinstance(v, AssociationProxy)}
output = {}
for k, v in relevant.items():
try:
check = v.foreign_keys
except AttributeError:
check = False
if check:
continue
value = getattr(self, k)
match value:
case datetime():
value = value.strftime()
output[k] = value
return output
class LogMixin(Base):

View File

@@ -1046,6 +1046,52 @@ class SubmissionType(BaseClass):
dicto = dict()
return dicto
@classproperty
def regex(cls) -> re.Pattern:
"""
Constructs catchall regex.
Returns:
re.Pattern: Regular expression pattern to discriminate between procedure types.
"""
res = [st.defaults['regex'] for st in cls.query() if st.defaults]
rstring = rf'{"|".join(res)}'
regex = re.compile(rstring, flags=re.IGNORECASE | re.VERBOSE)
return regex
@classmethod
def get_regex(cls, submission_type: SubmissionType | str | None = None) -> re.Pattern:
"""
Gets the regex string for identifying a certain class of procedure.
Args:
submission_type (SubmissionType | str | None, optional): procedure type of interest. Defaults to None.
Returns:
str: String from which regex will be compiled.
"""
# logger.debug(f"Class for regex: {cls}")
logger.debug(f"Looking for {submission_type}")
if not isinstance(submission_type, SubmissionType):
submission_type = cls.query(name=submission_type)
if isinstance(submission_type, list):
if len(submission_type) > 1:
regex = "|".join([item.defaults['regex'] for item in submission_type])
else:
regex = submission_type[0].defaults['regex']
else:
try:
regex = submission_type.defaults['regex']
except AttributeError as e:
logger.error(f"Couldn't get submission type for {submission_type.name}")
regex = None
try:
regex = re.compile(rf"{regex}", flags=re.IGNORECASE | re.VERBOSE)
except re.error as e:
regex = None
# logger.debug(f"Returning regex: {regex}")
return regex
class ProcedureType(BaseClass):
id = Column(INTEGER, primary_key=True)
@@ -1226,6 +1272,7 @@ class ProcedureType(BaseClass):
def total_wells(self):
return self.plate_rows * self.plate_columns
class Procedure(BaseClass):
id = Column(INTEGER, primary_key=True)
name = Column(String, unique=True)