From 8c3e7a9fe4831e3da1620179c482c0a3b4c43634 Mon Sep 17 00:00:00 2001 From: ThePhaseless Date: Sat, 4 Jul 2026 17:42:53 +0200 Subject: [PATCH] refactor: use pydantic-settings for environment configuration - Add pydantic-settings as direct dependency - Replace os.getenv calls with typed Settings class - Add BLOCK_MEDIA and RETURN_ONLY_COOKIES env defaults --- pyproject.toml | 1 + src/consts.py | 44 +++++++++++++++++++++++++++++++++++--------- src/models.py | 4 ++-- uv.lock | 2 ++ 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 07b5f6a..da9ae9a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ dependencies = [ "playwright==1.60.*", "playwright-captcha==0.1.*", "pydantic==2.*", + "pydantic-settings==2.*", ] urls = { repository = "https://github.com/ThePhaseless/Byparr" } [dependency-groups] diff --git a/src/consts.py b/src/consts.py index 29a9a4a..249d4ec 100644 --- a/src/consts.py +++ b/src/consts.py @@ -1,20 +1,46 @@ import logging -import os import sys + +from pydantic_settings import BaseSettings, SettingsConfigDict + from playwright_captcha import CaptchaType -LOG_LEVEL = logging.getLevelNamesMapping()[os.getenv("LOG_LEVEL", "INFO").upper()] -VERSION = os.getenv("VERSION", "unknown").removeprefix("v") +class Settings(BaseSettings): + model_config = SettingsConfigDict(env_file=".env", extra="ignore") -MAX_ATTEMPTS = sys.maxsize + log_level: str = "INFO" + version: str = "unknown" -PROXY_SERVER = os.getenv("PROXY_SERVER") -PROXY_USERNAME = os.getenv("PROXY_USERNAME") -PROXY_PASSWORD = os.getenv("PROXY_PASSWORD") + max_attempts: int = sys.maxsize -HOST = os.getenv("HOST", "0.0.0.0") # noqa: S104 -PORT = int(os.getenv("PORT", "8191")) + proxy_server: str | None = None + proxy_username: str | None = None + proxy_password: str | None = None + + host: str = "0.0.0.0" # noqa: S104 + port: int = 8191 + + block_media: bool = False + return_only_cookies: bool = False + + +settings = Settings() + +LOG_LEVEL = logging.getLevelNamesMapping()[settings.log_level.upper()] +VERSION = settings.version.removeprefix("v") + +MAX_ATTEMPTS = settings.max_attempts + +PROXY_SERVER = settings.proxy_server +PROXY_USERNAME = settings.proxy_username +PROXY_PASSWORD = settings.proxy_password + +HOST = settings.host +PORT = settings.port + +BLOCK_MEDIA = settings.block_media +RETURN_ONLY_COOKIES = settings.return_only_cookies CHALLENGE_TITLES_MAP: dict[CaptchaType, list[str]] = { # Cloudflare diff --git a/src/models.py b/src/models.py index d7d085e..baae038 100644 --- a/src/models.py +++ b/src/models.py @@ -24,12 +24,12 @@ class LinkRequest(BaseModel): description="Maximum timeout in seconds for resolving the anti-bot challenge.", ) block_media: bool = Field( - default=False, + default=consts.BLOCK_MEDIA, alias="blockMedia", description="Block image, media, and font resources from loading.", ) return_only_cookies: bool = Field( - default=False, + default=consts.RETURN_ONLY_COOKIES, alias="returnOnlyCookies", description="Return only cookies, skip the page HTML content in the response.", ) diff --git a/uv.lock b/uv.lock index 665504e..79b2a0e 100644 --- a/uv.lock +++ b/uv.lock @@ -65,6 +65,7 @@ dependencies = [ { name = "playwright" }, { name = "playwright-captcha" }, { name = "pydantic" }, + { name = "pydantic-settings" }, ] [package.dev-dependencies] @@ -88,6 +89,7 @@ requires-dist = [ { name = "playwright", specifier = "==1.60.*" }, { name = "playwright-captcha", specifier = "==0.1.*" }, { name = "pydantic", specifier = "==2.*" }, + { name = "pydantic-settings", specifier = "==2.*" }, ] [package.metadata.requires-dev]