agi-med-common 5.2.2__py3-none-any.whl → 5.2.4__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.
@@ -1,4 +1,4 @@
1
- __version__ = "5.2.2"
1
+ __version__ = "5.2.4"
2
2
 
3
3
  from .file_storage import FileStorage, ResourceId
4
4
  from .models.base import Base
@@ -9,6 +9,6 @@ from .models.enums import MTRSLabelEnum, DiagnosticsXMLTagEnum, MTRSXMLTagEnum,
9
9
  from .models.tracks import TrackInfo, DomainInfo
10
10
  from .models.widget import Widget
11
11
  from .parallel_map import parallel_map
12
- from .utils import make_session_id, read_json, try_parse_json, try_parse_int, try_parse_float, pretty_line
12
+ from .utils import make_session_id, read_json, try_parse_json, try_parse_int, try_parse_float, try_parse_bool, pretty_line
13
13
  from .validators import ExistingPath, ExistingFile, ExistingDir, StrNotEmpty, SecretStrNotEmpty, Prompt, Message
14
14
  from .xml_parser import XMLParser
@@ -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 | None:
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 download(self, rid: ResourceId) -> bytes:
54
- return Path(rid).read_bytes()
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, rid: ResourceId) -> str:
57
- return Path(rid).read_text(encoding="utf-8")
62
+ def download_text(self, resource_id: ResourceId) -> str:
63
+ return Path(resource_id).read_text(encoding="utf-8")
58
64
 
59
- def is_valid(self, rid: ResourceId | None) -> bool:
60
- return rid and Path(rid).exists() and Path(rid).is_file()
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 get_dtype(self, rid: ResourceId | None) -> str | None:
63
- return rid and rid.rsplit(".")[-1]
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():%y%m%d%H%M%S}"
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:
@@ -45,9 +45,11 @@ def try_parse_float(text: str) -> float | None:
45
45
  return None
46
46
 
47
47
 
48
- def try_parse_bool(v: str | bool) -> bool:
48
+ def try_parse_bool(v: str | bool | int) -> bool:
49
49
  if isinstance(v, bool):
50
50
  return v
51
+ if isinstance(v, int):
52
+ return bool(v)
51
53
  return v.lower() in ("yes", "true", "t", "1")
52
54
 
53
55
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agi_med_common
3
- Version: 5.2.2
3
+ Version: 5.2.4
4
4
  Summary: Сommon for agi-med team
5
5
  Author: AGI-MED-TEAM
6
6
  Requires-Python: >=3.11
@@ -1,9 +1,9 @@
1
- agi_med_common/__init__.py,sha256=RTzZYi5dcgt97c2nh9CYdAhXoaH4kb8MQc6HMCzh_L4,828
1
+ agi_med_common/__init__.py,sha256=8uZKFGUkRdvOgACl5rBXfWKbFxUDWbQ-yveg7oKFiYc,844
2
2
  agi_med_common/api.py,sha256=83Ew5SvcypjvAWQ6c1kAcnvHsPxZ8BeBHnVHXLkUJvU,1687
3
- agi_med_common/file_storage.py,sha256=lEh9TyzUu8dS9WkaEcshSUxESXQ1i7PAyXqejdambpg,1802
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=9nV01aSqUcudWmDI_Jzvb_8e0LJM3WJ6vsf9Vcv8DB0,1569
6
+ agi_med_common/utils.py,sha256=x3CpPX0j0t4SSfAXIvFMXb0qB2DB4wbGM5QrLvgMgwM,1631
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.2.dist-info/METADATA,sha256=9Kk0ayatnwaQEei0hq5sJE7mmiUnl7aEJA5FWBnPzk0,517
19
- agi_med_common-5.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
- agi_med_common-5.2.2.dist-info/top_level.txt,sha256=26o565jF_7wYQj7-YJfTedtT9yDxDcf8RNikOYuPq78,15
21
- agi_med_common-5.2.2.dist-info/RECORD,,
18
+ agi_med_common-5.2.4.dist-info/METADATA,sha256=TPzJ0j6I10Owalaqy4tqBOsLterQEBbsVAsySfD0WhI,517
19
+ agi_med_common-5.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ agi_med_common-5.2.4.dist-info/top_level.txt,sha256=26o565jF_7wYQj7-YJfTedtT9yDxDcf8RNikOYuPq78,15
21
+ agi_med_common-5.2.4.dist-info/RECORD,,