Pre- pydsubmission toForm method.

This commit is contained in:
Landon Wark
2023-10-25 14:58:41 -05:00
parent 4b1f88f1d0
commit f3a7d75c6a
11 changed files with 298 additions and 115 deletions

View File

@@ -138,7 +138,7 @@ def lookup_reagent_types(ctx:Settings,
assert reagent.type != []
logger.debug(f"Looking up reagent type for {type(kit_type)} {kit_type} and {type(reagent)} {reagent}")
logger.debug(f"Kit reagent types: {kit_type.reagent_types}")
logger.debug(f"Reagent reagent types: {reagent._sa_instance_state}")
# logger.debug(f"Reagent reagent types: {reagent._sa_instance_state}")
result = list(set(kit_type.reagent_types).intersection(reagent.type))
logger.debug(f"Result: {result}")
return result[0]

View File

@@ -7,6 +7,7 @@ from sqlalchemy.orm import relationship, validates
from sqlalchemy.ext.associationproxy import association_proxy
from datetime import date
import logging
from tools import Settings, check_authorization
logger = logging.getLogger(f'submissions.{__name__}')
@@ -100,6 +101,11 @@ class KitType(Base):
map['info'] = {}
return map
@check_authorization
def save(self, ctx:Settings):
ctx.database_session.add(self)
ctx.database_session.commit()
class ReagentType(Base):
"""
Base of reagent type abstract
@@ -265,12 +271,21 @@ class Reagent(Base):
rtype = reagent_role.name
except AttributeError:
rtype = "Unknown"
try:
expiry = self.expiry.strftime("%Y-%m-%d")
except:
expiry = date.today()
return {
"name":self.name,
"type": rtype,
"lot": self.lot,
"expiry": self.expiry.strftime("%Y-%m-%d")
}
def save(self, ctx:Settings):
ctx.database_session.add(self)
ctx.database_session.commit()
class Discount(Base):
"""

View File

@@ -853,7 +853,6 @@ class WastewaterSample(BasicSample):
output_dict["submitter_id"] = output_dict['ww_full_sample_id']
return output_dict
class BacterialCultureSample(BasicSample):
"""
base of bacterial culture sample

View File

@@ -112,7 +112,8 @@ class SheetParser(object):
kit = lookup_kit_types(ctx=self.ctx, name=self.sub['extraction_kit']['value'])
allowed_reagents = [item.name for item in kit.get_reagents()]
logger.debug(f"List of reagents for comparison with allowed_reagents: {pprint.pformat(self.sub['reagents'])}")
self.sub['reagents'] = [reagent for reagent in self.sub['reagents'] if reagent['value'].type in allowed_reagents]
# self.sub['reagents'] = [reagent for reagent in self.sub['reagents'] if reagent['value'].type in allowed_reagents]
self.sub['reagents'] = [reagent for reagent in self.sub['reagents'] if reagent.type in allowed_reagents]
def to_pydantic(self) -> PydSubmission:
"""
@@ -231,8 +232,9 @@ class ReagentParser(object):
lot = df.iat[relevant[item]['lot']['row']-1, relevant[item]['lot']['column']-1]
expiry = df.iat[relevant[item]['expiry']['row']-1, relevant[item]['expiry']['column']-1]
except (KeyError, IndexError):
listo.append(dict(value=PydReagent(ctx=self.ctx, type=item.strip(), lot=None, exp=None, name=None), parsed=False))
listo.append(PydReagent(ctx=self.ctx, type=item.strip(), lot=None, exp=None, name=None, parsed=False))
continue
# If the cell is blank tell the PydReagent
if check_not_nan(lot):
parsed = True
else:
@@ -240,7 +242,7 @@ class ReagentParser(object):
# logger.debug(f"Got lot for {item}-{name}: {lot} as {type(lot)}")
lot = str(lot)
logger.debug(f"Going into pydantic: name: {name}, lot: {lot}, expiry: {expiry}, type: {item.strip()}")
listo.append(dict(value=PydReagent(ctx=self.ctx, type=item.strip(), lot=lot, exp=expiry, name=name), parsed=parsed))
listo.append(PydReagent(ctx=self.ctx, type=item.strip(), lot=lot, expiry=expiry, name=name, parsed=parsed))
logger.debug(f"Returning listo: {listo}")
return listo
@@ -387,7 +389,11 @@ class SampleParser(object):
# Set row in lookup table to blank values to prevent multipe lookups.
try:
self.lookup_table.loc[self.lookup_table['Sample #']==addition['Sample #']] = np.nan
except ValueError:
except (ValueError, KeyError):
pass
try:
self.lookup_table.loc[self.lookup_table['Well']==addition['Well']] = np.nan
except (ValueError, KeyError):
pass
logger.debug(f"Output sample dict: {sample}")
logger.debug(f"Final lookup_table: \n\n {self.lookup_table}")

View File

@@ -2,6 +2,7 @@
Contains pydantic models and accompanying validators
'''
import uuid
from PyQt6 import QtCore
from pydantic import BaseModel, field_validator, Field
from datetime import date, datetime, timedelta
from dateutil.parser import parse
@@ -18,6 +19,7 @@ from backend.db.functions import (lookup_submissions, lookup_reagent_types, look
)
from backend.db.models import *
from sqlalchemy.exc import InvalidRequestError, StatementError
from PyQt6.QtWidgets import QComboBox, QWidget, QLabel, QVBoxLayout
logger = logging.getLogger(f"submissions.{__name__}")
@@ -25,8 +27,9 @@ class PydReagent(BaseModel):
ctx: Settings
lot: str|None
type: str|None
exp: date|None
expiry: date|None
name: str|None
parsed: bool = Field(default=False)
@field_validator("type", mode='before')
@classmethod
@@ -61,7 +64,7 @@ class PydReagent(BaseModel):
return value.upper()
return value
@field_validator("exp", mode="before")
@field_validator("expiry", mode="before")
@classmethod
def enforce_date(cls, value):
if value != None:
@@ -86,7 +89,7 @@ class PydReagent(BaseModel):
else:
return values.data['type']
def toSQL(self):# -> Tuple[Reagent, dict]:
def toSQL(self) -> Tuple[Reagent, dict]:
result = None
logger.debug(f"Reagent SQL constructor is looking up type: {self.type}, lot: {self.lot}")
reagent = lookup_reagents(ctx=self.ctx, lot_number=self.lot)
@@ -113,6 +116,10 @@ class PydReagent(BaseModel):
# NOTE: this will now be done only in the reporting phase to account for potential changes in end-of-life extensions
return reagent, result
def toForm(self, parent:QWidget, extraction_kit:str) -> QComboBox:
from frontend.custom_widgets.misc import ReagentFormWidget
return ReagentFormWidget(parent=parent, reagent=self, extraction_kit=extraction_kit)
class PydSample(BaseModel, extra='allow'):
submitter_id: str
@@ -127,13 +134,6 @@ class PydSample(BaseModel, extra='allow'):
return [value]
return value
# @field_validator(column)
# @classmethod
# def column_int_to_list(cls, value):
# if isinstance(value, int):
# return [value]
# return value
def toSQL(self, ctx:Settings, submission):
result = None
self.__dict__.update(self.model_extra)
@@ -302,6 +302,22 @@ class PydSubmission(BaseModel, extra='allow'):
value['value'] = values.data['submission_type']['value']
return value
def handle_duplicate_samples(self):
submitter_ids = list(set([sample.submitter_id for sample in self.samples]))
output = []
for id in submitter_ids:
relevants = [item for item in self.samples if item.submitter_id==id]
if len(relevants) <= 1:
output += relevants
else:
rows = [item.row[0] for item in relevants]
columns = [item.column[0] for item in relevants]
dummy = relevants[0]
dummy.row = rows
dummy.column = columns
output.append(dummy)
self.samples = output
def toSQL(self):
code = 0
msg = None
@@ -380,21 +396,7 @@ class PydSubmission(BaseModel, extra='allow'):
logger.debug(f"Constructed submissions message: {msg}")
return instance, {'code':code, 'message':msg}
def handle_duplicate_samples(self):
submitter_ids = list(set([sample.submitter_id for sample in self.samples]))
output = []
for id in submitter_ids:
relevants = [item for item in self.samples if item.submitter_id==id]
if len(relevants) <= 1:
output += relevants
else:
rows = [item.row[0] for item in relevants]
columns = [item.column[0] for item in relevants]
dummy = relevants[0]
dummy.row = rows
dummy.column = columns
output.append(dummy)
self.samples = output
def toForm(self):
class PydContact(BaseModel):
@@ -447,19 +449,21 @@ class PydReagentType(BaseModel):
assoc = None
if assoc == None:
assoc = KitTypeReagentTypeAssociation(kit_type=kit, reagent_type=instance, uses=self.uses, required=self.required)
kit.kit_reagenttype_associations.append(assoc)
# kit.kit_reagenttype_associations.append(assoc)
return instance
class PydKit(BaseModel):
name: str
reagent_types: List[PydReagentType]|None
reagent_types: List[PydReagentType] = []
def toSQL(self, ctx):
result = dict(message=None, status='Information')
instance = lookup_kit_types(ctx=ctx, name=self.name)
if instance == None:
instance = KitType(name=self.name)
instance.reagent_types = [item.toSQL(ctx, instance) for item in self.reagent_types]
return instance
# instance.reagent_types = [item.toSQL(ctx, instance) for item in self.reagent_types]
[item.toSQL(ctx, instance) for item in self.reagent_types]
return instance, result