dotpop
dotpop is a professional-grade configuration engine for Python that extends the standard .env format with strict type safety, AES-encrypted secrets, and conditional logic. Designed for startups, microservices, and AI-generated applications, it eliminates "silent failures" by validating your environment variables at startup and protecting sensitive data at rest.
Why dotpop?
Standard .env files are brittle—no validation, no types, no secrets protection. dotpop fixes this:
- ✅ Strong typing - int, float, bool, json, list, path, url, secret
- ✅ Validation rules - required, min/max, regex, one_of
- ✅ AES-encrypted secrets - Protect API keys and passwords at rest
- ✅ Conditional logic - Single file for dev/staging/prod
- ✅ Variable interpolation - DRY configuration with
${VAR}syntax
Installation
pip install dotpop
Quick Start
1. Basic usage - Works with existing .env files:
from dotpop import load
env = load(".env")
print(env["PORT"]) # "8080"
2. Add types - Create config.dpop with type safety:
HOST:str=localhost
PORT:int=8000 | required | min=1024 | max=65535
DEBUG:bool=true
TAGS:list=api,database,cache
env = load("config.dpop")
print(env["PORT"]) # 8000 (int, not string!)
3. Add environment logic - Single file for all environments:
ENV:str=development | one_of=development,staging,production
@if ENV == "production"
DEBUG:bool=false
WORKERS:int=8
@else
DEBUG:bool=true
WORKERS:int=2
@end
HOST=${HOST:-localhost}
PORT:int=${PORT:-8000}
API_URL=http://${HOST}:${PORT}
4. Encrypt secrets - Protect sensitive data:
# Generate master key
export DOTPOP_MASTER_KEY=$(openssl rand -hex 32)
# Encrypt secrets
echo "my-api-key" | dotpop encrypt > api.key.enc
API_KEY:secret=@encrypted:api.key.enc | required
DATABASE_PASSWORD:secret=@encrypted:db.password.enc | required
env = load("config.dpop")
api_key = env["API_KEY"] # Automatically decrypted!
Real-World Example
# config.dpop
ENV:str=${ENV:-development} | one_of=development,staging,production
@if ENV == "production"
DEBUG:bool=false
LOG_LEVEL=error
WORKERS:int=4
@else
DEBUG:bool=true
LOG_LEVEL=debug
WORKERS:int=1
@end
HOST:str=0.0.0.0
PORT:int=8000 | min=1024 | max=65535
DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}
API_KEY:secret=@encrypted:api.key.enc | required
CORS_ORIGINS:list=http://localhost:3000,https://app.example.com
CACHE_TTL:int=3600
from dotpop import load
from fastapi import FastAPI
env = load("config.dpop")
app = FastAPI(debug=env["DEBUG"])
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host=env["HOST"], port=env["PORT"], workers=env["WORKERS"])
CLI Tools
# Validate config
dotpop check config.dpop
# Encrypt secrets
dotpop encrypt --interactive
# View variables
dotpop print config.dpop
# Export formats
dotpop export config.dpop --format json
dotpop export config.dpop --format dotenv
Features at a Glance
Types: str, int, float, bool, json, list, path, url, secret
Validators: required, non_empty, one_of, regex, min, max
Conditionals: @if ENV == "prod", @elif, @else, @end
Interpolation: URL=http://${HOST}:${PORT}, ${VAR:-default}
Includes: @include "base.dpop", @include "configs/${ENV}.dpop"
Documentation
Migration from dotenv
dotpop works with existing .env files—no changes needed:
# Just change the import
from dotpop import load
env = load(".env")
Then add types and validation incrementally by renaming to .dpop.
License
MIT License
Questions? Check the docs or open an issue on GitHub.
Metadata
Release files for dotpop 1.0.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 | Provenance | |
|---|---|---|---|---|
| dotpop-1.0.1.tar.gz | 24.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dotpop-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.8 kB
Release files / dotpop-1.0.1.tar.gz
| Download URL | dotpop-1.0.1.tar.gz |
|---|---|
| Size | 24.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bf570e750ca72be1ad0a4314282bb62bad4dddf14dffd6249c6cd20baf4650b5
|
|
BLAKE2b-256 checksum How to use checksums |
288df7060e1d7be9af1b089507a7c6c81ee74e604cf32c50a37c332102ebe537
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.0
|
Release files / dotpop-1.0.1-py3-none-any.whl
| Download URL | dotpop-1.0.1-py3-none-any.whl |
|---|---|
| Size | 22.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2426ab317656a92478978262eafb4e6d7e31d15a23d825169808fa6db8d0a46c
|
|
BLAKE2b-256 checksum How to use checksums |
de9db5cedcb480957e044d142dcc6e954e76556295d7d56bcd3b274c187c61c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.0
|
Security for dotpop 1.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.