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

Finished first batch of MethodView-based routes

parent 5fb200ee
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ function updateCaptures(response) {
        // Generate inner HTML from capture object
        html = `
        <div class="clearfix">
            <div class="left-col"><img src="${element_uri}/thumbnail"></div>
            <div class="left-col"><img src="${element_uri}/download?thumbnail=true"></div>
            <div class="right-col"> 
                <b>${element.file}</b><br>
                <a href="${element_uri}/download" target="_blank">View</a> <a href="${element_uri}/download?as_attachment=true">Download</a> Delete <a href="${element_uri}/" target="_blank">JSON</a>
+106 −86
Original line number Diff line number Diff line
@@ -69,18 +69,37 @@ class MicroscopeView(MethodView):
        microscope object passed as an argument.
        """
        self.microscope = microscope
        MethodView.__init__(self)

# Test method
class TestAPI(MicroscopeView):

    def get(self):
        """
        Get method for my cool new MethodView
        """
        return jsonify(self.microscope.state)

    def post(self):
        """
        Post method for my cool new MethodView
        """
        return jsonify(request.get_json())

app.add_url_rule('/test', view_func=TestAPI.as_view('test', microscope=microscope))

# Define API routes

# Basic views


class StreamAPI(MicroscopeView):
    def get(self):
        """
        Video streaming route. Put this in the src attribute of an img tag.
        """
        # Restart stream worker thread
        microscope.camera.start_worker()
        self.microscope.camera.start_worker()

        return Response(
            gen(self.microscope.camera),
@@ -89,23 +108,30 @@ class StreamAPI(MicroscopeView):
app.add_url_rule(uri('/stream'), view_func=StreamAPI.as_view('stream', microscope=microscope))


@app.route(uri('/state'))
def state():
    """Return JSONified microscope state"""
    global microscope
class StateAPI(MicroscopeView):
    def get(self):
        """
        Return JSONified microscope state.
        """
        return jsonify(self.microscope.state)

app.add_url_rule(uri('/state'), view_func=StateAPI.as_view('state', microscope=microscope))

    return jsonify(microscope.state)

# Positioning routes

@app.route(uri('/position'), methods=['GET', 'POST', 'PUT'])
def position():
class PositionAPI(MicroscopeView):

    def get(self):
        """
    Set and get the microscope stage position
        Get current position
        """
    global microscope
        return jsonify(self.microscope.state['position'])

    if request.method == 'POST' or request.method == 'PUT':
    def post(self):
        """
        Update current position
        """
        # Get payload
        state = parse_payload(request)
        logging.debug(state)
@@ -118,7 +144,7 @@ def position():
            # Get coordinates from payload
            for axis, key in enumerate(['x', 'y', 'z']):
                if key in state:
                    position[axis] = int(state[key]-microscope.stage.position[axis])
                    position[axis] = int(state[key]-self.microscope.stage.position[axis])

        else:
            # Get coordinates from payload
@@ -139,21 +165,60 @@ def position():
                    response = {'error': 'Cannot move to absolute position beyond the safeguard limit.'}
                    return jsonify(response), 400

        microscope.stage.move_rel(position)
        self.microscope.stage.move_rel(position)

        return jsonify(self.microscope.state['position'])

    return jsonify(microscope.state['position'])
app.add_url_rule(uri('/position'), view_func=PositionAPI.as_view('position', microscope=microscope))


# Capture routes
class CaptureAPI(MicroscopeView):

@app.route(uri('/capture/'), methods=['GET', 'POST', 'PUT'])
def capture():
    """Return JSONified microscope state"""
    global microscope
    def get(self, capture_id):
        """
        Get list of image captures
        """
        if not capture_id:
            include_unavailable = get_bool(request.args.get('include_unavailable'))

    if request.method == 'POST' or request.method == 'PUT':
            if include_unavailable:
                captures = [image.metadata for image in self.microscope.camera.images if image.metadata['available']]
            else:
                captures = [image.metadata for image in self.microscope.camera.images]

            return jsonify(captures)
        else:
            print(capture_id)
            capture_obj = microscope.camera.image_from_id(capture_id)

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

            # Get capture metadata
            capture_metadata = capture_obj.metadata

            # Add API routes to returned metadata
            uri_dict = {
                'uri': {'metadata': uri('/capture/{}/'.format(capture_id))}
            }

            # If available, also add download link
            if capture_metadata['available']:
                uri_dict['uri']['download'] = uri('/capture/{}/download'.format(capture_id))

            capture_metadata.update(uri_dict)

            return jsonify(capture_metadata)

    def delete(self, capture_id):
        return jsonify({"error": "not yet implemented"})

    def post(self):
        """
        Create a new image capture
        """
        state = parse_payload(request)
        print(state)

        if 'filename' in state:
            filename = state['filename']
@@ -178,7 +243,7 @@ def capture():
        else:
            resize = None

        capture_obj = microscope.camera.capture(
        capture_obj = self.microscope.camera.capture(
            write_to_file=True,  # Always write data to disk when using API
            keep_on_disk=keep_on_disk,
            use_video_port=use_video_port,
@@ -187,85 +252,40 @@ def capture():

        return jsonify(capture_obj.metadata)

    else:  # GET requests
        include_unavailable = get_bool(request.args.get('include_unavailable'))

        if include_unavailable:
            captures = [image for image in microscope.camera.images if image.metadata['available']]
        else:
            captures = microscope.camera.images

        metadata_array = [capture.metadata for capture in captures]

        return jsonify(metadata_array)


@app.route(uri('/capture/<capture_uuid>/'), methods=['GET', 'DELETE'])
def get_capture(capture_uuid):
    """Return JSONified capture by UUID"""
    global microscope

    print(capture_uuid)
    capture_obj = microscope.camera.image_from_id(capture_uuid)

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

    # Get capture metadata
    capture_metadata = capture_obj.metadata

    # Add API routes to returned metadata
    uri_dict = {
        'uri': {'metadata': uri('/capture/{}/'.format(capture_uuid))}
    }

    # If available, also add download link
    if capture_metadata['available']:
        uri_dict['uri']['download'] = uri('/capture/{}/download'.format(capture_uuid))

    capture_metadata.update(uri_dict)

    if request.method == 'DELETE':
        print("DELETE NOT YET IMPLEMENETED")
        return jsonify(capture_metadata)

    else:  # GET requests
        return jsonify(capture_metadata)
capture_view = CaptureAPI.as_view('capture', microscope=microscope)
app.add_url_rule(uri('/capture/'), defaults={'capture_id': None}, view_func=capture_view, methods=['GET',])
app.add_url_rule(uri('/capture/<capture_id>/'), view_func=capture_view, methods=['GET', 'DELETE'])
app.add_url_rule(uri('/capture/'), view_func=capture_view, methods=['POST',])


@app.route(uri('/capture/<capture_uuid>/download'), methods=['GET'])
def download_capture(capture_uuid):
    """Return capture file by UUID"""
    global microscope

    print(capture_uuid)
    capture_obj = microscope.camera.image_from_id(capture_uuid)
# Capture download routes
class CaptureDlAPI(MicroscopeView):
    def get(self, capture_id):
        """
        Return image data for a capture.
        """
        print(capture_id)
        capture_obj = microscope.camera.image_from_id(capture_id)

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

        as_attachment = get_bool(request.args.get('as_attachment'))
        thumbnail = get_bool(request.args.get('thumbnail'))

        if thumbnail:
            img = capture_obj.thumbnail
        else:
            img = capture_obj.data

        return send_file(
        capture_obj.data,
            img,
            mimetype='image/jpeg',
            as_attachment=as_attachment,
            attachment_filename=capture_obj.filename)

@app.route(uri('/capture/<capture_uuid>/thumbnail'), methods=['GET'])
def thumb_capture(capture_uuid):
    """Return capture thumbnail by UUID"""
    global microscope
app.add_url_rule(uri('/capture/<capture_id>/download/'), view_func=CaptureDlAPI.as_view('capture_download', microscope=microscope))

    print(capture_uuid)
    capture_obj = microscope.camera.image_from_id(capture_uuid)

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

    return send_file(
        capture_obj.thumbnail,
        mimetype='image/jpeg')

if __name__ == "__main__":
    app.run(host='0.0.0.0', port="5000", threaded=True, debug=True, use_reloader=False)