Skip to content

Streaming

OxideHTTP supports streaming HTTP response bodies through OxideHTTP.stream().

Unlike regular requests, streaming does not load the entire response body into memory. Instead, it yields raw byte chunks as they are received.

Basic usage

Use stream() as an asynchronous context manager:

import asyncio

from oxidehttp import OxideHTTP


async def main() -> None:
    async with OxideHTTP() as client:
        async with client.stream(
            'GET', 'https://example.com/large-file'
        ) as chunks:
            async for chunk in chunks:
                print(f'Received {len(chunk)} bytes')


asyncio.run(main())

The stream is kept open for the duration of the context manager. Exiting the context closes the underlying streamed response.

Saving a streamed response

You can write chunks directly to a file without buffering the entire response:

import asyncio

from oxidehttp import OxideHTTP


async def download() -> None:
    async with OxideHTTP() as client:
        async with client.stream(
            'GET', 'https://example.com/large-file'
        ) as chunks:
            with open('download.bin', 'wb') as file:
                async for chunk in chunks:
                    file.write(chunk)


asyncio.run(download())

Each yielded chunk is a bytes object.

Request options

stream() accepts the following arguments:

Argument Description
method HTTP method to use.
url Request URL or path.
params Optional query parameters.
headers Optional request headers.
json Optional JSON request body.
body_text Optional text request body.
body_bytes Optional binary request body.
form Optional form-encoded request body.
buffer_limit Maximum size of the underlying streamed-read buffer. Defaults to 100.
middlewares Optional request-specific middleware.
extensions Optional request extensions.

The HTTP method is positional, while the remaining request options are keyword-only.

Buffer limit

The buffer_limit argument controls the underlying streamed-read buffer:

async with client.stream(
    'GET', 'https://example.com/large-file', buffer_limit=256
) as chunks:
    async for chunk in chunks:
        process_chunk(chunk)

The default value is 100.

Streaming with query parameters

Query parameters work the same way as regular requests:

async with client.stream(
    'GET',
    'https://example.com/events',
    params={'limit': 100, 'include_metadata': True},
) as chunks:
    async for chunk in chunks:
        process_chunk(chunk)

See Requests for query parameter serialization.

Streaming request bodies

Streaming supports the same request body representations as the request builder:

async with client.stream(
    'POST', 'https://example.com/upload', json={'name': 'example'}
) as chunks:
    async for chunk in chunks:
        process_chunk(chunk)

When multiple body arguments are supplied, the first non-None representation takes precedence in this order:

  1. json
  2. body_text
  3. body_bytes
  4. form

Middleware and extensions

You can pass middleware and request extensions directly:

async with client.stream(
    'GET',
    'https://example.com/large-file',
    middlewares=[my_middleware],
    extensions={'my_extension': 'value'},
) as chunks:
    async for chunk in chunks:
        process_chunk(chunk)

Client-level middleware configured through OxideHTTPConfig.request.middlewares also applies.

Error handling

Errors raised by the underlying HTTP client are translated into OxideHTTP exceptions.

Cancellation is propagated as asyncio.CancelledError, allowing normal asyncio cancellation handling:

import asyncio

from oxidehttp import OxideHTTP
from oxidehttp.exceptions import OxideHTTPError


async def download() -> None:
    async with OxideHTTP() as client:
        try:
            async with client.stream(
                'GET', 'https://example.com/large-file'
            ) as chunks:
                async for chunk in chunks:
                    process_chunk(chunk)

        except asyncio.CancelledError:
            raise

        except OxideHTTPError as exc:
            print(f'Streaming failed: {exc}')
            raise

The streamed response is closed when the context manager exits, including when an exception occurs.

API reference

See OxideHTTP.stream() for the complete method signature.