From c6b1a1d4b1311c24515fb59d0cba42617d33f73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wachiou=20BOURA=C3=8FMA?= <100234404+WassCodeur@users.noreply.github.com> Date: Sun, 14 Jul 2024 05:54:51 +0000 Subject: [PATCH] RF: add keyword arguments decorator (warn_on_args_to_kwargs) in the module: stream (#909) --- fury/stream/client.py | 13 ++++++-- fury/stream/server/async_app.py | 4 +++ fury/stream/server/main.py | 9 +++-- fury/stream/tools.py | 56 +++++++++++++++++++++++-------- fury/stream/widget.py | 15 ++++++--- fury/tests/test_stream.py | 58 ++++++++++++++++----------------- 6 files changed, 104 insertions(+), 51 deletions(-) diff --git a/fury/stream/client.py b/fury/stream/client.py index 88da17caa..4bc5ead23 100644 --- a/fury/stream/client.py +++ b/fury/stream/client.py @@ -6,6 +6,7 @@ import numpy as np import vtk +from fury.decorators import warn_on_args_to_kwargs from fury.stream.constants import PY_VERSION_8, _CQUEUE from fury.stream.tools import ( ArrayCircularQueue, @@ -47,9 +48,11 @@ def callback_stream_client(stream_client): class FuryStreamClient: """This obj is responsible to create a StreamClient.""" + @warn_on_args_to_kwargs() def __init__( self, showm, + *, max_window_size=None, use_raw_array=True, whithout_iren_start=False, @@ -119,7 +122,8 @@ def __init__( self.use_raw_array = use_raw_array self._started = False - def start(self, ms=0, use_asyncio=False): + @warn_on_args_to_kwargs() + def start(self, *, ms=0, use_asyncio=False): """Start the stream client. Parameters @@ -134,6 +138,7 @@ def start(self, ms=0, use_asyncio=False): """ + @warn_on_args_to_kwargs() def callback_for_vtk(caller, event, *args, **kwargs): callback_stream_client(**{"stream_client": kwargs["stream_client"]}) @@ -270,8 +275,9 @@ def interaction_callback(circular_queue, showm, iren, render_after): class FuryStreamInteraction: """This obj. is responsible to manage the user interaction""" + @warn_on_args_to_kwargs() def __init__( - self, showm, max_queue_size=50, use_raw_array=True, whithout_iren_start=False + self, showm, *, max_queue_size=50, use_raw_array=True, whithout_iren_start=False ): """Initialize the StreamInteraction obj. @@ -306,7 +312,8 @@ def __init__( self._whithout_iren_start = whithout_iren_start self._started = False - def start(self, ms=3, use_asyncio=False): + @warn_on_args_to_kwargs() + def start(self, *, ms=3, use_asyncio=False): """Start the stream interaction client. Parameters diff --git a/fury/stream/server/async_app.py b/fury/stream/server/async_app.py index eac612818..ad99b9a21 100644 --- a/fury/stream/server/async_app.py +++ b/fury/stream/server/async_app.py @@ -8,6 +8,8 @@ from aiohttp import MultipartWriter, WSCloseCode, web import numpy as np +from fury.decorators import warn_on_args_to_kwargs + try: from aiortc import RTCPeerConnection, RTCSessionDescription from aiortc.contrib.media import MediaRelay @@ -215,7 +217,9 @@ async def websocket_handler(request, **kwargs): return ws +@warn_on_args_to_kwargs() def get_app( + *, rtc_server=None, folder=None, circular_queue=None, diff --git a/fury/stream/server/main.py b/fury/stream/server/main.py index 1b7656857..dd795dd93 100644 --- a/fury/stream/server/main.py +++ b/fury/stream/server/main.py @@ -4,6 +4,7 @@ from aiohttp import web import numpy as np +from fury.decorators import warn_on_args_to_kwargs from fury.stream.constants import PY_VERSION_8, _CQUEUE from fury.stream.server.async_app import get_app from fury.stream.tools import ( @@ -111,7 +112,9 @@ def release(self): pass +@warn_on_args_to_kwargs() def web_server_raw_array( + *, image_buffers=None, info_buffer=None, queue_head_tail_buffer=None, @@ -183,7 +186,7 @@ def web_server_raw_array( ) app_fury = get_app( - rtc_server, + rtc_server=rtc_server, circular_queue=circular_queue, image_buffer_manager=image_buffer_manager, provides_mjpeg=provides_mjpeg, @@ -201,7 +204,9 @@ def web_server_raw_array( image_buffer_manager.cleanup() +@warn_on_args_to_kwargs() def web_server( + *, image_buffer_names=None, info_buffer_name=None, queue_head_tail_buffer_name=None, @@ -280,7 +285,7 @@ def web_server( ) app_fury = get_app( - rtc_server, + rtc_server=rtc_server, circular_queue=circular_queue, image_buffer_manager=image_buffer_manager, provides_mjpeg=provides_mjpeg, diff --git a/fury/stream/tools.py b/fury/stream/tools.py index a9cbe1c3f..b9fa90fde 100644 --- a/fury/stream/tools.py +++ b/fury/stream/tools.py @@ -9,6 +9,7 @@ from PIL import Image, ImageDraw import numpy as np +from fury.decorators import warn_on_args_to_kwargs from fury.stream.constants import PY_VERSION_8 if PY_VERSION_8: @@ -65,7 +66,8 @@ def fix_unregister(name, rtype): class GenericMultiDimensionalBuffer(ABC): """This implements a abstract (generic) multidimensional buffer.""" - def __init__(self, max_size=None, dimension=8): + @warn_on_args_to_kwargs() + def __init__(self, *, max_size=None, dimension=8): """Initialize the multidimensional buffer. Parameters @@ -129,7 +131,8 @@ def cleanup(self): ... # pragma: no cover class RawArrayMultiDimensionalBuffer(GenericMultiDimensionalBuffer): """This implements a multidimensional buffer with RawArray.""" - def __init__(self, max_size, dimension=4, buffer=None): + @warn_on_args_to_kwargs() + def __init__(self, max_size, *, dimension=4, buffer=None): """Stream system uses that to implement the CircularQueue with shared memory resources. @@ -147,7 +150,7 @@ def __init__(self, max_size, dimension=4, buffer=None): a already created RawArray """ - super().__init__(max_size, dimension) + super().__init__(max_size=max_size, dimension=dimension) if buffer is None: self.create_mem_resource() else: @@ -178,7 +181,8 @@ class SharedMemMultiDimensionalBuffer(GenericMultiDimensionalBuffer): with SharedMemory. """ - def __init__(self, max_size, dimension=4, buffer_name=None): + @warn_on_args_to_kwargs() + def __init__(self, max_size, *, dimension=4, buffer_name=None): """Stream system uses that to implement the CircularQueue with shared memory resources. @@ -193,7 +197,7 @@ def __init__(self, max_size, dimension=4, buffer_name=None): a already created SharedMemory """ - super().__init__(max_size, dimension) + super().__init__(max_size=max_size, dimension=dimension) if buffer_name is None: self.create_mem_resource() self._created = True @@ -271,8 +275,10 @@ class GenericCircularQueue(ABC): shared memory resources. """ + @warn_on_args_to_kwargs() def __init__( self, + *, max_size=None, dimension=8, use_shared_mem=False, @@ -389,7 +395,8 @@ class ArrayCircularQueue(GenericCircularQueue): Arrays and RawArrays. """ - def __init__(self, max_size=10, dimension=6, head_tail_buffer=None, buffer=None): + @warn_on_args_to_kwargs() + def __init__(self, *, max_size=10, dimension=6, head_tail_buffer=None, buffer=None): """Stream system uses that to implement user interactions Parameters @@ -410,7 +417,12 @@ def __init__(self, max_size=10, dimension=6, head_tail_buffer=None, buffer=None) RawArray to store the data """ - super().__init__(max_size, dimension, use_shared_mem=False, buffer=buffer) + super().__init__( + max_size=max_size, + dimension=dimension, + use_shared_mem=False, + buffer=buffer, + ) if head_tail_buffer is None: self.create_mem_resource() @@ -456,8 +468,9 @@ class SharedMemCircularQueue(GenericCircularQueue): SharedMemory. """ + @warn_on_args_to_kwargs() def __init__( - self, max_size=10, dimension=6, head_tail_buffer_name=None, buffer_name=None + self, *, max_size=10, dimension=6, head_tail_buffer_name=None, buffer_name=None ): """Stream system uses that to implement user interactions @@ -479,7 +492,10 @@ def __init__( """ super().__init__( - max_size, dimension, use_shared_mem=True, buffer_name=buffer_name + max_size=max_size, + dimension=dimension, + use_shared_mem=True, + buffer_name=buffer_name, ) if head_tail_buffer_name is None: @@ -564,7 +580,8 @@ class GenericImageBufferManager(ABC): the n-buffer technique. """ - def __init__(self, max_window_size=None, num_buffers=2, use_shared_mem=False): + @warn_on_args_to_kwargs() + def __init__(self, *, max_window_size=None, num_buffers=2, use_shared_mem=False): """Initialize the ImageBufferManager. Parameters @@ -669,7 +686,8 @@ def get_jpeg(self): return bytes_img - async def async_get_jpeg(self, ms=33): + @warn_on_args_to_kwargs() + async def async_get_jpeg(self, *, ms=33): jpeg = self.get_jpeg() await asyncio.sleep(ms / 1000) return jpeg @@ -690,8 +708,10 @@ def cleanup(self): class RawArrayImageBufferManager(GenericImageBufferManager): """This implements an ImageBufferManager using RawArrays.""" + @warn_on_args_to_kwargs() def __init__( self, + *, max_window_size=(100, 100), num_buffers=2, image_buffers=None, @@ -714,7 +734,11 @@ def __init__( A list of buffers with each one containing a frame. """ - super().__init__(max_window_size, num_buffers, use_shared_mem=False) + super().__init__( + max_window_size=max_window_size, + num_buffers=num_buffers, + use_shared_mem=False, + ) if image_buffers is None or info_buffer is None: self.create_mem_resource() else: @@ -767,8 +791,10 @@ class SharedMemImageBufferManager(GenericImageBufferManager): SharedMemory approach. """ + @warn_on_args_to_kwargs() def __init__( self, + *, max_window_size=(100, 100), num_buffers=2, image_buffer_names=None, @@ -795,7 +821,11 @@ def __init__( Python >=3.8 is a requirement to use this object. """ - super().__init__(max_window_size, num_buffers, use_shared_mem=True) + super().__init__( + max_window_size=max_window_size, + num_buffers=num_buffers, + use_shared_mem=True, + ) if image_buffer_names is None or info_buffer_name is None: self.create_mem_resource() self._created = True diff --git a/fury/stream/widget.py b/fury/stream/widget.py index 469da2ca9..14d9f1bbe 100644 --- a/fury/stream/widget.py +++ b/fury/stream/widget.py @@ -13,6 +13,7 @@ except ImportError: IPYTHON_AVAILABLE = False +from fury.decorators import warn_on_args_to_kwargs from fury.stream.client import FuryStreamClient, FuryStreamInteraction from fury.stream.constants import PY_VERSION_8 @@ -46,9 +47,11 @@ class Widget: using the SharedMemory object from Python multiprocessing. """ + @warn_on_args_to_kwargs() def __init__( self, showm, + *, ms_stream=33, ms_interaction=33, host="localhost", @@ -130,7 +133,8 @@ def command_string(self): s += ")" return s - def _start_fury_client(self, use_asyncio=False): + @warn_on_args_to_kwargs() + def _start_fury_client(self, *, use_asyncio=False): """Start the fury image buffer client and the interaction client Parameters @@ -193,12 +197,14 @@ def url(self): url += f"?iframe=1&encoding={self.encoding}" return url - def return_iframe(self, height=200): + @warn_on_args_to_kwargs() + def return_iframe(self, *, height=200): """Return the jupyter div iframe used to show the stream""" if IPYTHON_AVAILABLE: display(IFrame(self.url, "100%", f"{int(height)}px")) - def start(self, use_asyncio=False): + @warn_on_args_to_kwargs() + def start(self, *, use_asyncio=False): """Start the fury client and the interaction client and return the url Parameters @@ -215,7 +221,8 @@ def start(self, use_asyncio=False): return False print(f"url: {self.url}") - def display(self, height=150): + @warn_on_args_to_kwargs() + def display(self, *, height=150): """Start the server and display the url in an iframe""" self._start_fury_client() ok = self.run_command() diff --git a/fury/tests/test_stream.py b/fury/tests/test_stream.py index af2cf31b0..68e198d0a 100644 --- a/fury/tests/test_stream.py +++ b/fury/tests/test_stream.py @@ -78,7 +78,7 @@ def test(use_raw_array, ms_stream=16): rtc_server = RTCServer(img_buffer_manager) showm.render() - stream.start(ms_stream) + stream.start(ms=ms_stream) showm.render() loop.run_until_complete(rtc_server.recv()) # sassert frame.width == width_0 and frame.height == height_0 @@ -129,7 +129,7 @@ def test_pillow(): ) showm.render() - stream.start(ms_stream) + stream.start(ms=ms_stream) showm.render() # test jpeg method img_buffer_manager.get_jpeg() @@ -187,7 +187,7 @@ def test_rtc_video_stream_whitout_cython(loop: asyncio.AbstractEventLoop): rtc_server = RTCServer(img_buffer_manager) showm.render() - stream.start(ms_stream) + stream.start(ms=ms_stream) showm.render() loop.run_until_complete(rtc_server.recv()) # assert frame.width == showm.size[0] and frame.height == showm.size[1] @@ -233,7 +233,7 @@ def test(use_raw_array, ms_stream=16): ) showm.render() - stream.start(ms_stream) + stream.start(ms=ms_stream) showm.render() # test jpeg method img_buffer_manager.get_jpeg() @@ -286,10 +286,10 @@ def test(use_raw_array, ms_stream=16, whithout_iren_start=False): ) showm.render() - stream.start(ms_stream) + stream.start(ms=ms_stream) npt.assert_equal(stream._started, True) # test if stop method has been called - stream.start(ms_stream) + stream.start(ms=ms_stream) npt.assert_equal(stream._started, True) showm.render() stream.stop() @@ -423,7 +423,7 @@ async def test(use_raw_array, ms_stream=16): ) ) - stream_interaction.start(ms_stream, use_asyncio=True) + stream_interaction.start(ms=ms_stream, use_asyncio=True) while stream_interaction.circular_queue.head != -1: showm.render() await asyncio.sleep(0.01) @@ -464,11 +464,11 @@ def test(use_raw_array, ms_stream, whitouth_iren_start): # ms should always be greater than 0 with npt.assert_raises(ValueError): - stream_interaction.start(-1) + stream_interaction.start(ms=-1) - stream_interaction.start(ms_stream) + stream_interaction.start(ms=ms_stream) # test double start - stream_interaction.start(ms_stream) + stream_interaction.start(ms=ms_stream) while stream_interaction.circular_queue.head != -1: showm.render() time.sleep(0.01) @@ -563,14 +563,14 @@ def test_comm(use_raw_array=True): max_size=max_size, dimension=dimension ) m_buffer_0 = tools.RawArrayMultiDimensionalBuffer( - max_size, dimension, buffer=m_buffer_org.buffer + max_size, dimension=dimension, buffer=m_buffer_org.buffer ) else: m_buffer_org = tools.SharedMemMultiDimensionalBuffer( max_size=max_size, dimension=dimension ) m_buffer_0 = tools.SharedMemMultiDimensionalBuffer( - max_size, dimension, buffer_name=m_buffer_org.buffer_name + max_size, dimension=dimension, buffer_name=m_buffer_org.buffer_name ) m_buffer_0[1] = np.array([0.2, 0.3, 0.4, 0.5]) @@ -744,27 +744,27 @@ def test(use_raw_array): if use_raw_array: web_server_raw_array( - stream.img_manager.image_buffers, - stream.img_manager.info_buffer, - stream_interaction.circular_queue.head_tail_buffer, - stream_interaction.circular_queue.buffer._buffer, - 8000, - "localhost", - True, - True, + image_buffers=stream.img_manager.image_buffers, + info_buffer=stream.img_manager.info_buffer, + queue_head_tail_buffer=stream_interaction.circular_queue.head_tail_buffer, # noqa E501 + queue_buffer=stream_interaction.circular_queue.buffer._buffer, + port=8000, + host="localhost", + provides_mjpeg=True, + provides_webrtc=True, run_app=False, ) else: web_server( - stream.img_manager.image_buffer_names, - stream.img_manager.info_buffer_name, - stream_interaction.circular_queue.head_tail_buffer_name, - stream_interaction.circular_queue.buffer.buffer_name, - 8000, - "localhost", - True, - True, - True, + image_buffer_names=stream.img_manager.image_buffer_names, + info_buffer_name=stream.img_manager.info_buffer_name, + queue_head_tail_buffer_name=stream_interaction.circular_queue.head_tail_buffer_name, # noqa E501 + queue_buffer_name=stream_interaction.circular_queue.buffer.buffer_name, + port=8000, + host="localhost", + provides_mjpeg=True, + provides_webrtc=True, + avoid_unlink_shared_mem=True, run_app=False, )