dycw-utilities 0.175.29__py3-none-any.whl → 0.175.30__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.
- {dycw_utilities-0.175.29.dist-info → dycw_utilities-0.175.30.dist-info}/METADATA +1 -1
- {dycw_utilities-0.175.29.dist-info → dycw_utilities-0.175.30.dist-info}/RECORD +7 -7
- utilities/__init__.py +1 -1
- utilities/docker.py +88 -27
- utilities/subprocess.py +8 -7
- {dycw_utilities-0.175.29.dist-info → dycw_utilities-0.175.30.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.175.29.dist-info → dycw_utilities-0.175.30.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
utilities/__init__.py,sha256=
|
|
1
|
+
utilities/__init__.py,sha256=MtsJJrbSJrW256hO7llrT3qk9914hd3MBaFYuonK4KU,61
|
|
2
2
|
utilities/altair.py,sha256=TLfRFbG9HwG7SLXoJ-v0r-t49ZaGgTQZD82cpjVi4vs,9085
|
|
3
3
|
utilities/asyncio.py,sha256=aJySVxBY0gqsIYnoNmH7-1r8djKuf4vSsU69VCD08t8,16772
|
|
4
4
|
utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
|
|
@@ -11,7 +11,7 @@ utilities/contextvars.py,sha256=J8OhC7jqozAGYOCe2KUWysbPXNGe5JYz3HfaY_mIs08,883
|
|
|
11
11
|
utilities/cryptography.py,sha256=5PFrzsNUGHay91dFgYnDKwYprXxahrBqztmUqViRzBk,956
|
|
12
12
|
utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
|
|
13
13
|
utilities/dataclasses.py,sha256=xbU3QN1GFy7RC6hIJRZIeUZm7YRlodrgEWmahWG6k2g,32465
|
|
14
|
-
utilities/docker.py,sha256=
|
|
14
|
+
utilities/docker.py,sha256=nzeuR5-OQKL2yhtY-SSqLS2ftl-iev0cUrshwEMwB2k,9808
|
|
15
15
|
utilities/enum.py,sha256=5l6pwZD1cjSlVW4ss-zBPspWvrbrYrdtJWcg6f5_J5w,5781
|
|
16
16
|
utilities/errors.py,sha256=mFlDGSM0LI1jZ1pbqwLAH3ttLZ2JVIxyZLojw8tGVZU,1479
|
|
17
17
|
utilities/fastapi.py,sha256=TqyKvBjiMS594sXPjrz-KRTLMb3l3D3rZ1zAYV7GfOk,1454
|
|
@@ -80,7 +80,7 @@ utilities/sqlalchemy.py,sha256=HQYpd7LFxdTF5WYVWYtCJeEBI71EJm7ytvCGyAH9B-U,37163
|
|
|
80
80
|
utilities/sqlalchemy_polars.py,sha256=JCGhB37raSR7fqeWV5dTsciRTMVzIdVT9YSqKT0piT0,13370
|
|
81
81
|
utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
|
|
82
82
|
utilities/string.py,sha256=shmBK87zZwzGyixuNuXCiUbqzfeZ9xlrFwz6JTaRvDk,582
|
|
83
|
-
utilities/subprocess.py,sha256=
|
|
83
|
+
utilities/subprocess.py,sha256=ei0OD73S0WX7ZqHCQp9UB3hY9OWbAUVIrLoz9niIfQQ,53031
|
|
84
84
|
utilities/tempfile.py,sha256=a3_M1QyxGZql_VcGkBOQBeWbbkItjgkfIpVyzU1UAic,3843
|
|
85
85
|
utilities/testbook.py,sha256=j1KmaVbrX9VrbeMgtPh5gk55myAsn3dyRUn7jGbPbRk,1294
|
|
86
86
|
utilities/text.py,sha256=7SvwcSR2l_5cOrm1samGnR4C-ZI6qyFLHLzSpO1zeHQ,13958
|
|
@@ -97,7 +97,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
|
|
97
97
|
utilities/whenever.py,sha256=F4ek0-OBWxHYrZdmoZt76N2RnNyKY5KrEHt7rqO4AQE,60183
|
|
98
98
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
|
99
99
|
utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
|
|
100
|
-
dycw_utilities-0.175.
|
|
101
|
-
dycw_utilities-0.175.
|
|
102
|
-
dycw_utilities-0.175.
|
|
103
|
-
dycw_utilities-0.175.
|
|
100
|
+
dycw_utilities-0.175.30.dist-info/WHEEL,sha256=RRVLqVugUmFOqBedBFAmA4bsgFcROUBiSUKlERi0Hcg,79
|
|
101
|
+
dycw_utilities-0.175.30.dist-info/entry_points.txt,sha256=cOGtKeJI0KXLSV7MJ8Dhc2G8jPgDcBDm53MVNJU4ycI,136
|
|
102
|
+
dycw_utilities-0.175.30.dist-info/METADATA,sha256=X2Hiaa6YhG9ZkFu1AfxlEDbXKDKYepqcVZylTh5hVds,1443
|
|
103
|
+
dycw_utilities-0.175.30.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/docker.py
CHANGED
|
@@ -5,6 +5,7 @@ from pathlib import Path
|
|
|
5
5
|
from typing import TYPE_CHECKING, Literal, overload
|
|
6
6
|
|
|
7
7
|
from utilities.errors import ImpossibleCaseError
|
|
8
|
+
from utilities.iterables import always_iterable
|
|
8
9
|
from utilities.logging import to_logger
|
|
9
10
|
from utilities.subprocess import (
|
|
10
11
|
MKTEMP_DIR_CMD,
|
|
@@ -18,7 +19,60 @@ from utilities.subprocess import (
|
|
|
18
19
|
if TYPE_CHECKING:
|
|
19
20
|
from collections.abc import Iterator
|
|
20
21
|
|
|
21
|
-
from utilities.types import
|
|
22
|
+
from utilities.types import (
|
|
23
|
+
LoggerLike,
|
|
24
|
+
MaybeIterable,
|
|
25
|
+
PathLike,
|
|
26
|
+
Retry,
|
|
27
|
+
StrStrMapping,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def docker_compose_down(*, files: MaybeIterable[PathLike] | None = None) -> None:
|
|
32
|
+
"""Stop and remove containers."""
|
|
33
|
+
run(*docker_compose_down_cmd(files=files)) # pragma: no cover
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def docker_compose_down_cmd(
|
|
37
|
+
*, files: MaybeIterable[PathLike] | None = None
|
|
38
|
+
) -> list[str]:
|
|
39
|
+
"""Command to use 'docker compose down' to stop and remove containers."""
|
|
40
|
+
return _docker_compose_cmd("down", files=files)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def docker_compose_pull(*, files: MaybeIterable[PathLike] | None = None) -> None:
|
|
44
|
+
"""Pull service images."""
|
|
45
|
+
run(*docker_compose_pull_cmd(files=files)) # pragma: no cover
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def docker_compose_pull_cmd(
|
|
49
|
+
*, files: MaybeIterable[PathLike] | None = None
|
|
50
|
+
) -> list[str]:
|
|
51
|
+
"""Command to use 'docker compose pull' to pull service images."""
|
|
52
|
+
return _docker_compose_cmd("pull", files=files)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def docker_compose_up(*, files: MaybeIterable[PathLike] | None = None) -> None:
|
|
56
|
+
"""Create and start containers."""
|
|
57
|
+
run(*docker_compose_up_cmd(files=files)) # pragma: no cover
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def docker_compose_up_cmd(*, files: MaybeIterable[PathLike] | None = None) -> list[str]:
|
|
61
|
+
"""Command to use 'docker compose up' to create and start containers."""
|
|
62
|
+
return _docker_compose_cmd("up", files=files)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _docker_compose_cmd(
|
|
66
|
+
cmd: str, /, *, files: MaybeIterable[PathLike] | None = None
|
|
67
|
+
) -> list[str]:
|
|
68
|
+
args: list[str] = ["docker", "compose"]
|
|
69
|
+
if files is not None:
|
|
70
|
+
for file in always_iterable(files):
|
|
71
|
+
args.extend(["--file", str(file)])
|
|
72
|
+
return [*args, cmd]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
##
|
|
22
76
|
|
|
23
77
|
|
|
24
78
|
@overload
|
|
@@ -47,48 +101,39 @@ def docker_cp(
|
|
|
47
101
|
sudo: bool = False,
|
|
48
102
|
logger: LoggerLike | None = None,
|
|
49
103
|
) -> None:
|
|
104
|
+
"""Copy between a container and the local file system."""
|
|
50
105
|
match src, dest: # skipif-ci
|
|
51
106
|
case Path() | str(), (str() as cont, Path() | str() as dest_path):
|
|
52
107
|
docker_exec(
|
|
53
108
|
cont, *maybe_sudo_cmd(*mkdir_cmd(dest_path, parent=True), sudo=sudo)
|
|
54
109
|
)
|
|
55
|
-
run(*docker_cp_cmd(src, dest, sudo=sudo), logger=logger)
|
|
110
|
+
run(*maybe_sudo_cmd(*docker_cp_cmd(src, dest), sudo=sudo), logger=logger)
|
|
56
111
|
case (str(), Path() | str()), Path() | str():
|
|
57
112
|
mkdir(dest, parent=True, sudo=sudo)
|
|
58
|
-
run(*docker_cp_cmd(src, dest, sudo=sudo), logger=logger)
|
|
113
|
+
run(*maybe_sudo_cmd(*docker_cp_cmd(src, dest), sudo=sudo), logger=logger)
|
|
59
114
|
case _: # pragma: no cover
|
|
60
115
|
raise ImpossibleCaseError(case=[f"{src}", f"{dest=}"])
|
|
61
116
|
|
|
62
117
|
|
|
63
118
|
@overload
|
|
64
|
-
def docker_cp_cmd(
|
|
65
|
-
src: tuple[str, PathLike], dest: PathLike, /, *, sudo: bool = False
|
|
66
|
-
) -> list[str]: ...
|
|
119
|
+
def docker_cp_cmd(src: tuple[str, PathLike], dest: PathLike, /) -> list[str]: ...
|
|
67
120
|
@overload
|
|
121
|
+
def docker_cp_cmd(src: PathLike, dest: tuple[str, PathLike], /) -> list[str]: ...
|
|
68
122
|
def docker_cp_cmd(
|
|
69
|
-
src: PathLike
|
|
70
|
-
) -> list[str]: ...
|
|
71
|
-
def docker_cp_cmd(
|
|
72
|
-
src: PathLike | tuple[str, PathLike],
|
|
73
|
-
dest: PathLike | tuple[str, PathLike],
|
|
74
|
-
/,
|
|
75
|
-
*,
|
|
76
|
-
sudo: bool = False,
|
|
123
|
+
src: PathLike | tuple[str, PathLike], dest: PathLike | tuple[str, PathLike], /
|
|
77
124
|
) -> list[str]:
|
|
125
|
+
"""Command to use 'docker cp' to copy between a container and the local file system."""
|
|
126
|
+
args: list[str] = ["docker", "cp"]
|
|
78
127
|
match src, dest:
|
|
79
|
-
case (Path() | str()) as
|
|
80
|
-
str()
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
dest_use = f"{dest_cont}:{dest_path}"
|
|
84
|
-
case (str() as src_cont, (Path() | str()) as src_path), (
|
|
85
|
-
Path() | str() as dest_use
|
|
86
|
-
):
|
|
87
|
-
src_use = f"{src_cont}:{src_path}"
|
|
128
|
+
case ((Path() | str()), (str() as cont, Path() | str() as path)):
|
|
129
|
+
return [*args, str(src), f"{cont}:{path}"]
|
|
130
|
+
case (str() as cont, (Path() | str()) as path), (Path() | str() as dest):
|
|
131
|
+
return [*args, f"{cont}:{path}", str(dest)]
|
|
88
132
|
case _: # pragma: no cover
|
|
89
133
|
raise ImpossibleCaseError(case=[f"{src}", f"{dest=}"])
|
|
90
|
-
|
|
91
|
-
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
##
|
|
92
137
|
|
|
93
138
|
|
|
94
139
|
@overload
|
|
@@ -210,6 +255,7 @@ def docker_exec(
|
|
|
210
255
|
logger: LoggerLike | None = None,
|
|
211
256
|
**env_kwargs: str,
|
|
212
257
|
) -> str | None:
|
|
258
|
+
"""Execute a command in a container."""
|
|
213
259
|
cmd_and_args = docker_exec_cmd( # skipif-ci
|
|
214
260
|
container,
|
|
215
261
|
cmd,
|
|
@@ -245,7 +291,7 @@ def docker_exec_cmd(
|
|
|
245
291
|
workdir: PathLike | None = None,
|
|
246
292
|
**env_kwargs: str,
|
|
247
293
|
) -> list[str]:
|
|
248
|
-
"""
|
|
294
|
+
"""Command to use `docker exec` to execute a command in a container."""
|
|
249
295
|
args: list[str] = ["docker", "exec"]
|
|
250
296
|
mapping: dict[str, str] = ({} if env is None else dict(env)) | env_kwargs
|
|
251
297
|
for key, value in mapping.items():
|
|
@@ -259,6 +305,9 @@ def docker_exec_cmd(
|
|
|
259
305
|
return [*args, container, cmd, *cmds_or_args]
|
|
260
306
|
|
|
261
307
|
|
|
308
|
+
##
|
|
309
|
+
|
|
310
|
+
|
|
262
311
|
@contextmanager
|
|
263
312
|
def yield_docker_temp_dir(
|
|
264
313
|
container: str,
|
|
@@ -290,4 +339,16 @@ def yield_docker_temp_dir(
|
|
|
290
339
|
docker_exec(container, *rm_cmd(path), user=user, retry=retry, logger=logger)
|
|
291
340
|
|
|
292
341
|
|
|
293
|
-
__all__ = [
|
|
342
|
+
__all__ = [
|
|
343
|
+
"docker_compose_down",
|
|
344
|
+
"docker_compose_down_cmd",
|
|
345
|
+
"docker_compose_pull",
|
|
346
|
+
"docker_compose_pull_cmd",
|
|
347
|
+
"docker_compose_up",
|
|
348
|
+
"docker_compose_up_cmd",
|
|
349
|
+
"docker_cp",
|
|
350
|
+
"docker_cp_cmd",
|
|
351
|
+
"docker_exec",
|
|
352
|
+
"docker_exec_cmd",
|
|
353
|
+
"yield_docker_temp_dir",
|
|
354
|
+
]
|
utilities/subprocess.py
CHANGED
|
@@ -86,9 +86,10 @@ def apt_install(
|
|
|
86
86
|
"""Install packages."""
|
|
87
87
|
if update: # pragma: no cover
|
|
88
88
|
apt_update(sudo=sudo)
|
|
89
|
-
|
|
90
|
-
*
|
|
89
|
+
args = maybe_sudo_cmd( # pragma: no cover
|
|
90
|
+
*apt_install_cmd(package, *packages), sudo=sudo
|
|
91
91
|
)
|
|
92
|
+
run(*args) # pragma: no cover
|
|
92
93
|
|
|
93
94
|
|
|
94
95
|
def apt_install_cmd(package: str, /, *packages: str) -> list[str]:
|
|
@@ -101,9 +102,10 @@ def apt_install_cmd(package: str, /, *packages: str) -> list[str]:
|
|
|
101
102
|
|
|
102
103
|
def apt_remove(package: str, /, *packages: str, sudo: bool = False) -> None:
|
|
103
104
|
"""Remove a package."""
|
|
104
|
-
|
|
105
|
-
*
|
|
105
|
+
args = maybe_sudo_cmd( # pragma: no cover
|
|
106
|
+
*apt_remove_cmd(package, *packages), sudo=sudo
|
|
106
107
|
)
|
|
108
|
+
run(*args) # pragma: no cover
|
|
107
109
|
|
|
108
110
|
|
|
109
111
|
def apt_remove_cmd(package: str, /, *packages: str) -> list[str]:
|
|
@@ -246,9 +248,8 @@ class ChownCmdError(Exception):
|
|
|
246
248
|
|
|
247
249
|
def chpasswd(user_name: str, password: str, /, *, sudo: bool = False) -> None:
|
|
248
250
|
"""Update passwords."""
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
)
|
|
251
|
+
args = maybe_sudo_cmd(CHPASSWD, sudo=sudo) # pragma: no cover
|
|
252
|
+
run(*args, input=f"{user_name}:{password}") # pragma: no cover
|
|
252
253
|
|
|
253
254
|
|
|
254
255
|
##
|
|
File without changes
|
|
File without changes
|