settings.py•2.4 kB
"""Application settings loaded from environment variables."""
from __future__ import annotations
from functools import lru_cache
from typing import Any
from dotenv import load_dotenv
from pydantic import AnyHttpUrl, Field, computed_field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
load_dotenv()
DEFAULT_OCC_BASE_URL = "https://localhost:9002/occ/v2"
class Settings(BaseSettings):
"""Centralised configuration for the OCC MCP server."""
occ_base_url: AnyHttpUrl = Field(
DEFAULT_OCC_BASE_URL,
alias="OCC_BASE_URL",
validation_alias="OCC_BASE_URL",
)
occ_default_fields: str = Field("DEFAULT", alias="OCC_DEFAULT_FIELDS")
occ_accept: str = Field("application/json", alias="OCC_ACCEPT")
occ_timeout_seconds: int = Field(30, alias="OCC_TIMEOUT_SECONDS", ge=1)
occ_retry_attempts: int = Field(3, alias="OCC_RETRY_ATTEMPTS", ge=1)
occ_retry_backoff_max_seconds: float = Field(
10.0, alias="OCC_RETRY_BACKOFF_MAX_SECONDS", gt=0.0
)
oauth_token_url: AnyHttpUrl | None = Field(None, alias="OAUTH_TOKEN_URL")
oauth_client_id: str | None = Field(None, alias="OAUTH_CLIENT_ID")
oauth_client_secret: str | None = Field(None, alias="OAUTH_CLIENT_SECRET")
oauth_scope: str | None = Field(None, alias="OAUTH_SCOPE")
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
@field_validator(
"oauth_token_url",
"oauth_client_id",
"oauth_client_secret",
"oauth_scope",
mode="before",
)
@classmethod
def _empty_string_to_none(cls, value: Any) -> Any:
if isinstance(value, str) and not value.strip():
return None
return value
@computed_field # type: ignore[misc]
@property
def use_oauth(self) -> bool:
"""Return whether OAuth credentials are configured."""
return bool(self.oauth_token_url and self.oauth_client_id and self.oauth_client_secret)
@computed_field # type: ignore[misc]
@property
def accepts_json(self) -> bool:
"""Determine if the requested Accept header expects JSON responses."""
return "json" in self.occ_accept.lower()
@lru_cache(maxsize=1)
def get_settings() -> Settings:
"""Retrieve a cached `Settings` instance."""
return Settings.model_validate({})
settings = get_settings()