A CLI tool for managing a personal stash of reusable Python code snippets.
Project description
python-snacks
A personal CLI tool for managing a local stash of reusable Python code snippets. Browse, copy, and curate snippets across projects with a single command.
pipx install python-snacks
snack stash create default ~/snack-stash
snack unpack auth/google_oauth.py
Installation
Recommended (pipx):
pipx install python-snacks
Alternative (pip):
pip install python-snacks
Requires Python 3.10+.
Updating:
pipx upgrade python-snacks # if installed with pipx
pip install --upgrade python-snacks # if installed with pip
Configuration
First-time setup
Create a stash directory and register it:
snack stash create default ~/snack-stash
This creates ~/snack-stash, writes ~/.snackstashrc, and sets default as the active stash.
Environment variable (overrides config file)
export SNACK_STASH=~/snack-stash
Add to ~/.zshrc or ~/.bashrc to make it permanent. Takes priority over everything else.
Config file (~/.snackstashrc)
Created automatically by snack stash create. You can also edit it by hand:
[config]
active = default
[stash.default]
path = ~/snack-stash
[stash.work]
path = ~/work-stash
Priority order: SNACK_STASH env var → ~/.snackstashrc active stash → error.
Stash structure
A stash is a plain directory of .py files, organized into subdirectories by category:
~/snack-stash/
├── auth/
│ ├── google_oauth_fastapi.py
│ ├── google_oauth_flask.py
│ └── jwt_helpers.py
├── forms/
│ ├── contact_form.py
│ └── newsletter_signup.py
└── email/
└── smtp_sender.py
You can manage the directory with Git, Dropbox, or any sync tool independently of this CLI.
Commands
snack list [category]
List all snippets in the active stash.
snack list # all snippets
snack list auth # filtered by category (subdirectory)
snack search <keyword>
Search snippet filenames for a keyword (case-insensitive).
snack search oauth
# auth/google_oauth_fastapi.py
# auth/google_oauth_flask.py
snack unpack <snippet>
Copy a snippet from the stash into the current working directory.
snack unpack auth/google_oauth_fastapi.py
# → ./auth/google_oauth_fastapi.py
snack unpack auth/google_oauth_fastapi.py --flat
# → ./google_oauth_fastapi.py (no subdirectory)
snack unpack auth/google_oauth_fastapi.py --force
# Overwrites without prompting
snack pack <snippet>
Copy a file from the current directory back into the stash. Use this when you've improved a snippet on a project and want to update the canonical version.
snack pack auth/google_oauth_fastapi.py
snack pack auth/google_oauth_fastapi.py --force
Stash management
snack stash create <name> <path>
Register a new named stash. Creates the directory if it doesn't exist.
snack stash create default ~/snack-stash
snack stash create work ~/work-stash --no-activate
The first stash created is automatically set as active. Use --no-activate to add a stash without switching to it.
snack stash list
Show all configured stashes and which one is active.
snack stash list
# default /Users/you/snack-stash ← active
# work /Users/you/work-stash
snack stash move <name> <new-path>
Move a stash to a new location. Moves the directory on disk and updates the config.
snack stash move default ~/new-location/snack-stash
snack stash add-remote <repo>
Copy Python snippets from a public GitHub repository into the active stash. Downloads the repo as a tarball and copies all .py files, preserving directory structure.
snack stash add-remote owner/repo
snack stash add-remote https://github.com/owner/repo
snack stash add-remote owner/repo --subdir auth # only copy files under auth/
snack stash add-remote owner/repo --force # overwrite without prompting
Error handling
| Situation | Behaviour |
|---|---|
| No stash configured | Error with setup instructions |
| Stash path doesn't exist | Error with the attempted path |
| Snippet not found in stash | Error — use snack list or snack search |
| Source file not found | Error |
| Destination file already exists | Prompt to confirm, or skip with --force |
| Named stash already exists | Error |
| Move target already exists | Error |
| GitHub repo not found (HTTP 404) | Error with status code |
Project structure
python-snacks/
├── pyproject.toml
├── snacks/
│ ├── main.py # Typer app, all command definitions
│ ├── config.py # SnackConfig class, stash path resolution
│ └── ops.py # File copy logic (pack, unpack, add_remote)
└── tests/
├── test_commands.py # snippet commands
└── test_stash_commands.py # stash management commands
CI / CD
- CI: Tests run on every push and PR to
mainacross Python 3.10, 3.11, and 3.12. - Publish: Push a
v*tag to trigger a build, PyPI publish, and GitHub Release.
git tag v0.2.0 && git push origin v0.2.0
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file python_snacks-0.1.4.tar.gz.
File metadata
- Download URL: python_snacks-0.1.4.tar.gz
- Upload date:
- Size: 10.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a306b72bf6b0dfd66b44ef1b032e65a2defc28b808b6fa21c6cb459dd5b3c2d
|
|
| MD5 |
b6b63d9694e6a5c12bc49db2a9309846
|
|
| BLAKE2b-256 |
b5d7ea9693217d424e4fd3bed970fd53343dedb0d0bb7d289dca224a30236780
|
Provenance
The following attestation bundles were made for python_snacks-0.1.4.tar.gz:
Publisher:
publish.yml on kicka5h/python-snacks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_snacks-0.1.4.tar.gz -
Subject digest:
0a306b72bf6b0dfd66b44ef1b032e65a2defc28b808b6fa21c6cb459dd5b3c2d - Sigstore transparency entry: 1077006799
- Sigstore integration time:
-
Permalink:
kicka5h/python-snacks@2ecab5568b6ec2f749eab70c6ff847c7a4c441a0 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/kicka5h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2ecab5568b6ec2f749eab70c6ff847c7a4c441a0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file python_snacks-0.1.4-py3-none-any.whl.
File metadata
- Download URL: python_snacks-0.1.4-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd1ef53fcc6fc4ee58d3651764586461e68c55e7bd743b8a93b552b0c609ba60
|
|
| MD5 |
bdd15332281f79593b0a2646c9dd4000
|
|
| BLAKE2b-256 |
c28c98f1050f5cfbc7790152959440ab7ce5860e2e2dedc1b327237913275ce2
|
Provenance
The following attestation bundles were made for python_snacks-0.1.4-py3-none-any.whl:
Publisher:
publish.yml on kicka5h/python-snacks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python_snacks-0.1.4-py3-none-any.whl -
Subject digest:
fd1ef53fcc6fc4ee58d3651764586461e68c55e7bd743b8a93b552b0c609ba60 - Sigstore transparency entry: 1077006809
- Sigstore integration time:
-
Permalink:
kicka5h/python-snacks@2ecab5568b6ec2f749eab70c6ff847c7a4c441a0 -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/kicka5h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2ecab5568b6ec2f749eab70c6ff847c7a4c441a0 -
Trigger Event:
push
-
Statement type: