Skip to content

http

django_spire.contrib.sync.database.transport.http

logger = logging.getLogger(__name__) module-attribute

HttpTransport

Bases: Transport

Source code in django_spire/contrib/sync/database/transport/http.py
def __init__(
    self,
    url: str,
    headers: dict[str, str] | None = None,
    retries: int = 3,
    retry_delay: float = 1.0,
    timeout: float = 30.0,
    response_bytes_max: int = _RESPONSE_BYTES_MAX,
) -> None:
    _validate_url(url)

    if retries < 1:
        message = f'retries must be >= 1, got {retries}'
        raise InvalidParameterError(message)

    if retry_delay < 0.0:
        message = (
            f'retry_delay must be non-negative, '
            f'got {retry_delay}'
        )

        raise InvalidParameterError(message)

    if timeout <= 0.0:
        message = f'timeout must be positive, got {timeout}'
        raise InvalidParameterError(message)

    if response_bytes_max < 1:
        message = (
            f'response_bytes_max must be >= 1, '
            f'got {response_bytes_max}'
        )

        raise InvalidParameterError(message)

    self._headers = headers or {}
    self._response_bytes_max = response_bytes_max
    self._retries = retries
    self._retry_delay = retry_delay
    self._timeout = timeout
    self._url = url

    if not self._headers:
        logger.warning(
            'HttpTransport created without '
            'auth headers for %s',
            self._url,
        )

exchange

Source code in django_spire/contrib/sync/database/transport/http.py
def exchange(
    self,
    manifest: SyncManifest,
) -> SyncManifest:
    payload = manifest.to_dict()

    response_data = retry(
        lambda: self._post(payload),
        attempts=self._retries,
        delay=self._retry_delay,
        exceptions=_TRANSIENT_EXCEPTIONS,
    )

    if not isinstance(response_data, dict):
        message = 'Server returned an invalid response format'
        raise InvalidResponseError(message)

    for required in _REQUIRED_RESPONSE_FIELDS:
        if required not in response_data:
            error = response_data.get(
                'error',
                f"Missing required manifest field {required!r}",
            )

            message = (
                f'Server returned an invalid sync '
                f'response: {error}'
            )

            raise InvalidResponseError(message)

    logger.info(
        'Exchanged manifest with %s '
        '(%d payloads sent, %d received)',
        self._url,
        len(manifest.payloads),
        len(response_data.get('payloads', [])),
    )

    return SyncManifest.from_dict(response_data)