saviialib 0.9.0__py3-none-any.whl → 0.10.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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:
@@ -36,35 +40,48 @@ class UploadBackupToSharepointUsecase:
36
40
  self.sharepoint_config = input.sharepoint_config
37
41
  self.local_backup_source_path = input.local_backup_source_path
38
42
  self.destination_folders = input.destination_folders
39
- self.grouped_files_by_folder = self._extract_filesnames_by_folder()
40
43
  self.files_client = self._initialize_files_client()
41
- self.total_files = sum(
42
- len(files) for files in self.grouped_files_by_folder.values()
43
- )
44
+ self.dir_client = self._initialize_directory_client()
44
45
  self.log_history = []
46
+ self.grouped_files_by_folder = None
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"))
45
52
 
46
53
  def _initialize_files_client(self):
47
54
  return FilesClient(FilesClientInitArgs(client_name="aiofiles_client"))
48
55
 
49
- def _extract_filesnames_by_folder(self) -> dict[str, list[str]]:
56
+ async def _extract_filesnames_by_folder(self) -> dict[str, list[str]]:
50
57
  """Groups files by their parent folder."""
51
- if not os.path.exists(self.local_backup_source_path):
58
+ backup_folder_exists = await self.dir_client.path_exists(
59
+ self.local_backup_source_path
60
+ )
61
+
62
+ if not backup_folder_exists:
52
63
  return {}
64
+ folder_names = await self.dir_client.listdir(self.local_backup_source_path)
53
65
  return {
54
66
  folder_name: [
55
67
  file_name
56
- for file_name in os.listdir(
57
- 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
+ )
58
72
  )
59
73
  ]
60
- for folder_name in os.listdir(self.local_backup_source_path)
74
+ for folder_name in folder_names
61
75
  }
62
76
 
63
- def _save_log_history(self) -> None:
64
- text_file = "\n".join(self.log_history)
65
- log_history_filepath = "BACKUP_LOG_HISTORY.log"
66
- with open(log_history_filepath, "w") as file:
67
- 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
+ )
68
85
 
69
86
  async def export_file_to_sharepoint(
70
87
  self, folder_name: str, file_name: str, file_content: bytes
@@ -84,7 +101,9 @@ class UploadBackupToSharepointUsecase:
84
101
 
85
102
  async with sharepoint_client:
86
103
  try:
87
- destination_folder = self.destination_folders.get(folder_name, folder_name)
104
+ destination_folder = self.destination_folders.get(
105
+ folder_name, folder_name
106
+ )
88
107
  folder_url = f"{c.SHAREPOINT_BASE_URL}/{destination_folder}"
89
108
  args = SpUploadFileArgs(
90
109
  folder_relative_url=folder_url,
@@ -99,20 +118,22 @@ class UploadBackupToSharepointUsecase:
99
118
 
100
119
  return uploaded, error_message
101
120
 
102
- 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:
103
122
  """Task for uploads a file and logs progress."""
104
123
  uploading_message = (
105
124
  f"[BACKUP] Uploading file '{file_name}' from '{folder_name}' "
106
125
  )
107
126
  self.log_history.append(uploading_message)
108
- LOGGER.debug(uploading_message)
109
- 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
+ )
110
131
  file_content = await self.files_client.read(ReadArgs(file_path, mode="rb"))
111
132
  uploaded, error_message = await self.export_file_to_sharepoint(
112
133
  folder_name, file_name, file_content
113
134
  )
114
135
  result_message = show_upload_result(uploaded, file_name)
115
- LOGGER.debug(result_message)
136
+ self.logger.debug(result_message)
116
137
  self.log_history.append(result_message)
117
138
  return {
118
139
  "parent_folder": folder_name,
@@ -128,42 +149,55 @@ class UploadBackupToSharepointUsecase:
128
149
  f"[BACKUP] Retrying upload for {len(failed_files)} failed files... 🚨"
129
150
  )
130
151
  self.log_history.append(retry_message)
131
- LOGGER.debug(retry_message)
152
+ self.logger.debug(retry_message)
132
153
  for file in failed_files:
133
154
  tasks.append(
134
- self.upload_and_log_progress_task(
155
+ self._upload_and_log_progress_task(
135
156
  file["parent_folder"], file["file_name"]
136
157
  )
137
158
  )
138
159
  results = await asyncio.gather(*tasks, return_exceptions=True)
139
160
  success = calculate_percentage_uploaded(results, self.total_files)
140
161
  if success < 100.0:
141
- raise BackupUploadError(reason=extract_error_message(results, success))
162
+ raise BackupUploadError(
163
+ reason=extract_error_message(self.logger, results, success)
164
+ )
142
165
  else:
143
166
  successful_upload_retry = (
144
167
  "[BACKUP] All files uploaded successfully after retry."
145
168
  )
146
169
  self.log_history.append(successful_upload_retry)
147
- LOGGER.debug(successful_upload_retry)
148
- self._save_log_history()
170
+ self.logger.debug(successful_upload_retry)
171
+ await self._save_log_history()
149
172
  return parse_execute_response(results)
150
173
 
151
174
  async def execute(self):
152
175
  """Exports all files from the local backup folder to SharePoint cloud."""
176
+ self.grouped_files_by_folder = await self._extract_filesnames_by_folder()
177
+ self.total_files = sum(
178
+ len(files) for files in self.grouped_files_by_folder.values()
179
+ )
153
180
  tasks = []
154
181
  start_time = time()
155
-
182
+
156
183
  # Check if the local path exists in the main directory
157
- if not directory_exists(self.local_backup_source_path):
184
+ if not await self.dir_client.path_exists(self.local_backup_source_path):
158
185
  raise BackupSourcePathError(
159
186
  reason=f"'{self.local_backup_source_path}' doesn't exist."
160
187
  )
161
188
 
162
189
  # Check if the current folder only have files.
163
- for item in os.listdir(self.local_backup_source_path):
190
+ items = [
191
+ item
192
+ for item in await self.dir_client.listdir(self.local_backup_source_path)
193
+ ]
194
+ for item in items:
164
195
  folder_included = item in self.destination_folders.keys()
165
- is_file = not os.path.isdir(os.path.join(self.local_backup_source_path, item))
166
- if not folder_included and not is_file:
196
+ is_file = not await self.dir_client.isdir(
197
+ self.dir_client.join_paths(self.local_backup_source_path, item)
198
+ )
199
+
200
+ if not folder_included and not is_file:
167
201
  raise BackupSourcePathError(
168
202
  reason=(
169
203
  f"'{item}' must be included in the destination folders dictionary",
@@ -171,36 +205,34 @@ class UploadBackupToSharepointUsecase:
171
205
  )
172
206
  elif folder_included and is_file:
173
207
  print(folder_included, is_file)
174
- raise BackupSourcePathError(
175
- reason=(
176
- f"'{item}' must be a directory.",
177
- )
178
- )
179
-
208
+ raise BackupSourcePathError(reason=(f"'{item}' must be a directory.",))
209
+
180
210
  if self.total_files == 0:
181
211
  no_files_message = (
182
212
  f"[BACKUP] {self.local_backup_source_path} has no files ⚠️"
183
213
  )
184
214
  self.log_history.append(no_files_message)
185
- LOGGER.debug(no_files_message)
215
+ self.logger.debug(no_files_message)
186
216
  raise BackupEmptyError
187
217
  # Create task for each file stored in the the local backup folder.
188
218
  for folder_name in self.grouped_files_by_folder:
189
219
  if (
190
- count_files_in_directory(self.local_backup_source_path, folder_name)
220
+ await count_files_in_directory(
221
+ self.local_backup_source_path, folder_name
222
+ )
191
223
  == 0
192
224
  ):
193
225
  empty_folder_message = f"[BACKUP] The folder '{folder_name}' is empty ⚠️"
194
- LOGGER.debug(empty_folder_message)
226
+ self.logger.debug(empty_folder_message)
195
227
  self.log_history.append(empty_folder_message)
196
228
  continue
197
229
  extracting_files_message = (
198
230
  "[BACKUP]" + f" Extracting files from '{folder_name} ".center(15, "*")
199
231
  )
200
232
  self.log_history.append(extracting_files_message)
201
- LOGGER.debug(extracting_files_message)
233
+ self.logger.debug(extracting_files_message)
202
234
  for file_name in self.grouped_files_by_folder[folder_name]:
203
- tasks.append(self.upload_and_log_progress_task(folder_name, file_name))
235
+ tasks.append(self._upload_and_log_progress_task(folder_name, file_name))
204
236
 
205
237
  # Execution of multiple asynchronous tasks for files migration.
206
238
  results = await asyncio.gather(*tasks, return_exceptions=True)
@@ -220,5 +252,5 @@ class UploadBackupToSharepointUsecase:
220
252
  )
221
253
  self.log_history.append(finished_backup_message)
222
254
 
223
- self._save_log_history()
255
+ await self._save_log_history()
224
256
  return parse_execute_response(results)
@@ -1,12 +1,12 @@
1
1
  import re
2
+ from logging import Logger
2
3
  from typing import List, Dict, Optional
3
- import os
4
4
  from saviialib.general_types.error_types.api.epii_api_error_types import (
5
5
  BackupSourcePathError,
6
6
  )
7
- from saviialib.services.epii.use_cases.constants.upload_backup_to_sharepoint_constants import (
8
- LOGGER,
9
- )
7
+ from saviialib.libs.directory_client import DirectoryClient, DirectoryClientArgs
8
+
9
+ dir_client = DirectoryClient(DirectoryClientArgs(client_name="os_client"))
10
10
 
11
11
 
12
12
  def extract_error_information(error: str) -> Optional[Dict[str, str]]:
@@ -29,8 +29,8 @@ def explain_status_code(status_code: int) -> str:
29
29
  return explanations.get(status_code, "Unknown error occurred.")
30
30
 
31
31
 
32
- def extract_error_message(results: List[Dict], success: float) -> str:
33
- LOGGER.info(
32
+ def extract_error_message(logger: Logger, results: List[Dict], success: float) -> str:
33
+ logger.info(
34
34
  "[BACKUP] Not all files uploaded ⚠️\n"
35
35
  f"[BACKUP] Files failed to upload: {(1 - success):.2%}"
36
36
  )
@@ -58,9 +58,9 @@ def extract_error_message(results: List[Dict], success: float) -> str:
58
58
 
59
59
  # Summary
60
60
  for code, items in grouped_errors.items():
61
- LOGGER.info(f"[BACKUP] Status code {code} - {explain_status_code(int(code))}")
61
+ logger.info(f"[BACKUP] Status code {code} - {explain_status_code(int(code))}")
62
62
  for item in items:
63
- LOGGER.info(
63
+ logger.info(
64
64
  f"[BACKUP] File {item['file_name']}, url: {item['url']}, message: {item['message']}"
65
65
  )
66
66
 
@@ -93,9 +93,5 @@ def calculate_percentage_uploaded(results: List[Dict], total_files: int) -> floa
93
93
  return (uploaded_count / total_files) * 100 if total_files > 0 else 0
94
94
 
95
95
 
96
- def directory_exists(path: str) -> bool:
97
- return os.path.exists(path)
98
-
99
-
100
- def count_files_in_directory(path: str, folder_name: str) -> int:
101
- return len(os.listdir(os.path.join(path, folder_name)))
96
+ async def count_files_in_directory(path: str, folder_name: str) -> int:
97
+ 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.0
3
+ Version: 0.10.1
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=3XrkE2LNw3DRP3FA0SVpdD4AnCIL6uBSA-9sctjfKyw,9144
47
+ saviialib/services/epii/use_cases/upload_backup_to_sharepoint.py,sha256=V-O4x2du-lvTJRarvXbt4NjSGJ2jYWGTRrodiKPYIOU,10039
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=4psc4EHpgnuiOVc0Tn_PR2mDsDh774ERbhIewSwYSZg,3422
46
- saviialib-0.9.0.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
47
- saviialib-0.9.0.dist-info/METADATA,sha256=WnSLd2VoJRXqhypq0NXow8eqQ8Pu9swBbSn9oX5BPhc,4082
48
- saviialib-0.9.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
49
- saviialib-0.9.0.dist-info/RECORD,,
50
+ saviialib/services/epii/utils/upload_backup_to_sharepoint_utils.py,sha256=p1LIEz_iSnNSv5SxebfiR5ry5HY83ttJ7vJ97TEw2mk,3456
51
+ saviialib-0.10.1.dist-info/LICENSE,sha256=NWpf6b38xgBWPBo5HZsCbdfp9hZSliEbRqWQgm0fkOo,1076
52
+ saviialib-0.10.1.dist-info/METADATA,sha256=7Ru4sGRBiK6gcfnKPTUSMQeqp-OvNfAtlJJ6LK-WsrI,4083
53
+ saviialib-0.10.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
54
+ saviialib-0.10.1.dist-info/RECORD,,