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 parts. For Django, FastAPI, and Starlette.

FastAPI

Install the FastAPI adapter:

uv add "multipart-response[fastapi]"

Yield parts from an endpoint:

from fastapi import FastAPI
from multipart_response.fastapi import HTMLMultipartResponse

app = FastAPI()

@app.get("/updates", response_class=HTMLMultipartResponse)
async def updates():
    yield "<p>Ready</p>"
    yield "<p>Done</p>"

Each part is sent when it is yielded:

Content-Type: multipart/mixed; boundary=multipart-...

--multipart-...
content-length: 12
content-type: text/html; charset=utf-8

<p>Ready</p>
--multipart-...
content-length: 11
content-type: text/html; charset=utf-8

<p>Done</p>
--multipart-...--

The same API is available from multipart_response.starlette.

Django

Install the Django adapter:

uv add "multipart-response[django]"

Return a multipart response from a view:

from multipart_response.django import HTMLMultipartResponse


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

    return HTMLMultipartResponse(parts())

Use an async part source when Django runs under ASGI:

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

    return HTMLMultipartResponse(parts())

Django parts use Django response conventions:

from multipart_response.django import HTMLPart

part = HTMLPart("<p>Ready</p>")
part["HX-Target"] = "#status"
part.headers["HX-Swap"] = "innerHTML"
part.set_cookie("seen", "yes")

Part binds Django's header, charset, and cookie methods directly. JSONPart uses JsonResponse, including DjangoJSONEncoder and safe=True.

Django 4.2 or later is required. Sync iterators suit WSGI. Async iterators suit ASGI.

htmx

With the hx-multipart extension, each part is one swap. Part headers pick the target:

@app.get("/dashboard", response_class=HTMLMultipartResponse)
async def dashboard():
    yield ("<p>Ready</p>", {"HX-Target": "#status"})
    yield ("<li>New</li>", {"HX-Target": "#reports", "HX-Swap": "beforeend"})

The same shorthand works with Django's HTMLMultipartResponse.

Other part types

Use explicit parts when one response mixes content types:

from multipart_response.fastapi import JSONPart, Multipart, MultipartResponse, Part, TextPart

@app.get("/report", response_class=MultipartResponse)
async def report():
    yield TextPart("Preparing")
    yield JSONPart({"status": "ready"})
    yield Part(chunk_stream(), media_type="video/mp4")
    yield Multipart([...], subtype="alternative")

Import the Django versions from multipart_response.django. Django's Part uses content_type instead of media_type.

Notes

  • Return MultipartResponse([...], status_code=..., headers=...) with FastAPI or Starlette.
  • Return MultipartResponse([...], status=..., reason=..., headers=...) with Django.
  • The dependency-free core exports Multipart, MultipartPart, and MultipartWriter.
  • Boundaries and headers are validated against RFC 2046 limits.
  • Body chunks are checked for boundary collisions.

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.2.0.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.2.0-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: multipart_response-0.2.0.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.2.0.tar.gz
Algorithm Hash digest
SHA256 92c01808150367f643c73e557a978eef5607b2962ba378fbb20f1f6d4d0a6684
MD5 19f1eceb4d5e503dbf3db934f3683ffe
BLAKE2b-256 52fb10ea6c492f99714a617f23d0f7ba71515d083a2ab6100041469babd69341

See more details on using hashes here.

Provenance

The following attestation bundles were made for multipart_response-0.2.0.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.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for multipart_response-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 90e73c1a2a28fed1aa1d7aedf0fef59255ed886bf060981ca8ddb79db4bad461
MD5 656cf1a9e9762a75ac5a80e443fb7ca6
BLAKE2b-256 d6ee2f449e14fa4e7bd2a9bc5ed567ae973ede3706abb485006a9ef51df8eed4

See more details on using hashes here.

Provenance

The following attestation bundles were made for multipart_response-0.2.0-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