labthings_fastapi.outputs.mjpeg_stream

Module Contents

Classes

RingbufferEntry

A single entry in a ringbuffer

MJPEGStreamResponse

MJPEGStream

MJPEGStreamDescriptor

A descriptor that returns a MJPEGStream object when accessed

API

class labthings_fastapi.outputs.mjpeg_stream.RingbufferEntry

A single entry in a ringbuffer

frame: bytes

None

timestamp: datetime.datetime

None

index: int

None

class labthings_fastapi.outputs.mjpeg_stream.MJPEGStreamResponse(gen: AsyncGenerator[bytes, None], status_code: int = 200)

Bases: fastapi.responses.StreamingResponse

Initialization

A StreamingResponse that streams an MJPEG stream

This response is initialised with an async generator that yields bytes objects, each of which is a JPEG file. We add the –frame markers and mime types that enable it to work in an img tag.

NB the status_code argument is used by FastAPI to set the status code of the response in OpenAPI.

media_type

‘multipart/x-mixed-replace; boundary=frame’

async mjpeg_async_generator() AsyncGenerator[bytes, None]

A generator yielding an MJPEG stream

class labthings_fastapi.outputs.mjpeg_stream.MJPEGStream(ringbuffer_size: int = 10)

Initialization

reset(ringbuffer_size: Optional[int] = None)

Reset the stream and optionally change the ringbuffer size

stop()

Stop the stream

async ringbuffer_entry(i: int) labthings_fastapi.outputs.mjpeg_stream.RingbufferEntry

Return the ith frame acquired by the camera

Parameters:

i – The index of the frame to read

async buffer_for_reading(i: int) AsyncIterator[bytes]

Yields the ith frame as a bytes object

Parameters:

i – The index of the frame to read

async next_frame() int

Wait for the next frame, and return its index

async grab_frame() bytes

Wait for the next frame, and return it

This copies the frame for safety, so we can release the read lock on the buffer.

async next_frame_size() int

Wait for the next frame and return its size

This is useful if you want to use JPEG size as a sharpness metric.

async frame_async_generator() AsyncGenerator[bytes, None]

A generator that yields frames as bytes

async mjpeg_stream_response() labthings_fastapi.outputs.mjpeg_stream.MJPEGStreamResponse

Return a StreamingResponse that streams an MJPEG stream

add_frame(frame: bytes, portal: anyio.from_thread.BlockingPortal)

Return the next buffer in the ringbuffer to write to

Parameters:
  • frame – The frame to add

  • portal – The blocking portal to use for scheduling tasks. This is necessary because tasks are handled asynchronously. The blocking portal may be obtained with a dependency, in labthings_fastapi.dependencies.blocking_portal.BlockingPortal.

async notify_new_frame(i)

Notify any waiting tasks that a new frame is available

class labthings_fastapi.outputs.mjpeg_stream.MJPEGStreamDescriptor(**kwargs)

A descriptor that returns a MJPEGStream object when accessed

Initialization

__set_name__(owner, name)
__get__(obj: Optional[labthings_fastapi.thing.Thing], type=None) Union[labthings_fastapi.outputs.mjpeg_stream.MJPEGStream, typing_extensions.Self]

The value of the property

If obj is none (i.e. we are getting the attribute of the class), we return the descriptor.

If no getter is set, we’ll return either the initial value, or the value from the object’s __dict__, i.e. we behave like a variable.

If a getter is set, we will use it, unless the property is observable, at which point the getter is only ever used once, to set the initial value.

async viewer_page(url: str) fastapi.responses.HTMLResponse
add_to_fastapi(app: fastapi.FastAPI, thing: labthings_fastapi.thing.Thing)

Add the stream to the FastAPI app