pywhales 0.2.1__tar.gz

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.
Files changed (107) hide show
  1. pywhales-0.2.1/LICENSE +21 -0
  2. pywhales-0.2.1/MANIFEST.in +3 -0
  3. pywhales-0.2.1/PKG-INFO +206 -0
  4. pywhales-0.2.1/README.md +189 -0
  5. pywhales-0.2.1/docs/requirements.txt +11 -0
  6. pywhales-0.2.1/docs/template/docker_client.md +116 -0
  7. pywhales-0.2.1/docs/template/index.md +1 -0
  8. pywhales-0.2.1/docs/template/objects/builders.md +41 -0
  9. pywhales-0.2.1/docs/template/objects/configs.md +51 -0
  10. pywhales-0.2.1/docs/template/objects/containers.md +48 -0
  11. pywhales-0.2.1/docs/template/objects/images.md +56 -0
  12. pywhales-0.2.1/docs/template/objects/networks.md +50 -0
  13. pywhales-0.2.1/docs/template/objects/nodes.md +51 -0
  14. pywhales-0.2.1/docs/template/objects/plugins.md +50 -0
  15. pywhales-0.2.1/docs/template/objects/services.md +51 -0
  16. pywhales-0.2.1/docs/template/objects/tasks.md +31 -0
  17. pywhales-0.2.1/docs/template/objects/volumes.md +56 -0
  18. pywhales-0.2.1/docs/template/sub-commands/buildx.md +47 -0
  19. pywhales-0.2.1/docs/template/sub-commands/compose.md +84 -0
  20. pywhales-0.2.1/docs/template/sub-commands/context.md +40 -0
  21. pywhales-0.2.1/docs/template/user_guide/build_performance.md +374 -0
  22. pywhales-0.2.1/docs/template/user_guide/docker_run.md +105 -0
  23. pywhales-0.2.1/docs/template/user_guide/exceptions.md +35 -0
  24. pywhales-0.2.1/docs/template/user_guide/generic_resources.md +176 -0
  25. pywhales-0.2.1/docs/template/user_guide/running_pydocker_inside_a_container.md +107 -0
  26. pywhales-0.2.1/pyproject.toml +99 -0
  27. pywhales-0.2.1/pywhales/__init__.py +48 -0
  28. pywhales-0.2.1/pywhales/client_config.py +325 -0
  29. pywhales-0.2.1/pywhales/command_line_entrypoint.py +8 -0
  30. pywhales-0.2.1/pywhales/components/__init__.py +0 -0
  31. pywhales-0.2.1/pywhales/components/_swarm_inspect.py +78 -0
  32. pywhales-0.2.1/pywhales/components/buildx/__init__.py +0 -0
  33. pywhales-0.2.1/pywhales/components/buildx/cli_wrapper.py +1123 -0
  34. pywhales-0.2.1/pywhales/components/buildx/imagetools/__init__.py +0 -0
  35. pywhales-0.2.1/pywhales/components/buildx/imagetools/cli_wrapper.py +117 -0
  36. pywhales-0.2.1/pywhales/components/buildx/imagetools/models.py +40 -0
  37. pywhales-0.2.1/pywhales/components/buildx/models.py +27 -0
  38. pywhales-0.2.1/pywhales/components/compose/__init__.py +0 -0
  39. pywhales-0.2.1/pywhales/components/compose/cli_wrapper.py +1534 -0
  40. pywhales-0.2.1/pywhales/components/compose/models.py +147 -0
  41. pywhales-0.2.1/pywhales/components/config/__init__.py +0 -0
  42. pywhales-0.2.1/pywhales/components/config/cli_wrapper.py +186 -0
  43. pywhales-0.2.1/pywhales/components/config/models.py +30 -0
  44. pywhales-0.2.1/pywhales/components/container/__init__.py +0 -0
  45. pywhales-0.2.1/pywhales/components/container/cli_wrapper.py +2533 -0
  46. pywhales-0.2.1/pywhales/components/container/models.py +312 -0
  47. pywhales-0.2.1/pywhales/components/container/top.py +85 -0
  48. pywhales-0.2.1/pywhales/components/context/__init__.py +0 -0
  49. pywhales-0.2.1/pywhales/components/context/cli_wrapper.py +249 -0
  50. pywhales-0.2.1/pywhales/components/context/models.py +27 -0
  51. pywhales-0.2.1/pywhales/components/image/__init__.py +0 -0
  52. pywhales-0.2.1/pywhales/components/image/cli_wrapper.py +1058 -0
  53. pywhales-0.2.1/pywhales/components/image/models.py +47 -0
  54. pywhales-0.2.1/pywhales/components/image/streams.py +149 -0
  55. pywhales-0.2.1/pywhales/components/manifest/__init__.py +0 -0
  56. pywhales-0.2.1/pywhales/components/manifest/cli_wrapper.py +180 -0
  57. pywhales-0.2.1/pywhales/components/manifest/models.py +9 -0
  58. pywhales-0.2.1/pywhales/components/network/__init__.py +0 -0
  59. pywhales-0.2.1/pywhales/components/network/cli_wrapper.py +365 -0
  60. pywhales-0.2.1/pywhales/components/network/models.py +36 -0
  61. pywhales-0.2.1/pywhales/components/node/__init__.py +0 -0
  62. pywhales-0.2.1/pywhales/components/node/cli_wrapper.py +274 -0
  63. pywhales-0.2.1/pywhales/components/node/models.py +91 -0
  64. pywhales-0.2.1/pywhales/components/plugin/__init__.py +0 -0
  65. pywhales-0.2.1/pywhales/components/plugin/cli_wrapper.py +308 -0
  66. pywhales-0.2.1/pywhales/components/plugin/models.py +39 -0
  67. pywhales-0.2.1/pywhales/components/secret/__init__.py +0 -0
  68. pywhales-0.2.1/pywhales/components/secret/cli_wrapper.py +176 -0
  69. pywhales-0.2.1/pywhales/components/secret/models.py +19 -0
  70. pywhales-0.2.1/pywhales/components/service/__init__.py +0 -0
  71. pywhales-0.2.1/pywhales/components/service/cli_wrapper.py +617 -0
  72. pywhales-0.2.1/pywhales/components/service/models.py +93 -0
  73. pywhales-0.2.1/pywhales/components/stack/__init__.py +0 -0
  74. pywhales-0.2.1/pywhales/components/stack/cli_wrapper.py +170 -0
  75. pywhales-0.2.1/pywhales/components/swarm/__init__.py +0 -0
  76. pywhales-0.2.1/pywhales/components/swarm/cli_wrapper.py +229 -0
  77. pywhales-0.2.1/pywhales/components/system/__init__.py +0 -0
  78. pywhales-0.2.1/pywhales/components/system/cli_wrapper.py +192 -0
  79. pywhales-0.2.1/pywhales/components/system/models.py +214 -0
  80. pywhales-0.2.1/pywhales/components/task/__init__.py +0 -0
  81. pywhales-0.2.1/pywhales/components/task/cli_wrapper.py +117 -0
  82. pywhales-0.2.1/pywhales/components/task/models.py +158 -0
  83. pywhales-0.2.1/pywhales/components/top.py +172 -0
  84. pywhales-0.2.1/pywhales/components/trust/__init__.py +0 -0
  85. pywhales-0.2.1/pywhales/components/trust/cli_wrapper.py +22 -0
  86. pywhales-0.2.1/pywhales/components/volume/__init__.py +0 -0
  87. pywhales-0.2.1/pywhales/components/volume/cli_wrapper.py +393 -0
  88. pywhales-0.2.1/pywhales/components/volume/models.py +16 -0
  89. pywhales-0.2.1/pywhales/docker_client.py +391 -0
  90. pywhales-0.2.1/pywhales/exceptions.py +62 -0
  91. pywhales-0.2.1/pywhales/py.typed +1 -0
  92. pywhales-0.2.1/pywhales/test_utils.py +25 -0
  93. pywhales-0.2.1/pywhales/utils.py +541 -0
  94. pywhales-0.2.1/pywhales.egg-info/PKG-INFO +206 -0
  95. pywhales-0.2.1/pywhales.egg-info/SOURCES.txt +105 -0
  96. pywhales-0.2.1/pywhales.egg-info/dependency_links.txt +1 -0
  97. pywhales-0.2.1/pywhales.egg-info/entry_points.txt +2 -0
  98. pywhales-0.2.1/pywhales.egg-info/requires.txt +4 -0
  99. pywhales-0.2.1/pywhales.egg-info/top_level.txt +1 -0
  100. pywhales-0.2.1/scripts/docker-plugin-checksums.txt +3 -0
  101. pywhales-0.2.1/setup.cfg +4 -0
  102. pywhales-0.2.1/skills/pywhales/SKILL.md +61 -0
  103. pywhales-0.2.1/skills/pywhales/references/buildx.md +86 -0
  104. pywhales-0.2.1/skills/pywhales/references/client-and-errors.md +82 -0
  105. pywhales-0.2.1/skills/pywhales/references/compose.md +100 -0
  106. pywhales-0.2.1/skills/pywhales/references/containers-and-output.md +85 -0
  107. pywhales-0.2.1/skills/pywhales/references/validation.md +50 -0
pywhales-0.2.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Gabriel de Marmiesse de Lussan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ global-include *.txt
2
+ global-include *.md
3
+ global-include *.typed
@@ -0,0 +1,206 @@
1
+ Metadata-Version: 2.4
2
+ Name: pywhales
3
+ Version: 0.2.1
4
+ Summary: A Docker client for Python, designed to be fun and intuitive!
5
+ License-Expression: MIT
6
+ Project-URL: Source, https://github.com/MaraClaw/PyWhales
7
+ Project-URL: Documentation, https://github.com/MaraClaw/PyWhales
8
+ Project-URL: Bug Tracker, https://github.com/MaraClaw/PyWhales/issues
9
+ Requires-Python: >=3.14.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: pydantic>=2.14.1
13
+ Requires-Dist: typing_extensions>=4.16.0
14
+ Requires-Dist: boto3>=1.43.118
15
+ Requires-Dist: s3transfer>=0.19.3
16
+ Dynamic: license-file
17
+
18
+ # PyWhales
19
+
20
+ ------------------------------------------------------------------------
21
+
22
+ [![Run tests](https://github.com/MaraClaw/PyWhales/actions/workflows/python-package.yml/badge.svg)](https://github.com/MaraClaw/PyWhales/actions/workflows/python-package.yml)
23
+ [![Code style: Ruff](https://img.shields.io/badge/code%20style-Ruff-261230.svg)](https://docs.astral.sh/ruff/)
24
+ [![Types: ty](https://img.shields.io/badge/types-ty-261230.svg)](https://docs.astral.sh/ty/)
25
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/MaraClaw/PyWhales/blob/HEAD/LICENSE)
26
+
27
+ ------------------------------------------------------------------------
28
+ The Docker and its composer client for Python, designed to be fun and intuitive!
29
+
30
+ Works on Linux, macOS and Windows, for Python 3.14.8 and above.
31
+
32
+ * [Documentation](https://github.com/MaraClaw/PyWhales/tree/HEAD/docs)
33
+ * [GitHub repository](https://github.com/MaraClaw/PyWhales)
34
+
35
+ ------------------------------------------------------------------------
36
+
37
+ ## How to install?
38
+
39
+ ```bash
40
+ uv pip install pywhales
41
+ ```
42
+
43
+ See [the Docker CLI guide](https://github.com/MaraClaw/PyWhales/blob/HEAD/docs/template/docker_client.md#the-docker-cli)
44
+ for instructions on installing Docker.
45
+
46
+ ## Some cool examples
47
+
48
+ Start by doing
49
+
50
+ ```python
51
+ from pywhales import docker
52
+ ```
53
+
54
+ and then:
55
+
56
+ * `docker run hello-world` -> `docker.run("hello-world")`
57
+ * `docker pull ubuntu` -> `docker.pull("ubuntu")`
58
+ * `docker build ./` -> `docker.build("./")`
59
+ * `docker compose up my_service` -> `docker.compose.up(["my_service"])`
60
+ * `docker image ls` -> `docker.image.list()`
61
+ * `docker ps` -> `docker.ps()`
62
+ * `docker cp` -> `docker.copy()`
63
+
64
+ ```python
65
+ >>> from pywhales import docker
66
+
67
+ >>> output = docker.run("hello-world")
68
+ >>> print(output)
69
+
70
+ Hello from Docker!
71
+ This message shows that your installation appears to be working correctly.
72
+
73
+ ...
74
+ ```
75
+
76
+ ```python
77
+ >>> from pywhales import docker
78
+ >>> my_image = docker.build(".", tags="some_name") # uses Buildx/buildkit by default
79
+ [+] Building 1.6s (17/17) FINISHED
80
+ ...
81
+ ```
82
+
83
+ ## Some more `docker.run()` advanced examples with postgres
84
+
85
+ ```bash
86
+ docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres
87
+ ```
88
+
89
+ becomes
90
+
91
+ ```python
92
+ from pywhales import docker
93
+
94
+ docker.run(
95
+ "postgres:9.6",
96
+ name="some-postgres",
97
+ envs={"POSTGRES_PASSWORD": "mysecretpassword"},
98
+ detach=True,
99
+ )
100
+ print(docker.ps())
101
+ # [pywhales.Container(id='f5fb939c409d', name='some-postgres')]
102
+ ```
103
+
104
+ -----
105
+
106
+ ```bash
107
+ docker run -it --rm --network some-network postgres psql -h some-postgres -U postgres
108
+ ```
109
+
110
+ becomes
111
+
112
+ ```python
113
+ from pywhales import docker
114
+
115
+ # since it's interactive, you'll be dropped into the psql shell. The python code
116
+ # will continue only after you exit the shell.
117
+ docker.run(
118
+ "postgres:9.6",
119
+ ["psql", "-h", "some-postgres", "-U", "postgres"],
120
+ networks=["some-network"],
121
+ interactive=True,
122
+ tty=True,
123
+ remove=True,
124
+ )
125
+ ```
126
+
127
+ ----------
128
+
129
+ ```bash
130
+ docker run -d --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -e PGDATA=/var/lib/postgresql/data/pgdata -v /custom/mount:/var/lib/postgresql/data -v myvolume:/tmp/myvolume postgres -c shared_buffers=256MB -c max_connections=200
131
+ ```
132
+
133
+ becomes
134
+
135
+ ```python
136
+ from pywhales import docker
137
+
138
+ docker.run(
139
+ "postgres:9.6",
140
+ ["-c", "shared_buffers=256MB", "-c", "max_connections=200"],
141
+ name="some-postgres",
142
+ envs={
143
+ "POSTGRES_PASSWORD": "mysecretpassword",
144
+ "PGDATA": "/var/lib/postgresql/data/pgdata",
145
+ },
146
+ volumes=[
147
+ ("/custom/mount", "/var/lib/postgresql/data"),
148
+ ("myvolume", "/tmp/myvolume"),
149
+ ],
150
+ detach=True,
151
+ )
152
+ ```
153
+
154
+
155
+ Any Docker object can be used as a context manager to ensure it's removed even if an exception occurs:
156
+
157
+ ```python
158
+ from pywhales import docker
159
+
160
+ with docker.volume.create("random_name") as some_volume:
161
+ docker.run(
162
+ "postgres:9.6",
163
+ ["-c", "shared_buffers=256MB", "-c", "max_connections=200"],
164
+ name="some-postgres",
165
+ envs={
166
+ "POSTGRES_PASSWORD": "mysecretpassword",
167
+ "PGDATA": "/var/lib/postgresql/data/pgdata",
168
+ },
169
+ volumes=[
170
+ (some_volume, "/var/lib/postgresql/data"),
171
+ ("myvolume", "/tmp/myvolume"),
172
+ ],
173
+ detach=True,
174
+ )
175
+ # so some stuff here
176
+
177
+ # here we are out of the context manager, so the volume has been removed, even if there was an exception.
178
+ ```
179
+
180
+ ## Main features
181
+
182
+ * 1 to 1 mapping between the CLI interface and the Python API. No need to look in the docs
183
+ what is the name of the function/argument you need.
184
+ * Support for the latest Docker features:
185
+ [Docker buildx/buildkit](https://github.com/docker/buildx),
186
+ `docker run --gpu=all ...`
187
+ * Support for Docker stack, services and Swarm (same API as the command line).
188
+ * Progress bars and progressive outputs when pulling, pushing, loading, building...
189
+ * Support for some other CLI commands that are not in [Docker-py](https://docker-py.readthedocs.io/en/stable/):
190
+ `docker cp`, `docker run --cpus ...` and more.
191
+ * Nice SSH support for remote daemons.
192
+ * Docker object as Python objects: Container, Images, Volumes, Services... and their
193
+ attributes are updated in real-time!
194
+ * Each Docker object can be used as a context manager. When getting out of the
195
+ context, the Docker object is removed automatically, even if an exception occurs.
196
+ * A fully typed API (ty and IDE-friendly) compatible with `pathlib` and `os.path`
197
+ * All Docker objects and the Docker client are safe to use with multithreading and multiprocessing.
198
+ * Display the commands called and the environment variables used by setting `PYDOCKER_DEBUG=1`.
199
+ The legacy `PYTHON_ON_WHALES_DEBUG` variable is a fallback only when `PYDOCKER_DEBUG` is unset.
200
+ Setting `PYDOCKER_DEBUG=0` or leaving its value explicitly empty disables debug output even if the legacy variable is set.
201
+
202
+ ## What about the license?
203
+
204
+ It's a MIT license, so quite permissive.
205
+
206
+ The license can be found [in the git repository](https://github.com/MaraClaw/PyWhales/blob/HEAD/LICENSE).
@@ -0,0 +1,189 @@
1
+ # PyWhales
2
+
3
+ ------------------------------------------------------------------------
4
+
5
+ [![Run tests](https://github.com/MaraClaw/PyWhales/actions/workflows/python-package.yml/badge.svg)](https://github.com/MaraClaw/PyWhales/actions/workflows/python-package.yml)
6
+ [![Code style: Ruff](https://img.shields.io/badge/code%20style-Ruff-261230.svg)](https://docs.astral.sh/ruff/)
7
+ [![Types: ty](https://img.shields.io/badge/types-ty-261230.svg)](https://docs.astral.sh/ty/)
8
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/MaraClaw/PyWhales/blob/HEAD/LICENSE)
9
+
10
+ ------------------------------------------------------------------------
11
+ The Docker and its composer client for Python, designed to be fun and intuitive!
12
+
13
+ Works on Linux, macOS and Windows, for Python 3.14.8 and above.
14
+
15
+ * [Documentation](https://github.com/MaraClaw/PyWhales/tree/HEAD/docs)
16
+ * [GitHub repository](https://github.com/MaraClaw/PyWhales)
17
+
18
+ ------------------------------------------------------------------------
19
+
20
+ ## How to install?
21
+
22
+ ```bash
23
+ uv pip install pywhales
24
+ ```
25
+
26
+ See [the Docker CLI guide](https://github.com/MaraClaw/PyWhales/blob/HEAD/docs/template/docker_client.md#the-docker-cli)
27
+ for instructions on installing Docker.
28
+
29
+ ## Some cool examples
30
+
31
+ Start by doing
32
+
33
+ ```python
34
+ from pywhales import docker
35
+ ```
36
+
37
+ and then:
38
+
39
+ * `docker run hello-world` -> `docker.run("hello-world")`
40
+ * `docker pull ubuntu` -> `docker.pull("ubuntu")`
41
+ * `docker build ./` -> `docker.build("./")`
42
+ * `docker compose up my_service` -> `docker.compose.up(["my_service"])`
43
+ * `docker image ls` -> `docker.image.list()`
44
+ * `docker ps` -> `docker.ps()`
45
+ * `docker cp` -> `docker.copy()`
46
+
47
+ ```python
48
+ >>> from pywhales import docker
49
+
50
+ >>> output = docker.run("hello-world")
51
+ >>> print(output)
52
+
53
+ Hello from Docker!
54
+ This message shows that your installation appears to be working correctly.
55
+
56
+ ...
57
+ ```
58
+
59
+ ```python
60
+ >>> from pywhales import docker
61
+ >>> my_image = docker.build(".", tags="some_name") # uses Buildx/buildkit by default
62
+ [+] Building 1.6s (17/17) FINISHED
63
+ ...
64
+ ```
65
+
66
+ ## Some more `docker.run()` advanced examples with postgres
67
+
68
+ ```bash
69
+ docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres
70
+ ```
71
+
72
+ becomes
73
+
74
+ ```python
75
+ from pywhales import docker
76
+
77
+ docker.run(
78
+ "postgres:9.6",
79
+ name="some-postgres",
80
+ envs={"POSTGRES_PASSWORD": "mysecretpassword"},
81
+ detach=True,
82
+ )
83
+ print(docker.ps())
84
+ # [pywhales.Container(id='f5fb939c409d', name='some-postgres')]
85
+ ```
86
+
87
+ -----
88
+
89
+ ```bash
90
+ docker run -it --rm --network some-network postgres psql -h some-postgres -U postgres
91
+ ```
92
+
93
+ becomes
94
+
95
+ ```python
96
+ from pywhales import docker
97
+
98
+ # since it's interactive, you'll be dropped into the psql shell. The python code
99
+ # will continue only after you exit the shell.
100
+ docker.run(
101
+ "postgres:9.6",
102
+ ["psql", "-h", "some-postgres", "-U", "postgres"],
103
+ networks=["some-network"],
104
+ interactive=True,
105
+ tty=True,
106
+ remove=True,
107
+ )
108
+ ```
109
+
110
+ ----------
111
+
112
+ ```bash
113
+ docker run -d --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -e PGDATA=/var/lib/postgresql/data/pgdata -v /custom/mount:/var/lib/postgresql/data -v myvolume:/tmp/myvolume postgres -c shared_buffers=256MB -c max_connections=200
114
+ ```
115
+
116
+ becomes
117
+
118
+ ```python
119
+ from pywhales import docker
120
+
121
+ docker.run(
122
+ "postgres:9.6",
123
+ ["-c", "shared_buffers=256MB", "-c", "max_connections=200"],
124
+ name="some-postgres",
125
+ envs={
126
+ "POSTGRES_PASSWORD": "mysecretpassword",
127
+ "PGDATA": "/var/lib/postgresql/data/pgdata",
128
+ },
129
+ volumes=[
130
+ ("/custom/mount", "/var/lib/postgresql/data"),
131
+ ("myvolume", "/tmp/myvolume"),
132
+ ],
133
+ detach=True,
134
+ )
135
+ ```
136
+
137
+
138
+ Any Docker object can be used as a context manager to ensure it's removed even if an exception occurs:
139
+
140
+ ```python
141
+ from pywhales import docker
142
+
143
+ with docker.volume.create("random_name") as some_volume:
144
+ docker.run(
145
+ "postgres:9.6",
146
+ ["-c", "shared_buffers=256MB", "-c", "max_connections=200"],
147
+ name="some-postgres",
148
+ envs={
149
+ "POSTGRES_PASSWORD": "mysecretpassword",
150
+ "PGDATA": "/var/lib/postgresql/data/pgdata",
151
+ },
152
+ volumes=[
153
+ (some_volume, "/var/lib/postgresql/data"),
154
+ ("myvolume", "/tmp/myvolume"),
155
+ ],
156
+ detach=True,
157
+ )
158
+ # so some stuff here
159
+
160
+ # here we are out of the context manager, so the volume has been removed, even if there was an exception.
161
+ ```
162
+
163
+ ## Main features
164
+
165
+ * 1 to 1 mapping between the CLI interface and the Python API. No need to look in the docs
166
+ what is the name of the function/argument you need.
167
+ * Support for the latest Docker features:
168
+ [Docker buildx/buildkit](https://github.com/docker/buildx),
169
+ `docker run --gpu=all ...`
170
+ * Support for Docker stack, services and Swarm (same API as the command line).
171
+ * Progress bars and progressive outputs when pulling, pushing, loading, building...
172
+ * Support for some other CLI commands that are not in [Docker-py](https://docker-py.readthedocs.io/en/stable/):
173
+ `docker cp`, `docker run --cpus ...` and more.
174
+ * Nice SSH support for remote daemons.
175
+ * Docker object as Python objects: Container, Images, Volumes, Services... and their
176
+ attributes are updated in real-time!
177
+ * Each Docker object can be used as a context manager. When getting out of the
178
+ context, the Docker object is removed automatically, even if an exception occurs.
179
+ * A fully typed API (ty and IDE-friendly) compatible with `pathlib` and `os.path`
180
+ * All Docker objects and the Docker client are safe to use with multithreading and multiprocessing.
181
+ * Display the commands called and the environment variables used by setting `PYDOCKER_DEBUG=1`.
182
+ The legacy `PYTHON_ON_WHALES_DEBUG` variable is a fallback only when `PYDOCKER_DEBUG` is unset.
183
+ Setting `PYDOCKER_DEBUG=0` or leaving its value explicitly empty disables debug output even if the legacy variable is set.
184
+
185
+ ## What about the license?
186
+
187
+ It's a MIT license, so quite permissive.
188
+
189
+ The license can be found [in the git repository](https://github.com/MaraClaw/PyWhales/blob/HEAD/LICENSE).
@@ -0,0 +1,11 @@
1
+ astunparse==1.6.3
2
+ griffe==1.2.0
3
+ markdown==3.7
4
+ markupsafe==2.1.5
5
+ mkdocs==1.6.1
6
+ mkdocs-autorefs==1.1.0
7
+ mkdocs-get-deps==0.2.0
8
+ mkdocs-material==9.5.34
9
+ mkdocstrings==0.25.2
10
+ mkdocstrings-python==1.10.9
11
+ pymdown-extensions==10.9
@@ -0,0 +1,116 @@
1
+ # The Docker client object
2
+
3
+
4
+ {{autogenerated}}
5
+
6
+ ## Sub-commands
7
+
8
+ * [`docker.buildx`](sub-commands/buildx.md)
9
+ * [`docker.compose`](sub-commands/compose.md)
10
+ * [`docker.config`](sub-commands/config.md)
11
+ * [`docker.container`](sub-commands/container.md)
12
+ * [`docker.context`](sub-commands/context.md)
13
+ * [`docker.image`](sub-commands/image.md)
14
+ * [`docker.manifest`](sub-commands/manifest.md)
15
+ * [`docker.network`](sub-commands/network.md)
16
+ * [`docker.node`](sub-commands/node.md)
17
+ * [`docker.secret`](sub-commands/secret.md)
18
+ * [`docker.service`](sub-commands/service.md)
19
+ * [`docker.stack`](sub-commands/stack.md)
20
+ * [`docker.swarm`](sub-commands/swarm.md)
21
+ * [`docker.system`](sub-commands/system.md)
22
+ * [`docker.trust`](sub-commands/trust.md)
23
+ * [`docker.volume`](sub-commands/volume.md)
24
+
25
+
26
+ ## Other commands
27
+
28
+ They're actually aliases
29
+
30
+ * [`docker.attach`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.attach)
31
+ * [`docker.build`](sub-commands/buildx.md#pywhales.components.buildx.cli_wrapper.BuildxCLI.build)
32
+ * [`docker.commit`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.commit)
33
+ * [`docker.copy`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.copy)
34
+ * [`docker.create`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.create)
35
+ * [`docker.diff`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.diff)
36
+ * [`docker.execute`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.execute)
37
+ * [`docker.export`](sub-commands/container.md#pywhales.components.image.cli_wrapper.ImageCLI.export)
38
+ * [`docker.images`](sub-commands/image.md#pywhales.components.image.cli_wrapper.ImageCLI.list)
39
+ * [`docker.import_`](sub-commands/image.md#pywhales.components.image.cli_wrapper.ImageCLI.import_)
40
+ * [`docker.info`](sub-commands/system.md#pywhales.components.system.cli_wrapper.SystemCLI.info)
41
+ * [`docker.kill`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.kill)
42
+ * [`docker.load`](sub-commands/image.md#pywhales.components.image.cli_wrapper.ImageCLI.load)
43
+ * [`docker.logs`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.logs)
44
+ * [`docker.pause`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.pause)
45
+ * [`docker.ps`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.list)
46
+ * [`docker.pull`](sub-commands/image.md#pywhales.components.image.cli_wrapper.ImageCLI.pull)
47
+ * [`docker.push`](sub-commands/image.md#pywhales.components.image.cli_wrapper.ImageCLI.push)
48
+ * [`docker.rename`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.rename)
49
+ * [`docker.restart`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.rename)
50
+ * [`docker.remove`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.rename)
51
+ * [`docker.run`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.rename)
52
+ * [`docker.save`](sub-commands/image.md#pywhales.components.image.cli_wrapper.ImageCLI.save)
53
+ * [`docker.start`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.start)
54
+ * [`docker.stats`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.stats)
55
+ * [`docker.stop`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.stop)
56
+ * [`docker.tag`](sub-commands/image.md#pywhales.components.image.cli_wrapper.ImageCLI.tag)
57
+ * [`docker.top`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.top)
58
+ * [`docker.unpause`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.unpause)
59
+ * [`docker.update`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.update)
60
+ * [`docker.wait`](sub-commands/container.md#pywhales.components.container.cli_wrapper.ContainerCLI.wait)
61
+
62
+
63
+ ## About multithreading and multiprocessing
64
+
65
+ Behind the scenes, pywhales calls the Docker command line interface with
66
+ subprocess. The pywhales client does not store any intermediate state so it's safe
67
+ to use with multithreading.
68
+
69
+ The Docker objects store some intermediate states (the attributes
70
+ that you would normally get with `docker ... inspect`but no logic in
71
+ the codebase depends on those attributes. They're just here so that users can look at them.
72
+ So you can share them between process/threads and pickle containers, images, networks...
73
+
74
+ The Docker daemon works with its own objects internally and handles concurrent and conflicting requests.
75
+ For example, if you create two containers with the same name from different threads, only one will
76
+ succeed. If you pull the same docker image from multiple processes/threads, the Docker daemon will
77
+ only pull the image and layers once.
78
+
79
+ Just be careful with some scenario similar to this one
80
+
81
+ ```
82
+ Thread 1: my_container = docker.run(..., detach=True)
83
+ ...
84
+ # my_container finishes
85
+ ...
86
+ Thread 2: docker.container.prune()
87
+ ...
88
+ Thread 1: docker.logs(my_container) # will fail because the container was removed by thread 2
89
+ ```
90
+
91
+ In the end, unless you use this type of logic in your code,
92
+ pywhales is safe to use with multithreading and multiprocessing.
93
+
94
+
95
+ ## The Docker CLI
96
+
97
+ pywhales needs the Docker CLI to work (unlike docker-py).
98
+ Most of the time, users already have the CLI installed on their machines. It's possible to
99
+ verify that the CLI is there by doing `docker --help` in the command line.
100
+
101
+ Sometimes, the CLI might not be available on the system, it can happen if you want to control
102
+ Docker from within a container with `-v /var/run/docker.sock:/var/run/docker.sock`, or if you
103
+ want to connect to a remote daemon with the `host` argument.
104
+
105
+ Instructions for installing Docker can be found at <https://docs.docker.com/engine/install/>.
106
+ Note that if connecting to Docker remotely then a local Docker daemon (`dockerd`) is not needed.
107
+
108
+ Previously, when using python-on-whales, the Docker CLI was downloaded automatically, but
109
+ this functionality was removed under <https://github.com/gabrieldemarmiesse/python-on-whales/pull/633>.
110
+
111
+
112
+ ### Handling an unavailable client
113
+
114
+ Trying to use pywhales when it cannot find a Docker client binary
115
+ will trigger a `pywhales.ClientNotFoundError`. You can use a try-except around
116
+ a first `docker.ps()` call to handle the case when pywhales won't work.
@@ -0,0 +1 @@
1
+ --8<-- "README.md"
@@ -0,0 +1,41 @@
1
+ # Docker builders
2
+
3
+ The Buildx builders objects.
4
+
5
+ Don't use the constructor directly. Instead use
6
+ ```python
7
+ from pywhales import docker
8
+
9
+ my_builder = docker.buildx.inspect("my-builder")
10
+
11
+ # or
12
+
13
+ my_builder = docker.buildx.create()
14
+ ```
15
+ For type hints, use this
16
+
17
+ ```python
18
+ from pywhales import Builder
19
+ ```
20
+
21
+ ## Attributes
22
+
23
+ The attributes are the same as with the command line:
24
+ `docker buildx inspect ...`
25
+
26
+ Only a few are available at the moment
27
+ ```
28
+ In [1]: from pywhales import docker
29
+
30
+ In [2]: my_builder = docker.buildx.create()
31
+
32
+ In [4]: def super_print(obj):
33
+ ...: print(f"type={type(obj)}, value={obj}")
34
+ ...:
35
+
36
+ @INSERT_GENERATED_CODE@
37
+ ```
38
+
39
+ ## Methods
40
+
41
+ {{autogenerated}}
@@ -0,0 +1,51 @@
1
+ # Docker configs
2
+
3
+ Configs objects present in Swarm mode
4
+
5
+ Don't use the constructor directly. Instead use
6
+ ```python
7
+ from pywhales import docker
8
+
9
+ my_config = docker.config.inspect("my-config-name")
10
+
11
+ # or
12
+
13
+ my_config = docker.config.create("my_config_name", "my_config_file")
14
+ ```
15
+ For type hints, use this
16
+
17
+ ```python
18
+ from pywhales import Config
19
+
20
+
21
+ def print_config_labels(config: Config):
22
+ print(config.spec.labels)
23
+ ```
24
+
25
+
26
+ ## Attributes
27
+
28
+ The attributes are the same as with the command line:
29
+ `docker config inspect ...`
30
+
31
+ To get a complete description of those attributes, you
32
+ can take a look at the [daemon api reference page](https://docs.docker.com/engine/api/v1.40/#operation/ConfigInspect)
33
+ and click on "200 No error".
34
+
35
+ An example is worth many lines of descriptions.
36
+
37
+ ```
38
+ In [1]: from pywhales import docker
39
+
40
+ In [2]: config = docker.config.create("my_config", "./config_file.cfg", labels=dict(hello="world"))
41
+
42
+ In [3]: def super_print(obj):
43
+ ...: print(f"type={type(obj)}, value={obj}")
44
+ ...:
45
+
46
+ @INSERT_GENERATED_CODE@
47
+ ```
48
+
49
+ ## Methods
50
+
51
+ {{autogenerated}}