Reorganised stream resource
This commit is contained in:
parent
8c5af3486c
commit
0b2536a79b
6 changed files with 122 additions and 66 deletions
|
|
@ -148,8 +148,8 @@ app.register_blueprint(task_blueprint, url_prefix=uri("/task", "v1"))
|
||||||
v2_root_blueprint = v2.blueprints.root.construct_blueprint(api_microscope)
|
v2_root_blueprint = v2.blueprints.root.construct_blueprint(api_microscope)
|
||||||
app.register_blueprint(v2_root_blueprint, url_prefix=uri("/", "v2"))
|
app.register_blueprint(v2_root_blueprint, url_prefix=uri("/", "v2"))
|
||||||
|
|
||||||
v2_stream_blueprint = v2.blueprints.stream.construct_blueprint(api_microscope)
|
v2_streams_blueprint = v2.blueprints.streams.construct_blueprint(api_microscope)
|
||||||
app.register_blueprint(v2_stream_blueprint, url_prefix=uri("/", "v2"))
|
app.register_blueprint(v2_streams_blueprint, url_prefix=uri("/streams", "v2"))
|
||||||
|
|
||||||
# Captures routes
|
# Captures routes
|
||||||
v2_captures_blueprint = v2.blueprints.captures.construct_blueprint(api_microscope)
|
v2_captures_blueprint = v2.blueprints.captures.construct_blueprint(api_microscope)
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
from . import root, captures, settings, status, tasks, stream, plugins, actions
|
from . import root, captures, settings, status, tasks, streams, plugins, actions
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ from openflexure_microscope.api.views import MicroscopeView
|
||||||
|
|
||||||
from . import camera, stage, system
|
from . import camera, stage, system
|
||||||
|
|
||||||
|
class ActionsAPI(MicroscopeView):
|
||||||
|
def get(self):
|
||||||
|
return jsonify(actions_representation())
|
||||||
|
|
||||||
|
|
||||||
_actions = {
|
_actions = {
|
||||||
"capture": {
|
"capture": {
|
||||||
"rule": "/camera/capture/",
|
"rule": "/camera/capture/",
|
||||||
|
|
@ -67,9 +72,6 @@ def actions_representation():
|
||||||
|
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
class ActionsAPI(MicroscopeView):
|
|
||||||
def get(self):
|
|
||||||
return jsonify(actions_representation())
|
|
||||||
|
|
||||||
def construct_blueprint(microscope_obj):
|
def construct_blueprint(microscope_obj):
|
||||||
global _actions
|
global _actions
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ from openflexure_microscope.api.views import MicroscopeView
|
||||||
|
|
||||||
from openflexure_microscope.utilities import get_docstring, bottom_level_name
|
from openflexure_microscope.utilities import get_docstring, bottom_level_name
|
||||||
from openflexure_microscope.api.utilities import blueprint_name_for_module
|
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
|
# 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():
|
def root_representation():
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
112
openflexure_microscope/api/v2/blueprints/streams.py
Normal file
112
openflexure_microscope/api/v2/blueprints/streams.py
Normal 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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue