Skip to main content

Go-style file embedding for Python — embed static files into generated Python modules at build time

Project description

go-embed-py

PyPI Python License: MIT

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:embed in 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: --compress flag → zlib level 9
  • String decode: --string flag → UTF-8 str
  • 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

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

go_embed_py-0.1.1.tar.gz (8.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

go_embed_py-0.1.1-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

File details

Details for the file go_embed_py-0.1.1.tar.gz.

File metadata

  • Download URL: go_embed_py-0.1.1.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

Hashes for go_embed_py-0.1.1.tar.gz
Algorithm Hash digest
SHA256 808f2f232291b37e3c7f10f426cf599b0e1cab368a2792182b041d1e293c8371
MD5 53b3fd6ae9e5d9a443664d7b26f41552
BLAKE2b-256 5346d329e694d6c38e1cc7f4072fb3098d2f6644befd723b5a7aa640c3fc19e5

See more details on using hashes here.

File details

Details for the file go_embed_py-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: go_embed_py-0.1.1-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

Hashes for go_embed_py-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 12b6cfa8c4c2276f50cce17f4e4eebc5f270d92fbe1c3f500738e2c04216bf90
MD5 e76b241d40ac3adbb7bb014332a26e31
BLAKE2b-256 ced5572f6d08dc27a14600970b5a14890c1b9414888a5615a9d9cd39aa1c01b9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page