go-embed-py
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 go-embed-py 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 go-embed-py
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 go-embed-py
- run: staticembed generate --source src/app.py --root assets/
- run: git diff --exit-code _embedded.py # fail if stale
Go ↔ Python Comparison
| Go | go-embed-py |
|---|---|
//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/go-embed-py
cd go-embed-py
pip install -e ".[dev]"
pytest
License
MIT
Metadata
Release files for go-embed-py 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| go_embed_py-0.1.1.tar.gz | 8.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| go_embed_py-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.6 kB
Release files / go_embed_py-0.1.1.tar.gz
| Download URL | go_embed_py-0.1.1.tar.gz |
|---|---|
| Size | 8.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
808f2f232291b37e3c7f10f426cf599b0e1cab368a2792182b041d1e293c8371
|
|
BLAKE2b-256 checksum How to use checksums |
5346d329e694d6c38e1cc7f4072fb3098d2f6644befd723b5a7aa640c3fc19e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / go_embed_py-0.1.1-py3-none-any.whl
| Download URL | go_embed_py-0.1.1-py3-none-any.whl |
|---|---|
| Size | 10.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
12b6cfa8c4c2276f50cce17f4e4eebc5f270d92fbe1c3f500738e2c04216bf90
|
|
BLAKE2b-256 checksum How to use checksums |
ced5572f6d08dc27a14600970b5a14890c1b9414888a5615a9d9cd39aa1c01b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|