diff --git a/PythonTools/OpenIrisClient.py b/PythonTools/OpenIrisClient.py index db92b61..91c5d81 100644 --- a/PythonTools/OpenIrisClient.py +++ b/PythonTools/OpenIrisClient.py @@ -2,7 +2,7 @@ from typing import Optional, Callable import aiohttp -from PythonTools.models import ( +from .models import ( DeviceConfig, CameraConfig, WiFiConfig, @@ -16,7 +16,13 @@ class BaseAPIClient: def __init__(self, tracker_address: str): self.tracker_address = tracker_address self.base_endpoint = "control/builtin/command" + + async def __aenter__(self): self.session = aiohttp.ClientSession() + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.session.close() async def get( self, @@ -35,6 +41,7 @@ class BaseAPIClient: f"{self.tracker_address}/{self.base_endpoint}/{command}/", params=clean_params, ) as request: + await request.read() return request async def post( @@ -51,6 +58,7 @@ class BaseAPIClient: f"{self.tracker_address}/{self.base_endpoint}/{command}/", params=clean_params, ) as request: + await request.read() return request async def delete( @@ -67,6 +75,7 @@ class BaseAPIClient: f"{self.tracker_address}/{self.base_endpoint}/{command}/", params=clean_params, ) as request: + await request.read() return request @staticmethod diff --git a/PythonTools/__init__.py b/PythonTools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/PythonTools/conftest.py b/PythonTools/conftest.py new file mode 100644 index 0000000..a00a144 --- /dev/null +++ b/PythonTools/conftest.py @@ -0,0 +1,13 @@ +import pytest_asyncio + +from .OpenIrisClient import OpenIrisClient + + +@pytest_asyncio.fixture() +async def device_url(): + return "http://openiristracker.local:81" + + +@pytest_asyncio.fixture() +async def openiris_client(device_url): + return OpenIrisClient(tracker_address=device_url) diff --git a/PythonTools/models.py b/PythonTools/models.py index 1ce6b66..f8e5e9f 100644 --- a/PythonTools/models.py +++ b/PythonTools/models.py @@ -1,7 +1,7 @@ from pydantic import BaseModel from typing import Optional, List -from PythonTools.constants import FrameSize, WifiPowerPoint +from .constants import FrameSize, WifiPowerPoint class DeviceConfig(BaseModel): diff --git a/PythonTools/poetry.lock b/PythonTools/poetry.lock index 01c54db..5b32f7c 100644 --- a/PythonTools/poetry.lock +++ b/PythonTools/poetry.lock @@ -109,6 +109,21 @@ yarl = ">=1.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns", "cchardet"] +[[package]] +name = "aioresponses" +version = "0.7.4" +description = "Mock out requests made by ClientSession from aiohttp package" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "aioresponses-0.7.4-py2.py3-none-any.whl", hash = "sha256:1160486b5ea96fcae6170cf2bdef029b9d3a283b7dbeabb3d7f1182769bfb6b7"}, + {file = "aioresponses-0.7.4.tar.gz", hash = "sha256:9b8c108b36354c04633bad0ea752b55d956a7602fe3e3234b939fc44af96f1d8"}, +] + +[package.dependencies] +aiohttp = ">=2.0.0,<4.0.0" + [[package]] name = "aiosignal" version = "1.3.1" @@ -677,6 +692,25 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +[[package]] +name = "pytest-asyncio" +version = "0.21.0" +description = "Pytest support for asyncio" +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-asyncio-0.21.0.tar.gz", hash = "sha256:2b38a496aef56f56b0e87557ec313e11e1ab9276fc3863f6a7be0f1d0e415e1b"}, + {file = "pytest_asyncio-0.21.0-py3-none-any.whl", hash = "sha256:f2b3366b7cd501a4056858bd39349d5af19742aed2d81660b7998b6341c7eb9c"}, +] + +[package.dependencies] +pytest = ">=7.0.0" + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] + [[package]] name = "ruff" version = "0.0.259" @@ -834,4 +868,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "63ce5a8bfea22034068a1df7637c6d5c3246c23a9d7363c2fe6750a51c63cf53" +content-hash = "311f1994ec7c5d0df255d6514424b6da022cc1b2dfe81f6367ddea0b8dab480d" diff --git a/PythonTools/pyproject.toml b/PythonTools/pyproject.toml index 23c6d57..089a14f 100644 --- a/PythonTools/pyproject.toml +++ b/PythonTools/pyproject.toml @@ -13,6 +13,8 @@ ruff = "^0.0.259" pytest = "^7.2.2" aiohttp = "^3.8.4" pydantic = "^1.10.7" +pytest-asyncio = "^0.21.0" +aioresponses = "^0.7.4" [tool.poetry.dev-dependencies] diff --git a/PythonTools/tests/__init__.py b/PythonTools/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/PythonTools/tests/test_client.py b/PythonTools/tests/test_client.py new file mode 100644 index 0000000..a30d944 --- /dev/null +++ b/PythonTools/tests/test_client.py @@ -0,0 +1,18 @@ +import pytest +from aioresponses import aioresponses + +from ..OpenIrisClient import OpenIrisClient + + +@pytest.mark.asyncio +async def test_ping(device_url): + response_payload = {"message": "ok"} + + with aioresponses() as m: + m.get(f"{device_url}/control/builtin/command/ping/", status=200, payload=response_payload) + async with OpenIrisClient(device_url) as openiris_client: + response = await openiris_client.ping() + + m.assert_called_once() + assert response.status == 200 + assert await response.json() == {"message": "ok"} diff --git a/PythonTools/tests/test_hardware.py b/PythonTools/tests/test_hardware.py new file mode 100644 index 0000000..2cb226d --- /dev/null +++ b/PythonTools/tests/test_hardware.py @@ -0,0 +1,12 @@ +import pytest + +from ..OpenIrisClient import OpenIrisClient + + +@pytest.mark.asyncio +async def test_ping(device_url): + """tests whether the device will respond with a ping""" + async with OpenIrisClient as openiris_client: + result = await openiris_client.ping() + assert result.status == 200 + assert result.json() == {"message": "ok"}