From 1be0ebc85f18636b7215db7e248eb88bda3bc71c Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Tue, 18 Feb 2025 17:26:35 -0600 Subject: Extract common pattern into generic function. --- uploader/genotypes/views.py | 42 ++++++++------------------ uploader/phenotypes/views.py | 38 ++++++----------------- uploader/platforms/views.py | 2 +- uploader/population/views.py | 4 +-- uploader/route_utils.py | 41 +++++++++++++++++++++++++ uploader/samples/views.py | 72 ++++++++++++-------------------------------- 6 files changed, 85 insertions(+), 114 deletions(-) create mode 100644 uploader/route_utils.py diff --git a/uploader/genotypes/views.py b/uploader/genotypes/views.py index 5105730..54c2444 100644 --- a/uploader/genotypes/views.py +++ b/uploader/genotypes/views.py @@ -12,12 +12,12 @@ from flask import (flash, from uploader.ui import make_template_renderer from uploader.oauth2.client import oauth2_post from uploader.authorisation import require_login +from uploader.route_utils import generic_select_population +from uploader.datautils import safe_int, enumerate_sequence from uploader.species.models import all_species, species_by_id from uploader.monadic_requests import make_either_error_handler from uploader.request_checks import with_species, with_population -from uploader.datautils import safe_int, order_by_family, enumerate_sequence -from uploader.population.models import (populations_by_species, - population_by_species_and_id) +from uploader.population.models import population_by_species_and_id from .models import (genotype_markers, genotype_dataset, @@ -57,34 +57,16 @@ def index(): methods=["GET"]) @require_login @with_species(redirect_uri="species.populations.genotypes.index") -def select_population(species: dict, species_id: int): +def select_population(species: dict, species_id: int):# pylint: disable=[unused-argument] """Select the population under which the genotypes go.""" - with database_connection(app.config["SQL_URI"]) as conn: - if not bool(request.args.get("population_id")): - return render_template("genotypes/select-population.html", - species=species, - populations=populations_by_species( - conn, species_id), - activelink="genotypes") - - population_id = request.args["population_id"] - if population_id == "CREATE-POPULATION": - return redirect(url_for( - "species.populations.create_population", - species_id=species["SpeciesId"], - return_to="species.populations.samples.list_genotypes")) - - population = population_by_species_and_id( - conn, species_id, request.args.get("population_id")) - if not bool(population): - flash("Invalid population selected!", "alert-danger") - return redirect(url_for( - "species.populations.genotypes.select_population", - species_id=species_id)) - - return redirect(url_for("species.populations.genotypes.list_genotypes", - species_id=species_id, - population_id=population["Id"])) + return generic_select_population( + species, + "genotypes/select-population.html", + request.args.get("population_id") or "", + "species.populations.genotypes.select_population", + "species.populations.genotypes.list_genotypes", + "genotypes", + "Invalid population selected!") @genotypesbp.route( diff --git a/uploader/phenotypes/views.py b/uploader/phenotypes/views.py index bcbb3a9..dc2df8f 100644 --- a/uploader/phenotypes/views.py +++ b/uploader/phenotypes/views.py @@ -31,12 +31,11 @@ from uploader.files import save_file#, fullpath from uploader.ui import make_template_renderer from uploader.oauth2.client import oauth2_post from uploader.authorisation import require_login +from uploader.route_utils import generic_select_population +from uploader.datautils import safe_int, enumerate_sequence from uploader.species.models import all_species, species_by_id from uploader.monadic_requests import make_either_error_handler from uploader.request_checks import with_species, with_population -from uploader.datautils import safe_int, order_by_family, enumerate_sequence -from uploader.population.models import (populations_by_species, - population_by_species_and_id) from uploader.input_validation import (encode_errors, decode_errors, is_valid_representative_name) @@ -85,31 +84,14 @@ def index(): @with_species(redirect_uri="species.populations.phenotypes.index") def select_population(species: dict, **kwargs):# pylint: disable=[unused-argument] """Select the population for your phenotypes.""" - with database_connection(app.config["SQL_URI"]) as conn: - if not bool(request.args.get("population_id")): - return render_template("phenotypes/select-population.html", - species=species, - populations=populations_by_species( - conn, species["SpeciesId"]), - activelink="phenotypes") - - population_id = request.args["population_id"] - if population_id == "CREATE-POPULATION": - return redirect(url_for( - "species.populations.create_population", - species_id=species["SpeciesId"], - return_to="species.populations.phenotypes.list_datasets")) - population = population_by_species_and_id( - conn, species["SpeciesId"], int(population_id)) - if not bool(population): - flash("No such population found!", "alert-danger") - return redirect(url_for( - "species.populations.phenotypes.select_population", - species_id=species["SpeciesId"])) - - return redirect(url_for("species.populations.phenotypes.list_datasets", - species_id=species["SpeciesId"], - population_id=population["Id"])) + return generic_select_population( + species, + "phenotypes/select-population.html", + request.args.get("population_id") or "", + "species.populations.phenotypes.select_population", + "species.populations.phenotypes.list_datasets", + "phenotypes", + "No such population found!") diff --git a/uploader/platforms/views.py b/uploader/platforms/views.py index 114c1a9..d12a9ef 100644 --- a/uploader/platforms/views.py +++ b/uploader/platforms/views.py @@ -12,7 +12,7 @@ from flask import ( from uploader.ui import make_template_renderer from uploader.authorisation import require_login from uploader.species.models import all_species, species_by_id -from uploader.datautils import safe_int, order_by_family, enumerate_sequence +from uploader.datautils import safe_int, enumerate_sequence from .models import (save_new_platform, platforms_by_species, diff --git a/uploader/population/views.py b/uploader/population/views.py index f42e547..bc233a2 100644 --- a/uploader/population/views.py +++ b/uploader/population/views.py @@ -20,11 +20,9 @@ from uploader.genotypes.views import genotypesbp from uploader.datautils import enumerate_sequence from uploader.phenotypes.views import phenotypesbp from uploader.expression_data.views import exprdatabp +from uploader.species.models import all_species, species_by_id from uploader.monadic_requests import make_either_error_handler from uploader.input_validation import is_valid_representative_name -from uploader.species.models import (all_species, - species_by_id, - order_species_by_family) from .models import (save_population, population_families, diff --git a/uploader/route_utils.py b/uploader/route_utils.py new file mode 100644 index 0000000..18eadda --- /dev/null +++ b/uploader/route_utils.py @@ -0,0 +1,41 @@ +"""Generic routing utilities.""" +from flask import flash, url_for, redirect, render_template, current_app as app + +from gn_libs.mysqldb import database_connection + +from uploader.population.models import (populations_by_species, + population_by_species_and_id) + +def generic_select_population(# pylint: disable=[too-many-arguments] + species: dict, + template: str, + population_id: str, + back_to: str, + forward_to: str, + activelink: str, + error_message: str = "No such population found!" +): + """Handles common flow for 'select population' step.""" + with database_connection(app.config["SQL_URI"]) as conn: + if not bool(population_id): + return render_template( + template, + species=species, + populations=populations_by_species(conn, species["SpeciesId"]), + activelink=activelink) + + if population_id == "CREATE-POPULATION": + return redirect(url_for( + "species.populations.create_population", + species_id=species["SpeciesId"], + return_to=forward_to)) + + population = population_by_species_and_id( + conn, species["SpeciesId"], int(population_id)) + if not bool(population): + flash(error_message, "alert-danger") + return redirect(url_for(back_to, species_id=species["SpeciesId"])) + + return redirect(url_for(forward_to, + species_id=species["SpeciesId"], + population_id=population["Id"])) diff --git a/uploader/samples/views.py b/uploader/samples/views.py index 95a6f8c..27e5d3c 100644 --- a/uploader/samples/views.py +++ b/uploader/samples/views.py @@ -16,16 +16,15 @@ from uploader import jobs from uploader.files import save_file from uploader.ui import make_template_renderer from uploader.authorisation import require_login -from uploader.request_checks import with_population from uploader.input_validation import is_integer_input -from uploader.datautils import safe_int, order_by_family, enumerate_sequence -from uploader.population.models import population_by_id, populations_by_species +from uploader.population.models import population_by_id +from uploader.route_utils import generic_select_population +from uploader.datautils import safe_int, enumerate_sequence +from uploader.species.models import all_species, species_by_id +from uploader.request_checks import with_species, with_population from uploader.db_utils import (with_db_connection, database_connection, with_redis_connection) -from uploader.species.models import (all_species, - species_by_id, - order_species_by_family) from .models import samples_by_species_and_population @@ -59,62 +58,31 @@ def index(): @samplesbp.route("/samples/select-population", methods=["GET"]) @require_login -def select_population(species_id: int): +@with_species(redirect_uri="species.populations.samples.index") +def select_population(species: dict, **kwargs):# pylint: disable=[unused-argument] """Select the population to use for the samples.""" - with database_connection(app.config["SQL_URI"]) as conn: - species = species_by_id(conn, species_id) - if not bool(species): - flash("Invalid species!", "alert-danger") - return redirect(url_for("species.populations.samples.index")) - - if not bool(request.args.get("population_id")): - return render_template("samples/select-population.html", - species=species, - populations=populations_by_species( - conn, - species_id), - activelink="samples") - - population_id = request.args["population_id"] - if population_id == "CREATE-POPULATION": - return redirect(url_for( - "species.populations.create_population", - species_id=species["SpeciesId"], - return_to="species.populations.samples.list_samples")) - - population = population_by_id(conn, request.args.get("population_id")) - if not bool(population): - flash("Population not found!", "alert-danger") - return redirect(url_for( - "species.populations.samples.select_population", - species_id=species_id)) - - return redirect(url_for("species.populations.samples.list_samples", - species_id=species_id, - population_id=population["Id"])) + return generic_select_population( + species, + "samples/select-population.html", + request.args.get("population_id") or "", + "species.populations.samples.select_population", + "species.populations.samples.list_samples", + "samples", + "Population not found!") @samplesbp.route("/populations//samples") @require_login -def list_samples(species_id: int, population_id: int): +@with_population( + species_redirect_uri="species.populations.samples.index", + redirect_uri="species.populations.samples.select_population") +def list_samples(species: dict, population: dict, **kwargs):# pylint: disable=[unused-argument] """ List the samples in a particular population and give the ability to upload new ones. """ with database_connection(app.config["SQL_URI"]) as conn: - species = species_by_id(conn, species_id) - if not bool(species): - flash("Invalid species!", "alert-danger") - return redirect(url_for("species.populations.samples.index")) - - population = population_by_id(conn, population_id) - if not bool(population): - flash("Population not found!", "alert-danger") - return redirect(url_for( - "species.populations.samples.select_population", - species_id=species_id)) - all_samples = enumerate_sequence(samples_by_species_and_population( - conn, species_id, population_id)) + conn, species["SpeciesId"], population["Id"])) total_samples = len(all_samples) offset = max(safe_int(request.args.get("from") or 0), 0) count = int(request.args.get("count") or 20) -- cgit v1.2.3