Configuration Management¶
ArchiPy provides a robust configuration management system that ensures type safety, environment variable support, and consistent access patterns across your application.
Basic Configuration¶
Defining a Configuration¶
Create a configuration class by inheriting from BaseConfig
:
from archipy.configs.base_config import BaseConfig
from archipy.configs.environment_type import EnvironmentType
class AppConfig(BaseConfig):
# Application settings
APP_NAME: str = "MyService"
DEBUG: bool = False
# Database settings
DB_HOST: str = "localhost"
DB_PORT: int = 5432
DB_NAME: str = "myapp"
DB_USER: str = "postgres"
DB_PASSWORD: str = "password"
# Redis settings
REDIS_HOST: str = "localhost"
REDIS_PORT: int = 6379
# Environment
ENVIRONMENT: EnvironmentType = EnvironmentType.DEVELOPMENT
# API settings
API_PREFIX: str = "/api/v1"
# Logging
LOG_LEVEL: str = "INFO"
Using the Configuration¶
# Create and set as global configuration
config = AppConfig()
BaseConfig.set_global(config)
# Access configuration values from anywhere in your code
from archipy.configs.base_config import BaseConfig
current_config = BaseConfig.global_config()
db_url = f"postgresql://{current_config.DB_USER}:{current_config.DB_PASSWORD}@{current_config.DB_HOST}:{current_config.DB_PORT}/{current_config.DB_NAME}"
Environment Variables¶
ArchiPy configurations automatically load values from environment variables with the same name:
# .env file
APP_NAME=ProductionService
DB_HOST=db.example.com
DB_PASSWORD=secure-password
ENVIRONMENT=PRODUCTION
The environment variables override the default values in your configuration class:
config = AppConfig() # Will have values from environment variables
print(config.APP_NAME) # "ProductionService"
print(config.ENVIRONMENT) # EnvironmentType.PRODUCTION
Environment-Specific Configurations¶
You can create environment-specific configurations:
from archipy.configs.base_config import BaseConfig
from archipy.configs.environment_type import EnvironmentType
class BaseAppConfig(BaseConfig):
APP_NAME: str = "MyService"
DEBUG: bool = False
# Common settings...
class DevelopmentConfig(BaseAppConfig):
DEBUG: bool = True
ENVIRONMENT: EnvironmentType = EnvironmentType.DEVELOPMENT
LOG_LEVEL: str = "DEBUG"
class ProductionConfig(BaseAppConfig):
DEBUG: bool = False
ENVIRONMENT: EnvironmentType = EnvironmentType.PRODUCTION
LOG_LEVEL: str = "WARNING"
# Choose configuration based on environment
import os
env = os.getenv("ENVIRONMENT", "development").lower()
if env == "production":
config = ProductionConfig()
else:
config = DevelopmentConfig()
BaseConfig.set_global(config)
Nested Configurations¶
You can use nested Pydantic models for more complex configurations:
from pydantic import BaseModel
from archipy.configs.base_config import BaseConfig
class DatabaseConfig(BaseModel):
HOST: str = "localhost"
PORT: int = 5432
NAME: str = "myapp"
USER: str = "postgres"
PASSWORD: str = "password"
def connection_string(self) -> str:
return f"postgresql://{self.USER}:{self.PASSWORD}@{self.HOST}:{self.PORT}/{self.NAME}"
class RedisConfig(BaseModel):
HOST: str = "localhost"
PORT: int = 6379
DB: int = 0
class AppConfig(BaseConfig):
APP_NAME: str = "MyService"
DEBUG: bool = False
DATABASE: DatabaseConfig = DatabaseConfig()
REDIS: RedisConfig = RedisConfig()
# Usage
config = AppConfig()
print(config.DATABASE.connection_string())
Configuration Template¶
ArchiPy provides a template for common configurations:
from archipy.configs.config_template import ConfigTemplate
from archipy.configs.environment_type import EnvironmentType
class AppConfig(ConfigTemplate):
# Override only what you need
APP_NAME: str = "MyCustomApp"
# Use all the defaults from ConfigTemplate for the rest
config = AppConfig()
print(config.ENVIRONMENT) # Default value from ConfigTemplate
Configuration in Different Components¶
With FastAPI¶
from fastapi import FastAPI, Depends
from archipy.helpers.utils.app_utils import AppUtils
from archipy.configs.base_config import BaseConfig
# Create a FastAPI app with configuration
app = AppUtils.create_fastapi_app(BaseConfig.global_config())
# Access config in endpoint
@app.get("/config")
def get_config_info():
config = BaseConfig.global_config()
return {
"app_name": config.APP_NAME,
"environment": config.ENVIRONMENT.value,
"debug": config.DEBUG
}
With Database Adapters¶
from archipy.adapters.orm.sqlalchemy.session_manager_adapters import SessionManagerAdapter
from archipy.configs.base_config import BaseConfig
config = BaseConfig.global_config()
# Create session manager with config
session_manager = SessionManagerAdapter(
connection_string=config.DATABASE.connection_string(),
echo=config.DEBUG
)
With Redis Adapters¶
from archipy.adapters.redis.adapters import RedisAdapter
from archipy.configs.base_config import BaseConfig
config = BaseConfig.global_config()
# Create Redis adapter with config
redis_adapter = RedisAdapter(
host=config.REDIS.HOST,
port=config.REDIS.PORT,
db=config.REDIS.DB
)
Best Practices¶
-
Use meaningful defaults: Configure sensible defaults that work in local development
-
Never hardcode secrets: Always use environment variables for sensitive information
-
Validate configurations: Use Pydantic validators for complex validation rules
-
Document configuration options: Add clear docstrings to your configuration classes
-
Keep configurations centralized: Avoid creating multiple configuration sources