From fa57e53e0fe8db4f05f04c3b9fdb286a39daff62 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Wed, 5 Nov 2025 14:47:59 -0600 Subject: Fix issues caught by linter. --- scripts/compute-phenotype-means.py | 105 ------------------------------------- scripts/compute_phenotype_means.py | 101 +++++++++++++++++++++++++++++++++++ uploader/phenotypes/views.py | 10 +--- uploader/route_utils.py | 12 +++-- 4 files changed, 110 insertions(+), 118 deletions(-) delete mode 100644 scripts/compute-phenotype-means.py create mode 100644 scripts/compute_phenotype_means.py diff --git a/scripts/compute-phenotype-means.py b/scripts/compute-phenotype-means.py deleted file mode 100644 index 3b876b7..0000000 --- a/scripts/compute-phenotype-means.py +++ /dev/null @@ -1,105 +0,0 @@ -"""Compute phenotype means.""" -import sys -import logging -from pathlib import Path -from typing import TypeVar -from argparse import Namespace, ArgumentParser - -import MySQLdb - -from gn_libs import mysqldb -from uploader import setup_modules_logging -from .load_phenotypes_to_db import update_means - -logger = logging.getLogger(__name__) -logging.basicConfig( - encoding="utf-8", - format="%(asctime)s - %(name)s - %(levelname)s — %(message)s", - level=logging.INFO) - - -def fetch_xref_id(conn: mysqldb.Connection, population_id: int) -> tuple[int, ...]: - """Fetch a population's cross-reference IDs.""" - logger.debug("Fetching the xref IDs.") - with conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) as cursor: - query = "SELECT Id FROM PublishXRef WHERE InbredSetId=%(population_id)s" - cursor.execute(query, {"population_id": population_id}) - return tuple(int(row["Id"]) for row in cursor.fetchall()) - - -def run(args) -> int: - """Run the script.""" - logger.debug("Running the script!") - with mysqldb.database_connection(args.db_uri) as mariadb_conn: - xref_ids = args.cross_ref_ids or fetch_xref_id(mariadb_conn, args.population_id) - if len(xref_ids): - update_means(mariadb_conn, - args.population_id, - xref_ids) - logger.debug("Successfully computed means for %02d phenotypes.", - len(xref_ids)) - return 0 - _reasons = ( - "no population exists with the ID '%s'", - "the population exists but it has no phenotypes linked to it yet") - logger.error( - ("No cross-reference IDs to run against. Likely causes are: " - + " OR ".join(_reasons) + "."), - args.population_id) - return 1 - - -T = TypeVar("T") -def comma_separated_list(val: str, itemstype: T = str) -> tuple[T, ...]: - """Convert val into a list of items of type 'itemstype'.""" - return tuple(itemstype(item.strip()) for item in val.split(",")) - - -def comma_separated_list_of_integers(val: str) -> tuple[int, ...]: - """Convert 'val' into list of items of type 'int'.""" - return comma_separated_list(val, int) - - -if __name__ == "__main__": - def parse_args() -> Namespace: - """Define and parse the CLI parsers accepted by this script.""" - parser = ArgumentParser( - "compute-phenotype-means", - description="Compute/Recompute the phenotype means.") - parser.add_argument("db_uri", - metavar="db-uri", - type=str, - help="MariaDB/MySQL connection URL") - parser.add_argument("jobs_db_path", - metavar="jobs-db-path", - type=Path, - help="Path to jobs' SQLite database.") - parser.add_argument("population_id", - metavar="population-id", - type=int, - help=("Identifier for the InbredSet group/" - "population to run means against.")) - ## Optional arguments - parser.add_argument( - "--log-level", - type=str, - help="Determines what is logged out.", - choices=("debug", "info", "warning", "error", "critical"), - default="info") - parser.add_argument( - "--cross-ref-ids", - type=comma_separated_list_of_integers, - help=("Provide cross-reference IDs to narrow the number of " - "phenotypes that the means are computed against."), - default=[]) - - return parser.parse_args() - - def main() -> int: - """compute-phenotype-means: Entry-point function.""" - args = parse_args() - logger.setLevel(getattr(logging, args.log_level.upper())) - setup_modules_logging(logger, ("scripts.load_phenotypes_to_db",)) - return run(args) - - sys.exit(main()) diff --git a/scripts/compute_phenotype_means.py b/scripts/compute_phenotype_means.py new file mode 100644 index 0000000..ef2fabc --- /dev/null +++ b/scripts/compute_phenotype_means.py @@ -0,0 +1,101 @@ +"""Compute phenotype means.""" +import sys +import logging +from pathlib import Path +from typing import TypeVar +from argparse import Namespace, ArgumentParser + +import MySQLdb + +from gn_libs import mysqldb +from uploader import setup_modules_logging + +from .cli_parser import add_logging_option +from .load_phenotypes_to_db import update_means + +logger = logging.getLogger(__name__) +logging.basicConfig( + encoding="utf-8", + format="%(asctime)s - %(name)s - %(levelname)s — %(message)s", + level=logging.INFO) + + +def fetch_xref_id(conn: mysqldb.Connection, population_id: int) -> tuple[int, ...]: + """Fetch a population's cross-reference IDs.""" + logger.debug("Fetching the xref IDs.") + with conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) as cursor: + query = "SELECT Id FROM PublishXRef WHERE InbredSetId=%(population_id)s" + cursor.execute(query, {"population_id": population_id}) + return tuple(int(row["Id"]) for row in cursor.fetchall()) + + +def run(args) -> int: + """Run the script.""" + logger.debug("Running the script!") + with mysqldb.database_connection(args.db_uri) as mariadb_conn: + xref_ids = args.cross_ref_ids or fetch_xref_id(mariadb_conn, args.population_id) + if len(xref_ids): + update_means(mariadb_conn, + args.population_id, + xref_ids) + logger.debug("Successfully computed means for %02d phenotypes.", + len(xref_ids)) + return 0 + _reasons = ( + f"no population exists with the ID {args.population_id}", + "the population exists but it has no phenotypes linked to it yet") + logger.error( + "No cross-reference IDs to run against. Likely causes are: %s", + " OR ".join(_reasons) + ".") + return 1 + + +T = TypeVar("T") +def comma_separated_list(val: str, itemstype: T = str) -> tuple[T, ...]: + """Convert val into a list of items of type 'itemstype'.""" + return tuple(itemstype(item.strip()) for item in val.split(",")) + + +def comma_separated_list_of_integers(val: str) -> tuple[int, ...]: + """Convert 'val' into list of items of type 'int'.""" + return comma_separated_list(val, int) + + +if __name__ == "__main__": + def parse_args() -> Namespace: + """Define and parse the CLI parsers accepted by this script.""" + parser = ArgumentParser( + "compute-phenotype-means", + description="Compute/Recompute the phenotype means.") + parser.add_argument("db_uri", + metavar="db-uri", + type=str, + help="MariaDB/MySQL connection URL") + parser.add_argument("jobs_db_path", + metavar="jobs-db-path", + type=Path, + help="Path to jobs' SQLite database.") + parser.add_argument("population_id", + metavar="population-id", + type=int, + help=("Identifier for the InbredSet group/" + "population to run means against.")) + ## Optional arguments + parser = add_logging_option(parser) + parser.add_argument( + "--cross-ref-ids", + type=comma_separated_list_of_integers, + help=("Provide cross-reference IDs to narrow the number of " + "phenotypes that the means are computed against."), + default=[]) + + return parser.parse_args() + + def main() -> int: + """compute-phenotype-means: Entry-point function.""" + args = parse_args() + logger.setLevel(getattr(logging, args.log_level.upper())) + setup_modules_logging(logger, ("scripts.load_phenotypes_to_db",)) + return run(args) + + sys.exit(main()) diff --git a/uploader/phenotypes/views.py b/uploader/phenotypes/views.py index cefa6f2..7002ccd 100644 --- a/uploader/phenotypes/views.py +++ b/uploader/phenotypes/views.py @@ -234,11 +234,6 @@ def view_phenotype(# pylint: disable=[unused-argument] population["Id"], dataset["Id"], xref_id) - def __non_empty__(value) -> bool: - if isinstance(value, str): - return value.strip() != "" - return bool(value) - return render_template( "phenotypes/view-phenotype.html", species=species, @@ -1020,14 +1015,13 @@ def load_data_success( species_redirect_uri="species.populations.phenotypes.index", population_redirect_uri="species.populations.phenotypes.select_population", redirect_uri="species.populations.phenotypes.list_datasets") -def recompute_means( +def recompute_means(# pylint: disable=[unused-argument] species: dict, population: dict, dataset: dict, **kwargs ): """Compute/Recompute the means for phenotypes in a particular population.""" - form = request.form _jobs_db = app.config["ASYNCHRONOUS_JOBS_SQLITE_DB"] _job_id = uuid.uuid4() _xref_ids = tuple(int(item.split("_")[-1]) @@ -1038,7 +1032,7 @@ def recompute_means( sys.executable, "-u", "-m", - "scripts.compute-phenotype-means", + "scripts.compute_phenotype_means", app.config["SQL_URI"], _jobs_db, str(population["Id"]), diff --git a/uploader/route_utils.py b/uploader/route_utils.py index 63b2852..53247e6 100644 --- a/uploader/route_utils.py +++ b/uploader/route_utils.py @@ -1,5 +1,5 @@ """Generic routing utilities.""" -import json +import logging from json.decoder import JSONDecodeError from flask import (flash, @@ -15,6 +15,8 @@ from uploader.datautils import base64_encode_dict, base64_decode_to_dict from uploader.population.models import (populations_by_species, population_by_species_and_id) +logger = logging.getLogger(__name__) + def generic_select_population( # pylint: disable=[too-many-arguments, too-many-positional-arguments] species: dict, @@ -56,9 +58,9 @@ def redirect_to_next(default: dict): assert "uri" in default, "You must provide at least the 'uri' value." try: next_page = base64_decode_to_dict(request.args.get("next")) - return redirect(url_for( - next_page["uri"], - **{key:value for key,value in next_page.items()})) + _uri = next_page["uri"] + next_page.pop("uri") + return redirect(url_for(_uri, **next_page)) except (TypeError, JSONDecodeError) as _err: logger.debug("We could not decode the next value '%s'", next_page, @@ -66,7 +68,7 @@ def redirect_to_next(default: dict): return redirect(url_for( default["uri"], - **{key:value for key,value in default.items()})) + **{key:value for key,value in default.items() if key != "uri"})) def build_next_argument(uri: str, **kwargs) -> str: -- cgit 1.4.1