Added API route for returning API schemas

This commit is contained in:
Joel Collins 2019-06-14 17:18:13 +01:00
parent 7cb992adc4
commit e55c097a32
3 changed files with 51 additions and 7 deletions

View file

@ -1,15 +1,33 @@
from openflexure_microscope.api.v1.views import MicroscopeViewPlugin
from flask import Blueprint
from flask import Blueprint, jsonify
from openflexure_microscope.api.v1.views import MicroscopeView
import logging
import warnings
class PluginSchemaAPI(MicroscopeView):
def get(self):
"""
Return the current plugin schemas
.. :quickref: Plugin; Get schemas
"""
out = self.microscope.plugin.schemas
return jsonify(out)
def construct_blueprint(microscope_obj):
blueprint = Blueprint('plugin_blueprint', __name__)
# Create a base route to return plugin API schemas, if any exist
blueprint.add_url_rule(
'/',
view_func=PluginSchemaAPI.as_view('plugin_api_schema', microscope=microscope_obj)
)
all_routes = []
# For each plugin attached to the microscope object
@ -18,27 +36,37 @@ def construct_blueprint(microscope_obj):
# If plugin contains valid endpoints
if hasattr(plugin_obj, 'api_views') and isinstance(plugin_obj.api_views, dict):
# We'll keep a record of how each route was expanded
expanded_routes = {}
# For each defined endpoint
for view_route, view_class in plugin_obj.api_views.items():
# Remove all leading slashes from view route
while view_route[0] == '/':
view_route = view_route[1:]
cleaned_route = view_route
while cleaned_route[0] == '/':
cleaned_route = cleaned_route[1:]
# Construct a full view route from the plugin name
full_view_route = "/{}/{}".format(plugin_name, view_route)
full_view_route = "/{}/{}".format(plugin_name, cleaned_route)
logging.debug(full_view_route)
# Record how the view_route got expanded
expanded_routes[view_route] = full_view_route
# Check if endpoint name clashes
if full_view_route not in all_routes and issubclass(view_class, MicroscopeViewPlugin):
# Add route to main route dictionary
all_routes.append(full_view_route)
# Create a Python-safe name for the route
plugin_route_id = 'plugin{}'.format(full_view_route).replace('/', '_')
# Add route to the plugins blueprint
blueprint.add_url_rule(
full_view_route,
view_func=view_class.as_view(
'plugin_{}'.format(full_view_route).replace('/', '_'),
plugin_route_id,
microscope=microscope_obj,
plugin=plugin_obj
)
@ -52,9 +80,23 @@ def construct_blueprint(microscope_obj):
)
)
# If plugin includes an API schema
if hasattr(plugin_obj, 'api_schema') and isinstance(plugin_obj.api_schema, dict):
schema = plugin_obj.api_schema
# TODO: Validate schema?
schema['id'] = plugin_name
if 'forms' in schema and isinstance(schema['forms'], list):
for form in schema['forms']:
if 'route' in form and form['route'] in expanded_routes.keys():
form['route'] = expanded_routes[form['route']]
else:
logging.warn("No valid expandable route found for {}".format(form['route']))
# Store the complete schema in Microscope().plugin.schema
microscope_obj.plugin.schemas.append(schema)
else:
warnings.warn(
"No valid 'api_views' dictionary found in {}".format(plugin_obj)
)
return blueprint

View file

@ -22,5 +22,6 @@ class MicroscopeViewPlugin(MicroscopeView):
def __init__(self, microscope, plugin=None, **kwargs):
self.plugin = plugin
self.route = None
MicroscopeView.__init__(self, microscope=microscope, **kwargs)