Professional build automation for EmbedDesire Python applications
Project description
EmbedDesire - Professional Python Asset Embedding
embdes is a production-ready tool for embedding static resources (images, sounds, text files, folders) directly into Python applications and building standalone executables with PyInstaller.
Features
- Embed resources into Python applications with optional compression
- Automatic extraction with built-in caching (100% cache hit rate)
- Development/Runtime modes — swap between reading from disk and reading from embedded data with one call
- PyInstaller integration — automated build process via
embdesCLI - Persistent storage — save/load embedded data manually if needed
- Production-ready — comprehensive logging, validation, error handling
- Cross-platform — Windows, macOS, Linux support
- Global CLI — callable from any directory as
embdescommand
Installation
pip install embdes
How It Works
embed() always returns the original file path. What changes between modes is what happens under the hood:
| Mode | set_runtime_mode(...) |
embed() behavior |
|---|---|---|
| Runtime mode | True |
Skips embedding — just returns the path so you read from disk as normal |
| Embedded mode | False |
Reads and stores the file in memory — the returned path is used to access embedded data in the built exe |
This means your app code stays identical in both modes — you always just open(embed(...)).
Basic Usage
from embeddesire import embed, set_runtime_mode
set_runtime_mode(True) # Read from disk (development)
embedded = embed(".\\hello.txt", id="hello", compress=True)
with open(embedded, "r") as f:
print(f.read())
Switch to set_runtime_mode(False) when you want to work with embedded data (e.g. inside a built exe where the original files no longer exist on disk).
Building a Standalone Exe
Using embdes (Recommended)
embdes automates everything. Write your app normally, then build with one command.
app.py
from embeddesire import embed, set_runtime_mode
set_runtime_mode(True) # During dev, reads from disk
config = embed("config.json", id="config", compress=False)
sprites = embed("assets/sprites/",id="sprites", compress=True)
sounds = embed("assets/sounds/", id="sounds", compress=True)
with open(config, "r") as f:
print(f.read())
# Use sprites and sounds paths however your app needs them
Build
embdes app.py
embdes will:
- Validate all paths passed to
embed()exist on disk - Execute your script to collect all
embed()calls - Save the embedded data to
embedded_data.pkl - Call PyInstaller with the pickle bundled in automatically
- Clean up temporary files
The resulting exe in dist/ has all your assets baked in — no external files needed.
Manual Build (Full Control)
Use this if you have an existing PyInstaller setup, a .spec file, or prefer not to use embdes.
Step 1 — Generate the pickle
Run a small preparation script once before building:
# prepare.py
from embeddesire import embed, save_embedded, set_runtime_mode
set_runtime_mode(False) # Must be False so embed() actually stores the data
embed("config.json", id="config", compress=False)
embed("assets/sprites/",id="sprites", compress=True)
embed("assets/sounds/", id="sounds", compress=True)
save_embedded("embedded_data.pkl")
python prepare.py
Step 2 — Pass the pickle to PyInstaller yourself
pyinstaller app.py --onefile --add-data "embedded_data.pkl;."
Step 3 — Load it inside the exe
# app.py
import sys, os
from embeddesire import embed, set_runtime_mode, load_embedded, extract
if getattr(sys, "frozen", False):
# Inside the exe — load the bundled pickle, then use extract() to get files out
load_embedded(os.path.join(sys._MEIPASS, "embedded_data.pkl"))
config_dir = extract("config")
config_path = os.path.join(config_dir, "config.json")
with open(config_path, "r") as f:
print(f.read())
else:
# Development — read from disk as normal
set_runtime_mode(True)
config = embed("config.json", id="config", compress=False)
with open(config, "r") as f:
print(f.read())
Note:
extract()only works on data already in memory fromload_embedded(). It does not read from disk on its own.
Embedding Options
Disable compression for pre-compressed formats
Compression (compress=True) is on by default. Turn it off for files already compressed to avoid wasted CPU and larger output:
embed("photo.jpg", id="photo", compress=False)
embed("music.mp3", id="music", compress=False)
embed("archive.zip", id="archive", compress=False)
Extract to a specific location (manual builds)
path = extract("sprites", output_path="./runtime/sprites")
Managing Embedded Resources
from embeddesire import get_embedded_resources, remove_embedded_resource, get_cache_stats, clear_cache
# See all IDs currently embedded in memory
print(get_embedded_resources())
# ['config', 'sprites', 'sounds']
# Remove one to free memory
remove_embedded_resource("sounds")
# How many extract() calls were served from cache vs freshly written to disk
print(get_cache_stats())
# {'hits': 8, 'misses': 3, 'current_size': 0}
# Delete all temp extraction directories (next extract() call will re-extract)
clear_cache()
Error Handling
from embeddesire import embed, extract, load_embedded
from embeddesire import EmbedError, ExtractError, PersistenceError, ValidationError
try:
embed("nonexistent/path/file.txt", id="data")
except EmbedError as e:
print(f"Embed failed: {e}")
try:
extract("id_that_was_never_embedded")
except ExtractError as e:
print(f"Extract failed: {e}")
try:
load_embedded("missing_or_corrupt.pkl")
except PersistenceError as e:
print(f"Load failed: {e}")
Logging
from embeddesire import configure_logging, LogLevel
configure_logging(LogLevel.DEBUG) # Full trace — sizes, cache hits, paths
configure_logging(LogLevel.WARNING) # Quiet — only problems reported
configure_logging(LogLevel.INFO, format_string="%(levelname)s | %(message)s")
CLI Reference
embdes <script.py> [pyinstaller_args...]
Arguments after the script are passed directly to PyInstaller:
embdes app.py # Basic build
embdes app.py --windowed # No console window
embdes app.py --windowed --icon=app.ico # With custom icon
embdes app.py --name=MyApp # Custom exe name
embdes app.py --add-data "extra.db;." # Bundle extra files too
API Reference
| Function | Description |
|---|---|
embed(path, id, compress=True) |
Embed a file or folder; always returns the original path |
extract(id, output_path=None) |
Extract an in-memory resource to disk (cached) |
set_runtime_mode(value) |
True = read from disk, False = read from embedded data |
save_embedded(file_path) |
Save all embedded data to a pickle file |
load_embedded(file_path) |
Load embedded data from a pickle file into memory |
clear_cache() |
Delete all temp extraction directories |
get_cache_stats() |
Return {hits, misses, current_size} dict |
get_embedded_resources() |
List all currently embedded IDs |
remove_embedded_resource(id) |
Remove a resource from memory |
configure_logging(level, format_string) |
Set log level and format |
Configuration
export EMBEDDESIRE_COMPRESSION_LEVEL=9 # zlib level 0-9 (default 6)
export EMBEDDESIRE_MAX_FILE_SIZE=50000000 # bytes (default 100 MB)
export EMBEDDESIRE_MAX_CACHE_SIZE=250000000 # bytes (default 500 MB)
Requirements
- Python 3.7+
- PyInstaller (required only for
embdesCLI builds)
License
MIT License — See LICENSE file
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 embdes-1.0.2.tar.gz.
File metadata
- Download URL: embdes-1.0.2.tar.gz
- Upload date:
- Size: 9.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c3fcbe3e828cad6f10eb16583d0d10306a1b200016b82d3c2cddede49784f89
|
|
| MD5 |
9d6573db727c8641a572ea5e45f1eda7
|
|
| BLAKE2b-256 |
f4604cec7f9cebbd5f75aee4a648fe14d9968992f14ded98da2cde678c7d1311
|
File details
Details for the file embdes-1.0.2-py3-none-any.whl.
File metadata
- Download URL: embdes-1.0.2-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
480de7fc59111de98830f461467f0eee548497ff866eeb9f36f6bc961dcddc89
|
|
| MD5 |
ded9a7653e7238b21b1e862923fdab56
|
|
| BLAKE2b-256 |
a80c2b9c8c0e7f09111bb35d0d06937580b4d217eaafd0bd4cd48e434e71f32a
|