container-magic 0.1.0__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 (31) hide show
  1. container_magic-0.1.0/LICENSE +21 -0
  2. container_magic-0.1.0/PKG-INFO +372 -0
  3. container_magic-0.1.0/README.md +338 -0
  4. container_magic-0.1.0/pyproject.toml +82 -0
  5. container_magic-0.1.0/setup.cfg +4 -0
  6. container_magic-0.1.0/src/container_magic/__init__.py +3 -0
  7. container_magic-0.1.0/src/container_magic/cli/__init__.py +1 -0
  8. container_magic-0.1.0/src/container_magic/cli/main.py +520 -0
  9. container_magic-0.1.0/src/container_magic/core/__init__.py +1 -0
  10. container_magic-0.1.0/src/container_magic/core/cache.py +142 -0
  11. container_magic-0.1.0/src/container_magic/core/config.py +381 -0
  12. container_magic-0.1.0/src/container_magic/core/runtime.py +60 -0
  13. container_magic-0.1.0/src/container_magic/core/templates.py +78 -0
  14. container_magic-0.1.0/src/container_magic/generators/__init__.py +1 -0
  15. container_magic-0.1.0/src/container_magic/generators/build_script.py +41 -0
  16. container_magic-0.1.0/src/container_magic/generators/dockerfile.py +262 -0
  17. container_magic-0.1.0/src/container_magic/generators/justfile.py +97 -0
  18. container_magic-0.1.0/src/container_magic/generators/run_script.py +55 -0
  19. container_magic-0.1.0/src/container_magic/generators/standalone_commands.py +81 -0
  20. container_magic-0.1.0/src/container_magic/templates/Dockerfile.j2 +99 -0
  21. container_magic-0.1.0/src/container_magic/templates/Justfile.j2 +232 -0
  22. container_magic-0.1.0/src/container_magic/templates/build.sh.j2 +95 -0
  23. container_magic-0.1.0/src/container_magic/templates/custom_command.j2 +85 -0
  24. container_magic-0.1.0/src/container_magic/templates/run.sh.j2 +109 -0
  25. container_magic-0.1.0/src/container_magic/templates/standalone_command.sh.j2 +57 -0
  26. container_magic-0.1.0/src/container_magic.egg-info/PKG-INFO +372 -0
  27. container_magic-0.1.0/src/container_magic.egg-info/SOURCES.txt +29 -0
  28. container_magic-0.1.0/src/container_magic.egg-info/dependency_links.txt +1 -0
  29. container_magic-0.1.0/src/container_magic.egg-info/entry_points.txt +4 -0
  30. container_magic-0.1.0/src/container_magic.egg-info/requires.txt +12 -0
  31. container_magic-0.1.0/src/container_magic.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mark Hedley Jones
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,372 @@
1
+ Metadata-Version: 2.4
2
+ Name: container-magic
3
+ Version: 0.1.0
4
+ Summary: A tool for rapidly creating containerised development environments
5
+ Author-email: Mark Hedley Jones <mark@hedleyjones.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/markhedleyjones/container-magic
8
+ Project-URL: Repository, https://github.com/markhedleyjones/container-magic
9
+ Project-URL: Issues, https://github.com/markhedleyjones/container-magic/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.8
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: pyyaml>=6.0
23
+ Requires-Dist: jinja2>=3.1.0
24
+ Requires-Dist: click>=8.1.0
25
+ Requires-Dist: pydantic>=2.0.0
26
+ Requires-Dist: requests>=2.31.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
29
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
30
+ Requires-Dist: black>=23.0.0; extra == "dev"
31
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
32
+ Requires-Dist: python-semantic-release>=8.0.0; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ <div align="center">
36
+ <img src="https://raw.githubusercontent.com/markhedleyjones/container-magic-artwork/main/sparkles/original-vector.svg" alt="Container Magic - Sparkles the Otter" width="200"/>
37
+
38
+ # container-magic
39
+
40
+ A tool for rapidly creating containerised development environments. Configure once in YAML, use anywhere with Docker or Podman.
41
+ </div>
42
+
43
+ ## What It Does
44
+
45
+ Container-magic takes a single YAML configuration file and generates:
46
+ 1. A **Dockerfile** with multi-stage builds
47
+ 2. A **Justfile** for development (with live workspace mounting)
48
+ 3. Standalone **build.sh** and **run.sh** scripts for production
49
+
50
+ The Dockerfile and standalone scripts are committed to your repository, so anyone can use your project with just `docker` or `podman` - no need to install container-magic or just.
51
+
52
+ ## Key Features
53
+
54
+ * **YAML configuration** - Single source of truth for your container setup
55
+ * **Transparent execution** - Run commands in container from anywhere in your repo with path translation
56
+ * **Custom commands** - Define commands once, use in both dev and prod
57
+ * **Smart features** - GPU, display (X11/Wayland), and audio support
58
+ * **Multi-stage builds** - Separate base, development, and production stages
59
+ * **Live workspace mounting** - Edit code on host, run in container (development)
60
+ * **Standalone scripts** - Production needs only docker/podman (no dependencies)
61
+
62
+ ## Quick Start
63
+
64
+ ```bash
65
+ # Install
66
+ pip install container-magic
67
+
68
+ # Create a new project
69
+ cm init python my-project
70
+ cd my-project
71
+
72
+ # Build the container
73
+ build
74
+
75
+ # Run commands inside the container
76
+ run python --version
77
+ run bash -c "echo Hello from container"
78
+ run # starts an interactive shell
79
+ ```
80
+
81
+ The `run` command works from anywhere in your repository and translates your working directory automatically. When using the `run` alias (not `just run` directly), path translation ensures the container's working directory matches your position in the repository.
82
+
83
+ ## Workflow
84
+
85
+ ```
86
+ ┌─────────────────────┐
87
+ │ cm.yaml │ ← You edit this
88
+ │ (central config) │
89
+ └──────────┬──────────┘
90
+
91
+ │ cm init / cm update
92
+
93
+ ├─────────────┬──────────────────┬──────────────────┐
94
+ ▼ ▼ ▼ ▼
95
+ Dockerfile Development Production Command Scripts
96
+ ┌───────────────┐ ┌──────────────┐ ┌──────────────┐
97
+ │ • Justfile │ │ • build.sh │ │ • <cmd>.sh │
98
+ │ │ │ • run.sh │ │ (optional) │
99
+ │ (mounts live │ │ │ │ │
100
+ │ workspace) │ │ (standalone, │ │ (standalone, │
101
+ └───────────────┘ │ no cm deps) │ │ no cm deps) │
102
+ └──────────────┘ └──────────────┘
103
+ ```
104
+
105
+ Production files (Dockerfile, build.sh, run.sh, command scripts) are committed to git.
106
+ The Justfile is generated locally for developers.
107
+
108
+ ## Basic Example
109
+
110
+ A minimal `cm.yaml`:
111
+
112
+ ```yaml
113
+ project:
114
+ name: my-project
115
+ workspace: workspace
116
+
117
+ stages:
118
+ base:
119
+ from: python:3.11-slim
120
+ packages:
121
+ apt: [git, build-essential]
122
+ pip: [numpy, pandas]
123
+
124
+ development:
125
+ from: base
126
+
127
+ production:
128
+ from: base
129
+ ```
130
+
131
+ This generates everything you need to build and run your project.
132
+
133
+ ## Example with Features
134
+
135
+ ```yaml
136
+ project:
137
+ name: ml-training
138
+ workspace: workspace
139
+ auto_update: true
140
+
141
+ runtime:
142
+ features:
143
+ - gpu # NVIDIA GPU
144
+ - display # X11/Wayland
145
+
146
+ stages:
147
+ base:
148
+ from: pytorch/pytorch
149
+ packages:
150
+ pip: [transformers, datasets]
151
+ env:
152
+ HF_HOME: /models
153
+
154
+ development:
155
+ from: base
156
+ packages:
157
+ pip: [pytest, ipython]
158
+
159
+ production:
160
+ from: base
161
+
162
+ commands:
163
+ train:
164
+ command: python workspace/train.py
165
+ description: Train the model
166
+ standalone: true # Generate dedicated train.sh script
167
+ ```
168
+
169
+ **Development:**
170
+ ```bash
171
+ build
172
+ run train # Use custom command directly (from anywhere)
173
+ ```
174
+
175
+ **Production:**
176
+ ```bash
177
+ ./build.sh
178
+ ./run.sh train # Run via run.sh
179
+ ./train.sh # Or use dedicated standalone script
180
+ ```
181
+
182
+ ## YAML Reference
183
+
184
+ ### Project
185
+
186
+ ```yaml
187
+ project:
188
+ name: my-project # Required: image name
189
+ workspace: workspace # Required: directory with your code
190
+ auto_update: true # Optional: auto-regenerate on config changes
191
+ ```
192
+
193
+ ### Runtime
194
+
195
+ ```yaml
196
+ runtime:
197
+ backend: auto # docker, podman, or auto
198
+ privileged: false # privileged mode
199
+ features:
200
+ - gpu # NVIDIA GPU
201
+ - display # X11/Wayland
202
+ - audio # PulseAudio/PipeWire
203
+ ```
204
+
205
+ ### Stages
206
+
207
+ ```yaml
208
+ stages:
209
+ base:
210
+ from: python:3.11-slim # Any Docker Hub image
211
+ packages:
212
+ apt: [git, curl]
213
+ pip: [numpy, pandas]
214
+ env:
215
+ VAR: value
216
+
217
+ development:
218
+ from: base # Inherit from base
219
+ packages:
220
+ pip: [pytest]
221
+
222
+ production:
223
+ from: base
224
+ ```
225
+
226
+ You can use any image from Docker Hub as your base (e.g., `python:3.11`, `ubuntu:22.04`, `pytorch/pytorch`, `nvidia/cuda:12.4.0-runtime-ubuntu22.04`).
227
+
228
+ ### Commands
229
+
230
+ Define custom commands that work in both dev and prod:
231
+
232
+ ```yaml
233
+ commands:
234
+ train:
235
+ command: python workspace/train.py
236
+ description: Train model
237
+ env:
238
+ CUDA_VISIBLE_DEVICES: "0"
239
+ standalone: false # Default: false (no dedicated script)
240
+
241
+ deploy:
242
+ command: bash workspace/deploy.sh
243
+ description: Deploy the model
244
+ standalone: true # Generates deploy.sh script
245
+ ```
246
+
247
+ The `standalone` flag (default: `false`) controls script generation:
248
+ - **`standalone: false`** (default) - Command available via `run <command>` and `./run.sh <command>` only
249
+ - **`standalone: true`** - Also generates a dedicated `<command>.sh` script for direct execution
250
+
251
+ **Development:**
252
+ - `run train` - from anywhere in your repository
253
+ - `just train` - from repository root (if you have `just` installed)
254
+
255
+ **Production (standalone: false):**
256
+ - `./run.sh train` - only way to run
257
+
258
+ **Production (standalone: true):**
259
+ - `./run.sh deploy` - via run.sh
260
+ - `./deploy.sh` - dedicated standalone script
261
+
262
+ ### Build Script
263
+
264
+ Configure the standalone `build.sh` script behaviour:
265
+
266
+ ```yaml
267
+ build_script:
268
+ default_target: production # Optional: default stage to build (default: production)
269
+ ```
270
+
271
+ The `build.sh` script can build any defined stage:
272
+
273
+ ```bash
274
+ ./build.sh # Builds the default target (production) → tagged as 'latest'
275
+ ./build.sh production # Builds production stage → tagged as 'latest'
276
+ ./build.sh testing # Builds testing stage → tagged as 'testing'
277
+ ./build.sh development # Builds development stage → tagged as 'development'
278
+ ./build.sh --help # Shows all available targets
279
+ ```
280
+
281
+ **Image Tagging:**
282
+ - Production stage is tagged as `<project-name>:latest`
283
+ - All other stages are tagged as `<project-name>:<stage-name>`
284
+
285
+ This is useful when you have multiple build targets beyond just development and production (e.g., testing, staging, or platform-specific builds).
286
+
287
+ ## CLI Commands
288
+
289
+ ```bash
290
+ # Create new project
291
+ cm init <image> <name>
292
+ cm init --here <image> # Initialize in current dir
293
+ cm init --compact <image> # Use cm.yaml instead of container-magic.yaml
294
+
295
+ # Regenerate files after editing YAML
296
+ cm update
297
+
298
+ # Development (aliases)
299
+ build
300
+ run <command>
301
+
302
+ # Production (standalone scripts)
303
+ ./build.sh
304
+ ./run.sh <command>
305
+ ./run.sh <custom-command>
306
+ ```
307
+
308
+ The `<image>` can be any Docker Hub image like `python:3.11`, `ubuntu:22.04`, `pytorch/pytorch`, etc.
309
+
310
+ **Note:** Both `just` and the `build`/`run` aliases work from anywhere in your project by searching upward for the Justfile/config. For basic development, you only need `just` installed. Installing container-magic is recommended primarily for generating and regenerating files from your YAML config. As a bonus, it also provides command aliases with automatic working directory translation - the `run` alias (not `just run`) adjusts the container's working directory to match your position in the repository, making it feel like you're running commands on the host.
311
+
312
+ ## Using `just` vs `run` Alias
313
+
314
+ **When calling `just` directly:**
315
+ - Paths must be relative to the project root (where the Justfile is)
316
+ - Works from anywhere, but you must always specify paths from the project root
317
+ - Limitation: `just` changes to the Justfile directory, losing context of where you ran the command
318
+
319
+ **When using the `run` alias (requires container-magic installed):**
320
+ - Automatically translates your working directory to the container
321
+ - Paths can be relative to your current location
322
+ - The container's working directory matches your position in the repository
323
+
324
+ **Example:**
325
+ ```bash
326
+ # From project root - both work the same:
327
+ just run workspace/script.py # ✓ Works
328
+ run workspace/script.py # ✓ Works
329
+
330
+ # Now cd into workspace/ subdirectory:
331
+ cd workspace
332
+
333
+ # just fails because it looks for paths from project root:
334
+ just run script.py # ❌ Fails - looks for script.py in project root (not workspace/)
335
+
336
+ # run works because it translates your working directory:
337
+ run script.py # ✓ Works - finds script.py in current dir
338
+ ```
339
+
340
+ **Note:** You can make `just` work from subdirectories by always using full paths from the project root (e.g., `just run workspace/script.py` would work from anywhere).
341
+
342
+ ## Development vs Production
343
+
344
+ **Development:**
345
+ - Workspace mounted from host (edit code live, not baked into image)
346
+ - Runs as your user (correct permissions)
347
+ - Includes dev dependencies
348
+
349
+ **Production** (build.sh/run.sh):
350
+ - Workspace baked into image
351
+ - Standalone scripts (only need docker/podman)
352
+ - Minimal dependencies
353
+
354
+ ## Project Structure
355
+
356
+ ```
357
+ my-project/
358
+ ├── cm.yaml # Your config (committed)
359
+ ├── Dockerfile # Generated (committed)
360
+ ├── build.sh # Generated (committed)
361
+ ├── run.sh # Generated (committed)
362
+ ├── <command>.sh # Generated for each command where standalone: true (committed)
363
+ ├── Justfile # Generated locally for dev (gitignored)
364
+ ├── workspace/ # Your code
365
+ └── .cm-cache/ # Downloaded assets (gitignored)
366
+ ```
367
+
368
+ Command scripts (e.g., `train.sh`, `deploy.sh`) are only generated for commands with `standalone: true` and are committed to the repository.
369
+
370
+ ## Contributing
371
+
372
+ Container-magic is in early development. Contributions and feedback welcome!