Added API route for returning API schemas
This commit is contained in:
parent
7cb992adc4
commit
e55c097a32
3 changed files with 51 additions and 7 deletions
|
|
@ -1,15 +1,33 @@
|
||||||
from openflexure_microscope.api.v1.views import MicroscopeViewPlugin
|
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 logging
|
||||||
import warnings
|
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):
|
def construct_blueprint(microscope_obj):
|
||||||
|
|
||||||
blueprint = Blueprint('plugin_blueprint', __name__)
|
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 = []
|
all_routes = []
|
||||||
|
|
||||||
# For each plugin attached to the microscope object
|
# For each plugin attached to the microscope object
|
||||||
|
|
@ -18,27 +36,37 @@ def construct_blueprint(microscope_obj):
|
||||||
# If plugin contains valid endpoints
|
# If plugin contains valid endpoints
|
||||||
if hasattr(plugin_obj, 'api_views') and isinstance(plugin_obj.api_views, dict):
|
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 each defined endpoint
|
||||||
for view_route, view_class in plugin_obj.api_views.items():
|
for view_route, view_class in plugin_obj.api_views.items():
|
||||||
|
|
||||||
# Remove all leading slashes from view route
|
# Remove all leading slashes from view route
|
||||||
while view_route[0] == '/':
|
cleaned_route = view_route
|
||||||
view_route = view_route[1:]
|
while cleaned_route[0] == '/':
|
||||||
|
cleaned_route = cleaned_route[1:]
|
||||||
|
|
||||||
# Construct a full view route from the plugin name
|
# 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)
|
logging.debug(full_view_route)
|
||||||
|
|
||||||
|
# Record how the view_route got expanded
|
||||||
|
expanded_routes[view_route] = full_view_route
|
||||||
|
|
||||||
# Check if endpoint name clashes
|
# Check if endpoint name clashes
|
||||||
if full_view_route not in all_routes and issubclass(view_class, MicroscopeViewPlugin):
|
if full_view_route not in all_routes and issubclass(view_class, MicroscopeViewPlugin):
|
||||||
# Add route to main route dictionary
|
# Add route to main route dictionary
|
||||||
all_routes.append(full_view_route)
|
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
|
# Add route to the plugins blueprint
|
||||||
blueprint.add_url_rule(
|
blueprint.add_url_rule(
|
||||||
full_view_route,
|
full_view_route,
|
||||||
view_func=view_class.as_view(
|
view_func=view_class.as_view(
|
||||||
'plugin_{}'.format(full_view_route).replace('/', '_'),
|
plugin_route_id,
|
||||||
microscope=microscope_obj,
|
microscope=microscope_obj,
|
||||||
plugin=plugin_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:
|
else:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"No valid 'api_views' dictionary found in {}".format(plugin_obj)
|
"No valid 'api_views' dictionary found in {}".format(plugin_obj)
|
||||||
)
|
)
|
||||||
|
|
||||||
return blueprint
|
return blueprint
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,6 @@ class MicroscopeViewPlugin(MicroscopeView):
|
||||||
def __init__(self, microscope, plugin=None, **kwargs):
|
def __init__(self, microscope, plugin=None, **kwargs):
|
||||||
|
|
||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
|
self.route = None
|
||||||
|
|
||||||
MicroscopeView.__init__(self, microscope=microscope, **kwargs)
|
MicroscopeView.__init__(self, microscope=microscope, **kwargs)
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,8 @@ class PluginMount(object):
|
||||||
"""
|
"""
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.plugins = []
|
self.plugins = [] # List of plugin objects
|
||||||
|
self.schemas = [] # List of plugin schemas
|
||||||
logging.info("Creating plugin mount")
|
logging.info("Creating plugin mount")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue