saviialib 0.9.1__py3-none-any.whl → 0.10.2__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.

Potentially problematic release.


This version of saviialib might be problematic. Click here for more details.

@@ -1,4 +1,5 @@
1
1
  from dataclasses import dataclass
2
+ from logging import Logger
2
3
 
3
4
 
4
5
  @dataclass
@@ -27,6 +28,7 @@ class EpiiAPIConfig:
27
28
  sharepoint_tenant_id: str
28
29
  sharepoint_tenant_name: str
29
30
  sharepoint_site_name: str
31
+ logger: Logger
30
32
 
31
33
 
32
34
  @dataclass
@@ -80,3 +82,4 @@ class EpiiSharepointBackupConfig:
80
82
  sharepoint_site_name: str
81
83
  local_backup_source_path: str
82
84
  destination_folders: str
85
+ logger: Logger
@@ -0,0 +1,4 @@
1
+ from .directory_client import DirectoryClient
2
+ from .types.directory_client_types import DirectoryClientArgs
3
+
4
+ __all__ = ["DirectoryClient", "DirectoryClientArgs"]
@@ -0,0 +1,23 @@
1
+ from saviialib.libs.directory_client.directory_client_contract import (
2
+ DirectoryClientContract,
3
+ )
4
+ import os
5
+ import asyncio
6
+
7
+
8
+ class OsClient(DirectoryClientContract):
9
+ @staticmethod
10
+ def join_paths(*paths: str) -> str:
11
+ return os.path.join(*paths)
12
+
13
+ @staticmethod
14
+ async def path_exists(path: str) -> bool:
15
+ return await asyncio.to_thread(os.path.exists, path)
16
+
17
+ @staticmethod
18
+ async def listdir(path: str) -> list:
19
+ return await asyncio.to_thread(os.listdir, path)
20
+
21
+ @staticmethod
22
+ async def isdir(path: str) -> list:
23
+ return await asyncio.to_thread(os.path.isdir, path)
@@ -0,0 +1,28 @@
1
+ from .client.os_client import OsClient
2
+ from .directory_client_contract import DirectoryClientContract
3
+ from .types.directory_client_types import DirectoryClientArgs
4
+
5
+
6
+ class DirectoryClient(DirectoryClientContract):
7
+ CLIENTS = {"os_client"}
8
+
9
+ def __init__(self, args: DirectoryClientArgs) -> None:
10
+ if args.client_name not in DirectoryClient.CLIENTS:
11
+ msg = f"Unsupported client {args.client_name}"
12
+ raise KeyError(msg)
13
+
14
+ if args.client_name == "os_client":
15
+ self.client_obj = OsClient()
16
+ self.client_name = args.client_name
17
+
18
+ def join_paths(self, *paths: str) -> str:
19
+ return self.client_obj.join_paths(*paths)
20
+
21
+ async def path_exists(self, path: str) -> bool:
22
+ return await self.client_obj.path_exists(path)
23
+
24
+ async def listdir(self, path: str) -> list:
25
+ return await self.client_obj.listdir(path)
26
+
27
+ async def isdir(self, path: str) -> bool:
28
+ return await self.client_obj.isdir(path)
@@ -0,0 +1,19 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class DirectoryClientContract(ABC):
5
+ @abstractmethod
6
+ def join_paths(self, *paths: str) -> str:
7
+ pass
8
+
9
+ @abstractmethod
10
+ async def path_exists(self, path: str) -> bool:
11
+ pass
12
+
13
+ @abstractmethod
14
+ async def listdir(self, path: str) -> list:
15
+ pass
16
+
17
+ @abstractmethod
18
+ async def isdir(self, path) -> bool:
19
+ pass
@@ -0,0 +1,6 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class DirectoryClientArgs:
6
+ client_name: str = "os_client"
@@ -1,4 +1,4 @@
1
1
  from .files_client import FilesClient
2
- from .types.files_client_types import FilesClientInitArgs, ReadArgs
2
+ from .types.files_client_types import FilesClientInitArgs, ReadArgs, WriteArgs
3
3
 
4
- __all__ = ["FilesClient", "FilesClientInitArgs", "ReadArgs"]
4
+ __all__ = ["FilesClient", "FilesClientInitArgs", "ReadArgs", "WriteArgs"]
@@ -1,5 +1,8 @@
1
1
  import aiofiles
2
-
2
+ from saviialib.libs.directory_client.directory_client import (
3
+ DirectoryClient,
4
+ DirectoryClientArgs,
5
+ )
3
6
  from saviialib.libs.files_client.files_client_contract import FilesClientContract
4
7
  from saviialib.libs.files_client.types.files_client_types import (
5
8
  FilesClientInitArgs,
@@ -10,7 +13,7 @@ from saviialib.libs.files_client.types.files_client_types import (
10
13
 
11
14
  class AioFilesClient(FilesClientContract):
12
15
  def __init__(self, args: FilesClientInitArgs):
13
- pass
16
+ self.dir_client = DirectoryClient(DirectoryClientArgs(client_name="os_client"))
14
17
 
15
18
  async def read(self, args: ReadArgs) -> str | bytes:
16
19
  encoding = None if args.mode == "rb" else args.encoding
@@ -18,4 +21,10 @@ class AioFilesClient(FilesClientContract):
18
21
  return await file.read()
19
22
 
20
23
  async def write(self, args: WriteArgs) -> None:
21
- return None
24
+ file_path = (
25
+ self.dir_client.join_paths(args.destination_path, args.file_name)
26
+ if args.destination_path
27
+ else args.file_name
28
+ )
29
+ async with aiofiles.open(file_path, args.mode) as file:
30
+ await file.write(args.file_content)
@@ -26,6 +26,7 @@ class ReadArgs:
26
26
 
27
27
  @dataclass
28
28
  class WriteArgs:
29
- destination_path: str
30
29
  file_name: str
31
30
  file_content: str | bytes
31
+ mode: Literal["w", "wb", "a"]
32
+ destination_path: str = ""
@@ -28,6 +28,7 @@ class EpiiAPI:
28
28
  self.sharepoint_tenant_id = config.sharepoint_tenant_id
29
29
  self.sharepoint_tenant_name = config.sharepoint_tenant_name
30
30
  self.sharepoint_site_name = config.sharepoint_site_name
31
+ self.logger = config.logger
31
32
 
32
33
  async def update_thies_data(self) -> Dict[str, Any]:
33
34
  """
@@ -70,7 +71,8 @@ class EpiiAPI:
70
71
  sharepoint_tenant_id=self.sharepoint_tenant_id,
71
72
  sharepoint_tenant_name=self.sharepoint_tenant_name,
72
73
  local_backup_source_path=local_backup_source_path,
73
- destination_folders=destination_folders
74
+ destination_folders=destination_folders,
75
+ logger=self.logger,
74
76
  )
75
77
 
76
78
  controller = UploadBackupToSharepointController(
@@ -34,7 +34,8 @@ class UploadBackupToSharepointController:
34
34
  sharepoint_tenant_id=input.config.sharepoint_tenant_id,
35
35
  ),
36
36
  local_backup_source_path=input.config.local_backup_source_path,
37
- destination_folders=input.config.destination_folders
37
+ destination_folders=input.config.destination_folders,
38
+ logger=input.config.logger,
38
39
  )
39
40
  )
40
41
 
@@ -2,4 +2,5 @@ import logging
2
2
 
3
3
  SHAREPOINT_BASE_URL = "/sites/uc365_CentrosyEstacionesRegionalesUC/Shared%20Documents/General/Test_Raspberry"
4
4
 
5
+ logging.basicConfig(level=logging.DEBUG)
5
6
  LOGGER = logging.getLogger(__package__)
@@ -1,5 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from saviialib.general_types.api.epii_api_types import SharepointConfig
3
+ from logging import Logger
3
4
 
4
5
 
5
6
  @dataclass
@@ -7,3 +8,4 @@ class UploadBackupToSharepointUseCaseInput:
7
8
  sharepoint_config: SharepointConfig
8
9
  local_backup_source_path: str
9
10
  destination_folders: dict
11
+ logger: Logger
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
- import os
3
2
  from time import time
3
+ from logging import Logger
4
4
  import saviialib.services.epii.use_cases.constants.upload_backup_to_sharepoint_constants as c
5
5
  from saviialib.general_types.error_types.api.epii_api_error_types import (
6
6
  BackupEmptyError,
@@ -10,7 +10,13 @@ from saviialib.general_types.error_types.api.epii_api_error_types import (
10
10
  from saviialib.general_types.error_types.common import (
11
11
  SharepointClientError,
12
12
  )
13
- from saviialib.libs.files_client import FilesClient, FilesClientInitArgs, ReadArgs
13
+ from saviialib.libs.directory_client import DirectoryClient, DirectoryClientArgs
14
+ from saviialib.libs.files_client import (
15
+ FilesClient,
16
+ FilesClientInitArgs,
17
+ ReadArgs,
18
+ WriteArgs,
19
+ )
14
20
  from saviialib.libs.sharepoint_client import (
15
21
  SharepointClient,
16
22
  SharepointClientInitArgs,
@@ -19,7 +25,6 @@ from saviialib.libs.sharepoint_client import (
19
25
  from saviialib.services.epii.utils.upload_backup_to_sharepoint_utils import (
20
26
  calculate_percentage_uploaded,
21
27
  count_files_in_directory,
22
- directory_exists,
23
28
  extract_error_message,
24
29
  parse_execute_response,
25
30
  show_upload_result,
@@ -28,7 +33,6 @@ from saviialib.services.epii.utils.upload_backup_to_sharepoint_utils import (
28
33
  from .types.upload_backup_to_sharepoint_types import (
29
34
  UploadBackupToSharepointUseCaseInput,
30
35
  )
31
- from .constants.upload_backup_to_sharepoint_constants import LOGGER
32
36
 
33
37
 
34
38
  class UploadBackupToSharepointUsecase:
@@ -37,38 +41,47 @@ class UploadBackupToSharepointUsecase:
37
41
  self.local_backup_source_path = input.local_backup_source_path
38
42
  self.destination_folders = input.destination_folders
39
43
  self.files_client = self._initialize_files_client()
44
+ self.dir_client = self._initialize_directory_client()
40
45
  self.log_history = []
41
46
  self.grouped_files_by_folder = None
42
47
  self.total_files = None
48
+ self.logger: Logger = input.logger
49
+
50
+ def _initialize_directory_client(self):
51
+ return DirectoryClient(DirectoryClientArgs(client_name="os_client"))
43
52
 
44
53
  def _initialize_files_client(self):
45
54
  return FilesClient(FilesClientInitArgs(client_name="aiofiles_client"))
46
55
 
47
56
  async def _extract_filesnames_by_folder(self) -> dict[str, list[str]]:
48
57
  """Groups files by their parent folder."""
49
- backup_folder_exists = await asyncio.to_thread(
50
- os.path.exists, self.local_backup_source_path
58
+ backup_folder_exists = await self.dir_client.path_exists(
59
+ self.local_backup_source_path
51
60
  )
61
+
52
62
  if not backup_folder_exists:
53
63
  return {}
54
- folder_names = await asyncio.to_thread(
55
- os.listdir, self.local_backup_source_path
56
- )
64
+ folder_names = await self.dir_client.listdir(self.local_backup_source_path)
57
65
  return {
58
66
  folder_name: [
59
67
  file_name
60
- for file_name in await asyncio.to_thread(
61
- os.listdir, os.path.join(self.local_backup_source_path, folder_name)
68
+ for file_name in await self.dir_client.listdir(
69
+ self.dir_client.join_paths(
70
+ self.local_backup_source_path, folder_name
71
+ )
62
72
  )
63
73
  ]
64
74
  for folder_name in folder_names
65
75
  }
66
76
 
67
- def _save_log_history(self) -> None:
68
- text_file = "\n".join(self.log_history)
69
- log_history_filepath = "BACKUP_LOG_HISTORY.log"
70
- with open(log_history_filepath, "w") as file:
71
- file.write(text_file)
77
+ async def _save_log_history(self) -> None:
78
+ await self.files_client.write(
79
+ WriteArgs(
80
+ file_name="BACKUP_LOG_HISTORY.log",
81
+ file_content="\n".join(self.log_history),
82
+ mode="w",
83
+ )
84
+ )
72
85
 
73
86
  async def export_file_to_sharepoint(
74
87
  self, folder_name: str, file_name: str, file_content: bytes
@@ -105,20 +118,22 @@ class UploadBackupToSharepointUsecase:
105
118
 
106
119
  return uploaded, error_message
107
120
 
108
- async def upload_and_log_progress_task(self, folder_name, file_name) -> dict:
121
+ async def _upload_and_log_progress_task(self, folder_name, file_name) -> dict:
109
122
  """Task for uploads a file and logs progress."""
110
123
  uploading_message = (
111
- f"[BACKUP] Uploading file '{file_name}' from '{folder_name}' "
124
+ f"[local_backup_lib] Uploading file '{file_name}' from '{folder_name}' "
112
125
  )
113
126
  self.log_history.append(uploading_message)
114
- LOGGER.debug(uploading_message)
115
- file_path = os.path.join(self.local_backup_source_path, folder_name, file_name)
127
+ self.logger.debug(uploading_message)
128
+ file_path = self.dir_client.join_paths(
129
+ self.local_backup_source_path, folder_name, file_name
130
+ )
116
131
  file_content = await self.files_client.read(ReadArgs(file_path, mode="rb"))
117
132
  uploaded, error_message = await self.export_file_to_sharepoint(
118
133
  folder_name, file_name, file_content
119
134
  )
120
135
  result_message = show_upload_result(uploaded, file_name)
121
- LOGGER.debug(result_message)
136
+ self.logger.debug(result_message)
122
137
  self.log_history.append(result_message)
123
138
  return {
124
139
  "parent_folder": folder_name,
@@ -130,28 +145,28 @@ class UploadBackupToSharepointUsecase:
130
145
  async def retry_upload_failed_files(self, results) -> None:
131
146
  failed_files = [item for item in results if not item["uploaded"]]
132
147
  tasks = []
133
- retry_message = (
134
- f"[BACKUP] Retrying upload for {len(failed_files)} failed files... 🚨"
135
- )
148
+ retry_message = f"[local_backup_lib] Retrying upload for {len(failed_files)} failed files... 🚨"
136
149
  self.log_history.append(retry_message)
137
- LOGGER.debug(retry_message)
150
+ self.logger.debug(retry_message)
138
151
  for file in failed_files:
139
152
  tasks.append(
140
- self.upload_and_log_progress_task(
153
+ self._upload_and_log_progress_task(
141
154
  file["parent_folder"], file["file_name"]
142
155
  )
143
156
  )
144
157
  results = await asyncio.gather(*tasks, return_exceptions=True)
145
158
  success = calculate_percentage_uploaded(results, self.total_files)
146
159
  if success < 100.0:
147
- raise BackupUploadError(reason=extract_error_message(results, success))
160
+ raise BackupUploadError(
161
+ reason=extract_error_message(self.logger, results, success)
162
+ )
148
163
  else:
149
164
  successful_upload_retry = (
150
- "[BACKUP] All files uploaded successfully after retry."
165
+ "[local_backup_lib] All files uploaded successfully after retry."
151
166
  )
152
167
  self.log_history.append(successful_upload_retry)
153
- LOGGER.debug(successful_upload_retry)
154
- self._save_log_history()
168
+ self.logger.debug(successful_upload_retry)
169
+ await self._save_log_history()
155
170
  return parse_execute_response(results)
156
171
 
157
172
  async def execute(self):
@@ -164,7 +179,7 @@ class UploadBackupToSharepointUsecase:
164
179
  start_time = time()
165
180
 
166
181
  # Check if the local path exists in the main directory
167
- if not await directory_exists(self.local_backup_source_path):
182
+ if not await self.dir_client.path_exists(self.local_backup_source_path):
168
183
  raise BackupSourcePathError(
169
184
  reason=f"'{self.local_backup_source_path}' doesn't exist."
170
185
  )
@@ -172,14 +187,12 @@ class UploadBackupToSharepointUsecase:
172
187
  # Check if the current folder only have files.
173
188
  items = [
174
189
  item
175
- for item in await asyncio.to_thread(
176
- os.listdir, self.local_backup_source_path
177
- )
190
+ for item in await self.dir_client.listdir(self.local_backup_source_path)
178
191
  ]
179
192
  for item in items:
180
193
  folder_included = item in self.destination_folders.keys()
181
- is_file = not await asyncio.to_thread(
182
- os.path.isdir, os.path.join(self.local_backup_source_path, item)
194
+ is_file = not await self.dir_client.isdir(
195
+ self.dir_client.join_paths(self.local_backup_source_path, item)
183
196
  )
184
197
 
185
198
  if not folder_included and not is_file:
@@ -194,10 +207,10 @@ class UploadBackupToSharepointUsecase:
194
207
 
195
208
  if self.total_files == 0:
196
209
  no_files_message = (
197
- f"[BACKUP] {self.local_backup_source_path} has no files ⚠️"
210
+ f"[local_backup_lib] {self.local_backup_source_path} has no files ⚠️"
198
211
  )
199
212
  self.log_history.append(no_files_message)
200
- LOGGER.debug(no_files_message)
213
+ self.logger.debug(no_files_message)
201
214
  raise BackupEmptyError
202
215
  # Create task for each file stored in the the local backup folder.
203
216
  for folder_name in self.grouped_files_by_folder:
@@ -207,17 +220,20 @@ class UploadBackupToSharepointUsecase:
207
220
  )
208
221
  == 0
209
222
  ):
210
- empty_folder_message = f"[BACKUP] The folder '{folder_name}' is empty ⚠️"
211
- LOGGER.debug(empty_folder_message)
223
+ empty_folder_message = (
224
+ f"[local_backup_lib] The folder '{folder_name}' is empty ⚠️"
225
+ )
226
+ self.logger.debug(empty_folder_message)
212
227
  self.log_history.append(empty_folder_message)
213
228
  continue
214
229
  extracting_files_message = (
215
- "[BACKUP]" + f" Extracting files from '{folder_name} ".center(15, "*")
230
+ "[local_backup_lib]"
231
+ + f" Extracting files from '{folder_name} ".center(15, "*")
216
232
  )
217
233
  self.log_history.append(extracting_files_message)
218
- LOGGER.debug(extracting_files_message)
234
+ self.logger.debug(extracting_files_message)
219
235
  for file_name in self.grouped_files_by_folder[folder_name]:
220
- tasks.append(self.upload_and_log_progress_task(folder_name, file_name))
236
+ tasks.append(self._upload_and_log_progress_task(folder_name, file_name))
221
237
 
222
238
  # Execution of multiple asynchronous tasks for files migration.
223
239
  results = await asyncio.gather(*tasks, return_exceptions=True)
@@ -228,14 +244,14 @@ class UploadBackupToSharepointUsecase:
228
244
  end_time = time()
229
245
  backup_time = end_time - start_time
230
246
  successful_backup_message = (
231
- f"[BACKUP] Migration time: {backup_time:.2f} seconds ✨"
247
+ f"[local_backup_lib] Migration time: {backup_time:.2f} seconds ✨"
232
248
  )
233
249
  self.log_history.append(successful_backup_message)
234
250
 
235
251
  finished_backup_message = (
236
- "[BACKUP] All the files were uploaded successfully 🎉"
252
+ "[local_backup_lib] All the files were uploaded successfully 🎉"
237
253
  )
238
254
  self.log_history.append(finished_backup_message)
239
255
 
240
- self._save_log_history()
256
+ await self._save_log_history()
241
257
  return parse_execute_response(results)
@@ -1,13 +1,12 @@
1
1
  import re
2
+ from logging import Logger
2
3
  from typing import List, Dict, Optional
3
- import asyncio
4
- import os
5
4
  from saviialib.general_types.error_types.api.epii_api_error_types import (
6
5
  BackupSourcePathError,
7
6
  )
8
- from saviialib.services.epii.use_cases.constants.upload_backup_to_sharepoint_constants import (
9
- LOGGER,
10
- )
7
+ from saviialib.libs.directory_client import DirectoryClient, DirectoryClientArgs
8
+
9
+ dir_client = DirectoryClient(DirectoryClientArgs(client_name="os_client"))
11
10
 
12
11
 
13
12
  def extract_error_information(error: str) -> Optional[Dict[str, str]]:
@@ -30,10 +29,10 @@ def explain_status_code(status_code: int) -> str:
30
29
  return explanations.get(status_code, "Unknown error occurred.")
31
30
 
32
31
 
33
- def extract_error_message(results: List[Dict], success: float) -> str:
34
- LOGGER.info(
35
- "[BACKUP] Not all files uploaded ⚠️\n"
36
- f"[BACKUP] Files failed to upload: {(1 - success):.2%}"
32
+ def extract_error_message(logger: Logger, results: List[Dict], success: float) -> str:
33
+ logger.info(
34
+ "[local_backup_lib] Not all files uploaded ⚠️\n"
35
+ f"[local_backup_lib] Files failed to upload: {(1 - success):.2%}"
37
36
  )
38
37
 
39
38
  failed_files = [item for item in results if not item.get("uploaded")]
@@ -59,10 +58,12 @@ def extract_error_message(results: List[Dict], success: float) -> str:
59
58
 
60
59
  # Summary
61
60
  for code, items in grouped_errors.items():
62
- LOGGER.info(f"[BACKUP] Status code {code} - {explain_status_code(int(code))}")
61
+ logger.info(
62
+ f"[local_backup_lib] Status code {code} - {explain_status_code(int(code))}"
63
+ )
63
64
  for item in items:
64
- LOGGER.info(
65
- f"[BACKUP] File {item['file_name']}, url: {item['url']}, message: {item['message']}"
65
+ logger.info(
66
+ f"[local_backup_lib] File {item['file_name']}, url: {item['url']}, message: {item['message']}"
66
67
  )
67
68
 
68
69
  failed_file_names = [item["file_name"] for item in failed_files]
@@ -83,7 +84,7 @@ def parse_execute_response(results: List[Dict]) -> Dict[str, List[str]]:
83
84
  def show_upload_result(uploaded: bool, file_name: str) -> str:
84
85
  status = "✅" if uploaded else "❌"
85
86
  message = "was uploaded successfully" if uploaded else "failed to upload"
86
- result = f"[BACKUP] File {file_name} {message} {status}"
87
+ result = f"[local_backup_lib] File {file_name} {message} {status}"
87
88
  return result
88
89
 
89
90
 
@@ -94,9 +95,5 @@ def calculate_percentage_uploaded(results: List[Dict], total_files: int) -> floa
94
95
  return (uploaded_count / total_files) * 100 if total_files > 0 else 0
95
96
 
96
97
 
97
- async def directory_exists(path: str) -> bool:
98
- return await asyncio.to_thread(os.path.exists, path)
99
-
100
-
101
98
  async def count_files_in_directory(path: str, folder_name: str) -> int:
102
- return len(await asyncio.to_thread(os.listdir, os.path.join(path, folder_name)))
99
+ return len(await dir_client.listdir(dir_client.join_paths(path, folder_name)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: saviialib
3
- Version: 0.9.1
3
+ Version: 0.10.2
4
4
  Summary: A client library for IoT projects in the RCER initiative
5
5
  License: MIT
6
6
  Author: pedropablozavalat
@@ -1,17 +1,22 @@
1
1
  saviialib/__init__.py,sha256=TMsEY8OOjo9KOz-0jf3QBh6WFOhCY07Rd7W2PK7C-1A,253
2
2
  saviialib/general_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  saviialib/general_types/api/__init__.py,sha256=jXhoMlbSv7UCizW_Fm2mqR_3n99qkocVwg6CF7s3w7w,145
4
- saviialib/general_types/api/epii_api_types.py,sha256=_3Q20yOTHn8Vmsx-fn_FR9XF2P719KobFrklxsdDr1U,2324
4
+ saviialib/general_types/api/epii_api_types.py,sha256=H4oUMnkYnl75mdCO4kyOqOdJ5jIh-J9tgGU_ZK2m7V8,2389
5
5
  saviialib/general_types/error_types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  saviialib/general_types/error_types/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  saviialib/general_types/error_types/api/epii_api_error_types.py,sha256=j1b2gE8zRTlh4gCB4kf9-JNlBzcZ9AmMKxRiFVbSqQ0,2722
8
8
  saviialib/general_types/error_types/common/__init__.py,sha256=yOBLZbt64Ki9Q0IJ0tMAubgq7PtrQ7XQ3RgtAzyOjiE,170
9
9
  saviialib/general_types/error_types/common/common_types.py,sha256=n5yuw-gVtkrtNfmaZ83ZkYxYHGl4jynOLUB9C8Tr32w,474
10
- saviialib/libs/files_client/__init__.py,sha256=eLmYkda0vsd8qB8oMjOq0nM7GIyShNmx3nmmcc0lN7Y,168
11
- saviialib/libs/files_client/clients/aiofiles_client.py,sha256=lGZ24YzNbCIIlgiwheoOdSh0hr07F893bX5NzrVlveg,651
10
+ saviialib/libs/directory_client/__init__.py,sha256=ys07nzp74fHew2mUkbGpntp5w4t_PnhZIS6D4_mJw2A,162
11
+ saviialib/libs/directory_client/client/os_client.py,sha256=cL1ocxfLu6csBg7RKhP7sbpgCUr6_Me5cMOs4wrXmhw,628
12
+ saviialib/libs/directory_client/directory_client.py,sha256=mcYA2AY0f44ae39ImsetVRU8YW7xI25xTFTY5HmWivY,984
13
+ saviialib/libs/directory_client/directory_client_contract.py,sha256=eRTKPkpArMSi7gEDoowJ15hupLB_gr4ztO1Zc1BoXpc,396
14
+ saviialib/libs/directory_client/types/directory_client_types.py,sha256=ncMwVs_o6EYMuypXXmVInsjVDKJsdxVkmwj1M-LEInA,109
15
+ saviialib/libs/files_client/__init__.py,sha256=sIi9ne7Z3EfxnqGTaSmH-cZ8QsKyu0hoOz61GyA3njs,192
16
+ saviialib/libs/files_client/clients/aiofiles_client.py,sha256=Mu5pSnnEa3dT3GONmt1O-lCQstuQNXHtJHM3D2L6TU8,1107
12
17
  saviialib/libs/files_client/files_client.py,sha256=eoByr7ZzOJ3b4NWlrEH0jKO1i-Rv3hSJV2s2JLhaOJ0,1081
13
18
  saviialib/libs/files_client/files_client_contract.py,sha256=fYvd68IMpc1OFkxbzNSmRUoTWVctf3hkNVQ7QZV0m6I,304
14
- saviialib/libs/files_client/types/files_client_types.py,sha256=gsQrIFo9AWHIEEB9pTcDOpUY87QzAfHsSVHXdPzxd_g,679
19
+ saviialib/libs/files_client/types/files_client_types.py,sha256=8OHm4nvZTW9K3ryeIUvthE_Cj7wF4zVcqG0KCi_vQIU,718
15
20
  saviialib/libs/ftp_client/__init__.py,sha256=dW2Yutgc7mJJJzgKLhWKXMgQ6KIWJYfFa1sGpjHH5xU,191
16
21
  saviialib/libs/ftp_client/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
22
  saviialib/libs/ftp_client/clients/aioftp_client.py,sha256=gcPhLX1EE8_iiAGQ1eTWxzJ-qd3yjP9Ug1LJPibqGn8,1613
@@ -26,24 +31,24 @@ saviialib/libs/sharepoint_client/sharepoint_client_contract.py,sha256=xqNHzCjp7G
26
31
  saviialib/libs/sharepoint_client/types/sharepoint_client_types.py,sha256=OmPlCJ9rLrAFBeG6aDp5cxMiQ5BZlDyGVx5S4GN4aqg,414
27
32
  saviialib/libs/zero_dependency/utils/datetime_utils.py,sha256=NFPHxOTuCtfkYjUnsbRqw9ZK87UGAK-Eira2CwG8rJ8,754
28
33
  saviialib/services/epii/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- saviialib/services/epii/api.py,sha256=rAiyf6sumaW9DIdqT5KKGMk0iIP6_tnN2__oLIuDuiI,3488
34
+ saviialib/services/epii/api.py,sha256=ykS32tt2X3ocuHtEe8oyyg94a0l7IcMhxCMrqZ6Mc4U,3557
30
35
  saviialib/services/epii/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
36
  saviialib/services/epii/controllers/types/__init__.py,sha256=xzky-oTSojLNkWETp_k8a4dcXYvYSQY0VhWo23Yhb8U,195
32
37
  saviialib/services/epii/controllers/types/update_thies_data_types.py,sha256=Id86QaFt6A2EJgHJvmm3rvWGUkT2SM8D5OTxZGS-aTs,380
33
38
  saviialib/services/epii/controllers/types/upload_backup_to_sharepoint_types.py,sha256=k_vfqI4UfdSS62HY5pi8eq2PxYXRp4LexDgRB3V2lrc,400
34
39
  saviialib/services/epii/controllers/update_thies_data.py,sha256=5vi-CEXV9maCTHgyZRnGs8zlc2xkEQ3TJMVza4xr-Qw,4334
35
- saviialib/services/epii/controllers/upload_backup_to_sharepoint.py,sha256=l3oBiPU1GHYuVI8LCnDQhY_2xH7bqiQzJ4lB_is4VAM,3754
40
+ saviialib/services/epii/controllers/upload_backup_to_sharepoint.py,sha256=2op1yGEy9DNJW5ryzBNTniVQZqdc8twAs3VIsGsnidg,3799
36
41
  saviialib/services/epii/use_cases/constants/update_thies_data_constants.py,sha256=38f2WKV-zBO9O-CV8mh3tW3MFMiaJrrv4_FfQiyHApc,275
37
- saviialib/services/epii/use_cases/constants/upload_backup_to_sharepoint_constants.py,sha256=zkQLcI2ZIhGVGOcb-i-XCTdIcX78U4nAhpXPNenBjow,167
42
+ saviialib/services/epii/use_cases/constants/upload_backup_to_sharepoint_constants.py,sha256=8JwqAU1KP-WMUcZ67oSQY1_5I47jlaJnOpwKyTKdN_Y,208
38
43
  saviialib/services/epii/use_cases/types/__init__.py,sha256=u6fyodOEJE2j6FMqJux40Xf9ccYAi-UUYxqT-Kzc0kE,199
39
44
  saviialib/services/epii/use_cases/types/update_thies_data_types.py,sha256=BoT6N9YoVw3f8Cyb88T7fJTCCnkVybOh1K1u2fJ3X7k,419
40
- saviialib/services/epii/use_cases/types/upload_backup_to_sharepoint_types.py,sha256=rvuhJnjsCQpuNz5UO_0lGMR_KJRybNdq_11Be9ZaY1U,267
45
+ saviialib/services/epii/use_cases/types/upload_backup_to_sharepoint_types.py,sha256=v2CEvohTqkhKmmKn2upgaGWFbWrkL817Gt3T-bnlMcQ,313
41
46
  saviialib/services/epii/use_cases/update_thies_data.py,sha256=WLBpdAUkxAL_XdDnc49scmst1xMjrdScjr6Cmgg3UEE,6494
42
- saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py,sha256=rurCi-01Rm1SKa6o_SPcbsnOBfHlUD1ZMmIn6k7JbCQ,9608
47
+ saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py,sha256=gL2acEi9WH-HRbGPxZdZxZLg67itAP65KH5yPpC68II,10151
43
48
  saviialib/services/epii/utils/__init__.py,sha256=cYt2tvq65_OMjFaqb8-CCC7IGCQgFd4ziEUWJV7s1iY,98
44
49
  saviialib/services/epii/utils/update_thies_data_utils.py,sha256=EpjYWXqyHxJ-dO3MHhdXp-rGV7WyUckeFko-nnfnNac,555
45
- saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py,sha256=DnV4ddqZ0eeD50Wh66J9__m3Sqk5-1p_93e9YuQitpA,3499
46
- saviialib-0.9.1.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
47
- saviialib-0.9.1.dist-info/METADATA,sha256=8xbbpq_CG90pYR9SaNjkuVcGPM2vZ0-9qPrjd8aHazo,4082
48
- saviialib-0.9.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
49
- saviialib-0.9.1.dist-info/RECORD,,
50
+ saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py,sha256=hEeV4_kcG8YL6t_3V8AlhgDHtHiUNsdYpilfgTLaQMc,3528
51
+ saviialib-0.10.2.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
52
+ saviialib-0.10.2.dist-info/METADATA,sha256=_VBG9mtIJQr60KrfFPAyz-jHGNtUEwDJDUseN_M3YKM,4083
53
+ saviialib-0.10.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
54
+ saviialib-0.10.2.dist-info/RECORD,,