Source code for paperap.settings

"""
----------------------------------------------------------------------------

METADATA:

File:    settings.py
        Project: paperap
Created: 2025-03-09
        Version: 0.0.9
Author:  Jess Mann
Email:   jess@jmann.me
        Copyright (c) 2025 Jess Mann

----------------------------------------------------------------------------

LAST MODIFIED:

2025-03-09     By Jess Mann

"""

from __future__ import annotations

from typing import Annotated, Any, Self, TypedDict, override

from pydantic import Field, HttpUrl, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict

from paperap.exceptions import ConfigurationError


[docs] class SettingsArgs(TypedDict, total=False): """ Arguments for the settings class """ base_url: HttpUrl token: str | None username: str | None password: str | None timeout: int require_ssl: bool save_on_write: bool
[docs] class Settings(BaseSettings): """ Settings for the paperap library """ token: str | None = None username: str | None = None password: str | None = None base_url: HttpUrl timeout: int = 60 require_ssl: bool = False save_on_write: bool = True openai_key: str | None = Field(default=None, alias="openai_api_key") openai_model: str | None = Field(default=None, alias="openai_model_name") openai_url: str | None = Field(default=None, alias="openai_base_url") model_config = SettingsConfigDict(env_prefix="PAPERLESS_", extra="ignore")
[docs] @field_validator("base_url", mode="after") @classmethod def validate_url(cls, value: HttpUrl) -> HttpUrl: """Ensure the URL is properly formatted.""" # Make sure the URL has a scheme if not all([value.scheme, value.host]): raise ConfigurationError("Base URL must have a scheme and host") return value
[docs] @field_validator("timeout", mode="before") @classmethod def validate_timeout(cls, value: Any) -> int: """Ensure the timeout is a positive integer.""" try: if isinstance(value, str): # May raise ValueError value = int(value) if not isinstance(value, int): raise TypeError("Unknown type for timeout") except ValueError as ve: raise TypeError(f"Timeout must be an integer. Provided {value=} of type {type(value)}") from ve if value < 0: raise ConfigurationError("Timeout must be a positive integer") return value
[docs] @override def model_post_init(self, __context: Any) -> None: """ Validate the settings after they have been initialized. """ if self.token is None and (self.username is None or self.password is None): raise ConfigurationError("Provide a token, or a username and password") if not self.base_url: raise ConfigurationError("Base URL is required") if self.require_ssl and self.base_url.scheme != "https": raise ConfigurationError(f"URL must use HTTPS. Url: {self.base_url}. Scheme: {self.base_url.scheme}") return super().model_post_init(__context)