Debugging scripts import hell.

This commit is contained in:
lwark
2024-12-30 09:49:09 -06:00
parent 0808b54264
commit 482b641569
6 changed files with 67 additions and 63 deletions

View File

@@ -1,6 +1,5 @@
import sys, os import sys, os
from tools import ctx, setup_logger, check_if_app, timer from tools import ctx, setup_logger, check_if_app
from threading import Thread
# environment variable must be set to enable qtwebengine in network path # environment variable must be set to enable qtwebengine in network path
if check_if_app(): if check_if_app():
@@ -14,25 +13,9 @@ from PyQt6.QtWidgets import QApplication
from frontend.widgets.app import App from frontend.widgets.app import App
@timer
def run_startup():
for script in ctx.startup_scripts.values():
logger.info(f"Running startup script: {script.__name__}")
thread = Thread(target=script, args=(ctx,))
thread.start()
@timer
def run_teardown():
for script in ctx.teardown_scripts.values():
logger.info(f"Running teardown script: {script.__name__}")
thread = Thread(target=script, args=(ctx,))
thread.start()
if __name__ == '__main__': if __name__ == '__main__':
run_startup() ctx.run_startup()
app = QApplication(['', '--no-sandbox']) app = QApplication(['', '--no-sandbox'])
ex = App(ctx=ctx) ex = App(ctx=ctx)
app.exec() app.exec()
sys.exit(run_teardown()) sys.exit(ctx.run_teardown())

View File

@@ -8,6 +8,8 @@ import time
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from json import JSONDecodeError from json import JSONDecodeError
import logging, re, yaml, sys, os, stat, platform, getpass, inspect, json, numpy as np, pandas as pd import logging, re, yaml, sys, os, stat, platform, getpass, inspect, json, numpy as np, pandas as pd
from threading import Thread
from dateutil.easter import easter from dateutil.easter import easter
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from logging import handlers from logging import handlers
@@ -239,6 +241,27 @@ def get_first_blank_df_row(df: pd.DataFrame) -> int:
return df.shape[0] + 1 return df.shape[0] + 1
def timer(func):
"""
Performs timing of wrapped function
Args:
func (__function__): incoming function
"""
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
value = func(*args, **kwargs)
end_time = time.perf_counter()
run_time = end_time - start_time
logger.debug(f"Finished {func.__name__}() in {run_time:.4f} secs")
return value
return wrapper
# Settings # Settings
class Settings(BaseSettings, extra="allow"): class Settings(BaseSettings, extra="allow"):
@@ -421,7 +444,7 @@ class Settings(BaseSettings, extra="allow"):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.set_from_db() self.set_from_db()
# self.set_startup_teardown() self.set_scripts()
# pprint(f"User settings:\n{self.__dict__}") # pprint(f"User settings:\n{self.__dict__}")
def set_from_db(self): def set_from_db(self):
@@ -460,7 +483,38 @@ class Settings(BaseSettings, extra="allow"):
p = Path(__file__).parent.joinpath("scripts").absolute() p = Path(__file__).parent.joinpath("scripts").absolute()
subs = [item.stem for item in p.glob("*.py") if "__" not in item.stem] subs = [item.stem for item in p.glob("*.py") if "__" not in item.stem]
for sub in subs: for sub in subs:
importlib.import_module(f"tools.scripts.{sub}") mod = importlib.import_module(f"tools.scripts.{sub}")
try:
func = mod.__getattribute__(sub)
except AttributeError:
try:
func = mod.__getattribute__("script")
except AttributeError:
continue
if sub in self.startup_scripts.keys():
self.startup_scripts[sub] = func
if sub in self.teardown_scripts.keys():
self.teardown_scripts[sub] = func
@timer
def run_startup(self):
"""
Runs startup scripts.
"""
for script in self.startup_scripts.values():
logger.info(f"Running startup script: {script.__name__}")
thread = Thread(target=script, args=(ctx,))
thread.start()
@timer
def run_teardown(self):
"""
Runs teardown scripts.
"""
for script in self.teardown_scripts.values():
logger.info(f"Running teardown script: {script.__name__}")
thread = Thread(target=script, args=(ctx,))
thread.start()
@classmethod @classmethod
def get_alembic_db_path(cls, alembic_path, mode=Literal['path', 'schema', 'user', 'pass']) -> Path | str: def get_alembic_db_path(cls, alembic_path, mode=Literal['path', 'schema', 'user', 'pass']) -> Path | str:
@@ -1037,37 +1091,4 @@ def create_holidays_for_year(year: int | None = None) -> List[date]:
return sorted(holidays) return sorted(holidays)
def timer(func):
"""
Performs timing of wrapped function
Args:
func (__function__): incoming function
"""
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
value = func(*args, **kwargs)
end_time = time.perf_counter()
run_time = end_time - start_time
logger.debug(f"Finished {func.__name__}() in {run_time:.4f} secs")
return value
return wrapper
ctx = get_config(None) ctx = get_config(None)
def register_script(func):
"""Register a function as a plug-in"""
if func.__name__ in ctx.startup_scripts.keys():
ctx.startup_scripts[func.__name__] = func
if func.__name__ in ctx.teardown_scripts.keys():
ctx.teardown_scripts[func.__name__] = func
return func
ctx.set_scripts()

View File

@@ -5,11 +5,11 @@ import logging, shutil, pyodbc
from datetime import date from datetime import date
from pathlib import Path from pathlib import Path
from tools import Settings from tools import Settings
from .. import register_script # from .. import register_script
logger = logging.getLogger(f"submissions.{__name__}") logger = logging.getLogger(f"submissions.{__name__}")
@register_script # @register_script
def backup_database(ctx: Settings): def backup_database(ctx: Settings):
""" """
Copies the database into the backup directory the first time it is opened every month. Copies the database into the backup directory the first time it is opened every month.

View File

@@ -2,8 +2,8 @@
Test script for teardown_scripts Test script for teardown_scripts
""" """
from .. import register_script # from .. import register_script
@register_script # @register_script
def goodbye(ctx): def goodbye(ctx):
print("\n\nGoodbye. Thank you for using Robotics Submission Tracker.\n\n") print("\n\nGoodbye. Thank you for using Robotics Submission Tracker.\n\n")

View File

@@ -1,8 +1,8 @@
""" """
Test script for startup_scripts Test script for startup_scripts
""" """
from .. import register_script # from .. import register_script
@register_script # @register_script
def hello(ctx): def hello(ctx):
print("\n\nHello! Welcome to Robotics Submission Tracker.\n\n") print("\n\nHello! Welcome to Robotics Submission Tracker.\n\n")

View File

@@ -4,11 +4,11 @@ from datetime import datetime
from tools import Settings from tools import Settings
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from .. import register_script # from .. import register_script
logger = logging.getLogger(f"submissions.{__name__}") logger = logging.getLogger(f"submissions.{__name__}")
@register_script # @register_script
def import_irida(ctx: Settings): def import_irida(ctx: Settings):
""" """
Grabs Irida controls from secondary database. Grabs Irida controls from secondary database.