"""Views for the genotypes.""" from flask import (flash, request, url_for, redirect, Blueprint, render_template, current_app as app) from uploader.authorisation import require_login from uploader.db_utils import database_connection from uploader.species.models import all_species, species_by_id 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 .models import (genotype_markers, genotype_markers_count, genocode_by_population) genotypesbp = Blueprint("genotypes", __name__) @genotypesbp.route("populations/genotypes", methods=["GET"]) @require_login def index(): """Direct entry-point for genotypes.""" with database_connection(app.config["SQL_URI"]) as conn: if not bool(request.args.get("species_id")): return render_template("genotypes/index.html", species=order_by_family(all_species(conn)), activelink="genotypes") species = species_by_id(conn, request.args.get("species_id")) if not bool(species): flash(f"Could not find species with ID '{request.args.get('species_id')}'!", "alert-danger") return redirect(url_for("species.populations.genotypes.index")) return redirect(url_for("species.populations.genotypes.select_population", species_id=species["SpeciesId"])) @genotypesbp.route("//populations/genotypes/select-population", methods=["GET"]) @require_login def select_population(species_id: int): """Select the population under which the genotypes go.""" with database_connection(app.config["SQL_URI"]) as conn: species = species_by_id(conn, species_id) if not bool(species): flash("Invalid species provided!", "alert-danger") return redirect(url_for("species.populations.genotypes.index")) if not bool(request.args.get("population_id")): return render_template("genotypes/select-population.html", species=species, populations=order_by_family( populations_by_species(conn, species_id), order_key="FamilyOrder"), activelink="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"])) @genotypesbp.route( "//populations//genotypes", methods=["GET"]) @require_login def list_genotypes(species_id: int, population_id: int): """List genotype details for species and population.""" with database_connection(app.config["SQL_URI"]) as conn: species = species_by_id(conn, species_id) if not bool(species): flash("Invalid species provided!", "alert-danger") return redirect(url_for("species.populations.genotypes.index")) population = population_by_species_and_id( conn, species_id, 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 render_template("genotypes/list-genotypes.html", species=species, population=population, genocode=genocode_by_population( conn, population_id), total_markers=genotype_markers_count( conn, species_id), activelink="list-genotypes") @genotypesbp.route("//genotypes/list-markers", methods=["GET"]) @require_login def list_markers(species_id: int): """List a species' genetic markers.""" with database_connection(app.config["SQL_URI"]) as conn: species = species_by_id(conn, species_id) if not bool(species): flash("Invalid species provided!", "alert-danger") return redirect(url_for("species.populations.genotypes.index")) start_from = safe_int(request.args.get("start_from") or 0) if start_from < 0: start_from = 0 count = safe_int(request.args.get("count") or 20) markers = enumerate_sequence( genotype_markers(conn, species_id, offset=start_from, limit=count), start=start_from+1) return render_template("genotypes/list-markers.html", species=species, total_markers=genotype_markers_count( conn, species_id), start_from=start_from, count=count, markers=markers, activelink="list-markers")