From 052a10aa4ff7c33927c4755a91b5d24bb0599c97 Mon Sep 17 00:00:00 2001 From: Thomas Schmelzer Date: Sat, 22 Feb 2025 22:51:58 +0400 Subject: [PATCH 1/4] towards doc_test --- src/tests/conftest.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 1dc7498..7f6e0e9 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -13,11 +13,18 @@ # limitations under the License. """global fixtures""" +from pathlib import Path + import numpy as np import pyarrow as pa import pytest +@pytest.fixture(name="root_dir") +def root_fixture() -> Path: + return Path(__file__).parent.parent.parent + + @pytest.fixture def test_data(): """ From ec810c9fe5949f91882d1a7a276b92688290241c Mon Sep 17 00:00:00 2001 From: Thomas Schmelzer Date: Sat, 22 Feb 2025 22:52:52 +0400 Subject: [PATCH 2/4] return the server when starting it --- src/np/flight/numpy_server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/np/flight/numpy_server.py b/src/np/flight/numpy_server.py index 484c147..6bf62f8 100644 --- a/src/np/flight/numpy_server.py +++ b/src/np/flight/numpy_server.py @@ -111,7 +111,8 @@ def start(cls, host="0.0.0.0", port=8080, logger=None, **kwargs): # pragma: no """ server = cls(host=host, port=port, logger=logger, **kwargs) # Instantiate the server. server.logger.info(f"Starting {cls} Flight server on port {port}...") # Log the server start. - server.serve() # Start the server to handle incoming requests. + # server.serve() # Start the server to handle incoming requests. + return server @abstractmethod def f(self, matrices: dict[str, np.ndarray]) -> dict[str, np.ndarray]: ... # pragma: no cover From e5a5a8fadabb8bf3a8c1d6a122a7769118a52b9d Mon Sep 17 00:00:00 2001 From: Thomas Schmelzer Date: Sat, 22 Feb 2025 22:53:12 +0400 Subject: [PATCH 3/4] test for README --- src/tests/test_docs.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/tests/test_docs.py diff --git a/src/tests/test_docs.py b/src/tests/test_docs.py new file mode 100644 index 0000000..a1c7102 --- /dev/null +++ b/src/tests/test_docs.py @@ -0,0 +1,39 @@ +import doctest +import os +import re + +import pytest + + +@pytest.fixture() +def docstring(root_dir): + # Read the README.md file + with open(root_dir / "README.md") as f: + content = f.read() + + # Extract Python code blocks (assuming they are in triple backticks) + blocks = re.findall(r"```python(.*?)```", content, re.DOTALL) + + code = "\n".join(blocks).strip() + + # Add a docstring wrapper for doctest to process the code + docstring = f"\n{code}\n" + + return docstring + + +def test_blocks(root_dir, docstring, capfd): + os.chdir(root_dir) + + try: + doctest.run_docstring_examples(docstring, globals()) + except doctest.DocTestFailure as e: + # If a DocTestFailure occurs, capture it and manually fail the test + pytest.fail(f"Doctests failed: {e}") + + # Capture the output after running doctests + captured = capfd.readouterr() + + # If there is any output (error message), fail the test + if captured.out: + pytest.fail(f"Doctests failed with the following output:\n{captured.out} and \n{docstring}") From 5bcfbafc0c66d788894f68d229d1585d79ddbbca Mon Sep 17 00:00:00 2001 From: Thomas Schmelzer Date: Sat, 22 Feb 2025 23:01:29 +0400 Subject: [PATCH 4/4] test for README --- README.md | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 36370f9..ca1646c 100644 --- a/README.md +++ b/README.md @@ -43,27 +43,45 @@ pip install numpy-flight ### Basic Setup +We introduce the Baseclass 'Server': + ```python -import numpy as np -from np.flight import Client +>>> from np.flight import Server + +>>> class TestServer(Server): +... def f(self, matrices): +... self.logger.info(f"{matrices.keys()}") +... # Simple implementation for testing - just return the input +... return {key : 2*value for key, value in matrices.items()} +``` -# Initialize the Flight client -with Client('grpc://localhost:8815') as client: -... +All complexity is hidden in the class 'Server' which is itself a child +of the pyarrrow's FlightServerBase class. It is enough to implement +the method 'f' which is expecting a dictionary of numpy arrays. It will +also return a dictionary of numpy arrays. +The server can be started locally with + +```python +>>> server = TestServer.start(host="127.0.0.1", port=5555) ``` -### Sending Data +While the server is running we can use a client for computations ```python -# Prepare your NumPy arrays -data = { - 'values': np.array([1, 2, 3, 4, 5]), - 'labels': np.array(['a', 'b', 'c', 'd', 'e']) -} +>>> import numpy as np +>>> from np.flight import Client -# Send data to the server -client.write('store_data', data) +>>> with Client(location="grpc://127.0.0.1:5555") as client: +... output = client.compute(command="compute", data={"input": np.array([1,2,3])}) + +>>> print(output["input"]) +[2 4 6] + +``` + +```python +server.shutdown() ``` ### Retrieving Data