Source code for sqlspec.adapters.asyncpg.config

"""AsyncPG database configuration with direct field-based configuration."""

from typing import TYPE_CHECKING, Any, ClassVar, Literal, TypedDict, cast

from asyncpg import Connection, Record
from asyncpg import create_pool as asyncpg_create_pool
from asyncpg.connection import ConnectionMeta
from asyncpg.pool import Pool, PoolConnectionProxy, PoolConnectionProxyMeta
from mypy_extensions import mypyc_attr
from typing_extensions import NotRequired

from sqlspec.adapters.asyncpg._typing import (
    AsyncpgConnection,
    AsyncpgCursor,
    AsyncpgPool,
    AsyncpgPreparedStatement,
    AsyncpgSessionContext,
)
from sqlspec.adapters.asyncpg.core import (
    apply_driver_features,
    build_connection_config,
    build_postgres_extension_probe_names,
    default_statement_config,
    register_json_codecs,
    register_pgvector_support,
    resolve_postgres_extension_state,
    resolve_runtime_statement_config,
)
from sqlspec.adapters.asyncpg.driver import AsyncpgDriver, AsyncpgExceptionHandler
from sqlspec.config import AsyncDatabaseConfig, ExtensionConfigs
from sqlspec.driver._async import AsyncPoolConnectionContext, AsyncPoolSessionFactory
from sqlspec.exceptions import ImproperConfigurationError, MissingDependencyError
from sqlspec.extensions.events import EventRuntimeHints
from sqlspec.typing import ALLOYDB_CONNECTOR_INSTALLED, CLOUD_SQL_CONNECTOR_INSTALLED, PGVECTOR_INSTALLED
from sqlspec.utils.config_tools import normalize_connection_config
from sqlspec.utils.logging import get_logger
from sqlspec.utils.serializers import from_json, to_json

if TYPE_CHECKING:
    from asyncio.events import AbstractEventLoop
    from collections.abc import Awaitable, Callable

    from sqlspec.core import StatementConfig
    from sqlspec.observability import ObservabilityConfig


__all__ = (
    "PGVECTOR_INSTALLED",
    "AsyncpgConfig",
    "AsyncpgConnectionConfig",
    "AsyncpgDriverFeatures",
    "AsyncpgGSSLib",
    "AsyncpgPoolConfig",
    "AsyncpgTargetSessionAttrs",
    "register_json_codecs",
    "register_pgvector_support",
)


logger = get_logger(__name__)


AsyncpgTargetSessionAttrs = Literal["any", "primary", "standby", "read-write", "read-only", "prefer-standby"]
AsyncpgGSSLib = Literal["gssapi", "sspi"]


class AsyncpgConnectionConfig(TypedDict):
    """TypedDict for AsyncPG connection parameters."""

    dsn: NotRequired[str]
    host: NotRequired[str]
    port: NotRequired[int]
    user: NotRequired[str]
    password: NotRequired[str]
    database: NotRequired[str]
    ssl: NotRequired[Any]
    passfile: NotRequired[str]
    service: NotRequired[str]
    servicefile: NotRequired[str]
    direct_tls: NotRequired[bool]
    timeout: NotRequired[float]
    connect_timeout: NotRequired[float]
    command_timeout: NotRequired[float]
    statement_cache_size: NotRequired[int]
    max_cached_statement_lifetime: NotRequired[int]
    max_cacheable_statement_size: NotRequired[int]
    server_settings: NotRequired["dict[str, str]"]
    target_session_attrs: NotRequired[AsyncpgTargetSessionAttrs]
    krbsrvname: NotRequired[str]
    gsslib: NotRequired[AsyncpgGSSLib]
class AsyncpgPoolConfig(AsyncpgConnectionConfig): """TypedDict for AsyncPG pool parameters, inheriting connection parameters.""" min_size: NotRequired[int] max_size: NotRequired[int] max_queries: NotRequired[int] max_inactive_connection_lifetime: NotRequired[float] connect: NotRequired["Callable[..., Awaitable[AsyncpgConnection]]"] setup: NotRequired["Callable[[AsyncpgConnection], Awaitable[None]]"] init: NotRequired["Callable[[AsyncpgConnection], Awaitable[None]]"] reset: NotRequired["Callable[[AsyncpgConnection], Awaitable[None]]"] loop: NotRequired["AbstractEventLoop"] connection_class: NotRequired[type["AsyncpgConnection"]] record_class: NotRequired[type[Record]] extra: NotRequired["dict[str, Any]"]