Skip to main content

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

Project description

staticembed

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 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:embed in 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: --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 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


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.0.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.0-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

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

Hashes for go_embed_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f86ef4880731a42c5efc7d8945646b3d04a24440a1f5ef3202eaeb601a6b8f35
MD5 2f4c79bd796effd20ffa3462528c61b3
BLAKE2b-256 bacd5363f2602e8bafa8d62435ead64f3359bb6df50398b0203eeacf072e4a58

See more details on using hashes here.

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

Hashes for go_embed_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 788a70c85ada9c8fcfbfbfa3087ec53bd018256b8c8fbefe081d25f2a90b2267
MD5 46220591794ba55c056388a533b84040
BLAKE2b-256 540f6b7c9bfbe065420fb2ff0d6e1e51b71714452f8253a44e994b0d3c51fea2

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