snapmyenv 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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 snapmyenv contributors
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,430 @@
1
+ Metadata-Version: 2.4
2
+ Name: snapmyenv
3
+ Version: 0.1.0
4
+ Summary: Snapshot and restore Python environments for reproducible notebooks
5
+ Author: snapmyenv contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/yourusername/snapmyenv
8
+ Project-URL: Documentation, https://github.com/yourusername/snapmyenv#readme
9
+ Project-URL: Repository, https://github.com/yourusername/snapmyenv
10
+ Project-URL: Bug Tracker, https://github.com/yourusername/snapmyenv/issues
11
+ Keywords: jupyter,colab,notebook,reproducibility,environment,snapshot
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Framework :: Jupyter
24
+ Classifier: Framework :: IPython
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=7.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
31
+ Requires-Dist: black>=23.0; extra == "dev"
32
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
33
+ Requires-Dist: mypy>=1.0; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # snapmyenv ðŸ“ļ
37
+
38
+ **Snapshot and restore Python environments for reproducible notebooks**
39
+
40
+ `snapmyenv` is a lightweight library designed for Google Colab and Jupyter users to capture and restore runtime environments, making notebooks fully reproducible. Share your notebooks with confidence knowing others can recreate your exact environment.
41
+
42
+ [![PyPI version](https://badge.fury.io/py/snapmyenv.svg)](https://badge.fury.io/py/snapmyenv)
43
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
44
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
45
+
46
+ ## Features
47
+
48
+ - ðŸ“ļ **Capture environments** - Snapshot Python version, OS, and all installed packages
49
+ - 🔄 **Restore environments** - Recreate exact package versions from snapshots
50
+ - 📓 **Notebook integration** - Embed snapshots directly in `.ipynb` metadata
51
+ - 🌐 **Colab-friendly** - Designed for Google Colab and local Jupyter
52
+ - ðŸŠķ **Zero dependencies** - No external dependencies beyond Python stdlib
53
+ - ðŸ›Ąïļ **Production-ready** - Clean error handling, validation, and logging
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ pip install snapmyenv
59
+ ```
60
+
61
+ Based on the files provided, here is an analysis of the **`snapmyenv`** project.
62
+
63
+ ### **Executive Summary**
64
+
65
+ `snapmyenv` is a lightweight Python library designed to solve the "it works on my machine" problem for **Google Colab** and **Jupyter Notebooks**. It allows users to capture the current state of a Python environment (libraries, versions, OS info) and embed that "snapshot" directly into a notebook's metadata. This makes the notebook self-reproducible, allowing anyone who opens it to restore the exact environment used by the original author.
66
+
67
+ ### **Key Features**
68
+
69
+ 1. **Environment Capture**: It records the Python version, Operating System details (Platform), and a complete list of installed pip packages with their exact versions.
70
+ 2. **Notebook Embedding**: Unlike `requirements.txt` which is a separate file, `snapmyenv` embeds the dependency snapshot directly into the `.ipynb` file's JSON metadata under the key `snapmyenv_snapshot`.
71
+ 3. **Restoration**: It can read a snapshot (from memory, a file, or notebook metadata) and reinstall the specific package versions using `pip`.
72
+ 4. **Colab Integration**: It includes specific utilities to detect if code is running in Google Colab or a standard Jupyter environment.
73
+ 5. **Zero Dependencies**: The library itself has no external dependencies (only uses the Python standard library), making it easy to install without causing dependency conflicts.
74
+
75
+ ### **Technical Architecture**
76
+
77
+ * **Data Models (`models.py`)**:
78
+ The core data structure is the `EnvironmentSnapshot` dataclass, which holds metadata (timestamp, python version) and a list of `Package` objects. It handles serialization to and from JSON/dict formats.
79
+ * **Capture Mechanism (`capture.py`)**:
80
+ Instead of relying on `pkg_resources` or `importlib.metadata` directly, it spawns a subprocess running `pip list --format=json`. This is a robust way to get the exact list of installed packages as `pip` sees them.
81
+ * **Restore Mechanism (`restore.py`)**:
82
+ Restoration involves iterating through the captured package list and calling `pip install package==version` via subprocess. It includes a `dry_run` mode to preview changes without installing them. It also warns the user if the Python version differs from the snapshot.
83
+ * **Notebook Integration (`notebook.py`)**:
84
+ This module reads the raw JSON of a `.ipynb` file, injects the snapshot dictionary into `metadata["snapmyenv_snapshot"]`, and writes it back to disk. This allows the environment data to travel with the notebook file itself.
85
+
86
+ ### **Code Quality & Best Practices**
87
+
88
+ * **Modern Packaging**: The project uses `pyproject.toml` for configuration, adhering to modern Python packaging standards (PEP 517/518).
89
+ * **Type Hinting**: The code is fully type-hinted, improving readability and allowing for static analysis.
90
+ * **Testing**: There is a comprehensive test suite using `pytest` located in the `tests/` directory, covering capture, models, and restoration logic.
91
+ * **Safety**: The code includes a verification script (`verify_package.py`) to check structure and imports before distribution.
92
+
93
+ ### **Potential Limitations**
94
+
95
+ * **Pip Only**: The README explicitly notes it only captures pip-installed packages, not Conda packages or system-level binaries.
96
+ * **Virtual Environments**: It captures the *state* of packages, but does not recreate the virtual environment directory structure itself; it simply installs packages into currently active environment.
97
+
98
+ ### **Use Cases**
99
+
100
+ * **Research Papers**: Researchers can embed the exact environment used to generate their results into the supplementary notebook files.
101
+ * **Teaching**: Instructors can distribute problem sets with embedded environments so students don't face version mismatch errors.
102
+ * **Debugging**: Developers can capture a "broken" environment state to share with a colleague for troubleshooting.
103
+
104
+
105
+ ## Quick Start
106
+
107
+ ### Basic Usage
108
+
109
+ ```python
110
+ import snapmyenv
111
+
112
+ # Capture your current environment
113
+ snapshot = snapmyenv.capture("my-analysis")
114
+ # ✓ Captured environment 'my-analysis'
115
+ # Python: 3.10.12
116
+ # Platform: Linux
117
+ # Packages: 147
118
+ # Colab: Yes
119
+
120
+ # Later, restore the exact environment
121
+ snapmyenv.restore("my-analysis")
122
+ # Installing 147 packages...
123
+ # ✓ Restoration complete: 147 succeeded, 0 failed
124
+ ```
125
+
126
+ ### Make Notebooks Self-Reproducible
127
+
128
+ Embed your environment snapshot directly into your notebook:
129
+
130
+ ```python
131
+ # In your notebook:
132
+ import snapmyenv
133
+
134
+ # 1. Capture environment
135
+ snapmyenv.capture("v1")
136
+
137
+ # 2. Embed in notebook metadata
138
+ snapmyenv.embed("v1", "my_analysis.ipynb")
139
+ # ✓ Embedded snapshot 'v1' into my_analysis.ipynb
140
+
141
+ # Now anyone opening your notebook can restore:
142
+ snapmyenv.restore_from_nb("my_analysis.ipynb")
143
+ ```
144
+
145
+ ## Google Colab Example
146
+
147
+ Perfect for sharing reproducible analyses on Colab:
148
+
149
+ ```python
150
+ # At the top of your Colab notebook:
151
+ !pip install snapmyenv
152
+
153
+ import snapmyenv
154
+
155
+ # Capture your carefully crafted environment
156
+ snapmyenv.capture("colab-analysis-v1")
157
+
158
+ # Save it to your notebook
159
+ snapmyenv.embed("colab-analysis-v1", "/content/drive/MyDrive/analysis.ipynb")
160
+ ```
161
+
162
+ When someone else opens your notebook:
163
+
164
+ ```python
165
+ import snapmyenv
166
+
167
+ # Restore the exact environment
168
+ snapmyenv.restore_from_nb("/content/drive/MyDrive/analysis.ipynb")
169
+ ```
170
+
171
+ ## API Reference
172
+
173
+ ### `capture(name: str = "default", metadata: dict = None) -> dict`
174
+
175
+ Capture the current Python environment.
176
+
177
+ **Parameters:**
178
+ - `name` (str): Name for this snapshot (default: "default")
179
+ - `metadata` (dict): Optional metadata to store with snapshot
180
+
181
+ **Returns:**
182
+ - Dictionary containing snapshot data
183
+
184
+ **Example:**
185
+ ```python
186
+ snapshot = snapmyenv.capture("my-project", metadata={"author": "Alice"})
187
+ ```
188
+
189
+ ### `restore(name: str = "default", dry_run: bool = False) -> None`
190
+
191
+ Restore environment from a previously captured snapshot.
192
+
193
+ **Parameters:**
194
+ - `name` (str): Name of snapshot to restore (default: "default")
195
+ - `dry_run` (bool): If True, show what would be installed without installing
196
+
197
+ **Example:**
198
+ ```python
199
+ # Preview what would be installed
200
+ snapmyenv.restore("my-project", dry_run=True)
201
+
202
+ # Actually restore
203
+ snapmyenv.restore("my-project")
204
+ ```
205
+
206
+ ### `embed(name: str = "default", notebook_path: str = None) -> None`
207
+
208
+ Embed snapshot into Jupyter notebook metadata.
209
+
210
+ **Parameters:**
211
+ - `name` (str): Name of snapshot to embed (default: "default")
212
+ - `notebook_path` (str): Path to notebook file (optional, auto-detected in some environments)
213
+
214
+ **Example:**
215
+ ```python
216
+ snapmyenv.embed("v1", "analysis.ipynb")
217
+ ```
218
+
219
+ ### `restore_from_nb(notebook_path: str = None, dry_run: bool = False) -> None`
220
+
221
+ Restore environment from notebook-embedded snapshot.
222
+
223
+ **Parameters:**
224
+ - `notebook_path` (str): Path to notebook file (optional, auto-detected in some environments)
225
+ - `dry_run` (bool): If True, show what would be installed without installing
226
+
227
+ **Example:**
228
+ ```python
229
+ snapmyenv.restore_from_nb("shared_analysis.ipynb")
230
+ ```
231
+
232
+ ## What Gets Captured?
233
+
234
+ Each snapshot includes:
235
+
236
+ - **Python version** - Major, minor, and patch version
237
+ - **Platform information** - OS, release, and machine architecture
238
+ - **All installed packages** - With exact version numbers
239
+ - **Colab detection** - Whether running in Google Colab
240
+ - **Timestamp** - When snapshot was created
241
+ - **Custom metadata** - Any additional information you provide
242
+
243
+ ## Use Cases
244
+
245
+ ### 1. Reproducible Research
246
+
247
+ ```python
248
+ # At the start of your research
249
+ import snapmyenv
250
+ snapmyenv.capture("paper-v1")
251
+
252
+ # ... months of analysis ...
253
+
254
+ # Before submission, embed in your analysis notebook
255
+ snapmyenv.embed("paper-v1", "analysis.ipynb")
256
+ ```
257
+
258
+ ### 2. Teaching & Tutorials
259
+
260
+ ```python
261
+ # Create a tutorial notebook with specific package versions
262
+ snapmyenv.capture("tutorial-2024")
263
+ snapmyenv.embed("tutorial-2024", "lesson.ipynb")
264
+
265
+ # Students can restore the exact environment
266
+ snapmyenv.restore_from_nb("lesson.ipynb")
267
+ ```
268
+
269
+ ### 3. Team Collaboration
270
+
271
+ ```python
272
+ # Team member A captures their working environment
273
+ snapmyenv.capture("project-stable")
274
+ snapshot = snapmyenv.capture("project-stable")
275
+
276
+ # Share the snapshot dict via git, email, etc.
277
+ # Team member B restores it
278
+ snapmyenv.restore_from_dict(snapshot)
279
+ ```
280
+
281
+ ### 4. Environment Debugging
282
+
283
+ ```python
284
+ # When something works on one machine but not another
285
+ snapmyenv.capture("working-config")
286
+
287
+ # On the broken machine, compare:
288
+ snapmyenv.restore("working-config", dry_run=True)
289
+ ```
290
+
291
+ ## Advanced Usage
292
+
293
+ ### Preview Changes (Dry Run)
294
+
295
+ ```python
296
+ # See what would be installed without actually installing
297
+ snapmyenv.restore("my-project", dry_run=True)
298
+ ```
299
+
300
+ ### Multiple Snapshots
301
+
302
+ ```python
303
+ # Capture different configurations
304
+ snapmyenv.capture("dev")
305
+ snapmyenv.capture("production")
306
+ snapmyenv.capture("minimal")
307
+
308
+ # Switch between them
309
+ snapmyenv.restore("production")
310
+ ```
311
+
312
+ ### Working with Snapshot Data
313
+
314
+ ```python
315
+ # Get the snapshot dictionary
316
+ snapshot = snapmyenv.capture("test")
317
+
318
+ # Access snapshot details
319
+ print(f"Python version: {snapshot['python_version']}")
320
+ print(f"Package count: {len(snapshot['packages'])}")
321
+ print(f"Created: {snapshot['timestamp']}")
322
+
323
+ # Save to file
324
+ import json
325
+ with open("snapshot.json", "w") as f:
326
+ json.dump(snapshot, f, indent=2)
327
+
328
+ # Restore from file later
329
+ with open("snapshot.json", "r") as f:
330
+ loaded = json.load(f)
331
+ snapmyenv.restore_from_dict(loaded)
332
+ ```
333
+
334
+ ## Error Handling
335
+
336
+ `snapmyenv` provides informative error messages and graceful degradation:
337
+
338
+ ```python
339
+ try:
340
+ snapmyenv.restore("my-project")
341
+ except snapmyenv.RestoreError as e:
342
+ print(f"Restoration failed: {e}")
343
+ ```
344
+
345
+ **Common scenarios:**
346
+ - Python version mismatches → Warning issued, continues with installation
347
+ - Package installation failures → Individual packages skipped with warnings
348
+ - Missing snapshots → Clear error message with available snapshot names
349
+
350
+ ## Limitations
351
+
352
+ - **Package sources**: Only captures pip-installed packages (not conda, system packages, etc.)
353
+ - **Binary dependencies**: Cannot capture system libraries or non-Python dependencies
354
+ - **Platform differences**: Snapshots capture platform info but cannot enforce it
355
+ - **Version conflicts**: Some package combinations may be impossible to install together
356
+
357
+ ## Development
358
+
359
+ ### Setup Development Environment
360
+
361
+ ```bash
362
+ git clone https://github.com/lovnishverma/snapmyenv.git
363
+ cd snapmyenv
364
+ pip install -e ".[dev]"
365
+ ```
366
+
367
+ ### Run Tests
368
+
369
+ ```bash
370
+ pytest
371
+ pytest --cov=snapmyenv --cov-report=html
372
+ ```
373
+
374
+ ### Code Quality
375
+
376
+ ```bash
377
+ black snapmyenv tests
378
+ ruff check snapmyenv tests
379
+ mypy snapmyenv
380
+ ```
381
+
382
+ ## Contributing
383
+
384
+ Contributions are welcome! Please:
385
+
386
+ 1. Fork the repository
387
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
388
+ 3. Make your changes with tests
389
+ 4. Run the test suite
390
+ 5. Submit a pull request
391
+
392
+ ## License
393
+
394
+ MIT License - see [LICENSE](LICENSE) file for details.
395
+
396
+ ## FAQ
397
+
398
+ **Q: Does this work outside of Jupyter/Colab?**
399
+ A: Yes! The core capture/restore functionality works in any Python environment. The notebook features require Jupyter.
400
+
401
+ **Q: Can I use this in production applications?**
402
+ A: `snapmyenv` is designed for notebooks and development workflows. For production, consider Docker, conda environments, or proper dependency management tools.
403
+
404
+ **Q: What if a package version isn't available anymore?**
405
+ A: `snapmyenv` will warn you and skip that package, installing everything else that's available.
406
+
407
+ **Q: Does this capture virtual environment state?**
408
+ A: No, it captures installed packages regardless of whether you're in a venv. It's meant for recreating package sets, not virtual environment structure.
409
+
410
+ **Q: How is this different from `pip freeze`?**
411
+ A: `snapmyenv` adds platform/Python version tracking, Jupyter integration, user-friendly interfaces, and graceful error handling. It's specifically designed for notebook reproducibility.
412
+
413
+ ## Changelog
414
+
415
+ ### v0.1.0 (2024)
416
+ - Initial release
417
+ - Core capture/restore functionality
418
+ - Notebook metadata embedding
419
+ - Google Colab support
420
+ - Comprehensive test suite
421
+
422
+ ## Support
423
+
424
+ - 📧 **Issues**: [GitHub Issues](https://github.com/lovnishverma/snapmyenv/issues)
425
+ - 💎 **Discussions**: [GitHub Discussions](https://github.com/lovnishverma/snapmyenv/discussions)
426
+ - 📖 **Documentation**: [README](https://github.com/lovnishverma/snapmyenv#readme)
427
+
428
+ ---
429
+
430
+ Made with âĪïļ for the Jupyter and Google Colab community