From 95ae203cc2b6bb6c15d3e54c8a6137a69f89c382 Mon Sep 17 00:00:00 2001 From: lwark Date: Wed, 8 Jan 2025 13:54:14 -0600 Subject: [PATCH] Bug fixing for new AddEdit forms. --- src/submissions/backend/db/models/__init__.py | 5 +- src/submissions/backend/db/models/controls.py | 6 +- src/submissions/backend/db/models/kits.py | 18 +++ .../backend/db/models/submissions.py | 19 ++- src/submissions/backend/excel/parser.py | 8 +- src/submissions/backend/validators/pydant.py | 40 ++++-- src/submissions/frontend/widgets/__init__.py | 2 + .../frontend/widgets/omni_add_edit.py | 123 +++++++++++++----- .../frontend/widgets/omni_manager.py | 7 +- .../frontend/widgets/submission_widget.py | 58 ++++++--- src/submissions/tools/__init__.py | 16 ++- 11 files changed, 217 insertions(+), 85 deletions(-) diff --git a/src/submissions/backend/db/models/__init__.py b/src/submissions/backend/db/models/__init__.py index fd3b0be..1da3742 100644 --- a/src/submissions/backend/db/models/__init__.py +++ b/src/submissions/backend/db/models/__init__.py @@ -243,7 +243,10 @@ class BaseClass(Base): @classmethod def get_pydantic_model(cls): from backend.validators import pydant - model = getattr(pydant, f"Pyd{cls.__name__}") + try: + model = getattr(pydant, f"Pyd{cls.__name__}") + except AttributeError: + return None return model diff --git a/src/submissions/backend/db/models/controls.py b/src/submissions/backend/db/models/controls.py index 87f0163..e285ebc 100644 --- a/src/submissions/backend/db/models/controls.py +++ b/src/submissions/backend/db/models/controls.py @@ -286,6 +286,10 @@ class Control(BaseClass): """ return None + def delete(self): + self.__database_session__.delete(self) + self.__database_session__.commit() + class PCRControl(Control): """ @@ -296,7 +300,7 @@ class PCRControl(Control): subtype = Column(String(16)) #: PC or NC target = Column(String(16)) #: N1, N2, etc. ct = Column(FLOAT) #: PCR result - reagent_lot = Column(String(64), ForeignKey("_reagent.name", ondelete="SET NULL", + reagent_lot = Column(String(64), ForeignKey("_reagent.lot", ondelete="SET NULL", name="fk_reagent_lot")) reagent = relationship("Reagent", foreign_keys=reagent_lot) #: reagent used for this control diff --git a/src/submissions/backend/db/models/kits.py b/src/submissions/backend/db/models/kits.py index 60a9ecc..79b97d8 100644 --- a/src/submissions/backend/db/models/kits.py +++ b/src/submissions/backend/db/models/kits.py @@ -540,6 +540,24 @@ class Reagent(BaseClass, LogMixin): report.add_result(Result(msg=f"Updating last used {rt} was not performed.", status="Information")) return report + @classmethod + def query_or_create(cls, **kwargs) -> Reagent: + from backend.validators.pydant import PydReagent + new = False + instance = cls.query(**kwargs) + if not instance or isinstance(instance, list): + if "role" not in kwargs: + try: + kwargs['role'] = kwargs['name'] + except KeyError: + pass + instance = PydReagent(**kwargs) + new = True + instance, _ = instance.toSQL() + logger.debug(f"Instance: {instance}") + return instance, new + + @classmethod @setup_lookup def query(cls, diff --git a/src/submissions/backend/db/models/submissions.py b/src/submissions/backend/db/models/submissions.py index c6378d6..81a154a 100644 --- a/src/submissions/backend/db/models/submissions.py +++ b/src/submissions/backend/db/models/submissions.py @@ -936,14 +936,20 @@ class BasicSubmission(BaseClass, LogMixin): Generator[dict, None, None]: Dictionaries of row values. """ location_map = cls.get_submission_type().sample_map['pcr_controls'] + # logger.debug(f"Location map: {location_map}") submission = cls.query(rsl_plate_num=rsl_plate_num) name_column = 1 for item in location_map: + logger.debug(f"Checking {item}") worksheet = xl[item['sheet']] for iii, row in enumerate(worksheet.iter_rows(max_row=len(worksheet['A']), max_col=name_column), start=1): + logger.debug(f"Checking row {row}, {iii}") for cell in row: + logger.debug(f"Checking cell: {cell}, with value {cell.value} against {item['name']}") if cell.value == item['name']: - subtype, target = item['name'].split("-") + subtype, _ = item['name'].split("-") + target = item['target'] + logger.debug(f"Subtype: {subtype}, target: {target}") ct = worksheet.cell(row=iii, column=item['ct_column']).value # NOTE: Kind of a stop gap solution to find control reagents. if subtype == "PC": @@ -955,6 +961,9 @@ class BasicSubmission(BaseClass, LogMixin): ctrl = next((assoc.reagent for assoc in submission.submission_reagent_associations if any(["molecular grade water" in item.name.lower() for item in assoc.reagent.role])), None) + else: + ctrl = None + logger.debug(f"Control reagent: {ctrl.__dict__}") try: ct = float(ct) except ValueError: @@ -963,13 +972,15 @@ class BasicSubmission(BaseClass, LogMixin): ctrl = ctrl.lot else: ctrl = None - yield dict( - name=f"{rsl_plate_num}<{item['name']}>", + output = dict( + name=f"{rsl_plate_num}<{item['name']}-{target}>", ct=ct, subtype=subtype, target=target, reagent_lot=ctrl ) + logger.debug(f"Control output: {pformat(output)}") + yield output @classmethod def filename_template(cls) -> str: @@ -1663,10 +1674,12 @@ class Wastewater(BasicSubmission): submitted_date = datetime.strptime(" ".join(parser.pcr['run_start_date/time'].split(" ")[:-1]), "%Y-%m-%d %I:%M:%S %p") for control in pcr_controls: + logger.debug(f"Control coming into save: {control}") new_control = PCRControl(**control) new_control.submitted_date = submitted_date new_control.controltype = controltype new_control.submission = self + logger.debug(f"Control coming into save: {new_control.__dict__}") new_control.save() return report diff --git a/src/submissions/backend/excel/parser.py b/src/submissions/backend/excel/parser.py index b54f710..6b5817a 100644 --- a/src/submissions/backend/excel/parser.py +++ b/src/submissions/backend/excel/parser.py @@ -257,9 +257,10 @@ class ReagentParser(object): extraction_kit = extraction_kit['value'] self.kit_object = KitType.query(name=extraction_kit) self.map = self.fetch_kit_info_map(submission_type=submission_type) + logger.debug(f"Setting map: {self.map}") self.xl = xl - @report_result + # @report_result def fetch_kit_info_map(self, submission_type: str | SubmissionType) -> Tuple[Report, dict]: """ Gets location of kit reagents from database @@ -298,7 +299,8 @@ class ReagentParser(object): msg=f"No kit map found for {self.kit_object.name}.\n\n" f"Are you sure you put the right kit in:\n\n{location_string}?", status="Critical")) - return report, reagent_map + logger.debug(f"Here is the map coming out: {reagent_map}") + return reagent_map def parse_reagents(self) -> Generator[dict, None, None]: """ @@ -310,7 +312,7 @@ class ReagentParser(object): for sheet in self.xl.sheetnames: ws = self.xl[sheet] relevant = {k.strip(): v for k, v in self.map.items() if sheet in self.map[k]['sheet']} - if relevant == {}: + if not relevant: continue for item in relevant: try: diff --git a/src/submissions/backend/validators/pydant.py b/src/submissions/backend/validators/pydant.py index b05803c..1f11295 100644 --- a/src/submissions/backend/validators/pydant.py +++ b/src/submissions/backend/validators/pydant.py @@ -22,8 +22,8 @@ logger = logging.getLogger(f"submissions.{__name__}") class PydReagent(BaseModel): lot: str | None role: str | None - expiry: date | Literal['NA'] | None - name: str | None + expiry: date | datetime | Literal['NA'] | None = Field(default=None, validate_default=True) + name: str | None = Field(default=None, validate_default=True) missing: bool = Field(default=True) comment: str | None = Field(default="", validate_default=True) @@ -79,6 +79,8 @@ class PydReagent(BaseModel): case str(): return parse(value) case date(): + return datetime.combine(value, datetime.max.time()) + case datetime(): return value case _: return convert_nans_to_nones(str(value)) @@ -939,6 +941,7 @@ class PydSubmission(BaseModel, extra='allow'): ext_kit.get_reagents(required=True, submission_type=self.submission_type['value'])] # NOTE: Exclude any reagenttype found in this pyd not expected in kit. expected_check = [item.role for item in ext_kit_rtypes] + logger.debug(self.reagents) output_reagents = [rt for rt in self.reagents if rt.role in expected_check] missing_check = [item.role for item in output_reagents] missing_reagents = [rt for rt in ext_kit_rtypes if rt.role not in missing_check and rt.role not in exempt] @@ -956,7 +959,7 @@ class PydSubmission(BaseModel, extra='allow'): report.add_result(result) return output_reagents, report, missing_reagents - def check_reagent_expiries(self, exempt: List[PydReagent]=[]): + def check_reagent_expiries(self, exempt: List[PydReagent] = []): report = Report() expired = [] for reagent in self.reagents: @@ -971,14 +974,11 @@ class PydSubmission(BaseModel, extra='allow'): if expired: output = '\n'.join(expired) result = Result(status="Warning", - msg = f"The following reagents are expired:\n\n{output}" + msg=f"The following reagents are expired:\n\n{output}" ) report.add_result(result) return report - - - def export_csv(self, filename: Path | str): try: worksheet = self.csv @@ -1009,14 +1009,34 @@ class PydContact(BaseModel): logger.debug(f"Output phone: {value}") return value - def toSQL(self) -> Contact: + def toSQL(self) -> Tuple[Contact, Report]: """ - Converts this instance into a backend.db.models.organization.Contact instance + Converts this instance into a backend.db.models.organization. Contact instance. + Does not query for existing contacts. Returns: Contact: Contact instance """ - return Contact(name=self.name, phone=self.phone, email=self.email) + report = Report() + instance = Contact.query(name=self.name, phone=self.phone, email=self.email) + if not instance or isinstance(instance, list): + instance = Contact() + try: + all_fields = self.model_fields + self.model_extra + except TypeError: + all_fields = self.model_fields + for field in all_fields: + value = getattr(self, field) + match field: + case "organization": + value = [Organization.query(name=value)] + case _: + pass + try: + instance.__setattr__(field, value) + except AttributeError as e: + logger.error(f"Could not set {instance} {field} to {value} due to {e}") + return instance, report class PydOrganization(BaseModel): diff --git a/src/submissions/frontend/widgets/__init__.py b/src/submissions/frontend/widgets/__init__.py index a3367f1..ff8d8fb 100644 --- a/src/submissions/frontend/widgets/__init__.py +++ b/src/submissions/frontend/widgets/__init__.py @@ -16,3 +16,5 @@ from .submission_table import * from .submission_widget import * from .summary import * from .turnaround import * +from .omni_add_edit import * +from .omni_manager import * diff --git a/src/submissions/frontend/widgets/omni_add_edit.py b/src/submissions/frontend/widgets/omni_add_edit.py index f15e6b9..f08978d 100644 --- a/src/submissions/frontend/widgets/omni_add_edit.py +++ b/src/submissions/frontend/widgets/omni_add_edit.py @@ -1,59 +1,78 @@ from datetime import date -from typing import Any - +from pprint import pformat +from typing import Any, List, Tuple +from pydantic import BaseModel from PyQt6.QtWidgets import ( QLabel, QDialog, QTableView, QWidget, QLineEdit, QGridLayout, QComboBox, QPushButton, QDialogButtonBox, QDateEdit ) from sqlalchemy import String, TIMESTAMP -from sqlalchemy.orm import InstrumentedAttribute +from sqlalchemy.orm import InstrumentedAttribute, ColumnProperty import logging +from sqlalchemy.orm.relationships import _RelationshipDeclared + +from tools import Report, Result + logger = logging.getLogger(f"submissions.{__name__}") class AddEdit(QDialog): - def __init__(self, parent, instance: Any|None=None): + def __init__(self, parent, instance: Any | None = None, manager: str = ""): super().__init__(parent) self.instance = instance self.object_type = instance.__class__ self.layout = QGridLayout(self) - + logger.debug(f"Manager: {manager}") QBtn = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel self.buttonBox = QDialogButtonBox(QBtn) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) - # fields = {k: v for k, v in self.object_type.__dict__.items() if - # isinstance(v, InstrumentedAttribute) and k != "id"} - fields = {k: v for k, v in self.object_type.__dict__.items() if k != "id"} + fields = {key: dict(class_attr=getattr(self.object_type, key), instance_attr=getattr(self.instance, key)) + for key in dir(self.object_type) if isinstance(getattr(self.object_type, key), InstrumentedAttribute) + and "id" not in key and key != manager} + # NOTE: Move 'name' to the front + try: + fields = {'name': fields.pop('name'), **fields} + except KeyError: + pass + logger.debug(pformat(fields, indent=4)) + height_counter = 0 for key, field in fields.items(): - logger.debug(f"") try: - widget = EditProperty(self, key=key, column_type=field.property.expression.type, - value=getattr(self.instance, key)) + value = getattr(self.instance, key) + except AttributeError: + value = None + try: + logger.debug(f"{key} property: {type(field['class_attr'].property)}") + # widget = EditProperty(self, key=key, column_type=field.property.expression.type, + # value=getattr(self.instance, key)) + logger.debug(f"Column type: {field}, Value: {value}") + widget = EditProperty(self, key=key, column_type=field, value=value) except AttributeError as e: logger.error(f"Problem setting widget {key}: {e}") continue - self.layout.addWidget(widget, self.layout.rowCount(), 0) + if widget: + self.layout.addWidget(widget, self.layout.rowCount(), 0) + height_counter += 1 self.layout.addWidget(self.buttonBox) self.setWindowTitle(f"Add/Edit {self.object_type.__name__}") - self.setMinimumSize(600, 50 * len(fields)) + self.setMinimumSize(600, 50 * height_counter) self.setLayout(self.layout) - def parse_form(self): - results = {result[0]:result[1] for result in [item.parse_form() for item in self.findChildren(EditProperty)]} - # logger.debug(results) + def parse_form(self) -> Tuple[BaseModel, Report]: + report = Report() + parsed = {result[0].strip(":"): result[1] for result in [item.parse_form() for item in self.findChildren(EditProperty)] if result[0]} + logger.debug(parsed) model = self.object_type.get_pydantic_model() - model = model(**results) - try: - extras = list(model.model_extra.keys()) - except AttributeError: - extras = [] - fields = list(model.model_fields.keys()) + extras - for field in fields: - # logger.debug(result) - self.instance.__setattr__(field, model.__getattribute__(field)) - return self.instance + # NOTE: Hand-off to pydantic model for validation. + # NOTE: Also, why am I not just using the toSQL method here. I could write one for contacts. + model = model(**parsed) + # output, result = model.toSQL() + # report.add_result(result) + # if len(report.results) < 1: + # report.add_result(Result(msg="Added new regeant.", icon="Information", owner=__name__)) + return model, report class EditProperty(QWidget): @@ -64,7 +83,36 @@ class EditProperty(QWidget): self.layout = QGridLayout() self.layout.addWidget(self.label, 0, 0, 1, 1) self.setObjectName(key) - match column_type: + match column_type['class_attr'].property: + case ColumnProperty(): + self.column_property_set(column_type, value=value) + case _RelationshipDeclared(): + self.relationship_property_set(column_type, value=value) + case _: + logger.error(f"{column_type} not a supported type.") + return + self.layout.addWidget(self.widget, 0, 1, 1, 3) + self.setLayout(self.layout) + + def relationship_property_set(self, relationship_property, value=None): + # print(relationship_property) + self.property_class = relationship_property['class_attr'].property.entity.class_ + self.is_list = relationship_property['class_attr'].property.uselist + choices = [item.name for item in self.property_class.query()] + try: + instance_value = getattr(self.parent().instance, self.objectName().strip(":")) + except AttributeError: + logger.debug(f"Unable to get instance {self.parent().instance} attribute: {self.objectName()}") + instance_value = None + if isinstance(instance_value, list): + instance_value = next((item.name for item in instance_value), None) + if instance_value: + choices.insert(0, choices.pop(choices.index(instance_value))) + self.widget = QComboBox() + self.widget.addItems(choices) + + def column_property_set(self, column_property, value=None): + match column_property['class_attr'].expression.type: case String(): if not value: value = "" @@ -76,22 +124,25 @@ class EditProperty(QWidget): value = date.today() self.widget.setDate(value) case _: - logger.error(f"{column_type} not a supported type.") + logger.error(f"{column_property} not a supported property.") self.widget = None - return - self.layout.addWidget(self.widget, 0, 1, 1, 3) - self.setLayout(self.layout) def parse_form(self): + try: + check = self.widget + except AttributeError: + return None, None match self.widget: case QLineEdit(): value = self.widget.text() case QDateEdit(): - value = self.widget.date() + value = self.widget.date().toPyDate() + case QComboBox(): + value = self.widget.currentText() + # if self.is_list: + # value = [self.property_class.query(name=prelim)] + # else: + # value = self.property_class.query(name=prelim) case _: value = None return self.objectName(), value - - - - diff --git a/src/submissions/frontend/widgets/omni_manager.py b/src/submissions/frontend/widgets/omni_manager.py index 5e79099..11b2c80 100644 --- a/src/submissions/frontend/widgets/omni_manager.py +++ b/src/submissions/frontend/widgets/omni_manager.py @@ -110,7 +110,7 @@ class ManagerWindow(QDialog): return self.instance def add_new(self): - dlg = AddEdit(parent=self, instance=self.object_type()) + dlg = AddEdit(parent=self, instance=self.object_type(), manager=self.object_type.__name__.lower()) if dlg.exec(): new_instance = dlg.parse_form() # logger.debug(new_instance.__dict__) @@ -182,7 +182,7 @@ class EditRelationship(QWidget): def add_new(self, instance: Any = None): if not instance: instance = self.entity() - dlg = AddEdit(self, instance=instance) + dlg = AddEdit(self, instance=instance, manager=self.parent().object_type.__name__.lower()) if dlg.exec(): new_instance = dlg.parse_form() # logger.debug(new_instance.__dict__) @@ -190,16 +190,15 @@ class EditRelationship(QWidget): if isinstance(addition, InstrumentedList): addition.append(new_instance) self.parent().instance.save() + self.parent().update_data() def add_existing(self): dlg = SearchBox(self, object_type=self.entity, returnable=True, extras=[]) if dlg.exec(): rows = dlg.return_selected_rows() - # print(f"Rows selected: {[row for row in rows]}") for row in rows: instance = self.entity.query(**row) - # logger.debug(instance) addition = getattr(self.parent().instance, self.objectName()) if isinstance(addition, InstrumentedList): addition.append(instance) diff --git a/src/submissions/frontend/widgets/submission_widget.py b/src/submissions/frontend/widgets/submission_widget.py index 6a5d150..b469eff 100644 --- a/src/submissions/frontend/widgets/submission_widget.py +++ b/src/submissions/frontend/widgets/submission_widget.py @@ -140,14 +140,22 @@ class SubmissionFormContainer(QWidget): self.layout().addWidget(self.form) return report - - def new_add_reagent(self): - instance = Reagent() + @report_result + def new_add_reagent(self, instance: Reagent | None = None): + report = Report() + if not instance: + instance = Reagent() dlg = AddEdit(parent=self, instance=instance) if dlg.exec(): - obj = dlg.parse_form() - print(obj) - + reagent, result = dlg.parse_form() + reagent.missing = False + logger.debug(f"Reagent: {reagent}, result: {result}") + report.add_result(result) + # NOTE: send reagent to db + sqlobj, result = reagent.toSQL() + sqlobj.save() + report.add_result(result) + return reagent, report @report_result def add_reagent(self, reagent_lot: str | None = None, reagent_role: str | None = None, expiry: date | None = None, @@ -183,7 +191,6 @@ class SubmissionFormContainer(QWidget): class SubmissionFormWidget(QWidget): - update_reagent_fields = ['extraction_kit'] def __init__(self, parent: QWidget, submission: PydSubmission, disable: list | None = None) -> None: @@ -235,7 +242,6 @@ class SubmissionFormWidget(QWidget): for reagent in self.findChildren(self.ReagentFormWidget): reagent.flip_check(self.disabler.checkbox.isChecked()) - def create_widget(self, key: str, value: dict | PydReagent, submission_type: str | SubmissionType | None = None, extraction_kit: str | None = None, sub_obj: BasicSubmission | None = None, disable: bool = False) -> "self.InfoItem": @@ -294,8 +300,10 @@ class SubmissionFormWidget(QWidget): if isinstance(reagent, self.ReagentFormWidget) or isinstance(reagent, QPushButton): reagent.setParent(None) reagents, integrity_report, missing_reagents = self.pyd.check_kit_integrity(extraction_kit=self.extraction_kit) + logger.debug(f"Reagents: {reagents}") expiry_report = self.pyd.check_reagent_expiries(exempt=missing_reagents) for reagent in reagents: + add_widget = self.ReagentFormWidget(parent=self, reagent=reagent, extraction_kit=self.extraction_kit) self.layout.addWidget(add_widget) report.add_result(integrity_report) @@ -432,7 +440,7 @@ class SubmissionFormWidget(QWidget): for widget in self.findChildren(QWidget): match widget: case self.ReagentFormWidget(): - reagent, _ = widget.parse_form() + reagent = widget.parse_form() if reagent is not None: reagents.append(reagent) case self.InfoItem(): @@ -440,6 +448,7 @@ class SubmissionFormWidget(QWidget): if field is not None: info[field] = value self.pyd.reagents = reagents + logger.debug(f"Reagents from form: {reagents}") for item in self.recover: if hasattr(self, item): value = getattr(self, item) @@ -661,7 +670,7 @@ class SubmissionFormWidget(QWidget): # NOTE: If changed set self.missing to True and update self.label self.lot.currentTextChanged.connect(self.updated) - def flip_check(self, checked:bool): + def flip_check(self, checked: bool): with QSignalBlocker(self.check) as b: self.check.setChecked(checked) self.lot.setEnabled(checked) @@ -675,6 +684,7 @@ class SubmissionFormWidget(QWidget): else: self.parent().disabler.checkbox.setChecked(True) + @report_result def parse_form(self) -> Tuple[PydReagent | None, Report]: """ Pulls form info into PydReagent @@ -686,18 +696,23 @@ class SubmissionFormWidget(QWidget): if not self.lot.isEnabled(): return None, report lot = self.lot.currentText() - wanted_reagent = Reagent.query(lot=lot, role=self.reagent.role) + wanted_reagent, new = Reagent.query_or_create(lot=lot, role=self.reagent.role) # NOTE: if reagent doesn't exist in database, offer to add it (uses App.add_reagent) - if wanted_reagent is None: + logger.debug(f"Wanted reagent: {wanted_reagent}, New: {new}") + # if wanted_reagent is None: + if new: dlg = QuestionAsker(title=f"Add {lot}?", message=f"Couldn't find reagent type {self.reagent.role}: {lot} in the database.\n\nWould you like to add it?") + if dlg.exec(): - wanted_reagent = self.parent().parent().add_reagent(reagent_lot=lot, - reagent_role=self.reagent.role, - expiry=self.reagent.expiry, - name=self.reagent.name, - kit=self.extraction_kit - ) + # wanted_reagent = self.parent().parent().add_reagent(reagent_lot=lot, + # reagent_role=self.reagent.role, + # expiry=self.reagent.expiry, + # name=self.reagent.name, + # kit=self.extraction_kit + # ) + wanted_reagent = self.parent().parent().new_add_reagent(instance=wanted_reagent) + return wanted_reagent, report else: # NOTE: In this case we will have an empty reagent and the submission will fail kit integrity check @@ -707,10 +722,13 @@ class SubmissionFormWidget(QWidget): # NOTE: Since this now gets passed in directly from the parser -> pyd -> form and the parser gets the name # from the db, it should no longer be necessary to query the db with reagent/kit, but with rt name directly. rt = ReagentRole.query(name=self.reagent.role) + logger.debug(f"Reagent role: {rt}") if rt is None: rt = ReagentRole.query(kit_type=self.extraction_kit, reagent=wanted_reagent) - return PydReagent(name=wanted_reagent.name, lot=wanted_reagent.lot, role=rt.name, - expiry=wanted_reagent.expiry, missing=False), report + final = PydReagent(name=wanted_reagent.name, lot=wanted_reagent.lot, role=rt.name, + expiry=wanted_reagent.expiry.date(), missing=False) + logger.debug(f"Final Reagent: {final}") + return final, report def updated(self): """ diff --git a/src/submissions/tools/__init__.py b/src/submissions/tools/__init__.py index a85a20c..628ca8c 100644 --- a/src/submissions/tools/__init__.py +++ b/src/submissions/tools/__init__.py @@ -1032,18 +1032,19 @@ def report_result(func): def wrapper(*args, **kwargs): logger.info(f"Report result being called by {func.__name__}") output = func(*args, **kwargs) + # logger.debug(f"Function output: {output}") match output: case Report(): report = output case tuple(): - try: - report = [item for item in output if isinstance(item, Report)][0] - except IndexError: - report = None + # try: + report = next((item for item in output if isinstance(item, Report)), None) + # except IndexError: + # report = None case _: - report = None - return report - logger.info(f"Got report: {report}") + report = Report() + # return report + # logger.info(f"Got report: {report}") try: results = report.results except AttributeError: @@ -1058,6 +1059,7 @@ def report_result(func): logger.error(result.msg) if output: true_output = tuple(item for item in output if not isinstance(item, Report)) + # logger.debug(f"True output: {true_output}") if len(true_output) == 1: true_output = true_output[0] else: