Validate scan shape on the server

The scan API view now uses a schema with validation
constraints to enforce a minimum size of 1 in any dimension.
This requires better error handling in the app, which I've added.
It also needs a fix in LabThings so the error propagates correctly
This commit is contained in:
Richard Bowman 2021-02-09 09:21:56 +00:00
parent df5d0dab68
commit 792e782968
2 changed files with 16 additions and 2 deletions

View file

@ -23,7 +23,7 @@ import os
from datetime import datetime from datetime import datetime
import pkg_resources import pkg_resources
from flask import abort, send_file from flask import abort, send_file, jsonify
from flask_cors import CORS, cross_origin from flask_cors import CORS, cross_origin
from labthings import create_app from labthings import create_app
from labthings.extensions import find_extensions from labthings.extensions import find_extensions
@ -105,6 +105,19 @@ app, labthing = create_app(
# Enable CORS for some routes outside of LabThings # Enable CORS for some routes outside of LabThings
cors: CORS = CORS(app) cors: CORS = CORS(app)
# Enable correct handling of Marshmallow/Webargs validation errors
# Return validation errors as JSON
# (see https://webargs.readthedocs.io/en/latest/framework_support.html)
@app.errorhandler(422)
@app.errorhandler(400)
def handle_error(err):
headers = err.data.get("headers", None)
messages = err.data.get("messages", ["Invalid request."])
if headers:
return jsonify({"errors": messages}), err.code, headers
else:
return jsonify({"errors": messages}), err.code
# Use custom JSON encoder # Use custom JSON encoder
labthing.json_encoder = JSONEncoder labthing.json_encoder = JSONEncoder
app.json_encoder = JSONEncoder app.json_encoder = JSONEncoder

View file

@ -2,6 +2,7 @@ import datetime
import logging import logging
import time import time
import uuid import uuid
import marshmallow
from functools import reduce from functools import reduce
from typing import Dict, List, Optional, Tuple from typing import Dict, List, Optional, Tuple
@ -361,7 +362,7 @@ class ScanExtension(BaseExtension):
class TileScanArgs(FullCaptureArgs): class TileScanArgs(FullCaptureArgs):
namemode = fields.String(missing="coordinates", example="coordinates") namemode = fields.String(missing="coordinates", example="coordinates")
grid = fields.List(fields.Integer, missing=[3, 3, 3], example=[3, 3, 3]) grid = fields.List(fields.Integer(validate=marshmallow.validate.Range(min=1)), missing=[3, 3, 3], example=[3, 3, 3], )
style = fields.String(missing="raster") style = fields.String(missing="raster")
autofocus_dz = fields.Integer(missing=50) autofocus_dz = fields.Integer(missing=50)
fast_autofocus = fields.Boolean(missing=False) fast_autofocus = fields.Boolean(missing=False)