Commit a40cb9b9 authored by Joel Collins's avatar Joel Collins
Browse files

Implemented basic threaded tasks for long-running functionality

parent 4a09727e
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -119,6 +119,10 @@ app.register_blueprint(camera_blueprint, url_prefix=uri('/camera', 'v1'))
plugin_blueprint = blueprints.plugins.construct_blueprint(api_microscope)
app.register_blueprint(plugin_blueprint, url_prefix=uri('/plugin', 'v1'))

# Task routes
task_blueprint = blueprints.task.construct_blueprint(api_microscope)
app.register_blueprint(task_blueprint, url_prefix=uri('/task', 'v1'))

# List all routes
list_routes(app)

+1 −1
Original line number Diff line number Diff line
from . import camera, stage, base, plugins
from . import camera, stage, base, plugins, task
+150 −0
Original line number Diff line number Diff line
from openflexure_microscope.api.v1.views import MicroscopeView
from flask import jsonify, abort, Blueprint

class TaskListAPI(MicroscopeView):

    def get(self):
        """
        Get list of long-running tasks.

        .. :quickref: Tasks; Get collection of tasks

        **Example response**:

        .. sourcecode:: http

          HTTP/1.1 200 OK
          Vary: Accept
          Content-Type: application/json

          [
            {
                "end_time": "2019-01-23 16-33-33", 
                "id": "db13a66787e1419bb06b1504e4d80b0c", 
                "return": [
                0.848622546386467, 
                0.6106785018091292, 
                ], 
                "start_time": "2019-01-23 16-33-13", 
                "status": "success"
            }, 
            {
                "end_time": null, 
                "id": "df46558cc8844924821bd0181881871e", 
                "return": null, 
                "start_time": "2019-01-23 16-34-54", 
                "status": "running"
            }
          ]

        :>header Accept: application/json
        :query include_unavailable: return json representations of captures that have been completely deleted

        :>header Content-Type: application/json
        """

        data = self.microscope.task.state

        return jsonify(data)

    def delete(self):
        """
        Clean list of long-running tasks (running tasks persist).

        .. :quickref: Tasks; Clean collection of tasks

        :>header Accept: application/json

        :>header Content-Type: application/json
        """

        self.microscope.task.clean()
        data = self.microscope.task.state

        return jsonify(data)

class TaskAPI(MicroscopeView):

    def get(self, task_id):
        """
        Get JSON representation of a task

        .. :quickref: Tasks; Get task

        **Example request**:

        .. sourcecode:: http

          GET /task/db13a66787e1419bb06b1504e4d80b0c/ HTTP/1.1
          Accept: application/json

        **Example response**:

        .. sourcecode:: http

          HTTP/1.1 200 OK
          Vary: Accept
          Content-Type: application/json

          {
            "end_time": "2019-01-23 16-33-33", 
            "id": "db13a66787e1419bb06b1504e4d80b0c", 
            "return": [
            0.848622546386467, 
            0.6106785018091292, 
            ], 
            "start_time": "2019-01-23 16-33-13", 
            "status": "success"
          }

        """

        task = self.microscope.task.task_from_id(task_id)

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

        # Return task state
        return jsonify(task.state)

    def delete(self, task_id):
        """
        Remove a particular task (fails if task is currently running).

        .. :quickref: Tasks; Remove a task

        :>header Accept: application/json

        :>header Content-Type: application/json
        """

        success = self.microscope.task.delete(task_id)
        
        if success:
            data = {
                'status': 'success',
                'message': 'task successfully deleted'
            }
        else:
            data = {
                'status': 'fail',
                'message': 'task could not be deleted, as it is currently running or does not exist'
            }

        return jsonify(data)

def construct_blueprint(microscope_obj):

    blueprint = Blueprint('task_blueprint', __name__)

    blueprint.add_url_rule(
        '/',
        view_func=TaskListAPI.as_view('task_list', microscope=microscope_obj)
    )

    blueprint.add_url_rule(
        '/<task_id>/',
        view_func=TaskAPI.as_view('task', microscope=microscope_obj)
    )

    return(blueprint)
+1 −8
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ except ImportError:

from .capture import CaptureObject, capture_from_dict, BASE_CAPTURE_PATH
from openflexure_microscope.config import USER_CONFIG_DIR
from openflexure_microscope.utilities import entry_by_id


def last_entry(object_list: list):
@@ -28,14 +29,6 @@ def last_entry(object_list: list):
        return None


def entry_by_id(id: str, object_list: list):
    """Return an object from a list, if <object>.id matches id argument."""
    found = None
    for o in object_list:
        if o.id == id:
            found = o
    return found


def generate_basename():
    """Return a default filename based on the capture datetime"""
+2 −0
Original line number Diff line number Diff line
class TaskDeniedException(Exception):
    pass
 No newline at end of file
Loading