Go-style file embedding for Python — embed static files into generated Python modules at build time
Project description
staticembed
Go-style file embedding for Python. Embed static files into generated Python modules at build time. At runtime, everything is in-memory — zero filesystem access.
Go: //go:embed schema.sql → var schema []byte
Python: # staticembed: schema.sql → SCHEMA: bytes
Why?
Python has importlib.resources for accessing package data, but it still reads from the filesystem at runtime. If you want true embedding — data baked into your code as byte literals, no open(), no Path, no filesystem dependency — you need a code generation step. That's what staticembed does.
Use cases:
- SQL schemas, migrations, and queries
- HTML/Jinja templates
- Default config files (JSON, YAML, TOML)
- Binary assets (icons, fonts, wasm)
- Anything you'd
//go:embedin Go
Install
pip install staticembed
Quick Start
Option 1: One-liner API
# build_embed.py — run once at build time
from staticembed import embed_files
embed_files({
"SCHEMA": "sql/schema.sql",
"TEMPLATES": "templates/*.html",
"CONFIG": "static/defaults.json",
}, root_dir="assets", as_string=True)
Then in your application:
from _embedded import SCHEMA, TEMPLATES, CONFIG
print(CONFIG) # str — zero file I/O
Option 2: Go-style Directives
Add # staticembed: comments to your source file:
# app.py
# staticembed: sql/schema.sql
SCHEMA: bytes
# staticembed: templates/*.html
TEMPLATES: dict[str, bytes]
# staticembed: static/config.json -> CONFIG string
Generate the embed module:
staticembed generate --source app.py --root assets/
Option 3: CLI Only
staticembed generate \
--root ./assets \
--output _embedded.py \
--string \
-f SCHEMA=sql/schema.sql \
TEMPLATES="templates/*.html" \
CONFIG=static/config.json
Directive Syntax
# staticembed: <glob> [-> VAR_NAME] [string] [compress]
| Part | Required | Description |
|---|---|---|
<glob> |
Yes | File path or glob pattern |
-> VAR_NAME |
No | Explicit variable name (auto-derived from filename otherwise) |
string |
No | Decode as UTF-8 str instead of bytes |
compress |
No | zlib compress (smaller module, tiny runtime cost) |
Annotation style — variable name + type hint on the next line:
# staticembed: sql/schema.sql
SCHEMA: bytes
# staticembed: templates/*.html
TEMPLATES: dict[str, bytes]
# staticembed: config.json
CONFIG: str # ← 'str' annotation enables string mode automatically
Features
- Glob support:
*.html,sql/**/*.sql,static/* - Single file → variable, glob →
dict[str, bytes|str] - Compression:
--compressflag → zlib level 9 - String decode:
--stringflag → UTF-8str - Binary safe: images, fonts, wasm, protobuf — anything
- Manifest: SHA-256 hashes + sizes for cache invalidation
- AST validation: generated code is syntax-checked before writing
- Inspect mode: preview what would be embedded without generating
- Zero dependencies: stdlib only, Python 3.9+
CLI Reference
# Generate from source directives
staticembed generate --source app.py --root ./data
# Generate from CLI args
staticembed generate -f SCHEMA=sql/*.sql CONFIG=config.json --root .
# With compression
staticembed generate -f DATA=big_file.json --compress --root .
# As strings instead of bytes
staticembed generate -f PAGES="*.html" --string --root .
# Inspect (dry run)
staticembed inspect --source app.py --root ./data
staticembed inspect -f SCHEMA=sql/*.sql --root .
# Version
staticembed --version
Integration
Makefile
embed:
staticembed generate --source app.py --root assets/
build: embed
pyinstaller --onefile app.py
pyproject.toml (hatch build hook)
[tool.hatch.build.hooks.custom]
path = "build_hooks.py"
# build_hooks.py
from staticembed import embed_files
embed_files({"SCHEMA": "sql/*.sql"}, root_dir="src/assets")
Pre-commit / CI
# .github/workflows/embed.yml
- run: pip install staticembed
- run: staticembed generate --source src/app.py --root assets/
- run: git diff --exit-code _embedded.py # fail if stale
Go ↔ Python Comparison
| Go | staticembed |
|---|---|
//go:embed schema.sql |
# staticembed: schema.sql |
var schema []byte |
SCHEMA: bytes |
//go:embed static/* |
# staticembed: static/* |
var static embed.FS |
STATIC: dict[str, bytes] |
| Compile-time | Build-time (pre-step) |
| In binary | In generated .py module |
API Reference
embed_files(file_map, root_dir=".", output="_embedded.py", compress=False, as_string=False)
One-liner API. Maps variable names to file paths/globs. Returns Path to the generated module.
embed_from_source(source_path, root_dir=None, output="_embedded.py", compress=False)
Parses # staticembed: directives from a Python source file. Returns Path.
generate(spec: EmbedSpec) -> str
Low-level: returns the generated module source as a string.
parse_directives(source_path: Path) -> list[EmbedDirective]
Extract directives from a source file without generating.
resolve_files(root: Path, pattern: str) -> list[tuple[str, bytes]]
Resolve a glob pattern and read matching files.
Contributing
git clone https://github.com/thirukguru/staticembed
cd staticembed
pip install -e ".[dev]"
pytest
License
MIT
Project details
Release history Release notifications | RSS feed
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 go_embed_py-0.1.0.tar.gz.
File metadata
- Download URL: go_embed_py-0.1.0.tar.gz
- Upload date:
- Size: 8.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f86ef4880731a42c5efc7d8945646b3d04a24440a1f5ef3202eaeb601a6b8f35
|
|
| MD5 |
2f4c79bd796effd20ffa3462528c61b3
|
|
| BLAKE2b-256 |
bacd5363f2602e8bafa8d62435ead64f3359bb6df50398b0203eeacf072e4a58
|
File details
Details for the file go_embed_py-0.1.0-py3-none-any.whl.
File metadata
- Download URL: go_embed_py-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
788a70c85ada9c8fcfbfbfa3087ec53bd018256b8c8fbefe081d25f2a90b2267
|
|
| MD5 |
46220591794ba55c056388a533b84040
|
|
| BLAKE2b-256 |
540f6b7c9bfbe065420fb2ff0d6e1e51b71714452f8253a44e994b0d3c51fea2
|