Source code for gamesheet_sdk.common.config
# Copyright (c) 2026 bdperkin
# SPDX-License-Identifier: MIT
"""Configuration for an SDK session.
Values are resolved by `pydantic-settings`_ in the following precedence:
1. Keyword arguments passed to :class:`Config`.
2. ``GAMESHEET_``-prefixed environment variables.
3. Built-in defaults defined on the model below.
A TOML config-file source is not loaded yet; it can be added later by
overriding ``settings_customise_sources`` without changing the public API.
.. _pydantic-settings:
https://docs.pydantic.dev/latest/concepts/pydantic_settings/
"""
from __future__ import annotations
import os
from pathlib import Path
from pydantic import Field, SecretStr
from pydantic_settings import BaseSettings
from gamesheet_sdk.common.constants import DEFAULT_BASE_URL
def _default_session_path() -> Path:
"""Return the XDG-compliant default path for persisted session state."""
xdg = os.environ.get("XDG_CACHE_HOME") or "~/.cache"
return Path(xdg).expanduser() / "gamesheet-sdk-py" / "session.json"
def _default_browser_state_path() -> Path:
"""Return the XDG-compliant default path for Playwright storage state."""
xdg = os.environ.get("XDG_CACHE_HOME") or "~/.cache"
return Path(xdg).expanduser() / "gamesheet-sdk-py" / "browser-state.json"
[docs]
class Config(BaseSettings, env_prefix="GAMESHEET_", extra="ignore"):
"""Resolved configuration for an SDK session.
This class extends :class:`pydantic_settings.BaseSettings` to provide
layered configuration resolution. Values are resolved in the following
precedence order:
1. Keyword arguments passed to the :class:`Config` constructor
2. Environment variables prefixed with ``GAMESHEET_``
3. Field defaults defined on the model
All fields have sensible defaults, so you can instantiate an empty
:class:`Config` for testing or override only the specific values you need.
:var base_url: Root URL of the GameSheet WebUI (the dashboard app)
:vartype base_url: str
:var username: GameSheet account username/email
:vartype username: str | None
:var password: GameSheet account password (stored as SecretStr)
:vartype password: SecretStr | None
:var session_path: Where to persist cookie state between runs
:vartype session_path: Path
:var timeout: Default per-request HTTP timeout in seconds (must be > 0)
:vartype timeout: float
:var user_agent: Override the default User-Agent header sent by the Session
:vartype user_agent: str | None
:var verify_ssl: Whether to verify TLS certificates on outgoing requests
:vartype verify_ssl: bool
:var request_retries: Automatic retries on 5xx responses and connection errors
:vartype request_retries: int
:var browser_state_path: Where to persist Playwright storage state between runs
:vartype browser_state_path: Path
:var browser_headless: Launch the Playwright browser in headless mode
:vartype browser_headless: bool
**Examples:**
Create a default config that picks up environment variables:
.. code-block:: python
from gamesheet_sdk import Config
# Reads GAMESHEET_USERNAME, GAMESHEET_PASSWORD, etc. if set
config = Config()
Override specific fields programmatically:
.. code-block:: python
from gamesheet_sdk import Config
config = Config(
username="user@example.com",
timeout=60.0,
browser_headless=False,
)
Use environment variables to configure the SDK:
.. code-block:: bash
export GAMESHEET_USERNAME="user@example.com"
export GAMESHEET_PASSWORD="secret" # pragma: allowlist secret
export GAMESHEET_TIMEOUT="60.0"
Then in Python:
.. code-block:: python
from gamesheet_sdk import Config
config = Config() # Picks up the env vars above
print(config.username) # "user@example.com"
print(config.timeout) # 60.0
"""
base_url: str = Field(
default=DEFAULT_BASE_URL,
description="Root URL of the GameSheet WebUI (the dashboard app).",
)
username: str | None = Field(
default=None,
description="GameSheet account username/email.",
)
password: SecretStr | None = Field(
default=None,
description="GameSheet account password.",
)
session_path: Path = Field(
default_factory=_default_session_path,
description="Where to persist cookie state between runs.",
)
timeout: float = Field(
default=30.0,
description="Default per-request HTTP timeout in seconds.",
gt=0,
)
user_agent: str | None = Field(
default=None,
description="Override the default User-Agent header sent by the Session.",
)
verify_ssl: bool = Field(
default=True,
description="Whether to verify TLS certificates on outgoing requests.",
)
request_retries: int = Field(
default=3,
description="Automatic retries on 5xx responses and connection errors.",
ge=0,
)
browser_state_path: Path = Field(
default_factory=_default_browser_state_path,
description="Where to persist Playwright storage state between runs.",
)
browser_headless: bool = Field(
default=True,
description="Launch the Playwright browser in headless mode.",
)