rcer-iot-client-pkg 0.5.0__py3-none-any.whl → 0.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,5 +4,6 @@ from importlib.metadata import version
4
4
  __version__ = version("rcer_iot_client_pkg")
5
5
 
6
6
  from .services.epii.api import EpiiAPI
7
+ from .general_types.api.update_thies_data_types import EpiiAPIConfig
7
8
 
8
- __all__ = ["EpiiAPI"]
9
+ __all__ = ["EpiiAPI", "EpiiAPIConfig"]
@@ -0,0 +1,3 @@
1
+ from .update_thies_data_types import EpiiAPIConfig
2
+
3
+ __all__ = ["EpiiAPIConfig"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rcer_iot_client_pkg
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: A client library for IoT projects in the RCER initiative
5
5
  License: MIT
6
6
  Author: pedropablozavalat
@@ -45,23 +45,29 @@ api_client = EpiiAPI()
45
45
  The library provides a method to synchronize THIES Data Logger files with the RCER SharePoint client. This method updates the folder containing binary files with meteorological data:
46
46
 
47
47
  ```python
48
+ from rcer_iot_client_pkg import EpiiAPIConfig
48
49
  import asyncio
49
50
 
50
51
  async def update_thies_data():
51
- response = await api_client.update_thies_data(
52
- ftp_port=PORT,
53
- ftp_host=LOCAL_HOST,
54
- ftp_password=PASSWORD,
55
- ftp_user=USER
52
+ config = EpiiAPIConfig(
53
+ ftp_port=FTP_PORT,
54
+ ftp_host=FTP_HOST,
55
+ ftp_user=FTP_USER,
56
+ ftp_password=FTP_PASSWORD,
57
+ sharepoint_client_id=SHAREPOINT_CLIENT_ID,
58
+ sharepoint_client_secret=SHAREPOINT_CLIENT_SECRET,
59
+ sharepoint_tenant_id=SHAREPOINT_TENANT_ID,
60
+ sharepoint_tenant_name=SHAREPOINT_TENANT_NAME,
61
+ sharepoint_site_name=SHAREPOINT_SITE_NAME
56
62
  )
63
+ response = await api_client.update_thies_data(config)
57
64
  return response
58
65
 
59
66
  asyncio.run(update_thies_data())
60
67
  ```
61
68
 
62
69
  **Notes:**
63
- - Store sensitive data like `PASSWORD` and `USER` securely, e.g., in environment variables or a secrets file.
64
- - Ensure `asyncio` is installed to run concurrent code with `EpiiAPI` methods.
70
+ - Store sensitive data like `FTP_PASSWORD`, `FTP_USER`, and SharePoint credentials securely. Use environment variables or a secrets management tool to avoid hardcoding sensitive information in your codebase.
65
71
 
66
72
  ## Development
67
73
 
@@ -1,19 +1,12 @@
1
- rcer_iot_client_pkg/__init__.py,sha256=Uy9WDPvHbwKUs7JeDHgQi_MGuXn6m7lKVniJgj49xOo,186
1
+ rcer_iot_client_pkg/__init__.py,sha256=ynL8ADM5u2SQTdGfqVLDWEu9bYQnp6znMCEXnhu5zRA,272
2
2
  rcer_iot_client_pkg/general_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- rcer_iot_client_pkg/general_types/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ rcer_iot_client_pkg/general_types/api/__init__.py,sha256=1afRFS8AkxkxOWmcNLFI3H1lb-w_5dVJMMDKobBYlOY,80
4
4
  rcer_iot_client_pkg/general_types/api/update_thies_data_types.py,sha256=NqViiGKm1FdhgxJrNkLBLzqI-8SnPieAYv21kEN752U,963
5
5
  rcer_iot_client_pkg/general_types/error_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  rcer_iot_client_pkg/general_types/error_types/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  rcer_iot_client_pkg/general_types/error_types/api/update_thies_data_error_types.py,sha256=lDVcK7RrqT4s0Bzxa5nEyIsNee93GaIRCyPV9k0s4-o,928
8
8
  rcer_iot_client_pkg/general_types/error_types/common/__init__.py,sha256=yOBLZbt64Ki9Q0IJ0tMAubgq7PtrQ7XQ3RgtAzyOjiE,170
9
9
  rcer_iot_client_pkg/general_types/error_types/common/common_types.py,sha256=n5yuw-gVtkrtNfmaZ83ZkYxYHGl4jynOLUB9C8Tr32w,474
10
- rcer_iot_client_pkg/libs/async_http_client/__init__.py,sha256=LF1KEh5Dhu0j9qZhSBGOsD-PWUFKEvS2oE0eUCyNLd0,279
11
- rcer_iot_client_pkg/libs/async_http_client/async_http_client.py,sha256=wlOvjThS8wnpyqdcY7HbeEx1X3eVNKxJ8DuCJtx0wFk,1135
12
- rcer_iot_client_pkg/libs/async_http_client/async_http_client_contract.py,sha256=PCoTt4R6vFwjvyOTETQ8jEw1uqzAQC3PYiIlg_d7iRI,816
13
- rcer_iot_client_pkg/libs/async_http_client/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- rcer_iot_client_pkg/libs/async_http_client/clients/aiohttp_client.py,sha256=exJ7yq_9ukKoGhdyEwUEe8N5syvEsv2vsQ5eJcQbKSc,1837
15
- rcer_iot_client_pkg/libs/async_http_client/types/__init__.py,sha256=TnJOBj5R6rVA5XAiId5dpQM6KjMIfi8KJkCCav7n930,154
16
- rcer_iot_client_pkg/libs/async_http_client/types/async_http_client_types.py,sha256=d-_rHQ21ajTr5AI66fH3-cpJzF8VhSqG0BHbVrlwND8,329
17
10
  rcer_iot_client_pkg/libs/ftp_client/__init__.py,sha256=dW2Yutgc7mJJJzgKLhWKXMgQ6KIWJYfFa1sGpjHH5xU,191
18
11
  rcer_iot_client_pkg/libs/ftp_client/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
12
  rcer_iot_client_pkg/libs/ftp_client/clients/aioftp_client.py,sha256=5CI9J4axAeoqlN-cYToVcPF9sAZEk0vIOhPOHrhlpk4,1633
@@ -39,7 +32,7 @@ rcer_iot_client_pkg/services/epii/use_cases/types/update_thies_data_types.py,sha
39
32
  rcer_iot_client_pkg/services/epii/use_cases/update_thies_data.py,sha256=Tc12NUnZ0or2Tz5BA9jE62I5XxmKvZ__v4w5dTBk_5A,5052
40
33
  rcer_iot_client_pkg/services/epii/utils/__init__.py,sha256=cYt2tvq65_OMjFaqb8-CCC7IGCQgFd4ziEUWJV7s1iY,98
41
34
  rcer_iot_client_pkg/services/epii/utils/update_thies_data_utils.py,sha256=-q8t-xZmpwFDADGlDu0S7EKvZK7R0GUR6JqOxQShWgE,415
42
- rcer_iot_client_pkg-0.5.0.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
43
- rcer_iot_client_pkg-0.5.0.dist-info/METADATA,sha256=0gMjeJqGyVtA_p-VFp6DIYOyLROhFAatUDXGCT_Qw48,3483
44
- rcer_iot_client_pkg-0.5.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
45
- rcer_iot_client_pkg-0.5.0.dist-info/RECORD,,
35
+ rcer_iot_client_pkg-0.5.1.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
36
+ rcer_iot_client_pkg-0.5.1.dist-info/METADATA,sha256=iM1HsE_ZZZA4ELdR0fA_GpujNOamSfd7PuYAPXR6AZc,3860
37
+ rcer_iot_client_pkg-0.5.1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
38
+ rcer_iot_client_pkg-0.5.1.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- """Export defined type classes."""
2
-
3
- from .async_http_client import AsyncHTTPClient
4
- from .types.async_http_client_types import (
5
- AsyncHttpClientInitArgs,
6
- GetArgs,
7
- UploadFileArgs,
8
- )
9
-
10
- __all__ = ["AsyncHTTPClient", "AsyncHttpClientInitArgs", "GetArgs", "UploadFileArgs"]
@@ -1,34 +0,0 @@
1
- from typing import Any
2
-
3
- from .async_http_client_contract import AsyncHTTPClientContract
4
- from .clients.aiohttp_client import AioHttpClient
5
- from .types.async_http_client_types import (
6
- AsyncHttpClientInitArgs,
7
- GetArgs,
8
- UploadFileArgs,
9
- )
10
-
11
-
12
- class AsyncHTTPClient(AsyncHTTPClientContract):
13
- CLIENTS = {"aiohttp_client"}
14
-
15
- def __init__(self, args: AsyncHttpClientInitArgs) -> None:
16
- if args.client_name not in AsyncHTTPClient.CLIENTS:
17
- msg = f"Unsupported client '{args.client_name}'"
18
- raise KeyError(msg)
19
- self.client_name = args.client_name
20
-
21
- if args.client_name == "aiohttp_client":
22
- self.client_obj = AioHttpClient(args)
23
-
24
- async def __aenter__(self):
25
- return await self.client_obj.__aenter__()
26
-
27
- async def __aexit__(self, exc_type, exc_val, exc_tb):
28
- await self.client_obj.__aexit__(exc_type, exc_val, exc_tb)
29
-
30
- async def get(self, args: GetArgs) -> dict[str, Any]:
31
- return await self.client_obj.get(args)
32
-
33
- async def upload_file(self, args: UploadFileArgs) -> dict[str, Any]:
34
- return await self.client_obj.upload_file(args)
@@ -1,29 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from typing import Any
3
-
4
- from .types.async_http_client_types import GetArgs, UploadFileArgs
5
-
6
-
7
- class AsyncHTTPClientContract(ABC):
8
- """
9
- A contract for asynchronous HTTP client implementations.
10
-
11
- This abstract base class defines the required methods for performing
12
- HTTP GET requests and uploading files asynchronously.
13
-
14
- Methods.
15
- -------
16
- get(args: GetArgs) -> dict[str, Any]
17
- Perform an HTTP GET request with the specified arguments.
18
-
19
- upload_file(args: UploadFileArgs) -> dict[str, Any]
20
- Upload a file using the specified arguments.
21
- """
22
-
23
- @abstractmethod
24
- async def get(self, args: GetArgs) -> dict[str, Any]:
25
- pass
26
-
27
- @abstractmethod
28
- async def upload_file(self, args: UploadFileArgs) -> dict[str, Any]:
29
- pass
@@ -1,50 +0,0 @@
1
- from typing import Any
2
-
3
- from aiohttp import ClientError, ClientSession
4
-
5
- from rcer_iot_client_pkg.libs.async_http_client.async_http_client_contract import (
6
- AsyncHTTPClientContract,
7
- )
8
- from rcer_iot_client_pkg.libs.async_http_client.types.async_http_client_types import (
9
- AsyncHttpClientInitArgs,
10
- GetArgs,
11
- UploadFileArgs,
12
- )
13
-
14
-
15
- class AioHttpClient(AsyncHTTPClientContract):
16
- def __init__(self, args: AsyncHttpClientInitArgs) -> None:
17
- self.access_token = args.access_token
18
- self.base_url = args.base_url
19
- self.headers = self._build_headers()
20
- self.session: ClientSession | None = None
21
-
22
- def _build_headers(self) -> dict:
23
- return {"Authorization": f"Bearer {self.access_token}"}
24
-
25
- async def __aenter__(self) -> "AioHttpClient":
26
- self.session = ClientSession(headers=self.headers, base_url=self.base_url)
27
- return self
28
-
29
- async def __aexit__(
30
- self, _exc_type: type[BaseException], _exc_val: BaseException, _exc_tb: Any
31
- ) -> None:
32
- await self.session.close()
33
-
34
- async def get(self, args: GetArgs) -> dict[str, Any]:
35
- try:
36
- endpoint, params = args.endpoint.lstrip("/"), args.params
37
- response = await self.session.get(endpoint, params=params)
38
- response.raise_for_status()
39
- return await response.json()
40
- except ClientError as error:
41
- raise ConnectionError(error) from error
42
-
43
- async def upload_file(self, args: UploadFileArgs) -> dict[str, Any]:
44
- try:
45
- endpoint, file_bytes = args.endpoint.lstrip("/"), args.file_bytes
46
- response = await self.session.put(endpoint, data=file_bytes)
47
- response.raise_for_status()
48
- return await response.json()
49
- except ClientError as error:
50
- raise ConnectionError(error) from error
@@ -1,3 +0,0 @@
1
- from .async_http_client_types import AsyncHttpClientInitArgs, GetArgs, UploadFileArgs
2
-
3
- __all__ = ["AsyncHttpClientInitArgs", "GetArgs", "UploadFileArgs"]
@@ -1,17 +0,0 @@
1
- from pydantic import BaseModel, Field
2
-
3
-
4
- class AsyncHttpClientInitArgs(BaseModel):
5
- access_token: str
6
- base_url: str
7
- client_name: str = "aiohttp_client"
8
-
9
-
10
- class GetArgs(BaseModel):
11
- endpoint: str
12
- params: dict | None = Field(default=None)
13
-
14
-
15
- class UploadFileArgs(BaseModel):
16
- endpoint: str
17
- file_bytes: bytes