Simplified environment variable parsing with type casting, validation, and framework integration
—
Parsing of temporal types, paths, identifiers, URLs, enums, and other specialized data types with format validation and automatic conversion to appropriate Python objects.
Parse ISO-formatted date and time strings into Python datetime objects with timezone support.
def datetime(self, name: str, default=..., *, validate=None, **kwargs):
"""
Parse environment variable as datetime.
Parameters:
- name: str, environment variable name
- default: datetime, default value if variable not set (optional)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments (format, etc.)
Returns:
datetime.datetime: Parsed datetime object
Raises:
EnvValidationError: If value is not a valid datetime format
"""
def date(self, name: str, default=..., *, validate=None, **kwargs):
"""
Parse environment variable as date.
Parameters:
- name: str, environment variable name
- default: date, default value if variable not set (optional)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments (format, etc.)
Returns:
datetime.date: Parsed date object
"""
def time(self, name: str, default=..., *, validate=None, **kwargs):
"""
Parse environment variable as time.
Parameters:
- name: str, environment variable name
- default: time, default value if variable not set (optional)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments (format, etc.)
Returns:
datetime.time: Parsed time object
"""Usage examples:
import os
from environs import env
from datetime import datetime, date, time
# DateTime parsing
os.environ["CREATED_AT"] = "2023-12-25T10:30:00"
created_at = env.datetime("CREATED_AT") # => datetime(2023, 12, 25, 10, 30)
# Date parsing
os.environ["BIRTH_DATE"] = "1990-05-15"
birth_date = env.date("BIRTH_DATE") # => date(1990, 5, 15)
# Time parsing
os.environ["DAILY_BACKUP_TIME"] = "02:30:00"
backup_time = env.time("DAILY_BACKUP_TIME") # => time(2, 30)Parse duration strings into Python timedelta objects with support for multiple formats including GEP-2257 duration specification.
def timedelta(self, name: str, default=..., *, validate=None, **kwargs):
"""
Parse environment variable as timedelta.
Parameters:
- name: str, environment variable name
- default: timedelta, default value if variable not set (optional)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments
Returns:
datetime.timedelta: Parsed duration
Supported formats:
- Seconds as number: "42"
- GEP-2257 duration strings: "1h30m", "2d4h", "30s", "500ms"
- Standard timedelta formats
"""Usage examples:
import os
from environs import env
# Simple seconds
os.environ["SESSION_TIMEOUT"] = "1800" # 30 minutes in seconds
timeout = env.timedelta("SESSION_TIMEOUT") # => timedelta(seconds=1800)
# GEP-2257 duration strings
os.environ["CACHE_TTL"] = "1h30m"
cache_ttl = env.timedelta("CACHE_TTL") # => timedelta(hours=1, minutes=30)
os.environ["RETRY_DELAY"] = "500ms"
retry_delay = env.timedelta("RETRY_DELAY") # => timedelta(milliseconds=500)
os.environ["BACKUP_INTERVAL"] = "2d4h"
backup_interval = env.timedelta("BACKUP_INTERVAL") # => timedelta(days=2, hours=4)Parse string paths into Python pathlib.Path objects with validation and normalization.
def path(self, name: str, default=..., *, validate=None, **kwargs):
"""
Parse environment variable as Path.
Parameters:
- name: str, environment variable name
- default: Path or str, default value if variable not set (optional)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments
Returns:
pathlib.Path: Parsed path object
"""Usage examples:
import os
from environs import env
from pathlib import Path
# File paths
os.environ["LOG_FILE"] = "/var/log/app.log"
log_file = env.path("LOG_FILE") # => Path('/var/log/app.log')
# Directory paths
os.environ["DATA_DIR"] = "~/data"
data_dir = env.path("DATA_DIR") # => Path('~/data')
# Relative paths
os.environ["CONFIG_FILE"] = "./config/settings.json"
config_file = env.path("CONFIG_FILE") # => Path('./config/settings.json')
# Path operations
if log_file.exists():
print(f"Log file size: {log_file.stat().st_size}")Parse UUID strings into Python UUID objects with format validation.
def uuid(self, name: str, default=..., *, validate=None, **kwargs):
"""
Parse environment variable as UUID.
Parameters:
- name: str, environment variable name
- default: UUID or str, default value if variable not set (optional)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments
Returns:
uuid.UUID: Parsed UUID object
Raises:
EnvValidationError: If value is not a valid UUID format
"""Usage examples:
import os
from environs import env
import uuid
# Standard UUID parsing
os.environ["REQUEST_ID"] = "550e8400-e29b-41d4-a716-446655440000"
request_id = env.uuid("REQUEST_ID") # => UUID('550e8400-e29b-41d4-a716-446655440000')
# UUID operations
print(f"Request ID: {request_id}")
print(f"UUID version: {request_id.version}")Parse URL strings into urllib.parse.ParseResult objects with validation and component access.
def url(self, name: str, default=..., *, validate=None, **kwargs):
"""
Parse environment variable as URL.
Parameters:
- name: str, environment variable name
- default: str or ParseResult, default value if variable not set (optional)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments
Returns:
urllib.parse.ParseResult: Parsed URL with components
Raises:
EnvValidationError: If value is not a valid URL format
"""Usage examples:
import os
from environs import env
# HTTP URL parsing
os.environ["API_URL"] = "https://api.example.com:8080/v1/users?limit=10"
api_url = env.url("API_URL")
print(f"Scheme: {api_url.scheme}") # => "https"
print(f"Hostname: {api_url.hostname}") # => "api.example.com"
print(f"Port: {api_url.port}") # => 8080
print(f"Path: {api_url.path}") # => "/v1/users"
print(f"Query: {api_url.query}") # => "limit=10"
# Database URL parsing
os.environ["DATABASE_URL"] = "postgresql://user:pass@localhost:5432/mydb"
db_url = env.url("DATABASE_URL")
print(f"Database: {db_url.path[1:]}") # => "mydb" (strip leading /)Parse logging level names or numbers into Python logging constants.
def log_level(self, name: str, default=..., *, validate=None, **kwargs):
"""
Parse environment variable as logging level.
Parameters:
- name: str, environment variable name
- default: int or str, default value if variable not set (optional)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments
Returns:
int: Logging level constant
Supported values:
- Level names: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" (case-insensitive)
- Level numbers: 10, 20, 30, 40, 50
"""Usage examples:
import os
import logging
from environs import env
# Level name parsing
os.environ["LOG_LEVEL"] = "DEBUG"
log_level = env.log_level("LOG_LEVEL") # => 10 (logging.DEBUG)
# Level number parsing
os.environ["APP_LOG_LEVEL"] = "30"
app_log_level = env.log_level("APP_LOG_LEVEL") # => 30 (logging.WARNING)
# Configure logging
logging.basicConfig(level=log_level)
logger = logging.getLogger(__name__)
logger.debug("This will be visible if LOG_LEVEL is DEBUG")Parse string values into Python enum instances with validation against enum members.
def enum(self, name: str, default=..., *, enum, by_value=False, validate=None, **kwargs):
"""
Parse environment variable as enum.
Parameters:
- name: str, environment variable name
- default: enum instance, default value if variable not set (optional)
- enum: enum class to parse into
- by_value: bool, whether to match by value instead of name (default: False)
- validate: callable or list of callables for validation (optional)
- **kwargs: additional marshmallow field arguments
Returns:
enum instance: Parsed enum member
Raises:
EnvValidationError: If value is not a valid enum member
"""Usage examples:
import os
from environs import env
from enum import Enum
class Environment(Enum):
DEVELOPMENT = "dev"
STAGING = "stage"
PRODUCTION = "prod"
class LogFormat(Enum):
JSON = 1
TEXT = 2
# Parse by enum name
os.environ["ENV"] = "DEVELOPMENT"
environment = env.enum("ENV", enum=Environment) # => Environment.DEVELOPMENT
# Parse by enum value
os.environ["APP_ENV"] = "prod"
app_env = env.enum("APP_ENV", enum=Environment, by_value=True) # => Environment.PRODUCTION
# Numeric enum parsing
os.environ["LOG_FORMAT"] = "1"
log_format = env.enum("LOG_FORMAT", enum=LogFormat, by_value=True) # => LogFormat.JSONimport datetime as dt
import uuid
from pathlib import Path
from urllib.parse import ParseResult
from enum import Enum
from typing import Type, TypeVar
EnumType = TypeVar('EnumType', bound=Enum)Install with Tessl CLI
npx tessl i tessl/pypi-environs