Pre-refactor

This commit is contained in:
Landon Wark
2023-10-13 09:26:12 -05:00
parent 957edb814a
commit 80d77117e1
6 changed files with 41 additions and 16 deletions

View File

@@ -1,3 +1,4 @@
- [x] Change 'check_is_power_user' to decorator.
- [x] Drag and drop files into submission form area? - [x] Drag and drop files into submission form area?
- [ ] Get info for controls into their sample hitpicks. - [ ] Get info for controls into their sample hitpicks.
- [x] Move submission-type specific parser functions into class methods in their respective models. - [x] Move submission-type specific parser functions into class methods in their respective models.

View File

@@ -2,7 +2,7 @@
Used to construct models from input dictionaries. Used to construct models from input dictionaries.
''' '''
from getpass import getuser from getpass import getuser
from tools import Settings, RSLNamer, check_regex_match from tools import Settings, RSLNamer, check_regex_match, check_authorization, massage_common_reagents
from .. import models from .. import models
from .lookups import * from .lookups import *
import logging import logging
@@ -190,6 +190,7 @@ def construct_samples(ctx:Settings, instance:models.BasicSubmission, samples:Lis
continue continue
return instance return instance
@check_authorization
def construct_kit_from_yaml(ctx:Settings, kit_dict:dict) -> dict: def construct_kit_from_yaml(ctx:Settings, kit_dict:dict) -> dict:
""" """
Create and store a new kit in the database based on a .yml file Create and store a new kit in the database based on a .yml file
@@ -197,16 +198,16 @@ def construct_kit_from_yaml(ctx:Settings, kit_dict:dict) -> dict:
Args: Args:
ctx (Settings): Context object passed down from frontend ctx (Settings): Context object passed down from frontend
exp (dict): Experiment dictionary created from yaml file kit_dict (dict): Experiment dictionary created from yaml file
Returns: Returns:
dict: a dictionary containing results of db addition dict: a dictionary containing results of db addition
""" """
from tools import check_is_power_user, massage_common_reagents # from tools import check_is_power_user, massage_common_reagents
# Don't want just anyone adding kits # Don't want just anyone adding kits
if not check_is_power_user(ctx=ctx): # if not check_is_power_user(ctx=ctx):
logger.debug(f"{getuser()} does not have permission to add kits.") # logger.debug(f"{getuser()} does not have permission to add kits.")
return {'code':1, 'message':"This user does not have permission to add kits.", "status":"warning"} # return {'code':1, 'message':"This user does not have permission to add kits.", "status":"warning"}
submission_type = lookup_submission_type(ctx=ctx, name=kit_dict['used_for']) submission_type = lookup_submission_type(ctx=ctx, name=kit_dict['used_for'])
logger.debug(f"Looked up submission type: {kit_dict['used_for']} and got {submission_type}") logger.debug(f"Looked up submission type: {kit_dict['used_for']} and got {submission_type}")
kit = models.KitType(name=kit_dict["kit_name"]) kit = models.KitType(name=kit_dict["kit_name"])

View File

@@ -258,4 +258,3 @@ def get_polymorphic_subclass(base:object, polymorphic_identity:str|None=None):
logger.error(f"Could not get polymorph {polymorphic_identity} of {base} due to {e}") logger.error(f"Could not get polymorph {polymorphic_identity} of {base} due to {e}")
return base return base

View File

@@ -294,6 +294,19 @@ class BasicSubmission(Base):
Workbook: updated workbook Workbook: updated workbook
""" """
return input_excel return input_excel
@classmethod
def enforce_naming_schema(cls, input_str:str) -> str:
"""
Used to ensure proper custom naming of submission.
Args:
input_str (str): name parsed by default parser
Returns:
str: custom parser output.
"""
return input_str
# Below are the custom submission types # Below are the custom submission types

View File

@@ -2,7 +2,7 @@
Contains pydantic models and accompanying validators Contains pydantic models and accompanying validators
''' '''
import uuid import uuid
from pydantic import BaseModel, field_validator, Extra, Field from pydantic import BaseModel, field_validator, Field
from datetime import date, datetime from datetime import date, datetime
from dateutil.parser import parse from dateutil.parser import parse
from dateutil.parser._parser import ParserError from dateutil.parser._parser import ParserError
@@ -74,7 +74,7 @@ class PydReagent(BaseModel):
class PydSubmission(BaseModel, extra=Extra.allow): class PydSubmission(BaseModel, extra='allow'):
ctx: Settings ctx: Settings
filepath: Path filepath: Path
submission_type: dict|None submission_type: dict|None

View File

@@ -6,7 +6,6 @@ import re
import numpy as np import numpy as np
import logging import logging
import pandas as pd import pandas as pd
from datetime import datetime
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
import yaml import yaml
import sys, os, stat, platform, getpass import sys, os, stat, platform, getpass
@@ -18,6 +17,7 @@ from sqlalchemy import create_engine
from pydantic import field_validator from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
from typing import Any, Tuple from typing import Any, Tuple
from datetime import datetime
logger = logging.getLogger(f"submissions.{__name__}") logger = logging.getLogger(f"submissions.{__name__}")
@@ -133,18 +133,21 @@ def massage_common_reagents(reagent_name:str):
reagent_name = "molecular_grade_water" reagent_name = "molecular_grade_water"
reagent_name = reagent_name.replace("µ", "u") reagent_name = reagent_name.replace("µ", "u")
return reagent_name return reagent_name
class RSLNamer(object): class RSLNamer(object):
""" """
Object that will enforce proper formatting on RSL plate names. Object that will enforce proper formatting on RSL plate names.
""" """
def __init__(self, ctx, instr:str, sub_type:str|None=None): def __init__(self, ctx, instr:str, sub_type:str|None=None):
from backend.db.functions import get_polymorphic_subclass
from backend.db.models import BasicSubmission
self.ctx = ctx self.ctx = ctx
self.submission_type = sub_type self.submission_type = sub_type
self.retrieve_rsl_number(in_str=instr) self.retrieve_rsl_number(in_str=instr)
if self.submission_type != None: if self.submission_type != None:
parser = getattr(self, f"enforce_{self.submission_type.replace(' ', '_').lower()}") custom_enforcer = get_polymorphic_subclass(BasicSubmission, self.submission_type).enforce_naming_schema
parser() # parser = getattr(self, f"enforce_{self.submission_type.replace(' ', '_').lower()}")
# parser()
self.parsed_name = self.parsed_name.replace("_", "-") self.parsed_name = self.parsed_name.replace("_", "-")
def retrieve_rsl_number(self, in_str:str|Path): def retrieve_rsl_number(self, in_str:str|Path):
@@ -220,8 +223,6 @@ class RSLNamer(object):
repeat = "" repeat = ""
self.parsed_name = re.sub(r"(-\dR)\d?", rf"\1 {repeat}", self.parsed_name).replace(" ", "") self.parsed_name = re.sub(r"(-\dR)\d?", rf"\1 {repeat}", self.parsed_name).replace(" ", "")
def enforce_bacterial_culture(self): def enforce_bacterial_culture(self):
""" """
Uses regex to enforce proper formatting of bacterial culture samples Uses regex to enforce proper formatting of bacterial culture samples
@@ -588,6 +589,7 @@ def jinja_template_loading():
def check_is_power_user(ctx:Settings) -> bool: def check_is_power_user(ctx:Settings) -> bool:
""" """
Check to ensure current user is in power users list. Check to ensure current user is in power users list.
NOTE: Depreciated in favour of 'check_authorization' below.
Args: Args:
ctx (dict): settings passed down from gui. ctx (dict): settings passed down from gui.
@@ -604,6 +606,16 @@ def check_is_power_user(ctx:Settings) -> bool:
check = False check = False
return check return check
def check_authorization(func):
def wrapper(*args, **kwargs):
logger.debug(f"Checking authorization")
if getpass.getuser() in kwargs['ctx'].power_users:
return func(*args, **kwargs)
else:
logger.error(f"User {getpass.getuser()} is not authorized for this function.")
return dict(code=1, message="This user does not have permission for this function.", status="warning")
return wrapper
def check_if_app(ctx:Settings=None) -> bool: def check_if_app(ctx:Settings=None) -> bool:
""" """
Checks if the program is running from pyinstaller compiled Checks if the program is running from pyinstaller compiled
@@ -636,4 +648,3 @@ def convert_well_to_row_column(input_str:str) -> Tuple[int, int]:
except IndexError: except IndexError:
return None, None return None, None
return row, column return row, column