From 1ff6fb43ceb22f55b94f15a6d875cdadd9d70244 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Fri, 13 Sep 2024 14:30:27 -0500 Subject: Populations: Hook population creation to auth system. --- uploader/population/models.py | 57 +++++++++++++++++++++---------------------- uploader/population/views.py | 57 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 77 insertions(+), 37 deletions(-) diff --git a/uploader/population/models.py b/uploader/population/models.py index 782bc9f..c6c77ae 100644 --- a/uploader/population/models.py +++ b/uploader/population/models.py @@ -44,33 +44,32 @@ def population_genetic_types(conn) -> tuple: return tuple(row["GeneticType"] for row in cursor.fetchall()) -def save_population(conn: mdb.Connection, population_details: dict) -> dict: +def save_population(cursor: mdb.cursors.Cursor, population_details: dict) -> dict: """Save the population details to the db.""" - with conn.cursor(cursorclass=DictCursor) as cursor: - #TODO: Handle FamilyOrder here - cursor.execute( - "INSERT INTO InbredSet(" - "InbredSetId, InbredSetName, Name, SpeciesId, FullName, " - "public, MappingMethodId, GeneticType, Family, MenuOrderId, " - "InbredSetCode, Description" - ") " - "VALUES (" - "%(InbredSetId)s, %(InbredSetName)s, %(Name)s, %(SpeciesId)s, " - "%(FullName)s, %(public)s, %(MappingMethodId)s, %(GeneticType)s, " - "%(Family)s, %(MenuOrderId)s, %(InbredSetCode)s, %(Description)s" - ")", - { - "MenuOrderId": 0, - "InbredSetId": 0, - "public": 2, - **population_details - }) - new_id = cursor.lastrowid - cursor.execute("UPDATE InbredSet SET InbredSetId=%s WHERE Id=%s", - (new_id, new_id)) - return { - **population_details, - "Id": new_id, - "InbredSetId": new_id, - "population_id": new_id - } + #TODO: Handle FamilyOrder here + cursor.execute( + "INSERT INTO InbredSet(" + "InbredSetId, InbredSetName, Name, SpeciesId, FullName, " + "public, MappingMethodId, GeneticType, Family, MenuOrderId, " + "InbredSetCode, Description" + ") " + "VALUES (" + "%(InbredSetId)s, %(InbredSetName)s, %(Name)s, %(SpeciesId)s, " + "%(FullName)s, %(public)s, %(MappingMethodId)s, %(GeneticType)s, " + "%(Family)s, %(MenuOrderId)s, %(InbredSetCode)s, %(Description)s" + ")", + { + "MenuOrderId": 0, + "InbredSetId": 0, + "public": 2, + **population_details + }) + new_id = cursor.lastrowid + cursor.execute("UPDATE InbredSet SET InbredSetId=%s WHERE Id=%s", + (new_id, new_id)) + return { + **population_details, + "Id": new_id, + "InbredSetId": new_id, + "population_id": new_id + } diff --git a/uploader/population/views.py b/uploader/population/views.py index f9041be..af0a043 100644 --- a/uploader/population/views.py +++ b/uploader/population/views.py @@ -2,7 +2,10 @@ import re import json import base64 +import traceback +from MySQLdb.cursors import DictCursor +from pymonad.either import Left, Right, Either from flask import (flash, request, url_for, @@ -15,6 +18,7 @@ from uploader.ui import make_template_renderer from uploader.authorisation import require_login from uploader.db_utils import database_connection from uploader.genotypes.views import genotypesbp +from uploader.oauth2.client import oauth2_get, oauth2_post from uploader.species.models import (all_species, species_by_id, order_species_by_family) @@ -91,7 +95,8 @@ def valid_population_name(population_name: str) -> bool: @require_login def create_population(species_id: int): """Create a new population.""" - with database_connection(app.config["SQL_URI"]) as conn: + with (database_connection(app.config["SQL_URI"]) as conn, + conn.cursor(cursorclass=DictCursor) as cursor): species = species_by_id(conn, species_id) if request.method == "GET": @@ -151,10 +156,7 @@ def create_population(species_id: int): species_id=species["SpeciesId"], error_values=values)) - # TODO: Setup auth - # 1. Create new resource in gn-auth and add this population to it - # 2. Assign active user the "resource-creator" rights to the new resource - new_population = save_population(conn, { + new_population = save_population(cursor, { "SpeciesId": species["SpeciesId"], "Name": population_name, "InbredSetName": population_fullname, @@ -166,9 +168,48 @@ def create_population(species_id: int): "GeneticType": request.form.get("population_genetic_type") or None }) - return redirect(url_for("species.populations.view_population", - species_id=species["SpeciesId"], - population_id=new_population["InbredSetId"])) + def __select_inbredset_resource_category__(categories) -> Either: + from uploader.debug import __pk__ + _cat = tuple( + category for category in categories + if category["resource_category_key"] == "inbredset-group") + if len(_cat) == 0: + return Left("Could not find appropriate category key.") + if len(_cat) > 1: + return Left( + f"Invalid categories — Expected one, got {{len(_cat)}}") + return Right(_cat[0]) + + def __handle_error__(error): + error_format = ( + "\n\nThere was an error creating the population:\n\t%s\n\n") + if issubclass(type(error), Exception): + app.logger.debug(error_format, traceback.format_exc()) + raise error + app.logger.debug(error_format, error) + raise Exception(error) + + return oauth2_get( + "auth/resource/categories" + ).then( + __select_inbredset_resource_category__ + ).then( + lambda category: oauth2_post( + "auth/resource/create", + json={ + "resource_name": f"Population — {population_name}", + "resource_category": category["resource_category_id"], + "public": "on" + }) + ).then( + lambda resp: flash("Successfully created resource.", + "alert-success") or resp + ).either( + __handle_error__, + lambda _success: redirect(url_for( + "species.populations.view_population", + species_id=species["SpeciesId"], + population_id=new_population["InbredSetId"]))) @popbp.route("//populations/", -- cgit v1.2.3