2025-05-24 22:52:25 +02:00

115 lines
4.8 KiB
Python

import os
from typing import List, ClassVar
from pydantic_settings import BaseSettings
from pydantic import AnyHttpUrl, field_validator
class Settings(BaseSettings):
# Project settings
PROJECT_NAME: str = "SEREACT - Secure Image Management API"
API_V1_STR: str = "/api/v1"
# Environment
ENVIRONMENT: str = "development"
# CORS settings
CORS_ORIGINS: List[str] = ["*"]
CORS_METHODS: List[str] = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
CORS_HEADERS: List[str] = ["Content-Type", "Authorization", "X-Requested-With"]
CORS_EXPOSE_HEADERS: List[str] = ["Content-Length", "Content-Range"]
CORS_MAX_AGE: int = 3600
@field_validator("CORS_ORIGINS", mode="before")
def assemble_cors_origins(cls, v):
# Read from environment variable first
env_origins = os.getenv("CORS_ORIGINS")
if env_origins:
if env_origins.startswith("[") and env_origins.endswith("]"):
# Handle list format like "['*']"
import ast
try:
return ast.literal_eval(env_origins)
except:
pass
# Handle comma-separated format
return [i.strip().strip("'\"") for i in env_origins.split(",")]
# Fallback to default if no env var
if isinstance(v, str) and not v.startswith("["):
return [i.strip() for i in v.split(",")]
elif not v: # If empty list, use defaults
return ["http://localhost:3000", "http://localhost:8000", "http://127.0.0.1:8000", "http://127.0.0.1:3000", "https://localhost:3000", "https://localhost:8000"]
return v
@field_validator("CORS_METHODS", mode="before")
def assemble_cors_methods(cls, v):
env_methods = os.getenv("CORS_METHODS")
if env_methods:
return [i.strip() for i in env_methods.split(",")]
return v or ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
@field_validator("CORS_HEADERS", mode="before")
def assemble_cors_headers(cls, v):
env_headers = os.getenv("CORS_HEADERS")
if env_headers:
return [i.strip() for i in env_headers.split(",")]
return v or ["Content-Type", "Authorization", "X-Requested-With"]
@field_validator("CORS_EXPOSE_HEADERS", mode="before")
def assemble_cors_expose_headers(cls, v):
env_expose = os.getenv("CORS_EXPOSE_HEADERS")
if env_expose:
return [i.strip() for i in env_expose.split(",")]
return v or ["Content-Length", "Content-Range"]
@field_validator("CORS_MAX_AGE", mode="before")
def assemble_cors_max_age(cls, v):
env_max_age = os.getenv("CORS_MAX_AGE")
if env_max_age:
return int(env_max_age)
return v or 3600
# Firestore settings
FIRESTORE_PROJECT_ID: str = os.getenv("FIRESTORE_PROJECT_ID", "")
FIRESTORE_DATABASE_NAME: str = os.getenv("FIRESTORE_DATABASE_NAME", "sereact-db")
FIRESTORE_CREDENTIALS_FILE: str = os.getenv("FIRESTORE_CREDENTIALS_FILE", "firestore-credentials.json")
# Google Cloud Storage settings
GCS_BUCKET_NAME: str = os.getenv("GCS_BUCKET_NAME", "image-mgmt-bucket")
GCS_CREDENTIALS_FILE: str = os.getenv("GCS_CREDENTIALS_FILE", "credentials.json")
# Google Pub/Sub settings
PUBSUB_TOPIC: str = os.getenv("PUBSUB_TOPIC", "image-processing-topic")
PUBSUB_SUBSCRIPTION: str = os.getenv("PUBSUB_SUBSCRIPTION", "image-processing-subscription")
# Google Cloud Vision API
VISION_API_ENABLED: bool = os.getenv("VISION_API_ENABLED", "true").lower() == "true"
# Security settings
API_KEY_SECRET: str = os.getenv("API_KEY_SECRET", "super-secret-key-for-development-only")
API_KEY_EXPIRY_DAYS: int = int(os.getenv("API_KEY_EXPIRY_DAYS", "365"))
# Vector Database settings (for image embeddings)
VECTOR_DB_API_KEY: str = os.getenv("VECTOR_DB_API_KEY", "")
VECTOR_DB_ENVIRONMENT: str = os.getenv("VECTOR_DB_ENVIRONMENT", "")
VECTOR_DB_INDEX_NAME: str = os.getenv("VECTOR_DB_INDEX_NAME", "image-embeddings")
# Rate limiting
RATE_LIMIT_PER_MINUTE: int = int(os.getenv("RATE_LIMIT_PER_MINUTE", "100"))
# Qdrant settings
QDRANT_HOST: str = os.getenv("QDRANT_HOST", "localhost")
QDRANT_PORT: int = int(os.getenv("QDRANT_PORT", "6333"))
QDRANT_API_KEY: str = os.getenv("QDRANT_API_KEY", "")
QDRANT_COLLECTION: str = os.getenv("QDRANT_COLLECTION", "image_vectors")
QDRANT_HTTPS: bool = os.getenv("QDRANT_HTTPS", "").lower() in ("true", "1", "yes")
QDRANT_PREFER_GRPC: bool = os.getenv("QDRANT_PREFER_GRPC", "false").lower() in ("true", "1", "yes")
# Logging
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
model_config: ClassVar[dict] = {
"case_sensitive": True,
"env_file": ".env"
}
settings = Settings()