rcer-iot-client-pkg 0.4.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.
Files changed (25) hide show
  1. rcer_iot_client_pkg/__init__.py +2 -1
  2. rcer_iot_client_pkg/general_types/api/__init__.py +3 -0
  3. rcer_iot_client_pkg/general_types/api/update_thies_data_types.py +29 -0
  4. rcer_iot_client_pkg/libs/ftp_client/clients/aioftp_client.py +4 -4
  5. rcer_iot_client_pkg/libs/ftp_client/types/ftp_client_types.py +2 -4
  6. rcer_iot_client_pkg/libs/sharepoint_client/clients/sharepoint_rest_api.py +13 -13
  7. rcer_iot_client_pkg/libs/sharepoint_client/sharepoint_client.py +1 -1
  8. rcer_iot_client_pkg/libs/sharepoint_client/types/sharepoint_client_types.py +2 -0
  9. rcer_iot_client_pkg/services/epii/api.py +5 -20
  10. rcer_iot_client_pkg/services/epii/controllers/types/update_thies_data_types.py +2 -4
  11. rcer_iot_client_pkg/services/epii/controllers/update_thies_data.py +17 -1
  12. rcer_iot_client_pkg/services/epii/use_cases/types/__init__.py +6 -2
  13. rcer_iot_client_pkg/services/epii/use_cases/types/update_thies_data_types.py +16 -1
  14. rcer_iot_client_pkg/services/epii/use_cases/update_thies_data.py +12 -18
  15. {rcer_iot_client_pkg-0.4.0.dist-info → rcer_iot_client_pkg-0.5.1.dist-info}/METADATA +14 -8
  16. {rcer_iot_client_pkg-0.4.0.dist-info → rcer_iot_client_pkg-0.5.1.dist-info}/RECORD +18 -25
  17. rcer_iot_client_pkg/libs/async_http_client/__init__.py +0 -10
  18. rcer_iot_client_pkg/libs/async_http_client/async_http_client.py +0 -34
  19. rcer_iot_client_pkg/libs/async_http_client/async_http_client_contract.py +0 -29
  20. rcer_iot_client_pkg/libs/async_http_client/clients/__init__.py +0 -0
  21. rcer_iot_client_pkg/libs/async_http_client/clients/aiohttp_client.py +0 -50
  22. rcer_iot_client_pkg/libs/async_http_client/types/__init__.py +0 -3
  23. rcer_iot_client_pkg/libs/async_http_client/types/async_http_client_types.py +0 -17
  24. {rcer_iot_client_pkg-0.4.0.dist-info → rcer_iot_client_pkg-0.5.1.dist-info}/LICENSE +0 -0
  25. {rcer_iot_client_pkg-0.4.0.dist-info → rcer_iot_client_pkg-0.5.1.dist-info}/WHEEL +0 -0
@@ -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"]
@@ -0,0 +1,29 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class EpiiAPIConfig:
6
+ """
7
+ Configuration for Epii API.
8
+
9
+ Attributes:
10
+ ftp_port (int): Port number of the FTP server.
11
+ ftp_host (str): Hostname or IP address of the FTP server.
12
+ ftp_user (str): Username for the FTP server.
13
+ ftp_password (str): Password for the FTP server.
14
+ sharepoint_client_id (str): Client ID for SharePoint authentication.
15
+ sharepoint_client_secret (str): Client secret for SharePoint authentication.
16
+ sharepoint_tenant_id (str): Tenant ID for SharePoint authentication.
17
+ sharepoint_tenant_name (str): Tenant name for SharePoint.
18
+ sharepoint_site_name (str): Site name in SharePoint.
19
+ """
20
+
21
+ ftp_port: int
22
+ ftp_host: str
23
+ ftp_user: str
24
+ ftp_password: str
25
+ sharepoint_client_id: str
26
+ sharepoint_client_secret: str
27
+ sharepoint_tenant_id: str
28
+ sharepoint_tenant_name: str
29
+ sharepoint_site_name: str
@@ -12,10 +12,10 @@ from rcer_iot_client_pkg.libs.ftp_client.types.ftp_client_types import (
12
12
 
13
13
  class AioFTPClient(FTPClientContract):
14
14
  def __init__(self, args: FtpClientInitArgs) -> None:
15
- self.host = args.host
16
- self.port = args.port
17
- self.password = args.password
18
- self.user = args.user
15
+ self.host = args.config.ftp_host
16
+ self.port = args.config.ftp_port
17
+ self.password = args.config.ftp_password
18
+ self.user = args.config.ftp_user
19
19
  self.client = Client()
20
20
 
21
21
  async def _async_start(self) -> None:
@@ -1,13 +1,11 @@
1
1
  from dataclasses import dataclass
2
+ from typing import Any
2
3
 
3
4
 
4
5
  @dataclass
5
6
  class FtpClientInitArgs:
6
- host: str
7
- user: str
8
- password: str
7
+ config: Any
9
8
  client_name: str = "aioftp_client"
10
- port: int = 21
11
9
 
12
10
 
13
11
  @dataclass
@@ -11,17 +11,23 @@ from rcer_iot_client_pkg.libs.sharepoint_client.types.sharepoint_client_types im
11
11
  SpListFilesArgs,
12
12
  SpListFoldersArgs,
13
13
  SpUploadFileArgs,
14
+ SharepointClientInitArgs,
14
15
  )
15
16
 
16
17
  load_dotenv()
17
18
 
18
19
 
19
20
  class SharepointRestAPI(SharepointClientContract):
20
- def __init__(self):
21
+ def __init__(self, args: SharepointClientInitArgs):
21
22
  self.session: ClientSession | None = None
22
23
  self.base_headers = {}
23
24
  self.credentials = {}
24
25
  self.base_url = ""
26
+ self.tenant_id = args.config.sharepoint_tenant_id
27
+ self.tenant_name = args.config.sharepoint_tenant_name
28
+ self.client_secret = args.config.sharepoint_client_secret
29
+ self.client_id = args.config.sharepoint_client_id
30
+ self.site_name = args.config.sharepoint_site_name
25
31
 
26
32
  async def _load_form_digest_value(self) -> str:
27
33
  try:
@@ -32,18 +38,13 @@ class SharepointRestAPI(SharepointClientContract):
32
38
  raise ConnectionError(error) from error
33
39
 
34
40
  async def _load_credentials(self) -> dict:
35
- tenant_id = os.getenv("TENANT_ID")
36
- client_id = os.getenv("CLIENT_ID")
37
- client_secret = os.getenv("CLIENT_SECRET")
38
41
  resource_base = "00000003-0000-0ff1-ce00-000000000000"
39
- resource = (
40
- f"{resource_base}/{os.getenv('TENANT_NAME')}.sharepoint.com@{tenant_id}"
41
- )
42
- url = f"https://accounts.accesscontrol.windows.net/{tenant_id}/tokens/OAuth/2"
42
+ resource = f"{resource_base}/{self.tenant_name}.sharepoint.com@{self.tenant_id}"
43
+ url = f"https://accounts.accesscontrol.windows.net/{self.tenant_id}/tokens/OAuth/2"
43
44
  payload = {
44
45
  "grant_type": "client_credentials",
45
- "client_id": f"{client_id}@{tenant_id}",
46
- "client_secret": client_secret,
46
+ "client_id": f"{self.client_id}@{self.tenant_id}",
47
+ "client_secret": self.client_secret,
47
48
  "resource": resource,
48
49
  }
49
50
  headers = {
@@ -65,15 +66,14 @@ class SharepointRestAPI(SharepointClientContract):
65
66
 
66
67
  async def __aenter__(self) -> "SharepointRestAPI":
67
68
  self.credentials = await self._load_credentials()
68
- site_url = f"https://{os.getenv('TENANT_NAME')}.sharepoint.com"
69
- site_name = os.getenv("SITE_NAME")
69
+ site_url = f"https://{self.tenant_name}.sharepoint.com"
70
70
 
71
71
  self.base_headers = {
72
72
  "Authorization": f"Bearer {self.credentials['access_token']}",
73
73
  "Accept": "application/json",
74
74
  "Content-Type": "application/json",
75
75
  }
76
- self.base_url = f"{site_url}/sites/{site_name}/_api/"
76
+ self.base_url = f"{site_url}/sites/{self.site_name}/_api/"
77
77
  self.session = ClientSession(headers=self.base_headers, base_url=self.base_url)
78
78
  return self
79
79
 
@@ -16,7 +16,7 @@ class SharepointClient(SharepointClientContract):
16
16
  msg = f"Unsupported client {args.client_name}"
17
17
  raise KeyError(msg)
18
18
  elif args.client_name == "sharepoint_rest_api":
19
- self.client_obj = SharepointRestAPI()
19
+ self.client_obj = SharepointRestAPI(args)
20
20
 
21
21
  async def __aenter__(self):
22
22
  return await self.client_obj.__aenter__()
@@ -1,8 +1,10 @@
1
1
  from dataclasses import dataclass
2
+ from typing import Any
2
3
 
3
4
 
4
5
  @dataclass
5
6
  class SharepointClientInitArgs:
7
+ config: Any
6
8
  client_name: str = "sharepoint_rest_api"
7
9
 
8
10
 
@@ -1,7 +1,8 @@
1
- from typing import Dict, Any
1
+ from typing import Any, Dict
2
2
 
3
3
  from .controllers.types.update_thies_data_types import UpdateThiesDataControllerInput
4
4
  from .controllers.update_thies_data import UpdateThiesDataController
5
+ from rcer_iot_client_pkg.general_types.api.update_thies_data_types import EpiiAPIConfig
5
6
 
6
7
 
7
8
  class EpiiAPI:
@@ -9,31 +10,15 @@ class EpiiAPI:
9
10
  EpiiAPI is a service class that provides methods to interact with Patagonia Center system.
10
11
  """
11
12
 
12
- async def update_thies_data(
13
- self,
14
- ftp_port: int,
15
- ftp_host: str,
16
- ftp_password: str,
17
- ftp_user: str,
18
- ) -> Dict[str, Any]:
13
+ async def update_thies_data(self, config: EpiiAPIConfig) -> Dict[str, Any]:
19
14
  """
20
15
  This method establishes a connection to an FTP server using the provided
21
16
  credentials and updates data related to THIES Data Logger.
22
17
  Args:
23
- ftp_port (int): The port number of the FTP server.
24
- ftp_host (str): The hostname or IP address of the FTP server.
25
- ftp_password (str): The password for the FTP server.
26
- ftp_user (str): The username for the FTP server.
18
+ config (EpiiAPIConfig): configuration class for FTP Server and Microsoft SharePoint credentials.
27
19
  Returns:
28
20
  response (dict): A dictionary representation of the API response.
29
21
  """
30
- controller = UpdateThiesDataController(
31
- UpdateThiesDataControllerInput(
32
- ftp_port=ftp_port,
33
- ftp_host=ftp_host,
34
- ftp_password=ftp_password,
35
- ftp_user=ftp_user,
36
- )
37
- )
22
+ controller = UpdateThiesDataController(UpdateThiesDataControllerInput(config))
38
23
  response = await controller.execute()
39
24
  return response.__dict__
@@ -1,13 +1,11 @@
1
1
  from dataclasses import dataclass, field
2
2
  from typing import Dict
3
+ from rcer_iot_client_pkg.general_types.api.update_thies_data_types import EpiiAPIConfig
3
4
 
4
5
 
5
6
  @dataclass
6
7
  class UpdateThiesDataControllerInput:
7
- ftp_host: str
8
- ftp_port: str
9
- ftp_user: str
10
- ftp_password: str
8
+ config: EpiiAPIConfig
11
9
 
12
10
 
13
11
  @dataclass
@@ -16,6 +16,8 @@ from rcer_iot_client_pkg.services.epii.controllers.types.update_thies_data_types
16
16
  )
17
17
  from rcer_iot_client_pkg.services.epii.use_cases.types import (
18
18
  UpdateThiesDataUseCaseInput,
19
+ SharepointConfig,
20
+ FtpClientConfig,
19
21
  )
20
22
  from rcer_iot_client_pkg.services.epii.use_cases.update_thies_data import (
21
23
  UpdateThiesDataUseCase,
@@ -25,7 +27,21 @@ from rcer_iot_client_pkg.services.epii.use_cases.update_thies_data import (
25
27
  class UpdateThiesDataController:
26
28
  def __init__(self, input: UpdateThiesDataControllerInput):
27
29
  self.use_case = UpdateThiesDataUseCase(
28
- UpdateThiesDataUseCaseInput(**input.__dict__)
30
+ UpdateThiesDataUseCaseInput(
31
+ ftp_config=FtpClientConfig(
32
+ ftp_host=input.config.ftp_host,
33
+ ftp_password=input.config.ftp_password,
34
+ ftp_port=input.config.ftp_port,
35
+ ftp_user=input.config.ftp_user,
36
+ ),
37
+ sharepoint_config=SharepointConfig(
38
+ sharepoint_client_id=input.config.sharepoint_client_id,
39
+ sharepoint_client_secret=input.config.sharepoint_client_secret,
40
+ sharepoint_site_name=input.config.sharepoint_site_name,
41
+ sharepoint_tenant_name=input.config.sharepoint_tenant_name,
42
+ sharepoint_tenant_id=input.config.sharepoint_tenant_id,
43
+ ),
44
+ )
29
45
  )
30
46
 
31
47
  async def execute(self) -> UpdateThiesDataControllerOutput:
@@ -1,3 +1,7 @@
1
- from .update_thies_data_types import UpdateThiesDataUseCaseInput
1
+ from .update_thies_data_types import (
2
+ FtpClientConfig,
3
+ SharepointConfig,
4
+ UpdateThiesDataUseCaseInput,
5
+ )
2
6
 
3
- __all__ = ["UpdateThiesDataUseCaseInput"]
7
+ __all__ = ["UpdateThiesDataUseCaseInput", "FtpClientConfig", "SharepointConfig"]
@@ -3,13 +3,28 @@ from typing import Dict
3
3
 
4
4
 
5
5
  @dataclass
6
- class UpdateThiesDataUseCaseInput:
6
+ class FtpClientConfig:
7
7
  ftp_host: str
8
8
  ftp_port: int
9
9
  ftp_user: str
10
10
  ftp_password: str
11
11
 
12
12
 
13
+ @dataclass
14
+ class SharepointConfig:
15
+ sharepoint_client_id: str
16
+ sharepoint_client_secret: str
17
+ sharepoint_tenant_id: str
18
+ sharepoint_tenant_name: str
19
+ sharepoint_site_name: str
20
+
21
+
22
+ @dataclass
23
+ class UpdateThiesDataUseCaseInput:
24
+ ftp_config: FtpClientConfig
25
+ sharepoint_config: SharepointConfig
26
+
27
+
13
28
  @dataclass
14
29
  class UpdateThiesDataUseCaseOutput:
15
30
  message: str
@@ -24,6 +24,8 @@ from rcer_iot_client_pkg.libs.sharepoint_client import (
24
24
  )
25
25
  from rcer_iot_client_pkg.services.epii.use_cases.types import (
26
26
  UpdateThiesDataUseCaseInput,
27
+ FtpClientConfig,
28
+ SharepointConfig,
27
29
  )
28
30
  from rcer_iot_client_pkg.services.epii.utils import (
29
31
  parse_execute_response,
@@ -34,35 +36,27 @@ load_dotenv()
34
36
 
35
37
  class UpdateThiesDataUseCase:
36
38
  def __init__(self, input: UpdateThiesDataUseCaseInput):
37
- self.ftp_port = input.ftp_port
38
- self.ftp_host = input.ftp_host
39
- self.ftp_password = input.ftp_password
40
- self.ftp_user = input.ftp_user
41
- self.sharepoint_client = self._initialize_sharepoint_client()
42
- self.thies_ftp_client = self._initialize_thies_ftp_client()
39
+ self.sharepoint_client = self._initialize_sharepoint_client(
40
+ input.sharepoint_config
41
+ )
42
+ self.thies_ftp_client = self._initialize_thies_ftp_client(input.ftp_config)
43
43
  self.uploading = set()
44
44
 
45
- def _initialize_sharepoint_client(self) -> SharepointClient:
45
+ def _initialize_sharepoint_client(
46
+ self, config: SharepointConfig
47
+ ) -> SharepointClient:
46
48
  """Initialize the HTTP client."""
47
49
  try:
48
50
  return SharepointClient(
49
- SharepointClientInitArgs(client_name="sharepoint_rest_api")
51
+ SharepointClientInitArgs(config, client_name="sharepoint_rest_api")
50
52
  )
51
53
  except ConnectionError as error:
52
54
  raise SharepointClientError(error)
53
55
 
54
- def _initialize_thies_ftp_client(self) -> FTPClient:
56
+ def _initialize_thies_ftp_client(self, config: FtpClientConfig) -> FTPClient:
55
57
  """Initialize the FTP client."""
56
58
  try:
57
- return FTPClient(
58
- FtpClientInitArgs(
59
- client_name="aioftp_client",
60
- host=self.ftp_host,
61
- user=self.ftp_user,
62
- password=self.ftp_password,
63
- port=self.ftp_port,
64
- )
65
- )
59
+ return FTPClient(FtpClientInitArgs(config, client_name="aioftp_client"))
66
60
  except RuntimeError as error:
67
61
  raise FtpClientError(error)
68
62
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rcer_iot_client_pkg
3
- Version: 0.4.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,45 +1,38 @@
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
4
- rcer_iot_client_pkg/general_types/api/update_thies_data_types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ rcer_iot_client_pkg/general_types/api/__init__.py,sha256=1afRFS8AkxkxOWmcNLFI3H1lb-w_5dVJMMDKobBYlOY,80
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
- rcer_iot_client_pkg/libs/ftp_client/clients/aioftp_client.py,sha256=b0YYNXOTlYqsxwmxrcCqb__xy7CBv6PO5-WiZkOioRk,1589
12
+ rcer_iot_client_pkg/libs/ftp_client/clients/aioftp_client.py,sha256=5CI9J4axAeoqlN-cYToVcPF9sAZEk0vIOhPOHrhlpk4,1633
20
13
  rcer_iot_client_pkg/libs/ftp_client/ftp_client.py,sha256=RhWnGwfU8SN0tRqfDc3u6NKDj9qla4cOI2IANyb-S2s,820
21
14
  rcer_iot_client_pkg/libs/ftp_client/ftp_client_contract.py,sha256=2x1MPZNFVw3l-sVd65Z6kZYkXlk_8isH_ykzRZB9Cv8,326
22
15
  rcer_iot_client_pkg/libs/ftp_client/types/__init__.py,sha256=syfwf9feP4QK7fkCTfl4j8l11ic-jHtfi1DE2chaWbs,155
23
- rcer_iot_client_pkg/libs/ftp_client/types/ftp_client_types.py,sha256=4ywi5UROTR5TOaApPrm-JyV2PeTvD-cv5K_lL4Fj9AA,282
16
+ rcer_iot_client_pkg/libs/ftp_client/types/ftp_client_types.py,sha256=e4SmYkewldulaD8ms2q75zVgLFXyBxBqoa_L-IQOmso,256
24
17
  rcer_iot_client_pkg/libs/sharepoint_client/__init__.py,sha256=v7h-cNsK-BaPp-hTU3NWRNXYRD9ztU-hsCk0eNRPIKA,334
25
- rcer_iot_client_pkg/libs/sharepoint_client/clients/sharepoint_rest_api.py,sha256=fjmpP7ityjBRBLpok0GYQMrMNIhrCwVjIvLKbBdsQkk,5095
26
- rcer_iot_client_pkg/libs/sharepoint_client/sharepoint_client.py,sha256=cTHQan7vMCJ2In3D1s1Nizvnt7K5Y8n87WiYcmVdjhk,1230
18
+ rcer_iot_client_pkg/libs/sharepoint_client/clients/sharepoint_rest_api.py,sha256=e0f4F8_Elt-y8dgxLqviQUy8PR8E2Qn60ecP0v78VQM,5269
19
+ rcer_iot_client_pkg/libs/sharepoint_client/sharepoint_client.py,sha256=UYfAhckzmal5-Jjvbz0P4gt64w5gOYJYksVSHXdJPiQ,1234
27
20
  rcer_iot_client_pkg/libs/sharepoint_client/sharepoint_client_contract.py,sha256=xqNHzCjp7GvUGGUox9YTJj2QJgTc5819t2etOk8X26o,485
28
- rcer_iot_client_pkg/libs/sharepoint_client/types/sharepoint_client_types.py,sha256=NTV5kL1xEOr5tUZOJMkr3gFTwSXRG1V9PkmHtntyQk0,375
21
+ rcer_iot_client_pkg/libs/sharepoint_client/types/sharepoint_client_types.py,sha256=gfXhvKuqZjxSdbgbEgGF1EKYDDq7CjK9Tdth-Waq5xo,414
29
22
  rcer_iot_client_pkg/libs/zero_dependency/utils/datetime_utils.py,sha256=kD38wC087H3jwTIgrntBajE55cR2ioo_ftPUHiyGs_M,751
30
23
  rcer_iot_client_pkg/services/epii/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- rcer_iot_client_pkg/services/epii/api.py,sha256=lqoyBR6ub6BLqwOPR_kvtG8z80KqUNpJD8Yl6VT7z34,1369
24
+ rcer_iot_client_pkg/services/epii/api.py,sha256=imw7crOMCuGLztEf5MpfpdzWC9IBnvDZJ4N957wRcIE,1038
32
25
  rcer_iot_client_pkg/services/epii/constants/update_thies_data_constants.py,sha256=XeBNsQaTsc0mylQegB4Wf9ECIo0i1Fk-BurWm84WDqE,273
33
26
  rcer_iot_client_pkg/services/epii/controllers/__init__.py,sha256=mCdGgKGDgGxCtRoiZN9Rki-fTOyOuJWw9e7festpQYA,98
34
27
  rcer_iot_client_pkg/services/epii/controllers/types/__init__.py,sha256=xzky-oTSojLNkWETp_k8a4dcXYvYSQY0VhWo23Yhb8U,195
35
- rcer_iot_client_pkg/services/epii/controllers/types/update_thies_data_types.py,sha256=0zbNgjln7PXQRjFPAbiNV9n_cXV1H1-XtXMCC_VA4kE,336
36
- rcer_iot_client_pkg/services/epii/controllers/update_thies_data.py,sha256=Si-oGHyunp8lgxvjdZjRizAJuf2uoq5b6QD1dRHYVuM,3272
37
- rcer_iot_client_pkg/services/epii/use_cases/types/__init__.py,sha256=c2RRUbjWq2PIqYW8DcxmYDg0gLZ74kmHh3BkeQCVii0,108
38
- rcer_iot_client_pkg/services/epii/use_cases/types/update_thies_data_types.py,sha256=JGmBwQtQB-nfopNlGwuI8Jf3A2QBFTGtrzjrDZDWMQ0,334
39
- rcer_iot_client_pkg/services/epii/use_cases/update_thies_data.py,sha256=7H7Y6jDRb8ymsZv8spJ_NUWPBTiGFeD42FH1-eo1FS8,5268
28
+ rcer_iot_client_pkg/services/epii/controllers/types/update_thies_data_types.py,sha256=M5rYsjgqTndhPIRi77McxLyTrjmGsoVUIAGPETNXz9U,374
29
+ rcer_iot_client_pkg/services/epii/controllers/update_thies_data.py,sha256=Suxehwi1onUsc2rWGbzO1vBsBp0RfgCp6FUqe-lrY20,4054
30
+ rcer_iot_client_pkg/services/epii/use_cases/types/__init__.py,sha256=u6fyodOEJE2j6FMqJux40Xf9ccYAi-UUYxqT-Kzc0kE,199
31
+ rcer_iot_client_pkg/services/epii/use_cases/types/update_thies_data_types.py,sha256=C0TU50KKYodpaX87OnG0MnHyGY4gRzmluUHk-esCEVU,635
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.4.0.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
43
- rcer_iot_client_pkg-0.4.0.dist-info/METADATA,sha256=Byx8wk_eQeCPMTS_46IeXPkB6hxSlNW_M3Qhj-8x5Lo,3483
44
- rcer_iot_client_pkg-0.4.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
45
- rcer_iot_client_pkg-0.4.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