Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from functools import lru_cache | |
| from pathlib import Path | |
| from pydantic import Field | |
| from pydantic_settings import BaseSettings, SettingsConfigDict | |
| ROOT_DIR = Path(__file__).resolve().parents[2] | |
| class Settings(BaseSettings): | |
| app_name: str = Field(default="Recruitment Agent API", validation_alias="APP_NAME") | |
| environment: str = Field(default="development", validation_alias="APP_ENV") | |
| host: str = Field(default="0.0.0.0", validation_alias="APP_HOST") | |
| port: int = Field(default=7860, validation_alias="APP_PORT") | |
| cors_origins: str = Field(default="*", validation_alias="CORS_ORIGINS") | |
| gemini_api_key: str = Field(default="", validation_alias="GEMINI_API_KEY") | |
| gemini_model: str = Field(default="gemini-2.5-flash", validation_alias="GEMINI_MODEL") | |
| embedding_model: str = Field( | |
| default="models/text-embedding-004", | |
| validation_alias="GEMINI_EMBEDDING_MODEL", | |
| ) | |
| qdrant_url: str | None = Field(default=None, validation_alias="QDRANT_URL") | |
| qdrant_api_key: str | None = Field(default=None, validation_alias="QDRANT_API_KEY") | |
| qdrant_collection: str = Field( | |
| default="recruitment_candidates", | |
| validation_alias="QDRANT_COLLECTION", | |
| ) | |
| # Generic S3-compatible storage. Works with Supabase Storage, Backblaze B2, | |
| # AWS S3, MinIO, etc. — just point S3_ENDPOINT at the provider's URL. | |
| s3_endpoint: str | None = Field(default=None, validation_alias="S3_ENDPOINT") | |
| s3_access_key_id: str | None = Field(default=None, validation_alias="S3_ACCESS_KEY_ID") | |
| s3_secret_access_key: str | None = Field( | |
| default=None, | |
| validation_alias="S3_SECRET_ACCESS_KEY", | |
| ) | |
| s3_bucket: str | None = Field(default=None, validation_alias="S3_BUCKET") | |
| s3_region: str = Field(default="us-east-1", validation_alias="S3_REGION") | |
| s3_public_base_url: str | None = Field( | |
| default=None, | |
| validation_alias="S3_PUBLIC_BASE_URL", | |
| ) | |
| sqlite_db_path: str = Field( | |
| default=str(ROOT_DIR / "backend" / "data" / "candidates.db"), | |
| validation_alias="SQLITE_DB_PATH", | |
| ) | |
| uploads_dir: str = Field( | |
| default=str(ROOT_DIR / "backend" / "data" / "uploads"), | |
| validation_alias="UPLOADS_DIR", | |
| ) | |
| mcp_server_base_url: str = Field( | |
| default="http://127.0.0.1:7860/mcp-server/sse", | |
| validation_alias="MCP_SERVER_BASE_URL", | |
| ) | |
| chunk_size: int = Field(default=1100, validation_alias="CHUNK_SIZE") | |
| chunk_overlap: int = Field(default=150, validation_alias="CHUNK_OVERLAP") | |
| max_chunks_per_document: int = Field(default=50, validation_alias="MAX_CHUNKS_PER_DOC") | |
| smtp_host: str | None = Field(default=None, validation_alias="SMTP_HOST") | |
| smtp_port: int = Field(default=587, validation_alias="SMTP_PORT") | |
| smtp_user: str | None = Field(default=None, validation_alias="SMTP_USER") | |
| smtp_password: str | None = Field(default=None, validation_alias="SMTP_PASSWORD") | |
| smtp_from: str | None = Field(default=None, validation_alias="SMTP_FROM") | |
| smtp_use_tls: bool = Field(default=True, validation_alias="SMTP_USE_TLS") | |
| # Resend (https://resend.com) — HTTPS email API. Free 3000/month but | |
| # restricted to your own email address until you verify a sending domain. | |
| resend_api_key: str | None = Field(default=None, validation_alias="RESEND_API_KEY") | |
| # Brevo (https://brevo.com, formerly Sendinblue) — HTTPS email API. Free | |
| # 300 emails/day. Only needs a *single sender email* verified (no DNS | |
| # required), and you can send TO any recipient. Best free option when the | |
| # demo needs to email arbitrary addresses on day one. | |
| brevo_api_key: str | None = Field(default=None, validation_alias="BREVO_API_KEY") | |
| calendly_event_url: str | None = Field(default=None, validation_alias="CALENDLY_EVENT_URL") | |
| model_config = SettingsConfigDict( | |
| env_file=(str(ROOT_DIR / ".env"), str(ROOT_DIR.parent / ".env")), | |
| env_file_encoding="utf-8", | |
| extra="ignore", | |
| ) | |
| def sqlite_url(self) -> str: | |
| return f"sqlite:///{Path(self.sqlite_db_path).resolve()}" | |
| def cors_origin_list(self) -> list[str]: | |
| if self.cors_origins.strip() == "*": | |
| return ["*"] | |
| return [item.strip() for item in self.cors_origins.split(",") if item.strip()] | |
| def has_qdrant_config(self) -> bool: | |
| return bool(self.qdrant_url and self.qdrant_api_key) | |
| def has_s3_config(self) -> bool: | |
| return bool( | |
| self.s3_endpoint | |
| and self.s3_access_key_id | |
| and self.s3_secret_access_key | |
| and self.s3_bucket | |
| ) | |
| def has_smtp_config(self) -> bool: | |
| return bool(self.smtp_host and self.smtp_from) | |
| def get_settings() -> Settings: | |
| return Settings() | |