1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
"""Endpoints handling species."""
from flask import (flash,
request,
url_for,
redirect,
Blueprint,
current_app as app)
from uploader.population import popbp
from uploader.ui import make_template_renderer
from uploader.db_utils import database_connection
from uploader.authorisation import require_login, require_token
from .models import all_species, save_species, species_by_id
speciesbp = Blueprint("species", __name__)
speciesbp.register_blueprint(popbp, url_prefix="/")
render_template = make_template_renderer("species")
@speciesbp.route("/", methods=["GET"])
def list_species():
"""List and display all the species in the database."""
with database_connection(app.config["SQL_URI"]) as conn:
return render_template("species/list-species.html",
allspecies=all_species(conn))
@speciesbp.route("/<int:species_id>", methods=["GET"])
@require_login
def view_species(species_id: int):
"""View details of a particular species and menus to act upon it."""
with database_connection(app.config["SQL_URI"]) as conn:
species = species_by_id(conn, species_id)
if bool(species):
return render_template("species/view-species.html",
species=species,
activelink="view-species")
flash("Could not find a species with the given identifier.",
"alert-danger")
return redirect(url_for("species.view_species"))
@speciesbp.route("/create", methods=["GET", "POST"])
@require_login
def create_species():
"""Create a new species."""
# We can use uniprot's API to fetch the details with something like
# https://rest.uniprot.org/taxonomy/<taxonID> e.g.
# https://rest.uniprot.org/taxonomy/6239
if request.method == "GET":
return render_template("species/create-species.html",
activelink="create-species")
with (database_connection(app.config["SQL_URI"]) as conn,
conn.cursor() as cursor):
error = False
taxon_id = request.form.get("species_taxonomy_id", "").strip() or None
common_name = request.form.get("common_name", "").strip()
if not bool(common_name):
flash("The common species name MUST be provided.", "alert-danger")
error = True
scientific_name = request.form.get("scientific_name", "").strip()
if not bool(scientific_name):
flash("The species' scientific name MUST be provided.",
"alert-danger")
error = True
parts = tuple(name.strip() for name in scientific_name.split(" "))
if len(parts) != 2 or not all(bool(name) for name in parts):
flash("The scientific name you provided is invalid.", "alert-danger")
error = True
cursor.execute(
"SELECT * FROM Species WHERE FullName=%s", (scientific_name,))
res = cursor.fetchone()
if bool(res):
flash("A species already exists with the provided scientific name.",
"alert-danger")
error = True
if bool(taxon_id):
cursor.execute(
"SELECT * FROM Species WHERE TaxonomyId=%s", (taxon_id,))
res = cursor.fetchone()
if bool(res):
flash("A species already exists with the provided scientific name.",
"alert-danger")
error = True
if error:
return redirect(url_for("species.create_species",
common_name=common_name,
scientific_name=scientific_name,
taxon_id=taxon_id))
species = save_species(conn, common_name, scientific_name, taxon_id)
flash("Species saved successfully!", "alert-success")
return redirect(url_for("species.view_species", species_id=species["species_id"]))
@speciesbp.route("/<int:species_id>/edit")
@require_login
@require_token
#def edit_species(species_id: int):
def edit_species(token: dict, species_id: int):
"""Edit a species' details.
Parameters
----------
token: A JWT token used for authorisation.
species_id: An identifier for the species being edited.
"""
app.logger.debug("======================\n"
"Token: %s\n"
"SpeciesId: %s\n"
"======================",
token, species_id)
return "Would edit the species."
|