openapi-nexus 0.1.5

OpenAPI 3.x multi-language code generator
Documentation
"""HTTP client wrapping requests."""

from __future__ import annotations

from typing import Any, cast

import requests

from .auth import Authenticator


class Response:
    """Thin wrapper over requests.Response with strict types."""

    def __init__(self, raw: requests.Response) -> None:
        self._raw = raw

    @property
    def status_code(self) -> int:
        return self._raw.status_code  # type: ignore[return-value]

    @property
    def reason(self) -> str:
        return self._raw.reason or ""

    @property
    def content(self) -> bytes:
        return self._raw.content  # type: ignore[return-value]

    @property
    def text(self) -> str:
        return self._raw.text

    def json(self) -> Any:  # type: ignore[explicit-override]
        return self._raw.json()  # type: ignore[reportUnknownMemberType]


class Client:
    """Synchronous HTTP client for the generated SDK."""

    def __init__(
        self,
        base_url: str,
        *,
        http_client: requests.Session | None = None,
        authenticator: Authenticator | None = None,
    ) -> None:
        self._base_url = base_url.rstrip("/")
        self._http_client = http_client or requests.Session()
        self._authenticator = authenticator

    def request(
        self,
        method: str,
        path: str,
        *,
        params: dict[str, str] | None = None,
        json: Any = None,
        headers: dict[str, str] | None = None,
    ) -> Response:
        """Send an HTTP request and return the raw response."""
        url = f"{self._base_url}{path}"
        req_headers: dict[str, str] = {"Accept": "application/json"}
        if json is not None:
            req_headers["Content-Type"] = "application/json"
        if headers:
            req_headers.update(headers)
        if self._authenticator is not None:
            req_headers.update(self._authenticator.auth_headers())
        raw = cast(
            requests.Response,
            self._http_client.request(  # type: ignore[reportUnknownMemberType]
                method,
                url,
                params=params,
                json=json,
                headers=req_headers,
            ),
        )
        return Response(raw)

    def close(self) -> None:
        """Close the underlying HTTP client."""
        self._http_client.close()

    def __enter__(self) -> Client:
        return self

    def __exit__(self, *args: object) -> None:
        self.close()