Skip to content

Request Body

Zapros supports several body formats, each setting the appropriate Content-Type header automatically.

JSON

Pass any JSON-serialisable value to json=. The body is serialised with compact separators and encoded as UTF-8.

python
async with AsyncClient() as client:
    response = await client.request(
        "POST",
        "https://httpbin.org/post",
        json={
            "name": "alice",
            "age": 30,
        },
    )
python
with Client() as client:
    response = client.request(
        "POST",
        "https://httpbin.org/post",
        json={
            "name": "alice",
            "age": 30,
        },
    )

Content-Type: application/json is set automatically.

Form (URL-encoded)

Pass a str → str mapping to form=. The body is encoded as application/x-www-form-urlencoded.

python
async with AsyncClient() as client:
    response = await client.request(
        "POST",
        "https://httpbin.org/post",
        form={
            "username": "alice",
            "password": "secret",
        },
    )
python
with Client() as client:
    response = client.request(
        "POST",
        "https://httpbin.org/post",
        form={
            "username": "alice",
            "password": "secret",
        },
    )

Content-Type: application/x-www-form-urlencoded is set automatically.

Raw Bytes

Pass bytes directly to body= when you have a pre-encoded payload.

python
async with AsyncClient() as client:
    response = await client.request(
        "POST",
        "https://httpbin.org/post",
        body=b"\x00\x01\x02\x03",
        headers={
            "Content-Type": "application/octet-stream"
        },
    )
python
with Client() as client:
    response = client.request(
        "POST",
        "https://httpbin.org/post",
        body=b"\x00\x01\x02\x03",
        headers={
            "Content-Type": "application/octet-stream"
        },
    )

Content-Length is set automatically from the byte length. No Content-Type is inferred — set it explicitly if the server requires one.

Streaming Body

Pass a Stream (sync) or AsyncStream (async) to body= to send data without buffering it in memory. The request is sent with Transfer-Encoding: chunked.

python
from zapros import (
    AsyncClient,
    AsyncStream,
)


class FileStream(AsyncStream):
    def __init__(
        self,
        path: str,
        chunk_size: int = 65536,
    ) -> None:
        self._path = path
        self._chunk_size = chunk_size

    def __aiter__(self):
        return self

    async def __anext__(self) -> bytes:
        raise StopAsyncIteration

    async def aclose(self) -> None:
        pass


async with AsyncClient() as client:
    response = await client.request(
        "POST",
        "https://httpbin.org/post",
        body=FileStream("large-file.bin"),
        headers={
            "Content-Type": "application/octet-stream"
        },
    )
python
from zapros import Client, Stream


class FileStream(Stream):
    def __init__(
        self,
        path: str,
        chunk_size: int = 65536,
    ) -> None:
        self._file = open(path, "rb")
        self._chunk_size = chunk_size

    def __iter__(self):
        return self

    def __next__(self) -> bytes:
        chunk = self._file.read(self._chunk_size)
        if not chunk:
            raise StopIteration
        return chunk

    def close(self) -> None:
        self._file.close()


with Client() as client:
    response = client.request(
        "POST",
        "https://httpbin.org/post",
        body=FileStream("large-file.bin"),
        headers={
            "Content-Type": "application/octet-stream"
        },
    )

Multipart

Use Multipart to upload files or mixed form data. Each part can be text, raw bytes, or a stream, and can have an explicit filename and MIME type.

python
from zapros import (
    AsyncClient,
    Multipart,
)

multipart = (
    Multipart()
    .text("description", "monthly report")
    .file("file", "report.pdf")
)

async with AsyncClient() as client:
    response = await client.request(
        "POST",
        "https://httpbin.org/post",
        multipart=multipart,
    )
python
from zapros import Client, Multipart

multipart = (
    Multipart()
    .text("description", "monthly report")
    .file("file", "report.pdf")
)

with Client() as client:
    response = client.request(
        "POST",
        "https://httpbin.org/post",
        multipart=multipart,
    )

Content-Type: multipart/form-data; boundary="..." is set automatically. Multipart.file() infers the filename and MIME type from the path automatically.

For custom parts, use Part directly and add it with .part():

python
from zapros import Multipart, Part

file_part = (
    Part
    .bytes(b"file content")
    .file_name("report.txt")
    .mime_type("text/plain")
)
multipart = (
    Multipart()
    .text("description", "monthly report")
    .part("file", file_part)
)

Chain .file_name(name) and .mime_type(mime) on any part to override the filename disposition parameter and Content-Type.

Note: Only one of json, form, body, or multipart can be passed per request.