iker-python-common 1.0.62__py3-none-any.whl → 1.0.63__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,13 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iker-python-common
3
- Version: 1.0.62
3
+ Version: 1.0.63
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.12
6
6
  Classifier: Programming Language :: Python :: 3.13
7
7
  Classifier: Programming Language :: Python :: 3.14
8
8
  Requires-Python: <3.15,>=3.12
9
9
  Requires-Dist: asyncpg>=0.30
10
- Requires-Dist: docker>=7.1
11
10
  Requires-Dist: numpy>=2.3
12
11
  Requires-Dist: psycopg>=3.2
13
12
  Requires-Dist: pymysql>=1.1
@@ -4,7 +4,6 @@ iker/common/utils/argutils.py,sha256=hMLNqdZs_Kjc2hw4Npm6N47RivP6JRNzCKIbJr1jYy8
4
4
  iker/common/utils/config.py,sha256=z8rLqli961A-qAV9EaELp-pKuhNUNaq1Btdv-uwG7_I,4690
5
5
  iker/common/utils/csv.py,sha256=_V9OUrKcojec2L-hWagEIVnL2uvGjyJAFTrD7tHNr48,7573
6
6
  iker/common/utils/dbutils.py,sha256=09DgvfPVDCPXwOAO_FTynLXhSq--ZzRz2fCQ6vJ5qqk,16151
7
- iker/common/utils/dockerutils.py,sha256=n2WuzXaZB6_WocSljvPOnfExSIjIHRUbuWp2oBbaPKQ,8004
8
7
  iker/common/utils/dtutils.py,sha256=86vbaa4pgcBWERZvTfJ92PKB3IimxP6tf0O11ho2Ffk,12554
9
8
  iker/common/utils/funcutils.py,sha256=4AkkvK9_Z2tgk1-Sp6-vLLVhI15cIgN9xW58QqL5QL4,7780
10
9
  iker/common/utils/jsonutils.py,sha256=AkziMAYVQDODHRqZC-c1x7VqI2hHY3Kxrw7gmoss8mU,18527
@@ -18,7 +17,7 @@ iker/common/utils/span.py,sha256=u_KuWi2U7QDMUotl4AeW2_57ItL3YhVDSeCwaOiFDvs,596
18
17
  iker/common/utils/strutils.py,sha256=Tu_qFeH3K-SfwvMxdrZAc9iLPV8ZmtX4ntyyFGNslf8,5094
19
18
  iker/common/utils/testutils.py,sha256=2VieV5yeCDntSKQSpIeyqRT8BZmZYE_ArMeQz3g7fXY,5568
20
19
  iker/common/utils/typeutils.py,sha256=RVkYkFRgDrx77OHFH7PavMV0AIB0S8ly40rs4g7JWE4,8220
21
- iker_python_common-1.0.62.dist-info/METADATA,sha256=0xFB0M0zbyGoFcUy9Y-lfZGzNDbAhtW0574bl8XS7XU,894
22
- iker_python_common-1.0.62.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- iker_python_common-1.0.62.dist-info/top_level.txt,sha256=4_B8Prfc_lxFafFYTQThIU1ZqOYQ4pHHHnJ_fQ_oHs8,5
24
- iker_python_common-1.0.62.dist-info/RECORD,,
20
+ iker_python_common-1.0.63.dist-info/METADATA,sha256=QUw6lKzGDZRY3Aul1qTE4B_dxtO96Tw0Mvo_acp9Ilw,867
21
+ iker_python_common-1.0.63.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
22
+ iker_python_common-1.0.63.dist-info/top_level.txt,sha256=4_B8Prfc_lxFafFYTQThIU1ZqOYQ4pHHHnJ_fQ_oHs8,5
23
+ iker_python_common-1.0.63.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,236 +0,0 @@
1
- import contextlib
2
- import dataclasses
3
- import re
4
- from collections.abc import Generator, Iterator
5
- from typing import Any
6
-
7
- import docker
8
- import docker.errors
9
- import docker.models.containers
10
- import docker.models.images
11
- import requests.exceptions
12
-
13
- from iker.common.utils import logger
14
- from iker.common.utils.strutils import parse_int_or, trim_to_empty
15
-
16
- __all__ = [
17
- "ImageName",
18
- "docker_create_client",
19
- "docker_build_image",
20
- "docker_get_image",
21
- "docker_pull_image",
22
- "docker_fetch_image",
23
- "docker_run_detached",
24
- ]
25
-
26
-
27
- @dataclasses.dataclass
28
- class ImageName(object):
29
- registry_host: str | None
30
- registry_port: int | None
31
- components: list[str]
32
- tag: str | None
33
-
34
- @property
35
- def registry(self) -> str:
36
- if self.registry_host is None and self.registry_port is None:
37
- return ""
38
- if self.registry_port is None:
39
- return self.registry_host
40
- return f"{self.registry_host}:{self.registry_port}"
41
-
42
- @property
43
- def repository(self) -> str:
44
- return "/".join(self.components)
45
-
46
- @staticmethod
47
- def parse(s: str):
48
-
49
- # Registry absent version
50
- matcher = re.compile(
51
- r"^(?P<components>[a-z0-9]+((__?|-+)[a-z0-9]+)*(/[a-z0-9]+((__?|-+)[a-z0-9]+)*)*)(:(?P<tag>\w[\w.-]{0,127}))?$")
52
- match = matcher.match(s)
53
- if match:
54
- return ImageName(registry_host=None,
55
- registry_port=None,
56
- components=trim_to_empty(match.group("components")).split("/"),
57
- tag=match.group("tag"))
58
-
59
- # Registry present version
60
- matcher = re.compile(
61
- r"^((?P<host>[a-zA-Z0-9.-]+)(:(?P<port>\d+))?/)?(?P<components>[a-z0-9]+((__?|-+)[a-z0-9]+)*(/[a-z0-9]+((__?|-+)[a-z0-9]+)*)*)(:(?P<tag>\w[\w.-]{0,127}))?$")
62
- match = matcher.match(s)
63
- if match:
64
- return ImageName(registry_host=match.group("host"),
65
- registry_port=parse_int_or(match.group("port"), None),
66
- components=trim_to_empty(match.group("components")).split("/"),
67
- tag=match.group("tag"))
68
-
69
- return None
70
-
71
-
72
- def docker_create_client(
73
- registry: str,
74
- username: str,
75
- password: str,
76
- ) -> contextlib.AbstractContextManager[docker.DockerClient]:
77
- try:
78
- client = docker.DockerClient()
79
- client.login(registry=registry, username=username, password=password, reauth=True)
80
- return contextlib.closing(client)
81
- except docker.errors.APIError:
82
- logger.exception("Failed to login Docker server <%s>", registry)
83
- raise
84
-
85
-
86
- def docker_build_image(
87
- client: docker.DockerClient,
88
- tag: str,
89
- path: str,
90
- dockerfile: str,
91
- build_args: dict[str, str],
92
- ) -> tuple[docker.models.images.Image, Iterator[dict[str, str]]]:
93
- try:
94
- return client.images.build(tag=tag,
95
- path=path,
96
- dockerfile=dockerfile,
97
- buildargs=build_args,
98
- rm=True,
99
- forcerm=True,
100
- nocache=True)
101
-
102
- except docker.errors.BuildError:
103
- logger.exception("Failed to build image <%s>", tag)
104
- raise
105
- except docker.errors.APIError:
106
- logger.exception("Docker server returns an error while building image <%s>", tag)
107
- raise
108
- except Exception:
109
- logger.exception("Unexpected error occurred while building image <%s>", tag)
110
- raise
111
-
112
-
113
- def docker_get_image(
114
- client: docker.DockerClient,
115
- image: str,
116
- ) -> docker.models.images.Image:
117
- try:
118
- return client.images.get(image)
119
- except docker.errors.ImageNotFound:
120
- logger.exception("Image <%s> is not found from local repository", image)
121
- raise
122
- except docker.errors.APIError:
123
- logger.exception("Docker server returns an error while getting image <%s>", image)
124
- raise
125
- except Exception:
126
- logger.exception("Unexpected error occurred while getting image <%s>", image)
127
- raise
128
-
129
-
130
- def docker_pull_image(
131
- client: docker.DockerClient,
132
- image: str,
133
- fallback_local: bool = False,
134
- ) -> docker.models.images.Image:
135
- try:
136
- return client.images.pull(image)
137
- except docker.errors.ImageNotFound:
138
- if not fallback_local:
139
- logger.exception("Image <%s> is not found from remote repository", image)
140
- raise
141
- logger.warning("Image <%s> is not found from remote repository, try local repository instead", image)
142
- except docker.errors.APIError:
143
- if not fallback_local:
144
- logger.exception("Docker server returns an error while pulling image <%s>", image)
145
- raise
146
- logger.warning("Docker server returns an error while pulling image <%s>, try local repository instead", image)
147
- except Exception:
148
- logger.exception("Unexpected error occurred while pulling image <%s>", image)
149
- raise
150
-
151
- return docker_get_image(client, image)
152
-
153
-
154
- def docker_fetch_image(
155
- client: docker.DockerClient,
156
- image: str,
157
- force_pull: bool = False,
158
- ) -> docker.models.images.Image:
159
- if force_pull:
160
- return docker_pull_image(client, image, fallback_local=True)
161
- else:
162
- try:
163
- return docker_get_image(client, image)
164
- except Exception:
165
- return docker_pull_image(client, image, fallback_local=False)
166
-
167
-
168
- def docker_run_detached(
169
- client: docker.DockerClient,
170
- image: str,
171
- name: str,
172
- command: str | list[str],
173
- volumes: dict[str, dict[str, str]],
174
- environment: dict[str, str],
175
- extra_hosts: dict[str, str],
176
- timeout: int,
177
- **kwargs,
178
- ) -> tuple[dict[str, Any], Any]:
179
- @contextlib.contextmanager
180
- def managed_docker_run(
181
- client: docker.DockerClient,
182
- **kwargs,
183
- ) -> Generator[docker.models.containers.Container, None, None]:
184
- container_model = None
185
- try:
186
- container_model = client.containers.run(**kwargs)
187
- yield container_model
188
- except docker.errors.DockerException:
189
- raise
190
- finally:
191
- if container_model is not None:
192
- try:
193
- if container_model.status != "exited":
194
- try:
195
- container_model.stop()
196
- except docker.errors.DockerException:
197
- pass
198
- container_model.wait()
199
- try:
200
- container_model.remove()
201
- except docker.errors.DockerException:
202
- pass
203
- except Exception:
204
- raise
205
-
206
- try:
207
- run_args = kwargs.copy()
208
- run_args.update(dict(image=image,
209
- name=name,
210
- command=command,
211
- volumes=volumes,
212
- environment=environment,
213
- extra_hosts=extra_hosts,
214
- detach=True))
215
-
216
- with managed_docker_run(client, **run_args) as container_model:
217
- result = container_model.wait(timeout=timeout)
218
- logs = container_model.logs()
219
-
220
- return result, logs
221
-
222
- except requests.exceptions.ReadTimeout:
223
- logger.exception("Running container <%s> of image <%s> exceed the timeout", name, image)
224
- raise
225
- except docker.errors.ImageNotFound:
226
- logger.exception("Image <%s> is not found", image)
227
- raise
228
- except docker.errors.ContainerError:
229
- logger.exception("Failed to run container <%s> of image <%s>", name, image)
230
- raise
231
- except docker.errors.APIError:
232
- logger.exception("Docker server returns an error while running container <%s> of image <%s>", name, image)
233
- raise
234
- except Exception:
235
- logger.exception("Unexpected error occurred while running container <%s> of image <%s>", image)
236
- raise