Files
ai-software-factory/ai_software_factory/config.py

154 lines
4.4 KiB
Python

"""Configuration settings for AI Software Factory."""
import os
from typing import Optional
from pathlib import Path
from pydantic import Field
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
"""Application settings loaded from environment variables."""
# Server settings
HOST: str = "0.0.0.0"
PORT: int = 8000
LOG_LEVEL: str = "INFO"
# Ollama settings computed from environment
OLLAMA_URL: str = "http://ollama:11434"
OLLAMA_MODEL: str = "llama3"
# Gitea settings
GITEA_URL: str = "https://gitea.yourserver.com"
GITEA_TOKEN: str = ""
GITEA_OWNER: str = "ai-software-factory"
GITEA_REPO: str = "ai-software-factory"
# n8n settings
N8N_WEBHOOK_URL: str = ""
N8N_API_URL: str = ""
N8N_USER: str = ""
N8N_PASSWORD: str = ""
# Telegram settings
TELEGRAM_BOT_TOKEN: str = ""
TELEGRAM_CHAT_ID: str = ""
# PostgreSQL settings
POSTGRES_HOST: str = "localhost"
POSTGRES_PORT: int = 5432
POSTGRES_USER: str = "postgres"
POSTGRES_PASSWORD: str = ""
POSTGRES_DB: str = "ai_software_factory"
POSTGRES_TEST_DB: str = "ai_software_factory_test"
POSTGRES_URL: Optional[str] = None # Optional direct PostgreSQL connection URL
# SQLite settings for testing
USE_SQLITE: bool = True # Enable SQLite by default for testing
SQLITE_DB_PATH: str = "sqlite.db"
# Database connection pool settings (only for PostgreSQL)
DB_POOL_SIZE: int = 10
DB_MAX_OVERFLOW: int = 20
DB_POOL_RECYCLE: int = 3600
DB_POOL_TIMEOUT: int = 30
@property
def pool(self) -> dict:
"""Get database pool configuration."""
return {
"pool_size": self.DB_POOL_SIZE,
"max_overflow": self.DB_MAX_OVERFLOW,
"pool_recycle": self.DB_POOL_RECYCLE,
"pool_timeout": self.DB_POOL_TIMEOUT
}
@property
def database_url(self) -> str:
"""Get database connection URL."""
if self.USE_SQLITE:
return f"sqlite:///{self.SQLITE_DB_PATH}"
return (
f"postgresql://{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}"
f"@{self.POSTGRES_HOST}:{self.POSTGRES_PORT}/{self.POSTGRES_DB}"
)
@property
def test_database_url(self) -> str:
"""Get test database connection URL."""
if self.USE_SQLITE:
return f"sqlite:///{self.SQLITE_DB_PATH}"
return (
f"postgresql://{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}"
f"@{self.POSTGRES_HOST}:{self.POSTGRES_PORT}/{self.POSTGRES_TEST_DB}"
)
@property
def ollama_url(self) -> str:
"""Get Ollama URL with trimmed whitespace."""
return self.OLLAMA_URL.strip()
@property
def gitea_url(self) -> str:
"""Get Gitea URL with trimmed whitespace."""
return self.GITEA_URL.strip()
@property
def gitea_token(self) -> str:
"""Get Gitea token with trimmed whitespace."""
return self.GITEA_TOKEN.strip()
@property
def n8n_webhook_url(self) -> str:
"""Get n8n webhook URL with trimmed whitespace."""
return self.N8N_WEBHOOK_URL.strip()
@property
def telegram_bot_token(self) -> str:
"""Get Telegram bot token with trimmed whitespace."""
return self.TELEGRAM_BOT_TOKEN.strip()
@property
def telegram_chat_id(self) -> str:
"""Get Telegram chat ID with trimmed whitespace."""
return self.TELEGRAM_CHAT_ID.strip()
@property
def postgres_host(self) -> str:
"""Get PostgreSQL host."""
return self.POSTGRES_HOST.strip()
@property
def postgres_port(self) -> int:
"""Get PostgreSQL port as integer."""
return int(self.POSTGRES_PORT)
@property
def postgres_user(self) -> str:
"""Get PostgreSQL user."""
return self.POSTGRES_USER.strip()
@property
def postgres_password(self) -> str:
"""Get PostgreSQL password."""
return self.POSTGRES_PASSWORD.strip()
@property
def postgres_db(self) -> str:
"""Get PostgreSQL database name."""
return self.POSTGRES_DB.strip()
@property
def postgres_test_db(self) -> str:
"""Get test PostgreSQL database name."""
return self.POSTGRES_TEST_DB.strip()
class Config:
env_file = ".env"
env_file_encoding = "utf-8"
extra = "ignore"
# Create instance for module-level access
settings = Settings()