This commit is contained in:
lwark
2025-07-11 13:25:04 -05:00
parent 2386c7a8ff
commit 02c88256f2
7 changed files with 178 additions and 25 deletions

View File

@@ -596,6 +596,7 @@ class BaseClass(Base):
return output_date
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 = {}
@@ -618,14 +619,16 @@ class BaseClass(Base):
output[k.strip("_")] = value
return output
def to_pydantic(self, **kwargs):
def to_pydantic(self, pyd_model_name:str|None=None, **kwargs):
from backend.validators import pydant
pyd_model_name = f"Pyd{self.__class__.__name__}"
if not pyd_model_name:
pyd_model_name = f"Pyd{self.__class__.__name__}"
logger.debug(f"Looking for pydant model {pyd_model_name}")
try:
pyd = getattr(pydant, pyd_model_name)
except AttributeError:
raise AttributeError(f"Could not get pydantic class {pyd_model_name}")
logger.debug(f"Kwargs: {kwargs}")
return pyd(**self.details_dict(**kwargs))
def show_details(self, obj):

View File

@@ -1212,7 +1212,7 @@ class ProcedureType(BaseClass):
self.save()
def construct_field_map(self, field: Literal['equipment', 'tip']) -> Generator[(str, dict), None, None]:
def construct_field_map(self, field: Literal['equipment', 'tip']) -> Generator[(str, dict), None, None]:
"""
Make a map of all locations for tips or equipment.
@@ -1524,6 +1524,7 @@ class Procedure(BaseClass):
sample['active'] = False
# output['sample'] = [sample.details_dict() for sample in output['runsampleassociation']]
output['sample'] = active_samples + inactive_samples
logger.debug(f"Procedure samples: \n\n{pformat(output['sample'])}\n\n")
# output['sample'] = [sample.details_dict() for sample in output['sample']]
output['reagent'] = [reagent.details_dict() for reagent in output['procedurereagentassociation']]
output['equipment'] = [equipment.details_dict() for equipment in output['procedureequipmentassociation']]
@@ -1538,18 +1539,22 @@ class Procedure(BaseClass):
def to_pydantic(self, **kwargs):
from backend.validators.pydant import PydResults, PydReagent
output = super().to_pydantic()
logger.debug(f"Pydantic output: \n\n{pformat(output.__dict__)}\n\n")
output.kittype = dict(value=output.kittype['name'], missing=False)
output.sample = [item.to_pydantic() for item in output.proceduresampleassociation]
reagents = []
for reagent in output.reagent:
match reagent:
case dict():
reagent['reagentrole'] = next((reagentrole.name for reagentrole in self.kittype.reagentrole if reagentrole in reagent['reagentrole']), None)
reagents.append(PydResults(**reagent))
reagents.append(PydReagent(**reagent))
case PydReagent():
reagents.append(reagent)
case _:
pass
output.reagent = [PydReagent(**item) for item in output.reagent]
# output.reagent = [PydReagent(**item) for item in output.reagent]
output.reagent = reagents
results = []
for result in output.results:
match result:
@@ -2438,6 +2443,9 @@ class ProcedureEquipmentAssociation(BaseClass):
equipment = relationship(Equipment, back_populates="equipmentprocedureassociation") #: associated equipment
tips_id = Column(INTEGER, ForeignKey("_tips.id", ondelete="SET NULL",
name="SEA_Process_id"))
def __repr__(self) -> str:
try:
return f"<ProcedureEquipmentAssociation({self.procedure.name} & {self.equipment.name})>"
@@ -2472,6 +2480,13 @@ class ProcedureEquipmentAssociation(BaseClass):
def process(self):
return Process.query(id=self.process_id)
@property
def tips(self):
try:
return Tips.query(id=self.tips_id, limit=1)
except AttributeError:
return None
def to_sub_dict(self) -> dict:
"""
This RunEquipmentAssociation as a dictionary
@@ -2495,7 +2510,7 @@ class ProcedureEquipmentAssociation(BaseClass):
PydEquipment: pydantic equipment model
"""
from backend.validators import PydEquipment
return PydEquipment(**self.to_sub_dict())
return PydEquipment(**self.details_dict())
@classmethod
@setup_lookup
@@ -2533,6 +2548,10 @@ class ProcedureEquipmentAssociation(BaseClass):
output.update(relevant)
output['misc_info'] = misc
output['process'] = self.process.details_dict()
try:
output['tips'] = self.tips.details_dict()
except AttributeError:
output['tips'] = None
return output

View File

@@ -2197,8 +2197,20 @@ class ProcedureSampleAssociation(BaseClass):
# NOTE: Figure out how to merge the misc_info if doing .update instead.
relevant = {k: v for k, v in output.items() if k not in ['sample']}
output = output['sample'].details_dict()
logger.debug(f"Output: {pformat(output)}")
logger.debug(f"Relevant: {pformat(relevant)}")
# relevant['submission_rank'] = output['misc_info']['submission_rank']
misc = output['misc_info']
output.update(relevant)
output['misc_info'] = misc
output['results'] = [result.details_dict() for result in output['results']]
return output
def to_pydantic(self, **kwargs):
output = super().to_pydantic(pyd_model_name="PydSample")
try:
output.submission_rank = output.misc_info['submission_rank']
except KeyError:
logger.error(output)
return output