Writer and manager updates.

This commit is contained in:
lwark
2025-07-22 13:15:24 -05:00
parent 53c6668ce1
commit b9ca9586ec
21 changed files with 661 additions and 329 deletions

View File

@@ -1363,6 +1363,7 @@ class Procedure(BaseClass):
id = Column(INTEGER, primary_key=True)
name = Column(String, unique=True)
repeat = Column(INTEGER, nullable=False)
repeat_of = Column(String)
started_date = Column(TIMESTAMP)
completed_date = Column(TIMESTAMP)
@@ -1416,6 +1417,8 @@ class Procedure(BaseClass):
tips = association_proxy("proceduretipsassociation",
"tips")
@validates('repeat')
def validate_repeat(self, key, value):
if value > 1:
@@ -1461,9 +1464,16 @@ class Procedure(BaseClass):
def add_results(self, obj, resultstype_name: str):
logger.debug(f"Add Results! {resultstype_name}")
from ...managers import results
results_class = getattr(results, resultstype_name)
rs = results_class(procedure=self, parent=obj)
from backend.managers import results
results_manager = getattr(results, f"{resultstype_name}Manager")
rs = results_manager(procedure=self, parent=obj)
procedure = rs.procedure_to_pydantic()
samples = rs.samples_to_pydantic()
procedure_sql = procedure.to_sql()
procedure_sql.save()
for sample in samples:
sample_sql = sample.to_sql()
sample_sql.save()
def add_equipment(self, obj):
"""
@@ -1549,7 +1559,14 @@ class Procedure(BaseClass):
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)
try:
output.kittype = dict(value=output.kittype['name'], missing=False)
except KeyError:
try:
output.kittype = dict(value=output.kittype['value'], missing=False)
except KeyError as e:
logger.error(f"Output.kittype: {output.kittype}")
raise e
output.sample = [item.to_pydantic() for item in output.proceduresampleassociation]
reagents = []
for reagent in output.reagent:
@@ -1578,6 +1595,10 @@ class Procedure(BaseClass):
# sample.enabled = True
return output
def create_proceduresampleassociations(self, sample):
from backend.db.models import ProcedureSampleAssociation
return ProcedureSampleAssociation(procedure=self, sample=sample)
class ProcedureTypeKitTypeAssociation(BaseClass):
"""
@@ -1967,7 +1988,10 @@ class ProcedureReagentAssociation(BaseClass):
try:
return f"<ProcedureReagentAssociation({self.procedure.procedure.rsl_plate_number} & {self.reagent.lot})>"
except AttributeError:
logger.error(f"Reagent {self.reagent.lot} procedure association {self.reagent_id} has no procedure!")
try:
logger.error(f"Reagent {self.reagent.lot} procedure association {self.reagent_id} has no procedure!")
except AttributeError:
return "<ProcedureReagentAssociation(Unknown Submission & Unknown Reagent)>"
return f"<ProcedureReagentAssociation(Unknown Submission & {self.reagent.lot})>"
def __init__(self, reagent=None, procedure=None, reagentrole=""):
@@ -3093,12 +3117,12 @@ class Results(BaseClass):
_img = Column(String(128))
@property
def image(self) -> bytes:
def image(self) -> bytes|None:
dir = self.__directory_path__.joinpath("submission_imgs.zip")
try:
assert dir.exists()
except AssertionError:
raise FileNotFoundError(f"{dir} not found.")
return None
logger.debug(f"Getting image from {self.__directory_path__}")
with zipfile.ZipFile(dir) as zf:
with zf.open(self._img) as f:

View File

@@ -671,24 +671,18 @@ class Run(BaseClass, LogMixin):
def sample_count(self):
return len(self.sample)
def details_dict(self, **kwargs):
output = super().details_dict()
output['plate_number'] = self.plate_number
submission_samples = [sample for sample in self.clientsubmission.sample]
# logger.debug(f"Submission samples:{pformat(submission_samples)}")
active_samples = [sample.details_dict() for sample in output['runsampleassociation']
if sample.sample.sample_id in [s.sample_id for s in submission_samples]]
# logger.debug(f"Active samples:{pformat(active_samples)}")
for sample in active_samples:
sample['active'] = True
inactive_samples = [sample.details_dict() for sample in submission_samples if
sample.name not in [s['sample_id'] for s in active_samples]]
# logger.debug(f"Inactive samples:{pformat(inactive_samples)}")
for sample in inactive_samples:
sample['active'] = False
# output['sample'] = [sample.details_dict() for sample in output['runsampleassociation']]
output['sample'] = active_samples + inactive_samples
output['procedure'] = [procedure.details_dict() for procedure in output['procedure']]
output['permission'] = is_power_user()
@@ -983,7 +977,7 @@ class Run(BaseClass, LogMixin):
new_dict['name'] = field_value
case "id":
continue
case "clientsubmission":
case "clientsubmission" | "client_submission":
field_value = self.clientsubmission.to_pydantic()
case "procedure":
field_value = [item.to_pydantic() for item in self.procedure]
@@ -1243,8 +1237,20 @@ class Run(BaseClass, LogMixin):
logger.debug(f"Got ProcedureType: {procedure_type}")
dlg = ProcedureCreation(parent=obj, procedure=procedure_type.construct_dummy_procedure(run=self))
if dlg.exec():
sql, _ = dlg.return_sql()
logger.debug(f"Output run samples:\n{pformat(sql.run.sample)}")
sql, _ = dlg.return_sql(new=True)
# logger.debug(f"Output run samples:\n{pformat(sql.run.sample)}")
# previous = [proc for proc in self.procedure if proc.proceduretype == procedure_type]
# repeats = len([proc for proc in previous if proc.repeat])
# if sql.repeat:
# repeats += 1
# if repeats > 0:
# suffix = f"-{str(len(previous))}R{repeats}"
# else:
# suffix = f"-{str(len(previous)+1)}"
# sql.name = f"{sql.repeat}{suffix}"
# else:
# suffix = f"-{str(len(previous)+1)}"
# sql.name = f"{self.name}-{proceduretype_name}{suffix}"
sql.save()
obj.set_data()