Skip to content

Commit

Permalink
Merge pull request #62 from pblottiere/global_try_catch
Browse files Browse the repository at this point in the history
Add global try/except for requests
  • Loading branch information
pblottiere authored Jul 30, 2024
2 parents 97ec53d + 966c207 commit 721da35
Show file tree
Hide file tree
Showing 7 changed files with 624 additions and 426 deletions.
84 changes: 54 additions & 30 deletions qsa-api/qsa_api/api/instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,86 @@
from flask import current_app
from datetime import datetime

from ..utils import logger
from .utils import log_request


instances = Blueprint("instances", __name__)


@instances.get("/")
def instances_list():
monitor = current_app.config["MONITOR"]
log_request()
try:
monitor = current_app.config["MONITOR"]

if not monitor:
return {"error": "QGIS Server monitoring is not activated"}, 415
if not monitor:
return {"error": "QGIS Server monitoring is not activated"}, 415

conns = {"servers": []}
for uid in monitor.conns:
info = {}
info["id"] = uid
info["ip"] = monitor.conns[uid].ip
conns = {"servers": []}
for uid in monitor.conns:
info = {}
info["id"] = uid
info["ip"] = monitor.conns[uid].ip

d = datetime.now() - monitor.conns[uid].now
info["binded"] = int(d.total_seconds())
conns["servers"].append(info)
return conns
d = datetime.now() - monitor.conns[uid].now
info["binded"] = int(d.total_seconds())
conns["servers"].append(info)
return conns
except Exception as e:
logger().exception(str(e))
return {"error": "internal server error"}, 415


@instances.get("/<instance>")
def instances_metadata(instance):
monitor = current_app.config["MONITOR"]
log_request()
try:
monitor = current_app.config["MONITOR"]

if not monitor:
return {"error": "QGIS Server monitoring is not activated"}, 415
if not monitor:
return {"error": "QGIS Server monitoring is not activated"}, 415

if instance not in monitor.conns:
return {"error": "QGIS Server instance is not available"}, 415
if instance not in monitor.conns:
return {"error": "QGIS Server instance is not available"}, 415

return monitor.conns[instance].metadata
return monitor.conns[instance].metadata
except Exception as e:
logger().exception(str(e))
return {"error": "internal server error"}, 415


@instances.get("/<instance>/logs")
def instances_logs(instance):
monitor = current_app.config["MONITOR"]
log_request()
try:
monitor = current_app.config["MONITOR"]

if not monitor:
return {"error": "QGIS Server monitoring is not activated"}, 415
if not monitor:
return {"error": "QGIS Server monitoring is not activated"}, 415

if instance not in monitor.conns:
return {"error": "QGIS Server instance is not available"}, 415
if instance not in monitor.conns:
return {"error": "QGIS Server instance is not available"}, 415

return monitor.conns[instance].logs
return monitor.conns[instance].logs
except Exception as e:
logger().exception(str(e))
return {"error": "internal server error"}, 415


@instances.get("/<instance>/stats")
def instances_stats(instance):
monitor = current_app.config["MONITOR"]
log_request()
try:
monitor = current_app.config["MONITOR"]

if not monitor:
return {"error": "QGIS Server monitoring is not activated"}, 415
if not monitor:
return {"error": "QGIS Server monitoring is not activated"}, 415

if instance not in monitor.conns:
return {"error": "QGIS Server instance is not available"}, 415
if instance not in monitor.conns:
return {"error": "QGIS Server instance is not available"}, 415

return monitor.conns[instance].stats
return monitor.conns[instance].stats
except Exception as e:
logger().exception(str(e))
return {"error": "internal server error"}, 415
159 changes: 86 additions & 73 deletions qsa-api/qsa_api/api/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,92 +4,105 @@
from flask import Blueprint, jsonify, request
from jsonschema.exceptions import ValidationError

from ..utils import logger
from ..project import QSAProject
from ..processing import RasterCalculator, Histogram

from .utils import log_request


processing = Blueprint("processing", __name__)


@processing.post("/raster/calculator/<project>")
def raster_calculator(project: str):
schema = {
"type": "object",
"required": ["expression", "output"],
"properties": {
"expression": {"type": "string"},
"output": {"type": "string"},
},
}

data = request.get_json()
log_request()
try:
validate(data, schema)
except ValidationError as e:
return {"error": e.message}, 415

expression = data["expression"]
output = data["output"]

psql_schema = request.args.get("schema", default="public")
proj = QSAProject(project, psql_schema)

if not proj.exists():
return {"error": "Project doesn't exist"}, 415

calc = RasterCalculator(proj._qgis_project_uri, expression)
if not calc.is_valid():
return {"error": "Invalid expression"}, 415

rc, msg = calc.process(output)
if not rc:
return {
"error": f"Raster calculator failed to process expression ({msg})"
}, 415

return jsonify(rc), 201
schema = {
"type": "object",
"required": ["expression", "output"],
"properties": {
"expression": {"type": "string"},
"output": {"type": "string"},
},
}

data = request.get_json()
try:
validate(data, schema)
except ValidationError as e:
return {"error": e.message}, 415

expression = data["expression"]
output = data["output"]

psql_schema = request.args.get("schema", default="public")
proj = QSAProject(project, psql_schema)

if not proj.exists():
return {"error": "Project doesn't exist"}, 415

calc = RasterCalculator(proj._qgis_project_uri, expression)
if not calc.is_valid():
return {"error": "Invalid expression"}, 415

rc, msg = calc.process(output)
if not rc:
return {
"error": f"Raster calculator failed to process expression ({msg})"
}, 415

return jsonify(rc), 201
except Exception as e:
logger().exception(str(e))
return {"error": "internal server error"}, 415


@processing.post("/raster/histogram/<project>/<layer>")
def raster_histogram(project: str, layer: str):
schema = {
"type": "object",
"properties": {
"min": {"type": "number"},
"max": {"type": "number"},
"count": {"type": "number"},
},
}

data = request.get_json()
log_request()
try:
validate(data, schema)
except ValidationError as e:
return {"error": e.message}, 415

mini = None
if "min" in data:
mini = data["min"]

maxi = None
if "max" in data:
maxi = data["max"]

count = 1000
if "count" in data:
count = data["count"]

proj = QSAProject(project)
if proj.exists():
layer_infos = proj.layer(layer)
if layer_infos:
if "type" in layer_infos and layer_infos["type"] != "raster":
return {
"error": "Histogram is available for raster layer only"
}
histo = Histogram(proj._qgis_project_uri, layer)
return jsonify(histo.process(mini, maxi, count)), 201
schema = {
"type": "object",
"properties": {
"min": {"type": "number"},
"max": {"type": "number"},
"count": {"type": "number"},
},
}

data = request.get_json()
try:
validate(data, schema)
except ValidationError as e:
return {"error": e.message}, 415

mini = None
if "min" in data:
mini = data["min"]

maxi = None
if "max" in data:
maxi = data["max"]

count = 1000
if "count" in data:
count = data["count"]

proj = QSAProject(project)
if proj.exists():
layer_infos = proj.layer(layer)
if layer_infos:
if "type" in layer_infos and layer_infos["type"] != "raster":
return {
"error": "Histogram is available for raster layer only"
}
histo = Histogram(proj._qgis_project_uri, layer)
return jsonify(histo.process(mini, maxi, count)), 201
else:
return {"error": "Layer does not exist"}, 415
else:
return {"error": "Layer does not exist"}, 415
else:
return {"error": "Project does not exist"}, 415
return {"error": "Project does not exist"}, 415
except Exception as e:
logger().exception(str(e))
return {"error": "internal server error"}, 415
Loading

0 comments on commit 721da35

Please sign in to comment.