Reorganised stream resource

This commit is contained in:
Joel Collins 2019-11-20 13:48:27 +00:00
parent 8c5af3486c
commit 0b2536a79b
6 changed files with 122 additions and 66 deletions

View file

@ -148,8 +148,8 @@ app.register_blueprint(task_blueprint, url_prefix=uri("/task", "v1"))
v2_root_blueprint = v2.blueprints.root.construct_blueprint(api_microscope)
app.register_blueprint(v2_root_blueprint, url_prefix=uri("/", "v2"))
v2_stream_blueprint = v2.blueprints.stream.construct_blueprint(api_microscope)
app.register_blueprint(v2_stream_blueprint, url_prefix=uri("/", "v2"))
v2_streams_blueprint = v2.blueprints.streams.construct_blueprint(api_microscope)
app.register_blueprint(v2_streams_blueprint, url_prefix=uri("/streams", "v2"))
# Captures routes
v2_captures_blueprint = v2.blueprints.captures.construct_blueprint(api_microscope)

View file

@ -1 +1 @@
from . import root, captures, settings, status, tasks, stream, plugins, actions
from . import root, captures, settings, status, tasks, streams, plugins, actions

View file

@ -11,6 +11,11 @@ from openflexure_microscope.api.views import MicroscopeView
from . import camera, stage, system
class ActionsAPI(MicroscopeView):
def get(self):
return jsonify(actions_representation())
_actions = {
"capture": {
"rule": "/camera/capture/",
@ -67,9 +72,6 @@ def actions_representation():
return actions
class ActionsAPI(MicroscopeView):
def get(self):
return jsonify(actions_representation())
def construct_blueprint(microscope_obj):
global _actions

View file

@ -4,10 +4,10 @@ from openflexure_microscope.api.views import MicroscopeView
from openflexure_microscope.utilities import get_docstring, bottom_level_name
from openflexure_microscope.api.utilities import blueprint_name_for_module
from openflexure_microscope.api.v2.blueprints import settings, status, plugins, captures, actions, stream
from openflexure_microscope.api.v2.blueprints import settings, status, plugins, captures, actions, streams
# List of submodules containing create_blueprint methods using standard blueprint_for_module naming
_root_blueprint_modules = [settings, status, plugins, captures, actions, stream]
_root_blueprint_modules = [settings, status, plugins, captures, actions, streams]
def root_representation():
"""

View file

@ -1,58 +0,0 @@
from openflexure_microscope.api.utilities import gen, JsonResponse
from openflexure_microscope.api.views import MicroscopeView
from openflexure_microscope.api.utilities import blueprint_for_module
from flask import Response, Blueprint, jsonify, request
class StreamAPI(MicroscopeView):
def get(self):
"""
Real-time MJPEG stream from the microscope camera
.. :quickref: Stream; Camera MJPEG stream
:>header Accept: image/jpeg
:>header Content-Type: image/jpeg
:status 200: stream active
"""
# Restart stream worker thread
self.microscope.camera.start_worker()
return Response(
gen(self.microscope.camera),
mimetype="multipart/x-mixed-replace; boundary=frame",
)
class SnapshotAPI(MicroscopeView):
def get(self):
"""
Single snapshot from the camera stream
.. :quickref: Stream; Camera snapshot
:>header Accept: image/jpeg
:>header Content-Type: image/jpeg
:status 200: stream active
"""
# Restart stream worker thread
self.microscope.camera.start_worker()
return Response(self.microscope.camera.get_frame(), mimetype="image/jpeg")
def construct_blueprint(microscope_obj):
blueprint = blueprint_for_module(__name__)
blueprint.add_url_rule(
"/stream", view_func=StreamAPI.as_view("stream", microscope=microscope_obj)
)
blueprint.add_url_rule(
"/snapshot",
view_func=SnapshotAPI.as_view("snapshot", microscope=microscope_obj),
)
return blueprint

View file

@ -0,0 +1,112 @@
"""
Top-level description of routes related to live camera stream data
"""
from openflexure_microscope.api.utilities import gen, JsonResponse
from openflexure_microscope.api.views import MicroscopeView
from openflexure_microscope.api.utilities import blueprint_for_module, blueprint_name_for_module
from openflexure_microscope.utilities import description_from_view
from flask import Response, Blueprint, jsonify, request, url_for
class StreamAPI(MicroscopeView):
def get(self):
return jsonify(streams_representation())
class MjpegAPI(MicroscopeView):
"""
Real-time MJPEG stream from the microscope camera
"""
def get(self):
"""
Real-time MJPEG stream from the microscope camera
.. :quickref: Stream; Camera MJPEG stream
:>header Accept: image/jpeg
:>header Content-Type: image/jpeg
:status 200: stream active
"""
# Restart stream worker thread
self.microscope.camera.start_worker()
return Response(
gen(self.microscope.camera),
mimetype="multipart/x-mixed-replace; boundary=frame",
)
class SnapshotAPI(MicroscopeView):
"""
Single JPEG snapshot from the camera stream
"""
def get(self):
"""
Single snapshot from the camera stream
.. :quickref: Stream; Camera snapshot
:>header Accept: image/jpeg
:>header Content-Type: image/jpeg
:status 200: stream active
"""
# Restart stream worker thread
self.microscope.camera.start_worker()
return Response(self.microscope.camera.get_frame(), mimetype="image/jpeg")
_streams = {
"mjpeg": {
"rule": "/mjpeg",
"view_class": MjpegAPI,
"conditions": True,
},
"snapshot": {
"rule": "/snapshot",
"view_class": SnapshotAPI,
"conditions": True,
}
}
def enabled_streams():
global _streams
return {k: v for k, v in _streams.items() if v["conditions"]}
def streams_representation():
global _streams
streams = {}
for name, stream in enabled_streams().items():
d = {
"links": {"self": url_for(f".{name}")},
}
d.update(description_from_view(stream["view_class"]))
streams[name] = d
return streams
def construct_blueprint(microscope_obj):
blueprint = blueprint_for_module(__name__)
# For each enabled stream route defined in our dictionary above
for name, stream in enabled_streams().items():
# Add the action to our blueprint
blueprint.add_url_rule(
stream["rule"],
view_func=stream["view_class"].as_view(name, microscope=microscope_obj),
)
blueprint.add_url_rule(
"/", view_func=StreamAPI.as_view("streams", microscope=microscope_obj)
)
return blueprint