diff --git a/openflexure_microscope/api/app.py b/openflexure_microscope/api/app.py index 0a50ca38..a08d5602 100644 --- a/openflexure_microscope/api/app.py +++ b/openflexure_microscope/api/app.py @@ -19,7 +19,7 @@ from openflexure_microscope.config import ( USER_EXTENSIONS_PATH, ) -from openflexure_microscope.common.flask_labthings.labthing import LabThing +from openflexure_microscope.common.flask_labthings.quick import create_app from openflexure_microscope.common.flask_labthings.extensions import find_extensions from openflexure_microscope.api.microscope import default_microscope as api_microscope @@ -56,20 +56,16 @@ else: # Create flask app -app = Flask(__name__) -app.url_map.strict_slashes = False +app, labthing = create_app( + __name__, + prefix="/api/v2", + description="Test LabThing-based API for OpenFlexure Microscope", + title=f"OpenFlexure Microscope {api_microscope.name}", +) # Use custom JSON encoder app.json_encoder = JSONEncoder -# Enable CORS everywhere -CORS(app, resources=r"*") - -# Build a labthing -labthing = LabThing(app, prefix="/api/v2") -labthing.description = "Test LabThing-based API for OpenFlexure Microscope" -labthing.title = f"OpenFlexure Microscope {api_microscope.name}" - # Attach lab devices labthing.register_device(api_microscope, "openflexure_microscope") diff --git a/openflexure_microscope/common/flask_labthings/labthing.py b/openflexure_microscope/common/flask_labthings/labthing.py index 687b62f3..46ca187d 100644 --- a/openflexure_microscope/common/flask_labthings/labthing.py +++ b/openflexure_microscope/common/flask_labthings/labthing.py @@ -11,7 +11,6 @@ from .spec import view2path from .utilities import description_from_view from openflexure_microscope.common.labthings_core.utilities import get_docstring -from .exceptions import JSONExceptionHandler from . import EXTENSION_NAME @@ -26,7 +25,6 @@ class LabThing(object): title: str = "", description: str = "", version: str = "0.0.0", - handle_errors: bool = True, ): self.app = app @@ -45,10 +43,8 @@ class LabThing(object): self._title = title self._version = version - if handle_errors: - self.error_handler = JSONExceptionHandler() - else: - self.error_handler = None + # Store handlers for things like errors and CORS + self.handlers = {} self.spec = APISpec( title=self.title, @@ -96,10 +92,6 @@ class LabThing(object): app.extensions = getattr(app, "extensions", {}) app.extensions[EXTENSION_NAME] = self - # Register error handler if one exists - if self.error_handler: - self.error_handler.init_app(self.app) - # Add resources, if registered before tying to a Flask app if len(self.resources) > 0: for resource, urls, endpoint, kwargs in self.resources: diff --git a/openflexure_microscope/common/flask_labthings/quick.py b/openflexure_microscope/common/flask_labthings/quick.py new file mode 100644 index 00000000..67b0dc71 --- /dev/null +++ b/openflexure_microscope/common/flask_labthings/quick.py @@ -0,0 +1,41 @@ +from flask import Flask +from flask_cors import CORS + +from .labthing import LabThing +from .exceptions import JSONExceptionHandler + + +def create_app( + import_name, + prefix: str = "", + title: str = "", + description: str = "", + version: str = "0.0.0", + handle_errors: bool = True, + handle_cors: bool = True, + flask_kwargs: dict = {}, +): + app = Flask(import_name, **flask_kwargs) + app.url_map.strict_slashes = False + + # Handle CORS + if handle_cors: + cors_handler = CORS(app, resources=r"{prefix}/*") + + # Handle errors + if handle_errors: + error_handler = JSONExceptionHandler() + error_handler.init_app(app) + + # Create a LabThing + labthing = LabThing( + app, prefix=prefix, title=title, description=description, version=version + ) + + # Store references to added-in handlers + if cors_handler: + labthing.handlers["cors"] = cors_handler + if error_handler: + labthing.handlers["error"] = error_handler + + return app, labthing