Skip to content

HTTP

Retry-aware HTTP helpers used internally by the GitHub backends. Wrap transport-layer exceptions into the SDK's typed error hierarchy.

fetch_json

ocx_mirror_sdk.http.fetch_json

fetch_json(url: str, *, headers: dict[str, str] | None = None, params: dict[str, Any] | None = None, client: Client | None = None) -> Any

Fetch a URL and parse the response as JSON.

PARAMETER DESCRIPTION
url

Target URL.

TYPE: str

headers

Optional request headers (e.g. PRIVATE-TOKEN).

TYPE: dict[str, str] | None DEFAULT: None

params

Optional query-string parameters (e.g. {"per_page": 100}).

TYPE: dict[str, Any] | None DEFAULT: None

client

Optional injected client. Defaults to the module-level singleton (lazy-initialized with sane retry / timeout). Tests should pass httpx.Client(transport=httpx.MockTransport(...)).

TYPE: Client | None DEFAULT: None

RAISES DESCRIPTION
HttpStatusError

Response status was 4xx/5xx.

HttpTimeoutError

Request timed out.

ApiResponseError

Body was not valid JSON.

Source code in src/ocx_mirror_sdk/http.py
def fetch_json(
    url: str,
    *,
    headers: dict[str, str] | None = None,
    params: dict[str, Any] | None = None,
    client: httpx.Client | None = None,
) -> Any:
    """Fetch a URL and parse the response as JSON.

    Args:
        url: Target URL.
        headers: Optional request headers (e.g. ``PRIVATE-TOKEN``).
        params: Optional query-string parameters (e.g. ``{"per_page": 100}``).
        client: Optional injected client. Defaults to the module-level
            singleton (lazy-initialized with sane retry / timeout). Tests
            should pass ``httpx.Client(transport=httpx.MockTransport(...))``.

    Raises:
        HttpStatusError: Response status was 4xx/5xx.
        HttpTimeoutError: Request timed out.
        ApiResponseError: Body was not valid JSON.
    """
    try:
        response = (client or _get_client()).get(url, headers=headers, params=params)
        response.raise_for_status()
    except httpx.TimeoutException as e:
        raise HttpTimeoutError(url=url) from e
    except httpx.HTTPStatusError as e:
        raise _wrap_status(e) from e
    except httpx.TransportError as e:
        # NetworkError / ProtocolError / etc. — connection reset, read error,
        # or a response the server closed early. Transient; wrap so callers can
        # retry instead of seeing a raw httpx exception leak past the boundary.
        raise HttpTransportError(url=url, detail=str(e)) from e
    try:
        return response.json()
    except json.JSONDecodeError as e:
        raise ApiResponseError("response body is not valid JSON", payload=None) from e

fetch_text

ocx_mirror_sdk.http.fetch_text

fetch_text(url: str, *, client: Client | None = None) -> str

Fetch a URL and return the response body as text.

PARAMETER DESCRIPTION
url

Target URL.

TYPE: str

client

Optional injected client. See :func:fetch_json for details.

TYPE: Client | None DEFAULT: None

RAISES DESCRIPTION
HttpStatusError

Response status was 4xx/5xx.

HttpTimeoutError

Request timed out.

Source code in src/ocx_mirror_sdk/http.py
def fetch_text(url: str, *, client: httpx.Client | None = None) -> str:
    """Fetch a URL and return the response body as text.

    Args:
        url: Target URL.
        client: Optional injected client. See :func:`fetch_json` for details.

    Raises:
        HttpStatusError: Response status was 4xx/5xx.
        HttpTimeoutError: Request timed out.
    """
    try:
        response = (client or _get_client()).get(url)
        response.raise_for_status()
    except httpx.TimeoutException as e:
        raise HttpTimeoutError(url=url) from e
    except httpx.HTTPStatusError as e:
        raise _wrap_status(e) from e
    except httpx.TransportError as e:
        # NetworkError / ProtocolError / etc. — connection reset, read error,
        # or a response the server closed early. Transient; wrap so callers can
        # retry instead of seeing a raw httpx exception leak past the boundary.
        raise HttpTransportError(url=url, detail=str(e)) from e
    return response.text

post_json

ocx_mirror_sdk.http.post_json

post_json(url: str, *, body: Any, headers: dict[str, str] | None = None, client: Client | None = None) -> Any

POST a JSON payload and parse the response as JSON.

PARAMETER DESCRIPTION
url

Target URL.

TYPE: str

body

JSON-serializable request body.

TYPE: Any

headers

Optional request headers (e.g. Authorization).

TYPE: dict[str, str] | None DEFAULT: None

client

Optional injected client. See :func:fetch_json for details.

TYPE: Client | None DEFAULT: None

RAISES DESCRIPTION
HttpStatusError

Response status was 4xx/5xx.

HttpTimeoutError

Request timed out.

ApiResponseError

Body was not valid JSON.

Source code in src/ocx_mirror_sdk/http.py
def post_json(
    url: str,
    *,
    body: Any,
    headers: dict[str, str] | None = None,
    client: httpx.Client | None = None,
) -> Any:
    """POST a JSON payload and parse the response as JSON.

    Args:
        url: Target URL.
        body: JSON-serializable request body.
        headers: Optional request headers (e.g. ``Authorization``).
        client: Optional injected client. See :func:`fetch_json` for details.

    Raises:
        HttpStatusError: Response status was 4xx/5xx.
        HttpTimeoutError: Request timed out.
        ApiResponseError: Body was not valid JSON.
    """
    try:
        response = (client or _get_client()).post(url, headers=headers, json=body)
        response.raise_for_status()
    except httpx.TimeoutException as e:
        raise HttpTimeoutError(url=url) from e
    except httpx.HTTPStatusError as e:
        raise _wrap_status(e) from e
    except httpx.TransportError as e:
        # NetworkError / ProtocolError / etc. — connection reset, read error,
        # or a response the server closed early. Transient; wrap so callers can
        # retry instead of seeing a raw httpx exception leak past the boundary.
        raise HttpTransportError(url=url, detail=str(e)) from e
    try:
        return response.json()
    except json.JSONDecodeError as e:
        raise ApiResponseError("response body is not valid JSON", payload=None) from e