rcer-iot-client-pkg 0.4.0__tar.gz → 0.5.1__tar.gz
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.
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/PKG-INFO +14 -8
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/README.md +13 -7
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/pyproject.toml +1 -1
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/__init__.py +2 -1
- rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/general_types/api/__init__.py +3 -0
- rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/general_types/api/update_thies_data_types.py +29 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/ftp_client/clients/aioftp_client.py +4 -4
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/ftp_client/types/ftp_client_types.py +2 -4
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/sharepoint_client/clients/sharepoint_rest_api.py +13 -13
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/sharepoint_client/sharepoint_client.py +1 -1
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/sharepoint_client/types/sharepoint_client_types.py +2 -0
- rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/services/epii/api.py +24 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/controllers/types/update_thies_data_types.py +2 -4
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/controllers/update_thies_data.py +17 -1
- rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/services/epii/use_cases/types/__init__.py +7 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/use_cases/types/update_thies_data_types.py +16 -1
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/use_cases/update_thies_data.py +12 -18
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/general_types/api/update_thies_data_types.py +0 -0
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/__init__.py +0 -10
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/async_http_client.py +0 -34
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/async_http_client_contract.py +0 -29
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/clients/aiohttp_client.py +0 -50
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/types/__init__.py +0 -3
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/types/async_http_client_types.py +0 -17
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/ftp_client/clients/__init__.py +0 -0
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/services/epii/__init__.py +0 -0
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/services/epii/api.py +0 -39
- rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/services/epii/use_cases/types/__init__.py +0 -3
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/LICENSE +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/general_types/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/general_types/api → rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/general_types/error_types}/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/general_types/error_types → rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/general_types/error_types/api}/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/general_types/error_types/api/update_thies_data_error_types.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/general_types/error_types/common/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/general_types/error_types/common/common_types.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/ftp_client/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/general_types/error_types/api → rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/libs/ftp_client/clients}/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/ftp_client/ftp_client.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/ftp_client/ftp_client_contract.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/ftp_client/types/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/sharepoint_client/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/sharepoint_client/sharepoint_client_contract.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/libs/zero_dependency/utils/datetime_utils.py +0 -0
- {rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/clients → rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/services/epii}/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/constants/update_thies_data_constants.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/controllers/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/controllers/types/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/utils/__init__.py +0 -0
- {rcer_iot_client_pkg-0.4.0 → rcer_iot_client_pkg-0.5.1}/src/rcer_iot_client_pkg/services/epii/utils/update_thies_data_utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: rcer_iot_client_pkg
|
3
|
-
Version: 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
|
-
|
52
|
-
ftp_port=
|
53
|
-
ftp_host=
|
54
|
-
|
55
|
-
|
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 `
|
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
|
|
@@ -24,23 +24,29 @@ api_client = EpiiAPI()
|
|
24
24
|
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:
|
25
25
|
|
26
26
|
```python
|
27
|
+
from rcer_iot_client_pkg import EpiiAPIConfig
|
27
28
|
import asyncio
|
28
29
|
|
29
30
|
async def update_thies_data():
|
30
|
-
|
31
|
-
ftp_port=
|
32
|
-
ftp_host=
|
33
|
-
|
34
|
-
|
31
|
+
config = EpiiAPIConfig(
|
32
|
+
ftp_port=FTP_PORT,
|
33
|
+
ftp_host=FTP_HOST,
|
34
|
+
ftp_user=FTP_USER,
|
35
|
+
ftp_password=FTP_PASSWORD,
|
36
|
+
sharepoint_client_id=SHAREPOINT_CLIENT_ID,
|
37
|
+
sharepoint_client_secret=SHAREPOINT_CLIENT_SECRET,
|
38
|
+
sharepoint_tenant_id=SHAREPOINT_TENANT_ID,
|
39
|
+
sharepoint_tenant_name=SHAREPOINT_TENANT_NAME,
|
40
|
+
sharepoint_site_name=SHAREPOINT_SITE_NAME
|
35
41
|
)
|
42
|
+
response = await api_client.update_thies_data(config)
|
36
43
|
return response
|
37
44
|
|
38
45
|
asyncio.run(update_thies_data())
|
39
46
|
```
|
40
47
|
|
41
48
|
**Notes:**
|
42
|
-
- Store sensitive data like `
|
43
|
-
- Ensure `asyncio` is installed to run concurrent code with `EpiiAPI` methods.
|
49
|
+
- 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.
|
44
50
|
|
45
51
|
## Development
|
46
52
|
|
rcer_iot_client_pkg-0.5.1/src/rcer_iot_client_pkg/general_types/api/update_thies_data_types.py
ADDED
@@ -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.
|
16
|
-
self.port = args.
|
17
|
-
self.password = args.
|
18
|
-
self.user = args.
|
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:
|
@@ -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
|
-
|
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://{
|
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__()
|
@@ -0,0 +1,24 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
3
|
+
from .controllers.types.update_thies_data_types import UpdateThiesDataControllerInput
|
4
|
+
from .controllers.update_thies_data import UpdateThiesDataController
|
5
|
+
from rcer_iot_client_pkg.general_types.api.update_thies_data_types import EpiiAPIConfig
|
6
|
+
|
7
|
+
|
8
|
+
class EpiiAPI:
|
9
|
+
"""
|
10
|
+
EpiiAPI is a service class that provides methods to interact with Patagonia Center system.
|
11
|
+
"""
|
12
|
+
|
13
|
+
async def update_thies_data(self, config: EpiiAPIConfig) -> Dict[str, Any]:
|
14
|
+
"""
|
15
|
+
This method establishes a connection to an FTP server using the provided
|
16
|
+
credentials and updates data related to THIES Data Logger.
|
17
|
+
Args:
|
18
|
+
config (EpiiAPIConfig): configuration class for FTP Server and Microsoft SharePoint credentials.
|
19
|
+
Returns:
|
20
|
+
response (dict): A dictionary representation of the API response.
|
21
|
+
"""
|
22
|
+
controller = UpdateThiesDataController(UpdateThiesDataControllerInput(config))
|
23
|
+
response = await controller.execute()
|
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
|
-
|
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(
|
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:
|
@@ -3,13 +3,28 @@ from typing import Dict
|
|
3
3
|
|
4
4
|
|
5
5
|
@dataclass
|
6
|
-
class
|
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.
|
38
|
-
|
39
|
-
|
40
|
-
self.
|
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(
|
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
|
|
rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/general_types/api/update_thies_data_types.py
DELETED
File without changes
|
@@ -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"]
|
rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/async_http_client.py
DELETED
@@ -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
|
rcer_iot_client_pkg-0.4.0/src/rcer_iot_client_pkg/libs/async_http_client/clients/aiohttp_client.py
DELETED
@@ -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,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
|
File without changes
|
File without changes
|
@@ -1,39 +0,0 @@
|
|
1
|
-
from typing import Dict, Any
|
2
|
-
|
3
|
-
from .controllers.types.update_thies_data_types import UpdateThiesDataControllerInput
|
4
|
-
from .controllers.update_thies_data import UpdateThiesDataController
|
5
|
-
|
6
|
-
|
7
|
-
class EpiiAPI:
|
8
|
-
"""
|
9
|
-
EpiiAPI is a service class that provides methods to interact with Patagonia Center system.
|
10
|
-
"""
|
11
|
-
|
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]:
|
19
|
-
"""
|
20
|
-
This method establishes a connection to an FTP server using the provided
|
21
|
-
credentials and updates data related to THIES Data Logger.
|
22
|
-
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.
|
27
|
-
Returns:
|
28
|
-
response (dict): A dictionary representation of the API response.
|
29
|
-
"""
|
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
|
-
)
|
38
|
-
response = await controller.execute()
|
39
|
-
return response.__dict__
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|