Finished first batch of MethodView-based routes
This commit is contained in:
parent
5fb200eefe
commit
a274c561e7
2 changed files with 118 additions and 98 deletions
|
|
@ -67,7 +67,7 @@ function updateCaptures(response) {
|
||||||
// Generate inner HTML from capture object
|
// Generate inner HTML from capture object
|
||||||
html = `
|
html = `
|
||||||
<div class="clearfix">
|
<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">
|
<div class="right-col">
|
||||||
<b>${element.file}</b><br>
|
<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>
|
<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>
|
||||||
|
|
|
||||||
|
|
@ -69,18 +69,37 @@ class MicroscopeView(MethodView):
|
||||||
microscope object passed as an argument.
|
microscope object passed as an argument.
|
||||||
"""
|
"""
|
||||||
self.microscope = microscope
|
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
|
# Define API routes
|
||||||
|
|
||||||
# Basic views
|
# Basic views
|
||||||
|
|
||||||
|
|
||||||
class StreamAPI(MicroscopeView):
|
class StreamAPI(MicroscopeView):
|
||||||
def get(self):
|
def get(self):
|
||||||
"""
|
"""
|
||||||
Video streaming route. Put this in the src attribute of an img tag.
|
Video streaming route. Put this in the src attribute of an img tag.
|
||||||
"""
|
"""
|
||||||
# Restart stream worker thread
|
# Restart stream worker thread
|
||||||
microscope.camera.start_worker()
|
self.microscope.camera.start_worker()
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
gen(self.microscope.camera),
|
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.add_url_rule(uri('/stream'), view_func=StreamAPI.as_view('stream', microscope=microscope))
|
||||||
|
|
||||||
|
|
||||||
@app.route(uri('/state'))
|
class StateAPI(MicroscopeView):
|
||||||
def state():
|
def get(self):
|
||||||
"""Return JSONified microscope state"""
|
"""
|
||||||
global microscope
|
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
|
# Positioning routes
|
||||||
|
|
||||||
@app.route(uri('/position'), methods=['GET', 'POST', 'PUT'])
|
class PositionAPI(MicroscopeView):
|
||||||
def position():
|
|
||||||
"""
|
|
||||||
Set and get the microscope stage position
|
|
||||||
"""
|
|
||||||
global microscope
|
|
||||||
|
|
||||||
if request.method == 'POST' or request.method == 'PUT':
|
def get(self):
|
||||||
|
"""
|
||||||
|
Get current position
|
||||||
|
"""
|
||||||
|
return jsonify(self.microscope.state['position'])
|
||||||
|
|
||||||
|
def post(self):
|
||||||
|
"""
|
||||||
|
Update current position
|
||||||
|
"""
|
||||||
# Get payload
|
# Get payload
|
||||||
state = parse_payload(request)
|
state = parse_payload(request)
|
||||||
logging.debug(state)
|
logging.debug(state)
|
||||||
|
|
@ -118,7 +144,7 @@ def position():
|
||||||
# Get coordinates from payload
|
# Get coordinates from payload
|
||||||
for axis, key in enumerate(['x', 'y', 'z']):
|
for axis, key in enumerate(['x', 'y', 'z']):
|
||||||
if key in state:
|
if key in state:
|
||||||
position[axis] = int(state[key]-microscope.stage.position[axis])
|
position[axis] = int(state[key]-self.microscope.stage.position[axis])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Get coordinates from payload
|
# Get coordinates from payload
|
||||||
|
|
@ -139,21 +165,60 @@ def position():
|
||||||
response = {'error': 'Cannot move to absolute position beyond the safeguard limit.'}
|
response = {'error': 'Cannot move to absolute position beyond the safeguard limit.'}
|
||||||
return jsonify(response), 400
|
return jsonify(response), 400
|
||||||
|
|
||||||
microscope.stage.move_rel(position)
|
self.microscope.stage.move_rel(position)
|
||||||
|
|
||||||
return jsonify(microscope.state['position'])
|
return jsonify(self.microscope.state['position'])
|
||||||
|
|
||||||
|
app.add_url_rule(uri('/position'), view_func=PositionAPI.as_view('position', microscope=microscope))
|
||||||
|
|
||||||
|
|
||||||
# Capture routes
|
# Capture routes
|
||||||
|
class CaptureAPI(MicroscopeView):
|
||||||
|
|
||||||
@app.route(uri('/capture/'), methods=['GET', 'POST', 'PUT'])
|
def get(self, capture_id):
|
||||||
def capture():
|
"""
|
||||||
"""Return JSONified microscope state"""
|
Get list of image captures
|
||||||
global microscope
|
"""
|
||||||
|
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)
|
state = parse_payload(request)
|
||||||
print(state)
|
|
||||||
|
|
||||||
if 'filename' in state:
|
if 'filename' in state:
|
||||||
filename = state['filename']
|
filename = state['filename']
|
||||||
|
|
@ -178,7 +243,7 @@ def capture():
|
||||||
else:
|
else:
|
||||||
resize = None
|
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
|
write_to_file=True, # Always write data to disk when using API
|
||||||
keep_on_disk=keep_on_disk,
|
keep_on_disk=keep_on_disk,
|
||||||
use_video_port=use_video_port,
|
use_video_port=use_video_port,
|
||||||
|
|
@ -187,85 +252,40 @@ def capture():
|
||||||
|
|
||||||
return jsonify(capture_obj.metadata)
|
return jsonify(capture_obj.metadata)
|
||||||
|
|
||||||
else: # GET requests
|
capture_view = CaptureAPI.as_view('capture', microscope=microscope)
|
||||||
include_unavailable = get_bool(request.args.get('include_unavailable'))
|
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',])
|
||||||
|
|
||||||
if include_unavailable:
|
|
||||||
captures = [image for image in microscope.camera.images if image.metadata['available']]
|
# 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:
|
else:
|
||||||
captures = microscope.camera.images
|
img = capture_obj.data
|
||||||
|
|
||||||
metadata_array = [capture.metadata for capture in captures]
|
return send_file(
|
||||||
|
img,
|
||||||
|
mimetype='image/jpeg',
|
||||||
|
as_attachment=as_attachment,
|
||||||
|
attachment_filename=capture_obj.filename)
|
||||||
|
|
||||||
return jsonify(metadata_array)
|
app.add_url_rule(uri('/capture/<capture_id>/download/'), view_func=CaptureDlAPI.as_view('capture_download', microscope=microscope))
|
||||||
|
|
||||||
|
|
||||||
@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)
|
|
||||||
|
|
||||||
|
|
||||||
@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)
|
|
||||||
|
|
||||||
if not capture_obj:
|
|
||||||
return abort(404) # 404 Not Found
|
|
||||||
|
|
||||||
as_attachment = get_bool(request.args.get('as_attachment'))
|
|
||||||
|
|
||||||
return send_file(
|
|
||||||
capture_obj.data,
|
|
||||||
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
|
|
||||||
|
|
||||||
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__":
|
if __name__ == "__main__":
|
||||||
app.run(host='0.0.0.0', port="5000", threaded=True, debug=True, use_reloader=False)
|
app.run(host='0.0.0.0', port="5000", threaded=True, debug=True, use_reloader=False)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue