agi-med-common 5.2.2__py3-none-any.whl → 5.2.3__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.
- agi_med_common/__init__.py +1 -1
- agi_med_common/file_storage.py +65 -15
- agi_med_common/utils.py +2 -2
- {agi_med_common-5.2.2.dist-info → agi_med_common-5.2.3.dist-info}/METADATA +1 -1
- {agi_med_common-5.2.2.dist-info → agi_med_common-5.2.3.dist-info}/RECORD +7 -7
- {agi_med_common-5.2.2.dist-info → agi_med_common-5.2.3.dist-info}/WHEEL +0 -0
- {agi_med_common-5.2.2.dist-info → agi_med_common-5.2.3.dist-info}/top_level.txt +0 -0
agi_med_common/__init__.py
CHANGED
agi_med_common/file_storage.py
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
import string
|
2
2
|
from hashlib import md5
|
3
3
|
from pathlib import Path
|
4
|
+
from zipfile import ZipFile, is_zipfile
|
5
|
+
|
4
6
|
|
5
7
|
ResourceId = str
|
6
8
|
ASCII_DIGITS = set(string.ascii_lowercase + string.digits)
|
9
|
+
SUFFIX_DIR = ".dir"
|
7
10
|
|
8
11
|
|
9
12
|
def _validate_exist(files_dir):
|
@@ -30,34 +33,81 @@ class FileStorage:
|
|
30
33
|
self.files_dir.mkdir(exist_ok=True, parents=True)
|
31
34
|
_validate_exist(self.files_dir)
|
32
35
|
|
33
|
-
def _generate_fname_path(self, content, dtype):
|
36
|
+
def _generate_fname_path(self, content: bytes, dtype: str):
|
34
37
|
fpath = self.files_dir / generate_fname(content, dtype)
|
35
38
|
return fpath
|
36
39
|
|
37
|
-
def upload_maybe(
|
38
|
-
self,
|
39
|
-
content: bytes | None,
|
40
|
-
dtype: str,
|
41
|
-
) -> ResourceId | None:
|
40
|
+
def upload_maybe(self, content: bytes | None, dtype: str) -> ResourceId | None:
|
42
41
|
if not content:
|
43
42
|
return None
|
44
43
|
resource_id = self.upload(content, dtype)
|
45
44
|
return resource_id
|
46
45
|
|
47
|
-
def upload(self, content: bytes, dtype: str) -> ResourceId
|
46
|
+
def upload(self, content: bytes | str, dtype: str) -> ResourceId:
|
48
47
|
_validate_dtype(dtype)
|
48
|
+
if isinstance(content, str):
|
49
|
+
content = content.encode()
|
49
50
|
fpath = self._generate_fname_path(content, dtype)
|
50
51
|
fpath.write_bytes(content)
|
51
52
|
return str(fpath)
|
52
53
|
|
53
|
-
def
|
54
|
-
|
54
|
+
def upload_dir(self, resource_ids: list[ResourceId]) -> ResourceId:
|
55
|
+
content = "\n".join(resource_ids)
|
56
|
+
res = self.upload(content, "dir")
|
57
|
+
return res
|
58
|
+
|
59
|
+
def download(self, resource_id: ResourceId) -> bytes:
|
60
|
+
return Path(resource_id).read_bytes()
|
55
61
|
|
56
|
-
def download_text(self,
|
57
|
-
return Path(
|
62
|
+
def download_text(self, resource_id: ResourceId) -> str:
|
63
|
+
return Path(resource_id).read_text(encoding="utf-8")
|
58
64
|
|
59
|
-
def
|
60
|
-
|
65
|
+
def read_dir_or_none(self, resource_id: ResourceId) -> list[ResourceId] | None:
|
66
|
+
if not self.is_dir(resource_id):
|
67
|
+
return None
|
68
|
+
res = self.download_text(resource_id).split("\n")
|
69
|
+
return res
|
61
70
|
|
62
|
-
def
|
63
|
-
|
71
|
+
def _get_path(self, resource_id: ResourceId | None) -> Path | None:
|
72
|
+
if not resource_id:
|
73
|
+
return None
|
74
|
+
path = Path(resource_id)
|
75
|
+
return path if (path.exists() and path.is_file()) else None
|
76
|
+
|
77
|
+
def is_valid(self, resource_id: ResourceId | None) -> bool:
|
78
|
+
path = self._get_path(resource_id)
|
79
|
+
return path is not None
|
80
|
+
|
81
|
+
def is_file(self, resource_id: ResourceId | None) -> bool:
|
82
|
+
path = self._get_path(resource_id)
|
83
|
+
return path and path.suffix != SUFFIX_DIR
|
84
|
+
|
85
|
+
def is_dir(self, resource_id: ResourceId | None) -> bool:
|
86
|
+
path = self._get_path(resource_id)
|
87
|
+
return path and path.suffix == SUFFIX_DIR
|
88
|
+
|
89
|
+
def get_dtype(self, resource_id: ResourceId | None) -> str | None:
|
90
|
+
return resource_id and resource_id.rsplit(".")[-1]
|
91
|
+
|
92
|
+
def unzip_file(self, resource_id: str) -> ResourceId:
|
93
|
+
""" takes resource_id which refer to zip-archive, unpacks it and returns directory ResourceId with content of zip-archive """
|
94
|
+
path = self._get_path(resource_id)
|
95
|
+
if not path:
|
96
|
+
raise ValueError(f"Not found path: {resource_id}")
|
97
|
+
if not is_zipfile(resource_id):
|
98
|
+
raise ValueError(f"Expected zip archive but found: {resource_id}")
|
99
|
+
|
100
|
+
resource_ids = []
|
101
|
+
|
102
|
+
with ZipFile(path, mode='r') as zip_file:
|
103
|
+
files_info = zip_file.filelist
|
104
|
+
|
105
|
+
for file_info in zip_file.filelist:
|
106
|
+
file_dtype = file_info.filename.rsplit('.')[-1]
|
107
|
+
file_bytes = zip_file.read(file_info)
|
108
|
+
rid = self.upload(file_bytes, file_dtype)
|
109
|
+
resource_ids.append(rid)
|
110
|
+
|
111
|
+
res = self.upload_dir(resource_ids)
|
112
|
+
return res
|
113
|
+
|
agi_med_common/utils.py
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
import codecs
|
2
2
|
import json
|
3
3
|
import os
|
4
|
+
from collections.abc import Iterable
|
4
5
|
from datetime import datetime
|
5
6
|
from pathlib import Path
|
6
|
-
from collections.abc import Iterable
|
7
7
|
|
8
8
|
|
9
9
|
def make_session_id() -> str:
|
10
|
-
return f"{datetime.now():%
|
10
|
+
return f"{datetime.now():%Y-%m-%d--%H-%M-%S}"
|
11
11
|
|
12
12
|
|
13
13
|
def read_json(path: Path | os.PathLike[str] | str) -> list | dict:
|
@@ -1,9 +1,9 @@
|
|
1
|
-
agi_med_common/__init__.py,sha256=
|
1
|
+
agi_med_common/__init__.py,sha256=cwQe714hQGgtxAPXI-3X68PikBQg_wgMLwm78G-yubU,828
|
2
2
|
agi_med_common/api.py,sha256=83Ew5SvcypjvAWQ6c1kAcnvHsPxZ8BeBHnVHXLkUJvU,1687
|
3
|
-
agi_med_common/file_storage.py,sha256=
|
3
|
+
agi_med_common/file_storage.py,sha256=bwfpoYivOu6uXV5rg2OZQuk8MOpxbT5Zp4TaYD4XjdY,3841
|
4
4
|
agi_med_common/parallel_map.py,sha256=O6pxgPlHT9OVqqgry1yHy_0bV0U2AwvGJ42iG2e834U,1091
|
5
5
|
agi_med_common/type_union.py,sha256=diwmzcnbqkpGFckPHNw9o8zyQ955mOGNvhTlcBJ0RMI,1905
|
6
|
-
agi_med_common/utils.py,sha256=
|
6
|
+
agi_med_common/utils.py,sha256=xkuXctXBlNOxgnQpsb5VnC6F_UP4ua696tMXlNJjac4,1575
|
7
7
|
agi_med_common/validators.py,sha256=vMoPN42XzC8re-zdjekk5_lNQYHuTiAWD56YLvj2Z2w,2824
|
8
8
|
agi_med_common/xml_parser.py,sha256=VvLIX_XCZao9i0qqpTVx8nx0vbFXSe8pEbdJdXnj97g,568
|
9
9
|
agi_med_common/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -15,7 +15,7 @@ agi_med_common/models/tracks.py,sha256=HKDp-BX1p7AlDfSEKfOKCu0TRSK9cD4Dmq1vJt8oR
|
|
15
15
|
agi_med_common/models/widget.py,sha256=KXSP3d4yQNeificMfzRxROdByw9IkxwCjkDD0kc7tcQ,704
|
16
16
|
agi_med_common/models/base_config_models/__init__.py,sha256=KjS_bSCka8BOMsigwcIML-e6eNB2ouMU6gxlhRmzeuY,44
|
17
17
|
agi_med_common/models/base_config_models/gigachat_config.py,sha256=QvKTnp0VioXzd3_PUgNBeYx5RDTZT-45j-Ll-wXEI_o,421
|
18
|
-
agi_med_common-5.2.
|
19
|
-
agi_med_common-5.2.
|
20
|
-
agi_med_common-5.2.
|
21
|
-
agi_med_common-5.2.
|
18
|
+
agi_med_common-5.2.3.dist-info/METADATA,sha256=tpZTVKfNCzYNB-6VPnTGepK2fqNm6ZghhBiqjFqbX5Q,517
|
19
|
+
agi_med_common-5.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
20
|
+
agi_med_common-5.2.3.dist-info/top_level.txt,sha256=26o565jF_7wYQj7-YJfTedtT9yDxDcf8RNikOYuPq78,15
|
21
|
+
agi_med_common-5.2.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|