aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2024-09-25 10:11:50 -0500
committerFrederick Muriuki Muriithi2024-09-25 10:14:09 -0500
commit085df11315f5923b9b0c8a967e3dd76f69166258 (patch)
tree657fc97287e20672482b7bb71e4c10d402afc750
parentf29f79a00a7bfcaa858522a166d1639d3c9a3c40 (diff)
downloadgn-uploader-085df11315f5923b9b0c8a967e3dd76f69166258.tar.gz
Handle common checks in one place.
The checks for species and population are (before this commit) repeated over and over in different parts of the code. This commit extracts that common functionality into decorators in a new module.
-rw-r--r--uploader/request_checks.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/uploader/request_checks.py b/uploader/request_checks.py
new file mode 100644
index 0000000..a24b2f7
--- /dev/null
+++ b/uploader/request_checks.py
@@ -0,0 +1,75 @@
+"""Functions to perform common checks.
+
+These are useful for reusability, and hence maintainability of the code.
+"""
+from functools import wraps
+
+from flask import flash, url_for, redirect, current_app as app
+
+from uploader.species.models import species_by_id
+from uploader.db_utils import database_connection
+from uploader.population.models import population_by_species_and_id
+
+def with_species(redirect_uri: str):
+ """Ensure the species actually exists."""
+ def __decorator__(function):
+ @wraps(function)
+ def __with_species__(**kwargs):
+ try:
+ species_id = int(kwargs.get("species_id"))
+ if not bool(species_id):
+ flash("Expected species_id value to be present!",
+ "alert-danger")
+ return redirect(url_for(redirect_uri))
+ with database_connection(app.config["SQL_URI"]) as conn:
+ species = species_by_id(conn, species_id)
+ if not bool(species):
+ flash("Could not find species with that ID",
+ "alert-danger")
+ return redirect(url_for(redirect_uri))
+ except ValueError as _verr:
+ app.logger.debug(
+ "Exception converting value to integer: %s",
+ kwargs.get("species_id"),
+ exc_info=True)
+ flash("Expected an integer for 'species_id' value.",
+ "alert-danger")
+ return redirect(url_for(redirect_uri))
+ return function(**{**kwargs, "species": species})
+ return __with_species__
+ return __decorator__
+
+
+def with_population(species_redirect_uri: str, redirect_uri: str):
+ """Ensure the population actually exists."""
+ def __decorator__(function):
+ @wraps(function)
+ @with_species(redirect_uri=species_redirect_uri)
+ def __with_population__(**kwargs):
+ try:
+ species_id = int(kwargs["species_id"])
+ population_id = int(kwargs.get("population_id"))
+ select_population_uri = redirect(url_for(
+ redirect_uri, species_id=species_id))
+ if not bool(population_id):
+ flash("Expected population_id value to be present!",
+ "alert-danger")
+ return select_population_uri
+ with database_connection(app.config["SQL_URI"]) as conn:
+ population = population_by_species_and_id(
+ conn, species_id, population_id)
+ if not bool(population):
+ flash("Could not find population with that ID",
+ "alert-danger")
+ return select_population_uri
+ except ValueError as _verr:
+ app.logger.debug(
+ "Exception converting value to integer: %s",
+ kwargs.get("population_id"),
+ exc_info=True)
+ flash("Expected an integer for 'population_id' value.",
+ "alert-danger")
+ return select_population_uri
+ return function(**{**kwargs, "population": population})
+ return __with_population__
+ return __decorator__