Commit 9faa05ae authored by Joel Collins's avatar Joel Collins
Browse files

Added missing API documentation

parent 4003e4e6
Loading
Loading
Loading
Loading
+36 −25
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ from openflexure_microscope.common.flask_labthings.resource import Resource
from openflexure_microscope.common.flask_labthings.utilities import (
    description_from_view,
)
from openflexure_microscope.common.flask_labthings.decorators import marshal_with
from openflexure_microscope.common.flask_labthings.decorators import marshal_with, doc_response, Tag, ThingProperty

from openflexure_microscope.common.flask_labthings.find import find_component

@@ -64,25 +64,26 @@ capture_schema = CaptureSchema()
capture_list_schema = CaptureSchema(many=True)


@ThingProperty
@Tag("captures")
class CaptureList(Resource):
    @marshal_with(CaptureSchema(many=True))
    def get(self):
        """
        List all image captures
        """

    @marshal_with(CaptureSchema(many=True))
    def get(self):
        microscope = find_component("org.openflexure.microscope")
        image_list = microscope.camera.images
        return image_list


@Tag("captures")
class CaptureResource(Resource):
    @marshal_with(CaptureSchema())
    def get(self, id):
        """
        Description of a single image capture
        """

    @marshal_with(CaptureSchema())
    def get(self, id):
        microscope = find_component("org.openflexure.microscope")
        capture_obj = microscope.camera.image_from_id(id)

@@ -92,6 +93,9 @@ class CaptureResource(Resource):
        return capture_obj

    def delete(self, id):
        """
        Delete a single image capture
        """
        microscope = find_component("org.openflexure.microscope")
        capture_obj = microscope.camera.image_from_id(id)

@@ -103,13 +107,13 @@ class CaptureResource(Resource):
        return "", 204


@Tag("captures")
class CaptureDownload(Resource):
    @doc_response(200, mimetype="image/jpeg")
    def get(self, id, filename):
        """
        Image data for a single image capture
        """

    def get(self, id, filename):

        microscope = find_component("org.openflexure.microscope")
        capture_obj = microscope.camera.image_from_id(id)

@@ -139,13 +143,12 @@ class CaptureDownload(Resource):
        return send_file(img, mimetype="image/jpeg")


@Tag("captures")
class CaptureTags(Resource):
    def get(self, id):
        """
    Tags associated with a single image capture
        Get tags associated with a single image capture
        """

    def get(self, id):

        microscope = find_component("org.openflexure.microscope")
        capture_obj = microscope.camera.image_from_id(id)

@@ -155,13 +158,16 @@ class CaptureTags(Resource):
        return jsonify(capture_obj.tags)

    def put(self, id):

        """
        Add tags to a single image capture
        """
        microscope = find_component("org.openflexure.microscope")
        capture_obj = microscope.camera.image_from_id(id)

        if not capture_obj:
            return abort(404)  # 404 Not Found

        # TODO: Replace with normal Flask request JSON thing
        data_dict = JsonResponse(request).json

        if type(data_dict) != list:
@@ -172,7 +178,9 @@ class CaptureTags(Resource):
        return jsonify(capture_obj.tags)

    def delete(self, capture_id):

        """
        Delete tags from a single image capture
        """
        microscope = find_component("org.openflexure.microscope")
        capture_obj = microscope.camera.image_from_id(id)

@@ -190,12 +198,12 @@ class CaptureTags(Resource):
        return jsonify(capture_obj.tags)


@Tag("captures")
class CaptureMetadata(Resource):
    def get(self, id):
        """
    All metadata associated with a single image capture
        Get metadata associated with a single image capture
        """

    def get(self, id):
        microscope = find_component("org.openflexure.microscope")
        capture_obj = microscope.camera.image_from_id(id)

@@ -205,6 +213,9 @@ class CaptureMetadata(Resource):
        return jsonify(capture_obj.metadata)

    def put(self, id):
        """
        Update metadata for a single image capture
        """
        microscope = find_component("org.openflexure.microscope")
        capture_obj = microscope.camera.image_from_id(id)

+12 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ from openflexure_microscope.common.labthings_core.utilities import (
from openflexure_microscope.common.flask_labthings.find import find_component
from openflexure_microscope.common.flask_labthings.resource import Resource

from openflexure_microscope.common.flask_labthings.decorators import ThingProperty, marshal_with
from openflexure_microscope.common.flask_labthings.decorators import ThingProperty, Tag

from flask import jsonify, request, abort
import logging
@@ -40,8 +40,12 @@ class SettingsProperty(Resource):
        return self.get()


@Tag("properties")
class NestedSettingsProperty(Resource):
    def get(self, route):
        """
        Show a nested section of the current microscope settings
        """
        microscope = find_component("org.openflexure.microscope")
        keys = route.split("/")

@@ -53,6 +57,9 @@ class NestedSettingsProperty(Resource):
        return jsonify(value)

    def put(self, route):
        """
        Update a nested section of the current microscope settings
        """
        microscope = find_component("org.openflexure.microscope")
        keys = route.split("/")
        payload = JsonResponse(request)
@@ -76,8 +83,12 @@ class StatusProperty(Resource):
        return jsonify(microscope.status)


@Tag("properties")
class NestedStatusProperty(Resource):
    def get(self, route):
        """
        Show a nested section of the current microscope state
        """
        microscope = find_component("org.openflexure.microscope")
        keys = route.split("/")

+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ from openflexure_microscope.common.flask_labthings.decorators import doc_respons

from flask import Response


@ThingProperty
class MjpegStream(Resource):
    """
+15 −10
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ from . import EXTENSION_NAME # TODO: Move into .names
from .names import TASK_ENDPOINT, TASK_LIST_ENDPOINT, EXTENSION_LIST_ENDPOINT
from .extensions import BaseExtension
from .utilities import description_from_view
from .spec import view2path, get_spec
from .spec import rule2path, get_spec

from .views.extensions import ExtensionList
from .views.tasks import TaskList, TaskResource
@@ -188,8 +188,8 @@ class LabThing(object):

        return decorator

    def _register_view(self, app, resource, *urls, endpoint=None, **kwargs):
        endpoint = endpoint or resource.__name__.lower()
    def _register_view(self, app, view, *urls, endpoint=None, **kwargs):
        endpoint = endpoint or view.__name__.lower()
        self.endpoints.add(endpoint)
        resource_class_args = kwargs.pop("resource_class_args", ())
        resource_class_kwargs = kwargs.pop("resource_class_kwargs", {})
@@ -199,14 +199,14 @@ class LabThing(object):
            previous_view_class = app.view_functions[endpoint].__dict__["view_class"]

            # if you override the endpoint with a different class, avoid the collision by raising an exception
            if previous_view_class != resource:
            if previous_view_class != view:
                raise ValueError(
                    "This endpoint (%s) is already set to the class %s."
                    % (endpoint, previous_view_class.__name__)
                )

        resource.endpoint = endpoint
        resource_func = resource.as_view(
        view.endpoint = endpoint
        resource_func = view.as_view(
            endpoint, *resource_class_args, **resource_class_kwargs
        )

@@ -216,15 +216,20 @@ class LabThing(object):
            # Add the url to the application or blueprint
            app.add_url_rule(rule, view_func=resource_func, **kwargs)
            # Add the resource to our API spec
            self.spec.path(**view2path(rule, resource, self.spec))
            #self.spec.path(**view2path(rule, view, self.spec))

        # TEST: Getting Flask rule objects
        flask_rules = app.url_map._rules_by_endpoint.get(endpoint)
        for flask_rule in flask_rules:
            self.spec.path(**rule2path(flask_rule, view, self.spec))

        # Handle resource groups listed in API spec
        view_spec = get_spec(resource)
        view_spec = get_spec(view)
        view_groups = view_spec.get("_groups", {})
        if "actions" in view_groups:
            self.actions[resource.endpoint] = resource
            self.actions[view.endpoint] = view
        if "properties" in view_groups:
            self.properties[resource.endpoint] = resource
            self.properties[view.endpoint] = view

    ### Utilities

+15 −4
Original line number Diff line number Diff line
from .resource import Resource
from ..resource import Resource
from apispec import APISpec
from apispec.ext.marshmallow import MarshmallowPlugin

@@ -8,9 +8,12 @@ from openflexure_microscope.common.labthings_core.utilities import (
    rupdate,
)

from .fields import Field
from ..fields import Field
from marshmallow import Schema as BaseSchema

from .paths import rule_to_path, rule_to_params

from werkzeug.routing import Rule
from collections import Mapping
from http import HTTPStatus

@@ -26,14 +29,22 @@ def get_spec(obj):
    return obj.__apispec__


def view2path(rule: str, view: Resource, spec: APISpec):
def rule2path(rule: Rule, view: Resource, spec: APISpec):
    params = {
        "path": rule,  # TODO: Validate this slightly (leading / etc)
        "path": rule_to_path(rule),
        "operations": view2operations(view, spec),
        "description": get_docstring(view),
        "summary": get_summary(view),
    }

    # Add URL arguments
    if rule.arguments:
        for op in params.get("operations").keys():
            params["operations"][op].update({
                "parameters": rule_to_params(rule)
            })

    # Add extra parameters
    if hasattr(view, "__apispec__"):
        # Recursively update params
        rupdate(params, view.__apispec__)
Loading