post documentation and code clean-up.
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
'''
|
||||
"""
|
||||
All database related operations.
|
||||
'''
|
||||
"""
|
||||
from sqlalchemy import event
|
||||
from sqlalchemy.engine import Engine
|
||||
|
||||
|
||||
@event.listens_for(Engine, "connect")
|
||||
def set_sqlite_pragma(dbapi_connection, connection_record):
|
||||
"""
|
||||
@@ -19,4 +20,5 @@ def set_sqlite_pragma(dbapi_connection, connection_record):
|
||||
cursor.execute("PRAGMA foreign_keys=ON")
|
||||
cursor.close()
|
||||
|
||||
from .models import *
|
||||
|
||||
from .models import *
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'''
|
||||
"""
|
||||
Contains all models for sqlalchemy
|
||||
'''
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import sys, logging
|
||||
from sqlalchemy import Column, INTEGER, String, JSON
|
||||
@@ -27,6 +27,7 @@ class BaseClass(Base):
|
||||
|
||||
__table_args__ = {'extend_existing': True} #: Will only add new columns
|
||||
|
||||
@classmethod
|
||||
@declared_attr
|
||||
def __tablename__(cls) -> str:
|
||||
"""
|
||||
@@ -37,6 +38,7 @@ class BaseClass(Base):
|
||||
"""
|
||||
return f"_{cls.__name__.lower()}"
|
||||
|
||||
@classmethod
|
||||
@declared_attr
|
||||
def __database_session__(cls) -> Session:
|
||||
"""
|
||||
@@ -51,6 +53,7 @@ class BaseClass(Base):
|
||||
from test_settings import ctx
|
||||
return ctx.database_session
|
||||
|
||||
@classmethod
|
||||
@declared_attr
|
||||
def __directory_path__(cls) -> Path:
|
||||
"""
|
||||
@@ -65,6 +68,7 @@ class BaseClass(Base):
|
||||
from test_settings import ctx
|
||||
return ctx.directory_path
|
||||
|
||||
@classmethod
|
||||
@declared_attr
|
||||
def __backup_path__(cls) -> Path:
|
||||
"""
|
||||
@@ -192,3 +196,4 @@ from .controls import *
|
||||
from .organizations import *
|
||||
from .kits import *
|
||||
from .submissions import *
|
||||
BasicSubmission.reagents.creator = lambda reg: SubmissionReagentAssociation(reagent=reg)
|
||||
|
||||
@@ -8,7 +8,7 @@ from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from datetime import date
|
||||
import logging, re
|
||||
from tools import check_authorization, setup_lookup, Report, Result
|
||||
from typing import List, Literal, Any
|
||||
from typing import List, Literal
|
||||
from pandas import ExcelFile
|
||||
from pathlib import Path
|
||||
from . import Base, BaseClass, Organization
|
||||
@@ -126,8 +126,9 @@ class KitType(BaseClass):
|
||||
cascade="all, delete-orphan",
|
||||
) #: Relation to SubmissionType
|
||||
|
||||
used_for = association_proxy("kit_submissiontype_associations",
|
||||
"submission_type") #: Association proxy to SubmissionTypeKitTypeAssociation
|
||||
used_for = association_proxy("kit_submissiontype_associations", "submission_type",
|
||||
creator=lambda ST: SubmissionTypeKitTypeAssociation(
|
||||
submission_type=ST)) #: Association proxy to SubmissionTypeKitTypeAssociation
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""
|
||||
@@ -375,8 +376,9 @@ class Reagent(BaseClass):
|
||||
cascade="all, delete-orphan",
|
||||
) #: Relation to SubmissionSampleAssociation
|
||||
|
||||
submissions = association_proxy("reagent_submission_associations",
|
||||
"submission") #: Association proxy to SubmissionSampleAssociation.samples
|
||||
submissions = association_proxy("reagent_submission_associations", "submission",
|
||||
creator=lambda sub: SubmissionReagentAssociation(
|
||||
submission=sub)) #: Association proxy to SubmissionSampleAssociation.samples
|
||||
|
||||
def __repr__(self):
|
||||
if self.name is not None:
|
||||
@@ -597,7 +599,9 @@ class SubmissionType(BaseClass):
|
||||
cascade="all, delete-orphan",
|
||||
) #: Association of kittypes
|
||||
|
||||
kit_types = association_proxy("submissiontype_kit_associations", "kit_type") #: Proxy of kittype association
|
||||
kit_types = association_proxy("submissiontype_kit_associations", "kit_type",
|
||||
creator=lambda kit: SubmissionTypeKitTypeAssociation(
|
||||
kit_type=kit)) #: Proxy of kittype association
|
||||
|
||||
submissiontype_equipmentrole_associations = relationship(
|
||||
"SubmissionTypeEquipmentRoleAssociation",
|
||||
@@ -605,8 +609,8 @@ class SubmissionType(BaseClass):
|
||||
cascade="all, delete-orphan"
|
||||
) #: Association of equipmentroles
|
||||
|
||||
equipment = association_proxy("submissiontype_equipmentrole_associations",
|
||||
"equipment_role") #: Proxy of equipmentrole associations
|
||||
equipment = association_proxy("submissiontype_equipmentrole_associations", "equipment_role",
|
||||
creator=lambda eq: SubmissionTypeEquipmentRoleAssociation(equipment_role=eq)) #: Proxy of equipmentrole associations
|
||||
|
||||
submissiontype_kit_rt_associations = relationship(
|
||||
"KitTypeReagentRoleAssociation",
|
||||
@@ -710,7 +714,7 @@ class SubmissionType(BaseClass):
|
||||
|
||||
Returns:
|
||||
dict: Tip locations in the excel sheet.
|
||||
"""
|
||||
"""
|
||||
output = {}
|
||||
for item in self.submissiontype_tiprole_associations:
|
||||
tmap = item.uses
|
||||
@@ -827,12 +831,13 @@ class SubmissionTypeKitTypeAssociation(BaseClass):
|
||||
submission_type = relationship(SubmissionType,
|
||||
back_populates="submissiontype_kit_associations") #: joined submission type
|
||||
|
||||
def __init__(self, kit_type=None, submission_type=None):
|
||||
def __init__(self, kit_type=None, submission_type=None,
|
||||
mutable_cost_column: int = 0.00, mutable_cost_sample: int = 0.00, constant_cost: int = 0.00):
|
||||
self.kit_type = kit_type
|
||||
self.submission_type = submission_type
|
||||
self.mutable_cost_column = 0.00
|
||||
self.mutable_cost_sample = 0.00
|
||||
self.constant_cost = 0.00
|
||||
self.mutable_cost_column = mutable_cost_column
|
||||
self.mutable_cost_sample = mutable_cost_sample
|
||||
self.constant_cost = constant_cost
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""
|
||||
@@ -1539,15 +1544,15 @@ class Process(BaseClass):
|
||||
pass
|
||||
return cls.execute_query(query=query, limit=limit)
|
||||
|
||||
|
||||
@check_authorization
|
||||
def save(self):
|
||||
super().save()
|
||||
|
||||
|
||||
class TipRole(BaseClass):
|
||||
"""
|
||||
An abstract role that a tip fills during a process
|
||||
"""
|
||||
"""
|
||||
id = Column(INTEGER, primary_key=True) #: primary key
|
||||
name = Column(String(64)) #: name of reagent type
|
||||
instances = relationship("Tips", back_populates="role",
|
||||
@@ -1564,7 +1569,7 @@ class TipRole(BaseClass):
|
||||
|
||||
def __repr__(self):
|
||||
return f"<TipRole({self.name})>"
|
||||
|
||||
|
||||
@check_authorization
|
||||
def save(self):
|
||||
super().save()
|
||||
@@ -1573,7 +1578,7 @@ class TipRole(BaseClass):
|
||||
class Tips(BaseClass):
|
||||
"""
|
||||
A concrete instance of tips.
|
||||
"""
|
||||
"""
|
||||
id = Column(INTEGER, primary_key=True) #: primary key
|
||||
role = relationship("TipRole", back_populates="instances",
|
||||
secondary=tiproles_tips) #: joined parent reagent type
|
||||
@@ -1606,7 +1611,7 @@ class Tips(BaseClass):
|
||||
|
||||
Returns:
|
||||
Tips | List[Tips]: Tips matching criteria
|
||||
"""
|
||||
"""
|
||||
query = cls.__database_session__.query(cls)
|
||||
match name:
|
||||
case str():
|
||||
@@ -1622,7 +1627,7 @@ class Tips(BaseClass):
|
||||
case _:
|
||||
pass
|
||||
return cls.execute_query(query=query, limit=limit)
|
||||
|
||||
|
||||
@check_authorization
|
||||
def save(self):
|
||||
super().save()
|
||||
@@ -1642,7 +1647,7 @@ class SubmissionTypeTipRoleAssociation(BaseClass):
|
||||
back_populates="submissiontype_tiprole_associations") #: associated submission
|
||||
tip_role = relationship(TipRole,
|
||||
back_populates="tiprole_submissiontype_associations") #: associated equipment
|
||||
|
||||
|
||||
@check_authorization
|
||||
def save(self):
|
||||
super().save()
|
||||
@@ -1651,7 +1656,7 @@ class SubmissionTypeTipRoleAssociation(BaseClass):
|
||||
class SubmissionTipsAssociation(BaseClass):
|
||||
"""
|
||||
Association between a concrete submission instance and concrete tips
|
||||
"""
|
||||
"""
|
||||
tip_id = Column(INTEGER, ForeignKey("_tips.id"), primary_key=True) #: id of associated equipment
|
||||
submission_id = Column(INTEGER, ForeignKey("_basicsubmission.id"), primary_key=True) #: id of associated submission
|
||||
submission = relationship("BasicSubmission",
|
||||
@@ -1668,5 +1673,5 @@ class SubmissionTipsAssociation(BaseClass):
|
||||
|
||||
Returns:
|
||||
dict: Values of this object
|
||||
"""
|
||||
"""
|
||||
return dict(role=self.role_name, name=self.tips.name, lot=self.tips.lot)
|
||||
|
||||
@@ -79,7 +79,7 @@ class BasicSubmission(BaseClass):
|
||||
) #: Relation to SubmissionSampleAssociation
|
||||
|
||||
samples = association_proxy("submission_sample_associations",
|
||||
"sample") #: Association proxy to SubmissionSampleAssociation.samples
|
||||
"sample", creator=lambda sample: SubmissionSampleAssociation(sample=sample)) #: Association proxy to SubmissionSampleAssociation.samples
|
||||
|
||||
submission_reagent_associations = relationship(
|
||||
"SubmissionReagentAssociation",
|
||||
@@ -853,14 +853,14 @@ class BasicSubmission(BaseClass):
|
||||
@classmethod
|
||||
def custom_sample_autofill_row(cls, sample, worksheet: Worksheet) -> int:
|
||||
"""
|
||||
_summary_
|
||||
Updates row information
|
||||
|
||||
Args:
|
||||
sample (_type_): _description_
|
||||
worksheet (Workbook): _description_
|
||||
|
||||
Returns:
|
||||
int: _description_
|
||||
int: New row number
|
||||
"""
|
||||
return None
|
||||
|
||||
@@ -1307,7 +1307,6 @@ class BacterialCulture(BasicSubmission):
|
||||
row = idx.index.to_list()[0]
|
||||
return row + 1
|
||||
|
||||
|
||||
class Wastewater(BasicSubmission):
|
||||
"""
|
||||
derivative submission type from BasicSubmission
|
||||
@@ -2053,7 +2052,6 @@ class BasicSample(BaseClass):
|
||||
dict: well location and name (sample id, organism) NOTE: keys must sync with WWSample to_sub_dict above
|
||||
"""
|
||||
# logger.debug(f"Converting {self} to dict.")
|
||||
# start = time()
|
||||
sample = {}
|
||||
sample['submitter_id'] = self.submitter_id
|
||||
sample['sample_type'] = self.sample_type
|
||||
|
||||
@@ -69,6 +69,7 @@ class App(QMainWindow):
|
||||
helpMenu = menuBar.addMenu("&Help")
|
||||
helpMenu.addAction(self.helpAction)
|
||||
helpMenu.addAction(self.docsAction)
|
||||
helpMenu.addAction(self.githubAction)
|
||||
fileMenu.addAction(self.importAction)
|
||||
methodsMenu.addAction(self.searchLog)
|
||||
methodsMenu.addAction(self.searchSample)
|
||||
@@ -103,6 +104,7 @@ class App(QMainWindow):
|
||||
self.docsAction = QAction("&Docs", self)
|
||||
self.searchLog = QAction("Search Log", self)
|
||||
self.searchSample = QAction("Search Sample", self)
|
||||
self.githubAction = QAction("Github", self)
|
||||
|
||||
def _connectActions(self):
|
||||
"""
|
||||
@@ -118,6 +120,7 @@ class App(QMainWindow):
|
||||
self.docsAction.triggered.connect(self.openDocs)
|
||||
self.searchLog.triggered.connect(self.runSearch)
|
||||
self.searchSample.triggered.connect(self.runSampleSearch)
|
||||
self.githubAction.triggered.connect(self.openGithub)
|
||||
|
||||
def showAbout(self):
|
||||
"""
|
||||
@@ -138,6 +141,14 @@ class App(QMainWindow):
|
||||
# logger.debug(f"Attempting to open {url}")
|
||||
webbrowser.get('windows-default').open(f"file://{url.__str__()}")
|
||||
|
||||
def openGithub(self):
|
||||
"""
|
||||
Opens the instructions html page
|
||||
"""
|
||||
url = "https://github.com/landowark/submissions"
|
||||
webbrowser.get('windows-default').open(url)
|
||||
|
||||
|
||||
def result_reporter(self):
|
||||
"""
|
||||
Report any anomolous results - if any - to the user
|
||||
|
||||
@@ -18,7 +18,7 @@ class EquipmentUsage(QDialog):
|
||||
def __init__(self, parent, submission: BasicSubmission) -> QDialog:
|
||||
super().__init__(parent)
|
||||
self.submission = submission
|
||||
self.setWindowTitle("Equipment Checklist")
|
||||
self.setWindowTitle(f"Equipment Checklist - {submission.rsl_plate_num}")
|
||||
self.used_equipment = self.submission.get_used_equipment()
|
||||
self.kit = self.submission.extraction_kit
|
||||
# logger.debug(f"Existing equipment: {self.used_equipment}")
|
||||
|
||||
Reference in New Issue
Block a user