Simplified environment variable parsing with type casting, validation, and framework integration
—
Specialized parsers for Django framework integration including database URLs, email configuration, and cache settings with automatic dependency management and comprehensive configuration support.
Parse Django-compatible database URLs into configuration dictionaries using the dj-database-url library.
def dj_db_url(self, name: str, default=..., **kwargs):
"""
Parse environment variable as Django database URL.
Parameters:
- name: str, environment variable name
- default: any, default value if variable not set (optional)
- **kwargs: additional arguments passed to dj_database_url.parse()
Returns:
dj_database_url.DBConfig: Database configuration object
Raises:
RuntimeError: If dj-database-url package is not installed
EnvValidationError: If URL is not a valid database URL
Dependencies:
Requires 'dj-database-url' package: pip install dj-database-url
"""Usage examples:
import os
from environs import env
# PostgreSQL database URL
os.environ["DATABASE_URL"] = "postgres://user:password@localhost:5432/mydb"
db_config = env.dj_db_url("DATABASE_URL")
print(f"Engine: {db_config['ENGINE']}") # => 'django.db.backends.postgresql'
print(f"Name: {db_config['NAME']}") # => 'mydb'
print(f"User: {db_config['USER']}") # => 'user'
print(f"Password: {db_config['PASSWORD']}") # => 'password'
print(f"Host: {db_config['HOST']}") # => 'localhost'
print(f"Port: {db_config['PORT']}") # => 5432
# MySQL database URL
os.environ["MYSQL_URL"] = "mysql://root:secret@db.example.com:3306/production"
mysql_config = env.dj_db_url("MYSQL_URL")
# SQLite database URL
os.environ["SQLITE_URL"] = "sqlite:///path/to/database.db"
sqlite_config = env.dj_db_url("SQLITE_URL")
# Database URL with additional options
os.environ["DB_URL"] = "postgres://user:pass@host:5432/db?conn_max_age=600&autocommit=true"
db_config = env.dj_db_url("DB_URL")
print(f"Options: {db_config.get('OPTIONS', {})}")
# Use in Django settings.py
DATABASES = {
'default': env.dj_db_url("DATABASE_URL")
}
# With default value
default_db = env.dj_db_url("DATABASE_URL", "sqlite:///default.db")
# Multiple databases
os.environ["PRIMARY_DB"] = "postgres://user:pass@primary:5432/main"
os.environ["ANALYTICS_DB"] = "postgres://user:pass@analytics:5432/analytics"
DATABASES = {
'default': env.dj_db_url("PRIMARY_DB"),
'analytics': env.dj_db_url("ANALYTICS_DB")
}Parse Django-compatible email URLs into email backend configurations using the dj-email-url library.
def dj_email_url(self, name: str, default=..., **kwargs):
"""
Parse environment variable as Django email URL.
Parameters:
- name: str, environment variable name
- default: any, default value if variable not set (optional)
- **kwargs: additional arguments passed to dj_email_url.parse()
Returns:
dict: Email backend configuration dictionary
Raises:
RuntimeError: If dj-email-url package is not installed
EnvValidationError: If URL is not a valid email URL
Dependencies:
Requires 'dj-email-url' package: pip install dj-email-url
"""Usage examples:
import os
from environs import env
# SMTP email configuration
os.environ["EMAIL_URL"] = "smtp://user:password@smtp.gmail.com:587?tls=true"
email_config = env.dj_email_url("EMAIL_URL")
print(f"Backend: {email_config['EMAIL_BACKEND']}") # Email backend class
print(f"Host: {email_config['EMAIL_HOST']}") # => 'smtp.gmail.com'
print(f"Port: {email_config['EMAIL_PORT']}") # => 587
print(f"User: {email_config['EMAIL_HOST_USER']}") # => 'user'
print(f"Password: {email_config['EMAIL_HOST_PASSWORD']}")# => 'password'
print(f"Use TLS: {email_config['EMAIL_USE_TLS']}") # => True
# Console backend for development
os.environ["DEV_EMAIL_URL"] = "console:"
dev_email_config = env.dj_email_url("DEV_EMAIL_URL")
# File backend
os.environ["FILE_EMAIL_URL"] = "file:///tmp/emails"
file_email_config = env.dj_email_url("FILE_EMAIL_URL")
# SendGrid configuration
os.environ["SENDGRID_URL"] = "smtp://apikey:SG.xyz123@smtp.sendgrid.net:587?tls=true"
sendgrid_config = env.dj_email_url("SENDGRID_URL")
# Mailgun configuration
os.environ["MAILGUN_URL"] = "smtp://postmaster@mg.example.com:key123@smtp.mailgun.org:587?tls=true"
mailgun_config = env.dj_email_url("MAILGUN_URL")
# Use in Django settings.py
email_config = env.dj_email_url("EMAIL_URL", "console:")
EMAIL_BACKEND = email_config['EMAIL_BACKEND']
EMAIL_HOST = email_config.get('EMAIL_HOST', '')
EMAIL_PORT = email_config.get('EMAIL_PORT', 25)
EMAIL_HOST_USER = email_config.get('EMAIL_HOST_USER', '')
EMAIL_HOST_PASSWORD = email_config.get('EMAIL_HOST_PASSWORD', '')
EMAIL_USE_TLS = email_config.get('EMAIL_USE_TLS', False)
EMAIL_USE_SSL = email_config.get('EMAIL_USE_SSL', False)
# Simplified Django settings integration
locals().update(env.dj_email_url("EMAIL_URL", "console:"))Parse Django-compatible cache URLs into cache backend configurations using the django-cache-url library.
def dj_cache_url(self, name: str, default=..., **kwargs):
"""
Parse environment variable as Django cache URL.
Parameters:
- name: str, environment variable name
- default: any, default value if variable not set (optional)
- **kwargs: additional arguments passed to django_cache_url.parse()
Returns:
dict: Cache backend configuration dictionary
Raises:
RuntimeError: If django-cache-url package is not installed
EnvValidationError: If URL is not a valid cache URL or backend is unknown
Dependencies:
Requires 'django-cache-url' package: pip install django-cache-url
"""Usage examples:
import os
from environs import env
# Redis cache configuration
os.environ["CACHE_URL"] = "redis://localhost:6379/1?client_class=django_redis.client.DefaultClient"
cache_config = env.dj_cache_url("CACHE_URL")
print(f"Backend: {cache_config['BACKEND']}") # Redis backend class
print(f"Location: {cache_config['LOCATION']}") # => 'redis://localhost:6379/1'
print(f"Options: {cache_config.get('OPTIONS', {})}") # Client options
# Memcached configuration
os.environ["MEMCACHE_URL"] = "memcache://127.0.0.1:11211"
memcache_config = env.dj_cache_url("MEMCACHE_URL")
# Database cache backend
os.environ["DB_CACHE_URL"] = "db://cache_table"
db_cache_config = env.dj_cache_url("DB_CACHE_URL")
# File-based cache
os.environ["FILE_CACHE_URL"] = "file:///tmp/django_cache"
file_cache_config = env.dj_cache_url("FILE_CACHE_URL")
# Dummy cache for development
os.environ["DUMMY_CACHE_URL"] = "dummy:"
dummy_cache_config = env.dj_cache_url("DUMMY_CACHE_URL")
# Local memory cache
os.environ["LOCMEM_CACHE_URL"] = "locmem:unique-snowflake"
locmem_config = env.dj_cache_url("LOCMEM_CACHE_URL")
# Redis with additional options
os.environ["REDIS_CACHE_URL"] = "redis://redis.example.com:6379/0?client_class=django_redis.client.DefaultClient&connection_pool_kwargs={'max_connections':50}"
redis_config = env.dj_cache_url("REDIS_CACHE_URL")
# Use in Django settings.py
CACHES = {
'default': env.dj_cache_url("CACHE_URL", "locmem:")
}
# Multiple cache configurations
os.environ["DEFAULT_CACHE"] = "redis://localhost:6379/0"
os.environ["SESSION_CACHE"] = "redis://localhost:6379/1"
os.environ["TEMPLATE_CACHE"] = "memcache://localhost:11211"
CACHES = {
'default': env.dj_cache_url("DEFAULT_CACHE"),
'sessions': env.dj_cache_url("SESSION_CACHE"),
'templates': env.dj_cache_url("TEMPLATE_CACHE", "dummy:")
}
# Cache with timeout and versioning
os.environ["CACHE_WITH_OPTIONS"] = "redis://localhost:6379/0?timeout=300&version=2"
cache_with_options = env.dj_cache_url("CACHE_WITH_OPTIONS")Here's how to use all Django integration parsers together in a typical Django settings.py file:
# settings.py
import os
from environs import env
# Initialize environs
env.read_env() # Load .env file
# Database configuration
DATABASES = {
'default': env.dj_db_url("DATABASE_URL", "sqlite:///db.sqlite3")
}
# Cache configuration
CACHES = {
'default': env.dj_cache_url("CACHE_URL", "locmem:")
}
# Email configuration
email_config = env.dj_email_url("EMAIL_URL", "console:")
EMAIL_BACKEND = email_config['EMAIL_BACKEND']
EMAIL_HOST = email_config.get('EMAIL_HOST', '')
EMAIL_PORT = email_config.get('EMAIL_PORT', 25)
EMAIL_HOST_USER = email_config.get('EMAIL_HOST_USER', '')
EMAIL_HOST_PASSWORD = email_config.get('EMAIL_HOST_PASSWORD', '')
EMAIL_USE_TLS = email_config.get('EMAIL_USE_TLS', False)
EMAIL_USE_SSL = email_config.get('EMAIL_USE_SSL', False)
# Other environment-based settings
DEBUG = env.bool("DEBUG", False)
SECRET_KEY = env.str("SECRET_KEY")
ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", ["localhost", "127.0.0.1"])
# Static and media files
STATIC_URL = env.str("STATIC_URL", "/static/")
STATIC_ROOT = env.path("STATIC_ROOT", None)
MEDIA_URL = env.str("MEDIA_URL", "/media/")
MEDIA_ROOT = env.path("MEDIA_ROOT", None)
# Logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': env.log_level("LOG_LEVEL", "INFO"),
},
},
'root': {
'handlers': ['console'],
'level': env.log_level("ROOT_LOG_LEVEL", "INFO"),
},
}Corresponding .env file for the Django settings:
# .env file
DEBUG=true
SECRET_KEY=your-secret-key-here
ALLOWED_HOSTS=localhost,127.0.0.1,yoursite.com
# Database
DATABASE_URL=postgres://user:password@localhost:5432/myproject
# Cache
CACHE_URL=redis://localhost:6379/0
# Email
EMAIL_URL=smtp://username:password@smtp.gmail.com:587?tls=true
# Logging
LOG_LEVEL=DEBUG
ROOT_LOG_LEVEL=INFO
# Static files
STATIC_URL=/static/
STATIC_ROOT=/var/www/static/
MEDIA_URL=/media/
MEDIA_ROOT=/var/www/media/Handle missing dependencies and invalid configurations appropriately:
from environs import env, EnvValidationError
import os
# Handle missing dj-database-url
try:
db_config = env.dj_db_url("DATABASE_URL")
except RuntimeError as e:
print(f"Missing dependency: {e}")
# Fallback to manual configuration or default
db_config = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3'
}
# Handle invalid URLs
os.environ["INVALID_DB_URL"] = "not-a-valid-url"
try:
db_config = env.dj_db_url("INVALID_DB_URL")
except EnvValidationError as e:
print(f"Invalid database URL: {e}")
# Use default configuration
db_config = env.dj_db_url("DATABASE_URL", "sqlite:///default.db")from typing import Dict, Any, Optional
try:
from dj_database_url import DBConfig
except ImportError:
DBConfig = Dict[str, Any]
EmailConfig = Dict[str, Any]
CacheConfig = Dict[str, Any]Install with Tessl CLI
npx tessl i tessl/pypi-environs