Skip to main content

Stream one HTTP response as multiple parts. For Django, FastAPI, and Starlette.

Project description

multipart-response

Stream one HTTP response as multiple MIME parts. For FastAPI, Starlette, and Django.

FastAPI

uv add "multipart-response[fastapi]"

Yield HTML shorthand and explicit parts from one path operation:

from fastapi import FastAPI
from multipart_response.fastapi import HTMLMultipartResponse, JSONPart, Part

app = FastAPI()


@app.get("/updates", response_class=HTMLMultipartResponse)
async def updates():
    yield "<p>Ready</p>", {"HX-Target": "#status"}
    yield JSONPart({"status": "ready"})
    yield Part(chunk_stream(), media_type="video/mp4")
  • HTMLMultipartResponse accepts HTML strings, (HTML, headers), and explicit parts.
  • Part(content, headers=..., media_type=...) exposes headers, set_cookie(), and delete_cookie().
  • MultipartResponse accepts status_code, headers, subtype, background, and boundary.
  • Return MultipartResponse([...]) directly to set outer response options.

Starlette

uv add "multipart-response[starlette]"

Return a Starlette response from an endpoint:

from multipart_response.starlette import MultipartResponse, Part


async def updates(request):
    part = Part("Ready", media_type="text/plain", headers={"Content-ID": "status"})
    part.headers["HX-Target"] = "#status"
    part.set_cookie("seen", "yes")

    return MultipartResponse(
        [part],
        status_code=200,
        headers={"X-Stream": "updates"},
    )
  • Part(content, headers=..., media_type=...) exposes headers, set_cookie(), and delete_cookie().
  • HTMLMultipartResponse, HTMLPart, TextPart, and JSONPart provide content shortcuts.
  • MultipartResponse subclasses StreamingResponse and accepts status_code, headers, subtype, background, and boundary.

Django

uv add "multipart-response[django]"

Return explicit parts from a Django view:

from multipart_response.django import JsonPart, MultipartResponse, Part


def updates(request):
    def parts():
        part = Part(
            "Ready",
            content_type="text/plain",
            charset="utf-8",
            headers={"Content-ID": "status"},
        )
        part["HX-Target"] = "#status"
        part.headers["HX-Swap"] = "innerHTML"
        part.set_cookie("seen", "yes")

        yield part
        yield JsonPart({"status": "ready"})

    return MultipartResponse(
        parts(),
        status=200,
        reason="OK",
        headers={"X-Stream": "updates"},
    )
  • Part(content, content_type=..., charset=..., headers=...) defaults to HTML.
  • Part.content contains the rendered content or stream.
  • Parts support Django's header mapping, has_header(), get(), setdefault(), set_cookie(), set_signed_cookie(), and delete_cookie().
  • JsonPart accepts encoder, safe, json_dumps_params, content_type, charset, and headers.
  • MultipartResponse accepts status, reason, charset, headers, subtype, and boundary.

Use an async part source under ASGI:

async def updates(request):
    async def parts():
        yield Part("<p>Ready</p>")
        yield Part("<p>Done</p>")

    return MultipartResponse(parts())

MultipartResponse subclasses Django's StreamingHttpResponse. Django 4.2 or later is required.

Nested parts

MultipartResponse accepts Part, MultipartPart, and nested Multipart values:

from multipart_response.fastapi import HTMLPart, Multipart, TextPart

alternative = Multipart(
    [TextPart("Plain text"), HTMLPart("<p>HTML</p>")],
    subtype="alternative",
)

A sequence is buffered. A sync or async iterable streams.

htmx

The hx-multipart extension swaps each part as it arrives. Set HX-Target and HX-Swap on that part.

Core

The dependency-free core exports Multipart, MultipartPart, and MultipartWriter.

  • Boundaries and MIME headers are validated against RFC 2046 limits.
  • Body chunks are checked for boundary collisions.
  • Static, streamed, and nested multipart content is supported.

License

BSD-3-Clause

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

multipart_response-0.4.1.tar.gz (72.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

multipart_response-0.4.1-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file multipart_response-0.4.1.tar.gz.

File metadata

  • Download URL: multipart_response-0.4.1.tar.gz
  • Upload date:
  • Size: 72.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for multipart_response-0.4.1.tar.gz
Algorithm Hash digest
SHA256 6ee5a6cc45c9d88cddfe7e9183a0abb2d9bee4f97b99509d7e3c088d3af6df08
MD5 9f8a919496ba8e710829337673314109
BLAKE2b-256 b316ce9b141e1e26476cab103ca91cf9c5100402398b884fee7893b7c22fc4ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for multipart_response-0.4.1.tar.gz:

Publisher: release.yml on scriptogre/multipart-response

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file multipart_response-0.4.1-py3-none-any.whl.

File metadata

File hashes

Hashes for multipart_response-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e90e49be8296776252ae520a7cea5c471d36532a952f700aa8076d728ed8280d
MD5 3d86dd4dd90d907fbaf250028e56149f
BLAKE2b-256 226525e3010c10548d82de731b81adc6772ed60968bcd14bdb1c0332d4413006

See more details on using hashes here.

Provenance

The following attestation bundles were made for multipart_response-0.4.1-py3-none-any.whl:

Publisher: release.yml on scriptogre/multipart-response

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page