saviialib 1.3.0__tar.gz → 1.5.0__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.
Potentially problematic release.
This version of saviialib might be problematic. Click here for more details.
- saviialib-1.5.0/PKG-INFO +126 -0
- saviialib-1.5.0/README.md +98 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/pyproject.toml +4 -2
- saviialib-1.5.0/src/saviialib/__init__.py +79 -0
- saviialib-1.3.0/src/saviialib/general_types/api/epii_api_types.py → saviialib-1.5.0/src/saviialib/general_types/api/saviia_api_types.py +2 -38
- saviialib-1.5.0/src/saviialib/general_types/api/saviia_backup_api_types.py +24 -0
- saviialib-1.5.0/src/saviialib/general_types/api/saviia_netcamera_api_types.py +11 -0
- saviialib-1.5.0/src/saviialib/general_types/api/saviia_shakes_api_types.py +21 -0
- saviialib-1.5.0/src/saviialib/general_types/api/saviia_thies_api_types.py +31 -0
- saviialib-1.3.0/src/saviialib/general_types/error_types/api/epii_api_error_types.py → saviialib-1.5.0/src/saviialib/general_types/error_types/api/saviia_api_error_types.py +8 -0
- saviialib-1.5.0/src/saviialib/general_types/error_types/api/saviia_netcamera_error_types.py +7 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/general_types/error_types/common/common_types.py +9 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/directory_client/client/os_client.py +1 -1
- saviialib-1.5.0/src/saviialib/libs/ffmpeg_client/__init__.py +8 -0
- saviialib-1.5.0/src/saviialib/libs/ffmpeg_client/clients/ffmpeg_asyncio_client.py +101 -0
- saviialib-1.5.0/src/saviialib/libs/ffmpeg_client/ffmpeg_client.py +25 -0
- saviialib-1.5.0/src/saviialib/libs/ffmpeg_client/ffmpeg_client_contract.py +12 -0
- saviialib-1.5.0/src/saviialib/libs/ffmpeg_client/types/ffmpeg_client_types.py +28 -0
- saviialib-1.5.0/src/saviialib/libs/sftp_client/__init__.py +8 -0
- saviialib-1.5.0/src/saviialib/libs/sftp_client/clients/asyncssh_sftp_client.py +83 -0
- saviialib-1.5.0/src/saviialib/libs/sftp_client/sftp_client.py +26 -0
- saviialib-1.5.0/src/saviialib/libs/sftp_client/sftp_client_contract.py +13 -0
- saviialib-1.5.0/src/saviialib/libs/sftp_client/types/sftp_client_types.py +24 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/sharepoint_client/clients/sharepoint_rest_api.py +7 -3
- saviialib-1.5.0/src/saviialib/libs/zero_dependency/utils/strings_utils.py +5 -0
- saviialib-1.5.0/src/saviialib/services/backup/api.py +36 -0
- saviialib-1.5.0/src/saviialib/services/backup/controllers/__init__.py +0 -0
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/backup}/controllers/types/__init__.py +1 -1
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/backup}/controllers/types/upload_backup_to_sharepoint_types.py +2 -2
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/backup}/controllers/upload_backup_to_sharepoint.py +5 -5
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/backup}/use_cases/types/__init__.py +1 -1
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/backup}/use_cases/types/upload_backup_to_sharepoint_types.py +1 -1
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/backup}/use_cases/upload_backup_to_sharepoint.py +2 -2
- saviialib-1.5.0/src/saviialib/services/backup/utils/__init__.py +3 -0
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/backup}/utils/upload_backup_to_sharepoint_utils.py +1 -1
- saviialib-1.5.0/src/saviialib/services/netcamera/api.py +30 -0
- saviialib-1.5.0/src/saviialib/services/netcamera/controllers/get_media_files.py +40 -0
- saviialib-1.5.0/src/saviialib/services/netcamera/controllers/types/get_media_files_types.py +16 -0
- saviialib-1.5.0/src/saviialib/services/netcamera/use_cases/get_media_files.py +76 -0
- saviialib-1.5.0/src/saviialib/services/netcamera/use_cases/types/get_media_files_types.py +18 -0
- saviialib-1.5.0/src/saviialib/services/shakes/__init__.py +0 -0
- saviialib-1.5.0/src/saviialib/services/shakes/api.py +31 -0
- saviialib-1.5.0/src/saviialib/services/shakes/controllers/get_miniseed_files.py +48 -0
- saviialib-1.5.0/src/saviialib/services/shakes/controllers/types/get_miniseed_files_types.py +16 -0
- saviialib-1.5.0/src/saviialib/services/shakes/use_cases/get_miniseed_files.py +79 -0
- saviialib-1.5.0/src/saviialib/services/shakes/use_cases/types/get_miniseed_files_types.py +18 -0
- saviialib-1.5.0/src/saviialib/services/shakes/use_cases/utils/get_miniseed_files_utils.py +11 -0
- saviialib-1.5.0/src/saviialib/services/thies/__init__.py +0 -0
- saviialib-1.5.0/src/saviialib/services/thies/api.py +35 -0
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/thies}/controllers/types/update_thies_data_types.py +2 -4
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/thies}/controllers/update_thies_data.py +4 -4
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/thies}/use_cases/components/create_thies_statistics_file.py +11 -2
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/thies}/use_cases/types/update_thies_data_types.py +4 -1
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/thies}/use_cases/update_thies_data.py +19 -12
- saviialib-1.3.0/PKG-INFO +0 -122
- saviialib-1.3.0/README.md +0 -98
- saviialib-1.3.0/src/saviialib/__init__.py +0 -9
- saviialib-1.3.0/src/saviialib/general_types/api/__init__.py +0 -3
- saviialib-1.3.0/src/saviialib/services/epii/api.py +0 -94
- saviialib-1.3.0/src/saviialib/services/epii/utils/__init__.py +0 -3
- {saviialib-1.3.0 → saviialib-1.5.0}/LICENSE +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/general_types/__init__.py +0 -0
- {saviialib-1.3.0/src/saviialib/general_types/error_types → saviialib-1.5.0/src/saviialib/general_types/api}/__init__.py +0 -0
- {saviialib-1.3.0/src/saviialib/general_types/error_types/api → saviialib-1.5.0/src/saviialib/general_types/error_types}/__init__.py +0 -0
- {saviialib-1.3.0/src/saviialib/libs/ftp_client/clients → saviialib-1.5.0/src/saviialib/general_types/error_types/api}/__init__.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/general_types/error_types/common/__init__.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/directory_client/__init__.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/directory_client/directory_client.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/directory_client/directory_client_contract.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/directory_client/types/directory_client_types.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/files_client/__init__.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/files_client/clients/aiofiles_client.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/files_client/clients/csv_client.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/files_client/files_client.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/files_client/files_client_contract.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/files_client/types/files_client_types.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/ftp_client/__init__.py +0 -0
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/libs/ftp_client/clients}/__init__.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/ftp_client/clients/aioftp_client.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/ftp_client/clients/ftplib_client.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/ftp_client/ftp_client.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/ftp_client/ftp_client_contract.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/ftp_client/types/__init__.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/ftp_client/types/ftp_client_types.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/sharepoint_client/__init__.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/sharepoint_client/sharepoint_client.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/sharepoint_client/sharepoint_client_contract.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/sharepoint_client/types/sharepoint_client_types.py +0 -0
- {saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/libs/zero_dependency/utils/datetime_utils.py +0 -0
- {saviialib-1.3.0/src/saviialib/services/epii/controllers → saviialib-1.5.0/src/saviialib/services/backup}/__init__.py +0 -0
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/backup}/use_cases/constants/upload_backup_to_sharepoint_constants.py +0 -0
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/thies}/use_cases/components/thies_bp.py +0 -0
- {saviialib-1.3.0/src/saviialib/services/epii → saviialib-1.5.0/src/saviialib/services/thies}/utils/update_thies_data_utils.py +0 -0
saviialib-1.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: saviialib
|
|
3
|
+
Version: 1.5.0
|
|
4
|
+
Summary: A client library for IoT projects in the RCER initiative
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: pedropablozavalat
|
|
8
|
+
Requires-Python: >=3.11,<4.0
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Requires-Dist: aiofiles
|
|
16
|
+
Requires-Dist: aioftp
|
|
17
|
+
Requires-Dist: aiohttp
|
|
18
|
+
Requires-Dist: asyncssh (==2.21.1)
|
|
19
|
+
Requires-Dist: bitarray
|
|
20
|
+
Requires-Dist: build
|
|
21
|
+
Requires-Dist: certifi
|
|
22
|
+
Requires-Dist: dotenv (>=0.9.9,<0.10.0)
|
|
23
|
+
Requires-Dist: ffmpeg-asyncio (==0.1.3)
|
|
24
|
+
Requires-Dist: numpy (>=2.2.0,<2.4.0)
|
|
25
|
+
Requires-Dist: pandas (>=2.2.3,<2.3.1)
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# SAVIIA Library
|
|
29
|
+
*Sistema de Administración y Visualización de Información para la Investigación y Análisis*
|
|
30
|
+
|
|
31
|
+
[](https://github.com/pedrozavalat/saviia-lib/releases)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
This library is designed for use with the SAVIIA Home Assistant Integration. It provides an API to retrieve files from a THIES Data Logger via an FTP server and upload them to a Microsoft SharePoint folder using the SharePoint REST API.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install saviialib
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Saviia API Client Usage
|
|
42
|
+
|
|
43
|
+
### Initialize the Saviia API Client
|
|
44
|
+
Import the necessary classes from the library.
|
|
45
|
+
```python
|
|
46
|
+
from saviialib import SaviiaAPI, SaviiaAPIConfig
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
To start using the library, you need to create an `SaviiaAPI` client instance with its configuration class `SaviiaAPIConfig`. Provide the required parameters such as FTP server details and SharePoint credentials:
|
|
50
|
+
```python
|
|
51
|
+
config = SaviiaAPIConfig(
|
|
52
|
+
ftp_port=FTP_PORT,
|
|
53
|
+
ftp_host=FTP_HOST,
|
|
54
|
+
ftp_user=FTP_USER,
|
|
55
|
+
ftp_password=FTP_PASSWORD,
|
|
56
|
+
sharepoint_client_id=SHAREPOINT_CLIENT_ID,
|
|
57
|
+
sharepoint_client_secret=SHAREPOINT_CLIENT_SECRET,
|
|
58
|
+
sharepoint_tenant_id=SHAREPOINT_TENANT_ID,
|
|
59
|
+
sharepoint_tenant_name=SHAREPOINT_TENANT_NAME,
|
|
60
|
+
sharepoint_site_name=SHAREPOINT_SITE_NAME
|
|
61
|
+
)
|
|
62
|
+
```
|
|
63
|
+
```python
|
|
64
|
+
api_client = SaviiaAPI(config)
|
|
65
|
+
```
|
|
66
|
+
**Notes:**
|
|
67
|
+
- 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.
|
|
68
|
+
|
|
69
|
+
### Access THIES Data Logger Services
|
|
70
|
+
To interact with the THIES Data Logger services, you can access the `thies` attribute of the `SaviiaAPI` instance:
|
|
71
|
+
```python
|
|
72
|
+
thies_client = api_client.get('thies')
|
|
73
|
+
```
|
|
74
|
+
This instance provides methods to interact with the THIES Data Logger. Currently, it includes the main method for extracting files from the FTP server and uploading them to SharePoint.
|
|
75
|
+
|
|
76
|
+
#### THIES files extraction and synchronization
|
|
77
|
+
The library provides a method to extract and synchronize THIES Data Logger files with the Microsoft SharePoint client. This method downloads files from the FTP server and uploads them to the specified SharePoint folder:
|
|
78
|
+
```python
|
|
79
|
+
import asyncio
|
|
80
|
+
async def main():
|
|
81
|
+
# Before calling this method, you must have initialised the THIES service class ...
|
|
82
|
+
response = await thies_client.update_thies_data()
|
|
83
|
+
return response
|
|
84
|
+
|
|
85
|
+
asyncio.run(main())
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Access Backup Services
|
|
89
|
+
To interact with the Backup services, you can access the `backup` attribute of the `SaviiaAPI` instance:
|
|
90
|
+
```python
|
|
91
|
+
backup_client = api_client.get('backup')
|
|
92
|
+
```
|
|
93
|
+
This instance provides methods to interact with the Backup services. Currently, it includes the main method for creating backups of specified directories in a local folder from Home Assistant environment. Then each backup file is uploaded to a Microsoft SharePoint folder.
|
|
94
|
+
|
|
95
|
+
#### Create Backup
|
|
96
|
+
The library provides a method which creates a backup of a specified directory in a local folder from Home Assistant environment. Then each backup file is uploaded to a Microsoft SharePoint folder:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
import asyncio
|
|
100
|
+
async def main():
|
|
101
|
+
# Before calling this method, you must have initialised the Backup service class ...
|
|
102
|
+
response = await backup_client.upload_backup_to_sharepoint(
|
|
103
|
+
local_backup_path=LOCAL_BACKUP_PATH,
|
|
104
|
+
sharepoint_folder_path=SHAREPOINT_FOLDER_PATH
|
|
105
|
+
)
|
|
106
|
+
return response
|
|
107
|
+
asyncio.run(main())
|
|
108
|
+
```
|
|
109
|
+
**Notes:**
|
|
110
|
+
- Ensure that the `local_backup_path` exists and contains the files you want to back up. It is a relative path from the Home Assistant configuration directory.
|
|
111
|
+
- The `sharepoint_folder_path` should be the path to the folder in SharePoint where you want to upload the backup files. For example, if your url is `https://yourtenant.sharepoint.com/sites/yoursite/Shared Documents/Backups`, the folder path would be `sites/yoursite/Shared Documents/Backups`.
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
## Contributing
|
|
120
|
+
If you're interested in contributing to this project, please follow the contributing guidelines. By contributing to this project, you agree to abide by its terms.
|
|
121
|
+
Contributions are welcome and appreciated!
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
`saviialib` was created by Pedro Pablo Zavala Tejos. It is licensed under the terms of the MIT license.
|
|
126
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# SAVIIA Library
|
|
2
|
+
*Sistema de Administración y Visualización de Información para la Investigación y Análisis*
|
|
3
|
+
|
|
4
|
+
[](https://github.com/pedrozavalat/saviia-lib/releases)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
This library is designed for use with the SAVIIA Home Assistant Integration. It provides an API to retrieve files from a THIES Data Logger via an FTP server and upload them to a Microsoft SharePoint folder using the SharePoint REST API.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pip install saviialib
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Saviia API Client Usage
|
|
15
|
+
|
|
16
|
+
### Initialize the Saviia API Client
|
|
17
|
+
Import the necessary classes from the library.
|
|
18
|
+
```python
|
|
19
|
+
from saviialib import SaviiaAPI, SaviiaAPIConfig
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
To start using the library, you need to create an `SaviiaAPI` client instance with its configuration class `SaviiaAPIConfig`. Provide the required parameters such as FTP server details and SharePoint credentials:
|
|
23
|
+
```python
|
|
24
|
+
config = SaviiaAPIConfig(
|
|
25
|
+
ftp_port=FTP_PORT,
|
|
26
|
+
ftp_host=FTP_HOST,
|
|
27
|
+
ftp_user=FTP_USER,
|
|
28
|
+
ftp_password=FTP_PASSWORD,
|
|
29
|
+
sharepoint_client_id=SHAREPOINT_CLIENT_ID,
|
|
30
|
+
sharepoint_client_secret=SHAREPOINT_CLIENT_SECRET,
|
|
31
|
+
sharepoint_tenant_id=SHAREPOINT_TENANT_ID,
|
|
32
|
+
sharepoint_tenant_name=SHAREPOINT_TENANT_NAME,
|
|
33
|
+
sharepoint_site_name=SHAREPOINT_SITE_NAME
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
```python
|
|
37
|
+
api_client = SaviiaAPI(config)
|
|
38
|
+
```
|
|
39
|
+
**Notes:**
|
|
40
|
+
- 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.
|
|
41
|
+
|
|
42
|
+
### Access THIES Data Logger Services
|
|
43
|
+
To interact with the THIES Data Logger services, you can access the `thies` attribute of the `SaviiaAPI` instance:
|
|
44
|
+
```python
|
|
45
|
+
thies_client = api_client.get('thies')
|
|
46
|
+
```
|
|
47
|
+
This instance provides methods to interact with the THIES Data Logger. Currently, it includes the main method for extracting files from the FTP server and uploading them to SharePoint.
|
|
48
|
+
|
|
49
|
+
#### THIES files extraction and synchronization
|
|
50
|
+
The library provides a method to extract and synchronize THIES Data Logger files with the Microsoft SharePoint client. This method downloads files from the FTP server and uploads them to the specified SharePoint folder:
|
|
51
|
+
```python
|
|
52
|
+
import asyncio
|
|
53
|
+
async def main():
|
|
54
|
+
# Before calling this method, you must have initialised the THIES service class ...
|
|
55
|
+
response = await thies_client.update_thies_data()
|
|
56
|
+
return response
|
|
57
|
+
|
|
58
|
+
asyncio.run(main())
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Access Backup Services
|
|
62
|
+
To interact with the Backup services, you can access the `backup` attribute of the `SaviiaAPI` instance:
|
|
63
|
+
```python
|
|
64
|
+
backup_client = api_client.get('backup')
|
|
65
|
+
```
|
|
66
|
+
This instance provides methods to interact with the Backup services. Currently, it includes the main method for creating backups of specified directories in a local folder from Home Assistant environment. Then each backup file is uploaded to a Microsoft SharePoint folder.
|
|
67
|
+
|
|
68
|
+
#### Create Backup
|
|
69
|
+
The library provides a method which creates a backup of a specified directory in a local folder from Home Assistant environment. Then each backup file is uploaded to a Microsoft SharePoint folder:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import asyncio
|
|
73
|
+
async def main():
|
|
74
|
+
# Before calling this method, you must have initialised the Backup service class ...
|
|
75
|
+
response = await backup_client.upload_backup_to_sharepoint(
|
|
76
|
+
local_backup_path=LOCAL_BACKUP_PATH,
|
|
77
|
+
sharepoint_folder_path=SHAREPOINT_FOLDER_PATH
|
|
78
|
+
)
|
|
79
|
+
return response
|
|
80
|
+
asyncio.run(main())
|
|
81
|
+
```
|
|
82
|
+
**Notes:**
|
|
83
|
+
- Ensure that the `local_backup_path` exists and contains the files you want to back up. It is a relative path from the Home Assistant configuration directory.
|
|
84
|
+
- The `sharepoint_folder_path` should be the path to the folder in SharePoint where you want to upload the backup files. For example, if your url is `https://yourtenant.sharepoint.com/sites/yoursite/Shared Documents/Backups`, the folder path would be `sites/yoursite/Shared Documents/Backups`.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
## Contributing
|
|
93
|
+
If you're interested in contributing to this project, please follow the contributing guidelines. By contributing to this project, you agree to abide by its terms.
|
|
94
|
+
Contributions are welcome and appreciated!
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
`saviialib` was created by Pedro Pablo Zavala Tejos. It is licensed under the terms of the MIT license.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "saviialib"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.5.0"
|
|
4
4
|
description = "A client library for IoT projects in the RCER initiative"
|
|
5
5
|
authors = ["pedropablozavalat"]
|
|
6
6
|
license = "MIT"
|
|
@@ -12,11 +12,13 @@ aioftp = "*"
|
|
|
12
12
|
aiohttp = "*"
|
|
13
13
|
aiofiles = "*"
|
|
14
14
|
dotenv = "^0.9.9"
|
|
15
|
-
pytest-cov="^6.1.1"
|
|
16
15
|
build="*"
|
|
17
16
|
numpy = ">=2.2.0,<2.4.0"
|
|
18
17
|
pandas = ">=2.2.3,<2.3.1"
|
|
19
18
|
bitarray="*"
|
|
19
|
+
certifi="*"
|
|
20
|
+
ffmpeg-asyncio="0.1.3"
|
|
21
|
+
asyncssh="2.21.1"
|
|
20
22
|
|
|
21
23
|
[tool.poetry.group.dev.dependencies]
|
|
22
24
|
pytest = "8.3.5"
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# read version from installed package
|
|
2
|
+
from importlib.metadata import version
|
|
3
|
+
|
|
4
|
+
__version__ = version("saviialib")
|
|
5
|
+
|
|
6
|
+
from .general_types.api.saviia_api_types import SaviiaAPIConfig
|
|
7
|
+
|
|
8
|
+
from typing import Dict, Type, Any, overload, Literal, List
|
|
9
|
+
|
|
10
|
+
from saviialib.services.backup.api import SaviiaBackupAPI
|
|
11
|
+
from saviialib.services.thies.api import SaviiaThiesAPI
|
|
12
|
+
from saviialib.general_types.api.saviia_thies_api_types import SaviiaThiesConfig
|
|
13
|
+
from saviialib.general_types.api.saviia_backup_api_types import SaviiaBackupConfig
|
|
14
|
+
|
|
15
|
+
__all__ = ["SaviiaAPI", "SaviiaAPIConfig"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SaviiaAPI:
|
|
19
|
+
API_REGISTRY: Dict[str, Type] = {
|
|
20
|
+
"thies": SaviiaThiesAPI,
|
|
21
|
+
"backup": SaviiaBackupAPI,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@overload
|
|
25
|
+
def get(self, name: Literal["thies"]) -> SaviiaThiesAPI: ...
|
|
26
|
+
@overload
|
|
27
|
+
def get(self, name: Literal["backup"]) -> SaviiaBackupAPI: ...
|
|
28
|
+
|
|
29
|
+
def __init__(self, config: SaviiaAPIConfig):
|
|
30
|
+
"""
|
|
31
|
+
Receive a dictionary of configurations, with the same key
|
|
32
|
+
as those registered in API_REGISTRY.
|
|
33
|
+
|
|
34
|
+
:params configs: Dictionary of configurations for each API.
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
configs = {
|
|
38
|
+
"thies": SaviiaThiesConfig(...),
|
|
39
|
+
"backup": SaviiaBackupConfig(...)
|
|
40
|
+
}
|
|
41
|
+
"""
|
|
42
|
+
self._instances: Dict[str, Any] = {}
|
|
43
|
+
|
|
44
|
+
for name, api_class in SaviiaAPI.API_REGISTRY.items():
|
|
45
|
+
if name == "thies":
|
|
46
|
+
service_config = SaviiaThiesConfig(
|
|
47
|
+
ftp_host=config.ftp_host,
|
|
48
|
+
ftp_port=config.ftp_port,
|
|
49
|
+
ftp_user=config.ftp_user,
|
|
50
|
+
ftp_password=config.ftp_password,
|
|
51
|
+
sharepoint_client_id=config.sharepoint_client_id,
|
|
52
|
+
sharepoint_client_secret=config.sharepoint_client_secret,
|
|
53
|
+
sharepoint_tenant_id=config.sharepoint_tenant_id,
|
|
54
|
+
sharepoint_tenant_name=config.sharepoint_tenant_name,
|
|
55
|
+
sharepoint_site_name=config.sharepoint_site_name,
|
|
56
|
+
logger=config.logger,
|
|
57
|
+
)
|
|
58
|
+
elif name == "backup":
|
|
59
|
+
service_config = SaviiaBackupConfig(
|
|
60
|
+
sharepoint_client_id=config.sharepoint_client_id,
|
|
61
|
+
sharepoint_client_secret=config.sharepoint_client_secret,
|
|
62
|
+
sharepoint_tenant_id=config.sharepoint_tenant_id,
|
|
63
|
+
sharepoint_tenant_name=config.sharepoint_tenant_name,
|
|
64
|
+
sharepoint_site_name=config.sharepoint_site_name,
|
|
65
|
+
logger=config.logger,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
self._instances[name] = api_class(service_config)
|
|
69
|
+
|
|
70
|
+
def get(self, name: Literal["thies", "backup"]) -> Any:
|
|
71
|
+
"""Returns the API instance associated with the given name."""
|
|
72
|
+
try:
|
|
73
|
+
return self._instances[name]
|
|
74
|
+
except KeyError:
|
|
75
|
+
raise ValueError(f"API '{name}' is not registered or not configured.")
|
|
76
|
+
|
|
77
|
+
def list_available(self) -> List[str]:
|
|
78
|
+
"""List of available registered APIs."""
|
|
79
|
+
return list(self._instances.keys())
|
|
@@ -3,9 +3,9 @@ from logging import Logger
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
@dataclass
|
|
6
|
-
class
|
|
6
|
+
class SaviiaAPIConfig:
|
|
7
7
|
"""
|
|
8
|
-
Configuration for
|
|
8
|
+
Configuration for SAVIIA API.
|
|
9
9
|
|
|
10
10
|
Attributes:
|
|
11
11
|
ftp_port (int): Port number of the FTP server.
|
|
@@ -46,39 +46,3 @@ class SharepointConfig:
|
|
|
46
46
|
sharepoint_tenant_id: str
|
|
47
47
|
sharepoint_tenant_name: str
|
|
48
48
|
sharepoint_site_name: str
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@dataclass
|
|
52
|
-
class EpiiUpdateThiesConfig:
|
|
53
|
-
ftp_port: int
|
|
54
|
-
ftp_host: str
|
|
55
|
-
ftp_user: str
|
|
56
|
-
ftp_password: str
|
|
57
|
-
sharepoint_client_id: str
|
|
58
|
-
sharepoint_client_secret: str
|
|
59
|
-
sharepoint_tenant_id: str
|
|
60
|
-
sharepoint_tenant_name: str
|
|
61
|
-
sharepoint_site_name: str
|
|
62
|
-
logger: Logger
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@dataclass
|
|
66
|
-
class EpiiSharepointBackupConfig:
|
|
67
|
-
"""
|
|
68
|
-
Configuration for backing up files to SharePoint.
|
|
69
|
-
|
|
70
|
-
Attributes:
|
|
71
|
-
sharepoint_client_id (str): Client ID for SharePoint authentication.
|
|
72
|
-
sharepoint_client_secret (str): Client secret for SharePoint authentication.
|
|
73
|
-
sharepoint_tenant_id (str): Tenant ID for SharePoint authentication.
|
|
74
|
-
sharepoint_tenant_name (str): Tenant name for SharePoint.
|
|
75
|
-
sharepoint_site_name (str): Site name in SharePoint.
|
|
76
|
-
local_backup_source_path (str): Local path to backup.
|
|
77
|
-
"""
|
|
78
|
-
|
|
79
|
-
sharepoint_client_id: str
|
|
80
|
-
sharepoint_client_secret: str
|
|
81
|
-
sharepoint_tenant_id: str
|
|
82
|
-
sharepoint_tenant_name: str
|
|
83
|
-
sharepoint_site_name: str
|
|
84
|
-
logger: Logger
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from logging import Logger
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class SaviiaBackupConfig:
|
|
7
|
+
"""
|
|
8
|
+
Configuration for backing up files to SharePoint.
|
|
9
|
+
|
|
10
|
+
Attributes:
|
|
11
|
+
sharepoint_client_id (str): Client ID for SharePoint authentication.
|
|
12
|
+
sharepoint_client_secret (str): Client secret for SharePoint authentication.
|
|
13
|
+
sharepoint_tenant_id (str): Tenant ID for SharePoint authentication.
|
|
14
|
+
sharepoint_tenant_name (str): Tenant name for SharePoint.
|
|
15
|
+
sharepoint_site_name (str): Site name in SharePoint.
|
|
16
|
+
local_backup_source_path (str): Local path to backup.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
sharepoint_client_id: str
|
|
20
|
+
sharepoint_client_secret: str
|
|
21
|
+
sharepoint_tenant_id: str
|
|
22
|
+
sharepoint_tenant_name: str
|
|
23
|
+
sharepoint_site_name: str
|
|
24
|
+
logger: Logger
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from logging import Logger
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class SaviiaShakesConfig:
|
|
7
|
+
"""
|
|
8
|
+
Configuration for Raspberry shakes activities as Miniseed extraction, photo record and video record.
|
|
9
|
+
|
|
10
|
+
Attributes:
|
|
11
|
+
sftp_user (str): Username for SFTP Client connection
|
|
12
|
+
sftp_password (str): Password for SFTP Client connection
|
|
13
|
+
sftp_port (str): SFTP Server Port. Default port is 22.
|
|
14
|
+
ssh_key_path (str): Path to the SSH Private key for client-side authentication.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
sftp_user: str
|
|
18
|
+
sftp_password: str
|
|
19
|
+
ssh_key_path: str
|
|
20
|
+
logger: Logger
|
|
21
|
+
sftp_port: int = 22
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from logging import Logger
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class SaviiaThiesConfig:
|
|
7
|
+
"""
|
|
8
|
+
Configuration for Saviia Thies.
|
|
9
|
+
|
|
10
|
+
Attributes:
|
|
11
|
+
ftp_port (int): Port number of the FTP server.
|
|
12
|
+
ftp_host (str): Hostname or IP address of the FTP server.
|
|
13
|
+
ftp_user (str): Username for the FTP server.
|
|
14
|
+
ftp_password (str): Password for the FTP server.
|
|
15
|
+
sharepoint_client_id (str): Client ID for SharePoint authentication.
|
|
16
|
+
sharepoint_client_secret (str): Client secret for SharePoint authentication.
|
|
17
|
+
sharepoint_tenant_id (str): Tenant ID for SharePoint authentication.
|
|
18
|
+
sharepoint_tenant_name (str): Tenant name for SharePoint.
|
|
19
|
+
sharepoint_site_name (str): Site name in SharePoint.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
ftp_host: str
|
|
23
|
+
ftp_port: int
|
|
24
|
+
ftp_user: str
|
|
25
|
+
ftp_password: str
|
|
26
|
+
sharepoint_client_id: str
|
|
27
|
+
sharepoint_client_secret: str
|
|
28
|
+
sharepoint_tenant_id: str
|
|
29
|
+
sharepoint_tenant_name: str
|
|
30
|
+
sharepoint_site_name: str
|
|
31
|
+
logger: Logger
|
|
@@ -103,3 +103,11 @@ class BackupEmptyError(Exception):
|
|
|
103
103
|
|
|
104
104
|
def __str__(self):
|
|
105
105
|
return "The local backup folder is empty. "
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class ShakesNoContentError(Exception):
|
|
109
|
+
def __init__(self, *args):
|
|
110
|
+
super().__init__(*args)
|
|
111
|
+
|
|
112
|
+
def __str__(self):
|
|
113
|
+
return "All the miniSEED files have been downloaded and are in the local directory."
|
{saviialib-1.3.0 → saviialib-1.5.0}/src/saviialib/general_types/error_types/common/common_types.py
RENAMED
|
@@ -15,3 +15,12 @@ class SharepointClientError(Exception):
|
|
|
15
15
|
class FtpClientError(Exception):
|
|
16
16
|
def __str__(self):
|
|
17
17
|
return "Ftp Client initialization fails."
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SftpClientError(Exception):
|
|
21
|
+
def __init__(self, *args, reason):
|
|
22
|
+
super().__init__(*args, reason)
|
|
23
|
+
self.reason = reason
|
|
24
|
+
|
|
25
|
+
def __str__(self):
|
|
26
|
+
return "SFTP Client initialization fails." + self.reason.__str__()
|
|
@@ -19,7 +19,7 @@ class OsClient(DirectoryClientContract):
|
|
|
19
19
|
return await asyncio.to_thread(os.listdir, path)
|
|
20
20
|
|
|
21
21
|
@staticmethod
|
|
22
|
-
async def isdir(path: str) ->
|
|
22
|
+
async def isdir(path: str) -> bool:
|
|
23
23
|
return await asyncio.to_thread(os.path.isdir, path)
|
|
24
24
|
|
|
25
25
|
@staticmethod
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from saviialib.libs.ffmpeg_client.types.ffmpeg_client_types import (
|
|
2
|
+
FfmpegClientInitArgs,
|
|
3
|
+
RecordPhotoArgs,
|
|
4
|
+
RecordVideoArgs,
|
|
5
|
+
)
|
|
6
|
+
from saviialib.libs.ffmpeg_client.ffmpeg_client_contract import FfmpegClientContract
|
|
7
|
+
from typing import List
|
|
8
|
+
import asyncio
|
|
9
|
+
import shutil
|
|
10
|
+
|
|
11
|
+
from saviialib.libs.directory_client import DirectoryClient, DirectoryClientArgs
|
|
12
|
+
from saviialib.libs.zero_dependency.utils.datetime_utils import today, datetime_to_str
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class FfmpegAsyncioClient(FfmpegClientContract):
|
|
16
|
+
def __init__(self, args: FfmpegClientInitArgs) -> None:
|
|
17
|
+
self.dir_client = DirectoryClient(DirectoryClientArgs("os_client"))
|
|
18
|
+
|
|
19
|
+
def _setup_io_args(
|
|
20
|
+
self,
|
|
21
|
+
rtsp_user: str,
|
|
22
|
+
rtsp_pwd: str,
|
|
23
|
+
ip: str,
|
|
24
|
+
dest_path: str,
|
|
25
|
+
record_prefix: str,
|
|
26
|
+
record_type: str,
|
|
27
|
+
):
|
|
28
|
+
input_arg = f"rtsp://{rtsp_user}:{rtsp_pwd}@{ip}/stream1"
|
|
29
|
+
output_file = (
|
|
30
|
+
record_prefix
|
|
31
|
+
+ "_"
|
|
32
|
+
+ datetime_to_str(today(), date_format="%m-%d-%Y_%H-%M-%S")
|
|
33
|
+
+ f".{record_type}"
|
|
34
|
+
)
|
|
35
|
+
output_arg = self.dir_client.join_paths(dest_path, output_file)
|
|
36
|
+
return input_arg, output_arg
|
|
37
|
+
|
|
38
|
+
async def _ensure_ffmpeg_available(self):
|
|
39
|
+
if shutil.which("ffmpeg"):
|
|
40
|
+
return
|
|
41
|
+
install_cmd = ["apk", "add", "ffmpeg"] # Only for Home Assistant OS
|
|
42
|
+
process = await asyncio.create_subprocess_shell(
|
|
43
|
+
*install_cmd,
|
|
44
|
+
stdout=asyncio.subprocess.DEVNULL,
|
|
45
|
+
stdin=asyncio.subprocess.PIPE,
|
|
46
|
+
)
|
|
47
|
+
_, stderr = await process.communicate()
|
|
48
|
+
if process.returncode != 0:
|
|
49
|
+
raise ConnectionAbortedError("Failed to install ffmpeg: ", stderr.decode())
|
|
50
|
+
|
|
51
|
+
async def _setup_command(
|
|
52
|
+
self, input_arg: str, output_arg: str, extra: dict
|
|
53
|
+
) -> List[str]:
|
|
54
|
+
await self._ensure_ffmpeg_available() # Validate ffmpeg module is installed.
|
|
55
|
+
cmd = ["ffmpeg", "-y", "-i", input_arg, output_arg]
|
|
56
|
+
for k, v in extra.values():
|
|
57
|
+
cmd.insert(-1, k)
|
|
58
|
+
cmd.insert(-1, v)
|
|
59
|
+
return list(map(str, cmd))
|
|
60
|
+
|
|
61
|
+
async def record_video(self, args: RecordVideoArgs):
|
|
62
|
+
input_arg, output_arg = self._setup_io_args(
|
|
63
|
+
args.rtsp_user,
|
|
64
|
+
args.rtsp_password,
|
|
65
|
+
args.ip_address,
|
|
66
|
+
args.destination_path,
|
|
67
|
+
"Video",
|
|
68
|
+
args.extension,
|
|
69
|
+
)
|
|
70
|
+
cmd = await self._setup_command(
|
|
71
|
+
input_arg, output_arg, extra={"-t": args.duration}
|
|
72
|
+
)
|
|
73
|
+
process = await asyncio.create_subprocess_exec(
|
|
74
|
+
*cmd, stderr=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE
|
|
75
|
+
)
|
|
76
|
+
_, stderr = await process.communicate()
|
|
77
|
+
if process.returncode != 0:
|
|
78
|
+
raise ConnectionError(
|
|
79
|
+
"Unexpected error while recording the video: ", stderr.decode()
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
async def record_photo(self, args: RecordPhotoArgs):
|
|
83
|
+
input_arg, output_arg = self._setup_io_args(
|
|
84
|
+
args.rtsp_user,
|
|
85
|
+
args.rtsp_password,
|
|
86
|
+
args.ip_address,
|
|
87
|
+
args.destination_path,
|
|
88
|
+
"Photo",
|
|
89
|
+
args.extension,
|
|
90
|
+
)
|
|
91
|
+
cmd = await self._setup_command(
|
|
92
|
+
input_arg, output_arg, extra={"-frames:v": args.frames}
|
|
93
|
+
)
|
|
94
|
+
process = await asyncio.create_subprocess_exec(
|
|
95
|
+
*cmd, stderr=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE
|
|
96
|
+
)
|
|
97
|
+
_, stderr = await process.communicate()
|
|
98
|
+
if process.returncode != 0:
|
|
99
|
+
raise ConnectionError(
|
|
100
|
+
"Unexpected error while recording the photo: ", stderr.decode()
|
|
101
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from .ffmpeg_client_contract import FfmpegClientContract
|
|
2
|
+
from .types.ffmpeg_client_types import (
|
|
3
|
+
RecordPhotoArgs,
|
|
4
|
+
RecordVideoArgs,
|
|
5
|
+
FfmpegClientInitArgs,
|
|
6
|
+
)
|
|
7
|
+
from .clients.ffmpeg_asyncio_client import FfmpegAsyncioClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FfmpegClient(FfmpegClientContract):
|
|
11
|
+
CLIENTS = {"ffmpeg_asyncio"}
|
|
12
|
+
|
|
13
|
+
def __init__(self, args: FfmpegClientInitArgs) -> None:
|
|
14
|
+
if args.client_name not in FfmpegClient.CLIENTS:
|
|
15
|
+
msg = f"Unsupported client {args.client_name}"
|
|
16
|
+
raise KeyError(msg)
|
|
17
|
+
if args.client_name == "ffmpeg_asyncio":
|
|
18
|
+
self.client_obj = FfmpegAsyncioClient(args)
|
|
19
|
+
self.client_name = args.client_name
|
|
20
|
+
|
|
21
|
+
def record_photo(self, args: RecordPhotoArgs):
|
|
22
|
+
return self.client_obj.record_photo(args)
|
|
23
|
+
|
|
24
|
+
def record_video(self, args: RecordVideoArgs):
|
|
25
|
+
return self.client_obj.record_video(args)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from .types.ffmpeg_client_types import RecordPhotoArgs, RecordVideoArgs
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FfmpegClientContract(ABC):
|
|
6
|
+
@abstractmethod
|
|
7
|
+
async def record_photo(self, args: RecordPhotoArgs):
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
@abstractmethod
|
|
11
|
+
async def record_video(self, args: RecordVideoArgs):
|
|
12
|
+
pass
|