Loading openflexure_microscope/__init__.py +1 −1 Original line number Diff line number Diff line __all__ = ['Microscope', 'config', 'task', 'lock'] __all__ = ['Microscope', 'config', 'task', 'lock', 'utilities'] __version__ = "0.1.0" from .microscope import Microscope Loading openflexure_microscope/api/__init__.py +2 −0 Original line number Diff line number Diff line __all__ = ['utilities'] from . import utilities openflexure_microscope/api/app.py +18 −8 Original line number Diff line number Diff line #!/usr/bin/env python from flask import ( Flask, render_template, jsonify, send_file) Flask, jsonify, send_file) from flask.logging import default_handler from serial import SerialException from datetime import datetime Loading @@ -21,9 +20,12 @@ from openflexure_microscope.camera.capture import build_captures_from_exif from openflexure_microscope.config import USER_CONFIG_DIR from openflexure_microscope.api.v1 import blueprints import atexit import logging import sys, os import sys import os # Handle logging is_gunicorn = "gunicorn" in os.environ.get("SERVER_SOFTWARE", "") Loading Loading @@ -63,6 +65,7 @@ api_microscope = Microscope(None, None) # TODO: Offload to a thread? stored_image_list = build_captures_from_exif() # Generate API URI based on version from filename def uri(suffix, api_version, base=None): if not base: Loading Loading @@ -113,10 +116,9 @@ def attach_microscope(): logging.debug("Microscope successfully attached!") ##### WEBAPP ROUTES ###### # WEBAPP ROUTES ##### API ROUTES ###### from openflexure_microscope.api.v1 import blueprints # API ROUTES # Base routes base_blueprint = blueprints.base.construct_blueprint(api_microscope) Loading @@ -138,6 +140,7 @@ app.register_blueprint(plugin_blueprint, url_prefix=uri('/plugin', 'v1')) task_blueprint = blueprints.task.construct_blueprint(api_microscope) app.register_blueprint(task_blueprint, url_prefix=uri('/task', 'v1')) @app.route('/routes') def routes(): """ Loading @@ -145,13 +148,19 @@ def routes(): """ return jsonify(list_routes(app)) @app.route('/log') def err_log(): """ Most recent 1mb of log output """ timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") return send_file(DEFAULT_LOGFILE, as_attachment=True, attachment_filename='openflexure_microscope_{}.log'.format(timestamp)) return send_file( DEFAULT_LOGFILE, as_attachment=True, attachment_filename='openflexure_microscope_{}.log'.format(timestamp) ) # Automatically clean up microscope at exit def cleanup(): Loading @@ -166,6 +175,7 @@ def cleanup(): api_microscope.close() logging.debug("App teardown complete.") atexit.register(cleanup) if __name__ == "__main__": Loading openflexure_microscope/api/utilities.py +3 −2 Original line number Diff line number Diff line import pprint import logging from werkzeug.exceptions import BadRequest from flask import url_for class JsonPayload: def __init__(self, request): """ Loading Loading @@ -32,7 +32,8 @@ class JsonPayload: Args: key (str): JSON key to look for default: Value to return if no matching key-value pair is found. convert: Converter function. By passing a type, the value will be converted to that type. **Use with caution!** convert: Converter function. By passing a type, the value will be converted to that type. **Use with caution!** """ # If no JSON payload exists, make an empty dictionary if not self.json: Loading openflexure_microscope/api/v1/blueprints/camera/capture.py +27 −6 Original line number Diff line number Diff line from openflexure_microscope.api.utilities import gen, get_bool, JsonPayload from openflexure_microscope.api.utilities import get_bool, JsonPayload from openflexure_microscope.api.v1.views import MicroscopeView from openflexure_microscope.utilities import filter_dict Loading Loading @@ -201,7 +201,10 @@ class CaptureAPI(MicroscopeView): # If available, also add download link if capture_metadata['available']: uri_dict['uri']['download'] = '{}download/{}'.format(url_for('.capture', capture_id=capture_obj.id), capture_obj.filename) uri_dict['uri']['download'] = '{}download/{}'.format( url_for('.capture', capture_id=capture_obj.id), capture_obj.filename ) capture_metadata.update(uri_dict) Loading Loading @@ -297,7 +300,12 @@ class DownloadRedirectAPI(MicroscopeView): thumbnail = get_bool(request.args.get('thumbnail')) return redirect(url_for('.capture_download', capture_id=capture_id, filename=capture_obj.filename, thumbnail=thumbnail), code=307) return redirect(url_for( '.capture_download', capture_id=capture_id, filename=capture_obj.filename, thumbnail=thumbnail ), code=307) class DownloadAPI(MicroscopeView): Loading @@ -312,7 +320,12 @@ class DownloadAPI(MicroscopeView): # If no filename is specified, redirect to the capture's currently set filename if not filename: return redirect(url_for('capture_download', capture_id=capture_id, filename=capture_obj.filename, thumbnail=thumbnail), code=307) return redirect(url_for( 'capture_download', capture_id=capture_id, filename=capture_obj.filename, thumbnail=thumbnail ), code=307) # Download the image data using the requested filename if thumbnail: Loading Loading @@ -360,7 +373,11 @@ class MetadataRedirectAPI(MicroscopeView): if not capture_obj or not capture_obj.state['available']: return abort(404) # 404 Not Found return redirect(url_for('.metadata_download', capture_id=capture_id, filename=capture_obj.metadataname), code=307) return redirect(url_for( '.metadata_download', capture_id=capture_id, filename=capture_obj.metadataname ), code=307) class MetadataAPI(MicroscopeView): Loading @@ -373,7 +390,11 @@ class MetadataAPI(MicroscopeView): # If no filename is specified, redirect to the capture's currently set filename if not filename: return redirect(url_for('capture_download', capture_id=capture_id, filename=capture_obj.metadataname), code=307) return redirect(url_for( 'capture_download', capture_id=capture_id, filename=capture_obj.metadataname ), code=307) # Download the metadata using the requested filename data = capture_obj.yaml Loading Loading
openflexure_microscope/__init__.py +1 −1 Original line number Diff line number Diff line __all__ = ['Microscope', 'config', 'task', 'lock'] __all__ = ['Microscope', 'config', 'task', 'lock', 'utilities'] __version__ = "0.1.0" from .microscope import Microscope Loading
openflexure_microscope/api/__init__.py +2 −0 Original line number Diff line number Diff line __all__ = ['utilities'] from . import utilities
openflexure_microscope/api/app.py +18 −8 Original line number Diff line number Diff line #!/usr/bin/env python from flask import ( Flask, render_template, jsonify, send_file) Flask, jsonify, send_file) from flask.logging import default_handler from serial import SerialException from datetime import datetime Loading @@ -21,9 +20,12 @@ from openflexure_microscope.camera.capture import build_captures_from_exif from openflexure_microscope.config import USER_CONFIG_DIR from openflexure_microscope.api.v1 import blueprints import atexit import logging import sys, os import sys import os # Handle logging is_gunicorn = "gunicorn" in os.environ.get("SERVER_SOFTWARE", "") Loading Loading @@ -63,6 +65,7 @@ api_microscope = Microscope(None, None) # TODO: Offload to a thread? stored_image_list = build_captures_from_exif() # Generate API URI based on version from filename def uri(suffix, api_version, base=None): if not base: Loading Loading @@ -113,10 +116,9 @@ def attach_microscope(): logging.debug("Microscope successfully attached!") ##### WEBAPP ROUTES ###### # WEBAPP ROUTES ##### API ROUTES ###### from openflexure_microscope.api.v1 import blueprints # API ROUTES # Base routes base_blueprint = blueprints.base.construct_blueprint(api_microscope) Loading @@ -138,6 +140,7 @@ app.register_blueprint(plugin_blueprint, url_prefix=uri('/plugin', 'v1')) task_blueprint = blueprints.task.construct_blueprint(api_microscope) app.register_blueprint(task_blueprint, url_prefix=uri('/task', 'v1')) @app.route('/routes') def routes(): """ Loading @@ -145,13 +148,19 @@ def routes(): """ return jsonify(list_routes(app)) @app.route('/log') def err_log(): """ Most recent 1mb of log output """ timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") return send_file(DEFAULT_LOGFILE, as_attachment=True, attachment_filename='openflexure_microscope_{}.log'.format(timestamp)) return send_file( DEFAULT_LOGFILE, as_attachment=True, attachment_filename='openflexure_microscope_{}.log'.format(timestamp) ) # Automatically clean up microscope at exit def cleanup(): Loading @@ -166,6 +175,7 @@ def cleanup(): api_microscope.close() logging.debug("App teardown complete.") atexit.register(cleanup) if __name__ == "__main__": Loading
openflexure_microscope/api/utilities.py +3 −2 Original line number Diff line number Diff line import pprint import logging from werkzeug.exceptions import BadRequest from flask import url_for class JsonPayload: def __init__(self, request): """ Loading Loading @@ -32,7 +32,8 @@ class JsonPayload: Args: key (str): JSON key to look for default: Value to return if no matching key-value pair is found. convert: Converter function. By passing a type, the value will be converted to that type. **Use with caution!** convert: Converter function. By passing a type, the value will be converted to that type. **Use with caution!** """ # If no JSON payload exists, make an empty dictionary if not self.json: Loading
openflexure_microscope/api/v1/blueprints/camera/capture.py +27 −6 Original line number Diff line number Diff line from openflexure_microscope.api.utilities import gen, get_bool, JsonPayload from openflexure_microscope.api.utilities import get_bool, JsonPayload from openflexure_microscope.api.v1.views import MicroscopeView from openflexure_microscope.utilities import filter_dict Loading Loading @@ -201,7 +201,10 @@ class CaptureAPI(MicroscopeView): # If available, also add download link if capture_metadata['available']: uri_dict['uri']['download'] = '{}download/{}'.format(url_for('.capture', capture_id=capture_obj.id), capture_obj.filename) uri_dict['uri']['download'] = '{}download/{}'.format( url_for('.capture', capture_id=capture_obj.id), capture_obj.filename ) capture_metadata.update(uri_dict) Loading Loading @@ -297,7 +300,12 @@ class DownloadRedirectAPI(MicroscopeView): thumbnail = get_bool(request.args.get('thumbnail')) return redirect(url_for('.capture_download', capture_id=capture_id, filename=capture_obj.filename, thumbnail=thumbnail), code=307) return redirect(url_for( '.capture_download', capture_id=capture_id, filename=capture_obj.filename, thumbnail=thumbnail ), code=307) class DownloadAPI(MicroscopeView): Loading @@ -312,7 +320,12 @@ class DownloadAPI(MicroscopeView): # If no filename is specified, redirect to the capture's currently set filename if not filename: return redirect(url_for('capture_download', capture_id=capture_id, filename=capture_obj.filename, thumbnail=thumbnail), code=307) return redirect(url_for( 'capture_download', capture_id=capture_id, filename=capture_obj.filename, thumbnail=thumbnail ), code=307) # Download the image data using the requested filename if thumbnail: Loading Loading @@ -360,7 +373,11 @@ class MetadataRedirectAPI(MicroscopeView): if not capture_obj or not capture_obj.state['available']: return abort(404) # 404 Not Found return redirect(url_for('.metadata_download', capture_id=capture_id, filename=capture_obj.metadataname), code=307) return redirect(url_for( '.metadata_download', capture_id=capture_id, filename=capture_obj.metadataname ), code=307) class MetadataAPI(MicroscopeView): Loading @@ -373,7 +390,11 @@ class MetadataAPI(MicroscopeView): # If no filename is specified, redirect to the capture's currently set filename if not filename: return redirect(url_for('capture_download', capture_id=capture_id, filename=capture_obj.metadataname), code=307) return redirect(url_for( 'capture_download', capture_id=capture_id, filename=capture_obj.metadataname ), code=307) # Download the metadata using the requested filename data = capture_obj.yaml Loading