Files
orion/app/core/config.py
Samir Boulahtit b8a46e1746 fix: protect critical re-export imports from linter removal
Problem:
- Ruff removed 'from app.core.database import Base' from models/database/base.py
- Import appeared "unused" (F401) but was actually a critical re-export
- Caused ImportError: cannot import name 'Base' at runtime
- Re-export pattern: import in one file to export from package

Solution:
1. Added F401 ignore for models/database/base.py in pyproject.toml
2. Created scripts/verify_critical_imports.py verification script
3. Integrated verification into make check and CI pipeline
4. Updated documentation with explanation

New Verification Script:
- Checks all critical re-export imports exist
- Detects import variations (parentheses, 'as' clauses)
- Handles SQLAlchemy declarative_base alternatives
- Runs as part of make check automatically

Protected Files:
- models/database/base.py - Re-exports Base for all models
- models/__init__.py - Exports Base for Alembic
- models/database/__init__.py - Exports Base from package
- All __init__.py files (already protected)

Makefile Changes:
- make verify-imports - Run import verification
- make check - Now includes verify-imports
- make ci - Includes verify-imports in pipeline

Documentation Updated:
- Code quality guide explains re-export protection
- Pre-commit workflow includes verification
- Examples of why re-exports matter

This prevents future issues where linters remove seemingly
"unused" imports that are actually critical for application structure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 20:10:22 +01:00

262 lines
8.7 KiB
Python

# app/core/config.py
"""
Application configuration using Pydantic Settings.
This module provides classes and functions for:
- Configuration management via environment variables
- Database settings
- JWT and authentication configuration
- Platform domain and multi-tenancy settings
- Admin initialization settings
Note: Environment detection is handled by app.core.environment module.
This module focuses purely on configuration storage and validation.
"""
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
"""
Settings class for application configuration.
Environment detection is delegated to app.core.environment.
This class focuses on configuration values only.
"""
# =============================================================================
# PROJECT INFORMATION
# =============================================================================
project_name: str = "Wizamart - Multi-Vendor Marketplace Platform"
version: str = "2.2.0"
# Clean description without HTML
description: str = """
Marketplace product import and management system with multi-vendor support.
**Features:**
- JWT Authentication with role-based access
- Multi-marketplace product import (CSV processing)
- Inventory management across multiple locations
- Vendor management with individual configurations
**Documentation:** Visit /documentation for complete guides
**API Testing:** Use /docs for interactive API exploration
"""
# =============================================================================
# DATABASE
# =============================================================================
database_url: str = "sqlite:///./wizamart.db"
# =============================================================================
# ADMIN INITIALIZATION (for init_production.py)
# =============================================================================
admin_email: str = "admin@wizamart.com"
admin_username: str = "admin"
admin_password: str = "admin123" # CHANGE IN PRODUCTION!
admin_first_name: str = "Platform"
admin_last_name: str = "Administrator"
# =============================================================================
# JWT AUTHENTICATION
# =============================================================================
jwt_secret_key: str = "change-this-in-production"
jwt_expire_hours: int = 24
jwt_expire_minutes: int = 30
# =============================================================================
# API SERVER
# =============================================================================
api_host: str = "0.0.0.0"
api_port: int = 8000
debug: bool = True
# =============================================================================
# DOCUMENTATION
# =============================================================================
documentation_url: str = "http://localhost:8001"
# =============================================================================
# MIDDLEWARE & SECURITY
# =============================================================================
allowed_hosts: list[str] = ["*"] # Configure for production
# Rate Limiting
rate_limit_enabled: bool = True
rate_limit_requests: int = 100
rate_limit_window: int = 3600
# =============================================================================
# LOGGING
# =============================================================================
log_level: str = "INFO"
log_file: str | None = None
# =============================================================================
# PLATFORM DOMAIN CONFIGURATION
# =============================================================================
platform_domain: str = "wizamart.com"
# Custom domain features
allow_custom_domains: bool = True
require_domain_verification: bool = True
# SSL/TLS configuration for custom domains
ssl_provider: str = "letsencrypt" # or "cloudflare", "manual"
auto_provision_ssl: bool = False
# DNS verification
dns_verification_prefix: str = "_wizamart-verify"
dns_verification_ttl: int = 3600
# =============================================================================
# PLATFORM LIMITS
# =============================================================================
max_vendors_per_user: int = 5
max_team_members_per_vendor: int = 50
invitation_expiry_days: int = 7
# =============================================================================
# DEMO/SEED DATA CONFIGURATION
# =============================================================================
# Controls for demo data seeding
seed_demo_vendors: int = 3 # Number of demo vendors to create
seed_customers_per_vendor: int = 15 # Customers per vendor
seed_products_per_vendor: int = 20 # Products per vendor
seed_orders_per_vendor: int = 10 # Orders per vendor
model_config = {"env_file": ".env"}
# Singleton settings instance
settings = Settings()
# =============================================================================
# ENVIRONMENT UTILITIES - Module-level functions
# =============================================================================
# Import environment detection utilities
from app.core.environment import (
get_environment,
is_development,
is_production,
is_staging,
should_use_secure_cookies,
)
def get_current_environment() -> str:
"""
Get current environment.
Convenience function that delegates to app.core.environment.
Use this when you need just the environment string.
"""
return get_environment()
def is_production_environment() -> bool:
"""
Check if running in production.
Convenience function that delegates to app.core.environment.
Use this for production-specific logic.
"""
return is_production()
def is_development_environment() -> bool:
"""
Check if running in development.
Convenience function that delegates to app.core.environment.
Use this for development-specific logic.
"""
return is_development()
def is_staging_environment() -> bool:
"""
Check if running in staging.
Convenience function that delegates to app.core.environment.
Use this for staging-specific logic.
"""
return is_staging()
# =============================================================================
# VALIDATION FUNCTIONS
# =============================================================================
def validate_production_settings() -> list[str]:
"""
Validate settings for production environment.
Returns:
List of warning messages if configuration is insecure
"""
warnings = []
if is_production():
# Check for default/insecure values
if settings.admin_password == "admin123":
warnings.append("⚠️ Using default admin password in production!")
if settings.jwt_secret_key == "change-this-in-production":
warnings.append("⚠️ Using default JWT secret key in production!")
if settings.debug:
warnings.append("⚠️ Debug mode enabled in production!")
if "*" in settings.allowed_hosts:
warnings.append("⚠️ ALLOWED_HOSTS is set to wildcard (*) in production!")
return warnings
def print_environment_info():
"""Print current environment configuration."""
print("\n" + "=" * 70)
print(f" ENVIRONMENT: {get_environment().upper()}")
print("=" * 70)
print(f" Database: {settings.database_url}")
print(f" Debug mode: {settings.debug}")
print(f" API port: {settings.api_port}")
print(f" Platform: {settings.platform_domain}")
print(f" Secure cookies: {should_use_secure_cookies()}")
print("=" * 70 + "\n")
# Show warnings if in production
if is_production():
warnings = validate_production_settings()
if warnings:
print("\n⚠️ PRODUCTION WARNINGS:")
for warning in warnings:
print(f" {warning}")
print()
# =============================================================================
# PUBLIC API
# =============================================================================
__all__ = [
# Settings singleton
"settings",
# Environment detection (re-exported from app.core.environment)
"get_environment",
"is_development",
"is_production",
"is_staging",
"should_use_secure_cookies",
# Convenience functions
"get_current_environment",
"is_production_environment",
"is_development_environment",
"is_staging_environment",
# Validation
"validate_production_settings",
"print_environment_info",
]