Skip to main content

msgpack-asgi

Build Status Coverage Package version

msgpack-asgi allows you to add automatic MessagePack content negotiation to ASGI applications (Starlette, FastAPI, Quart, etc.), with a single line of code:

app.add_middleware(MessagePackMiddleware)

(Adapt this snippet to your framework-specific middleware API.)

This gives you the bandwitdth usage reduction benefits of MessagePack without having to change existing code.

Note: this comes at a CPU usage cost, since MessagePackMiddleware will perform MsgPack decoding while your application continues to decode and encode JSON data (see also How it works). If your use case is CPU-sensitive, rather than strictly focused on reducing network bandwidth, this package may not be for you.

Installation

Install with pip:

pip install "msgpack-asgi==3.*"

Be sure to pin to the latest major version, as above. Breaking changes may occur across major versions. If so, details on migration steps will be provided in CHANGELOG.md.

Quickstart

First, you'll need an ASGI application. Let's use this sample application, which exposes an endpoint that returns JSON data:

# For convenience, we use some ASGI components from Starlette.
# Install with: `$ pip install starlette`.
from starlette.requests import Request
from starlette.responses import JSONResponse


async def get_response(request):
    if request.method == "POST":
        data = await request.json()
        return JSONResponse({"data": data}, status_code=201)
    else:
        return JSONResponse({"message": "Hello, msgpack!"})


async def app(scope, receive, send):
    assert scope["type"] == "http"
    request = Request(scope=scope, receive=receive)
    response = await get_response(request)
    await response(scope, receive, send)

Then, wrap your application around MessagePackMiddleware:

from msgpack_asgi import MessagePackMiddleware

app = MessagePackMiddleware(app)

Serve your application using an ASGI server, for example with Uvicorn:

uvicorn app:app

Now, let's make a request that accepts MessagePack data in response:

curl -i http://localhost:8000 -H "Accept: application/vnd.msgpack"

You should get the following output:

HTTP/1.1 200 OK
date: Fri, 01 Nov 2019 17:40:14 GMT
server: uvicorn
content-length: 25
content-type: application/vnd.msgpack

��message�Hello, msgpack!

What happened? Since we told the application that we accepted MessagePack-encoded responses, msgpack-asgi automatically converted the JSON data returned by the Starlette application to MessagePack.

We can make sure the response contains valid MessagePack data by making the request again in Python, and decoding the response content:

>>> import requests
>>> import msgpack
>>> url = "http://localhost:8000"
>>> headers = {"accept": "application/vnd.msgpack"}
>>> r = requests.get(url, headers=headers)
>>> r.content
b'\x81\xa7message\xafHello, msgpack!'
>>> msgpack.unpackb(r.content, raw=False)
{'message': 'Hello, msgpack!'}

msgpack-asgi also works in reverse: it will automatically decode MessagePack-encoded data sent by the client to JSON. We can try this out by making a POST request to our sample application with a MessagePack-encoded body:

>>> import requests
>>> import msgpack
>>> url = "http://localhost:8000"
>>> data = msgpack.packb({"message": "Hi, there!"})
>>> headers = {"content-type": "application/vnd.msgpack"}
>>> r = requests.post(url, data=data, headers=headers)
>>> r.json()
{'data': {'message': 'Hi, there!'}}

That's all there is to it! You can now go reduce the size of your payloads.

Advanced usage

Custom implementations

msgpack-asgi supports customizing the default encoding/decoding implementation. This is useful for fine-tuning application performance via an alternative msgpack implementation for encoding, decoding, or both.

To do so, use the following arguments:

  • packb - (Optional, type: (obj: Any) -> bytes, default: msgpack.packb) - Used to encode outgoing data.
  • unpackb - (Optional, type: (data: bytes) -> Any, default: msgpack.unpackb) - Used to decode incoming data.

For example, to use the ormsgpack library for encoding:

import ormsgpack  # Installed separately.
from msgpack_asgi import MessagePackMiddleware

def packb(obj):
    option = ...  # See `ormsgpack` options.
    return ormsgpack.packb(obj, option=option)

app = MessagePackMiddleware(..., packb=packb)

Limitations

msgpack-asgi does not support request or response streaming. This is because the full request and response body content has to be loaded in memory before it can be re-encoded.

How it works

An ASGI application wrapped around MessagePackMiddleware will perform automatic content negotiation based on the client's capabilities. More precisely:

  • If the client sends MessagePack-encoded data with the application/vnd.msgpack content type, msgpack-asgi will automatically re-encode the body to JSON and re-write the request Content-Type to application/json for your application to consume. (Note: this means applications will not be able to distinguish between MessagePack and JSON client requests.)
  • If the client sent the Accept: application/vnd.msgpack header, msgpack-asgi will automatically re-encode any JSON response data to MessagePack for the client to consume.

(In other cases, msgpack-asgi won't intervene at all. NOTE: the content type to look for can be customized -- see API Reference below.)

API Referece

MessagePackMiddleware

Signature:

MessagePackMiddleware(
    app,
    *,
    packb=msgpack.packb,
    unpackb=msgpack.packb,
    content_type="application/vnd.msgpack"
)

Parameters described:

  • app: an ASGI app to add msgpack support to
  • packb - callable (Optional, Added in 1.1.0): msgpack encoding function. Defaults to msgpack.packb.
  • unpackb - callable (Optional, Added in 1.1.0): msgpack decoding function. Defaults to msgpack.unpackb.
  • content_type - str (Optional, Added in 2.0.0): the content type (a.k.a MIME type) to use for detecting incoming msgpack requests or sending msgpack responses. Defaults to the IANA-registered application/vnd.msgpack MIME type. Use this option when working with older systems that send or expect e.g. application/x-msgpack.

License

MIT

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog.

3.0.0 - 2026-02-03

Removed

  • Drop official support for Python 3.9 as it has reached EOL. (Pull #35)

Added

  • Add official support for Python 3.14. (Pull #35)
  • Add naive buffered request and response streaming, opt-in via allow_naive_streaming=True. (Pull #33, #34)

Fixed

  • Fix handling of non-http.request ASGI messages when receiving the request (including http.disconnect). They are now passed through instead of raising an error. (Pull #33)

2.0.0 - 2025-07-05

This release includes a potentially breaking change and updates the compatible Python versions.

Changed

  • (BREAKING) Use the IANA-registered application/vnd.msgpack MIME type, instead of application/x-msgpack previously.
    • This impacts both the detection of msgpack-acceptable requests, as well as the MIME type used for encoding responses.
    • To continue using application/x-msgpack or to use any other MIME type suitable for your needs, use the new content_type argument on MessagePackMiddleware. (Pull #30)

Removed

  • Drop official support for Python 3.6, 3.7 and 3.8 which have reached EOL. (It is likely this version remains compatible in practice, but no further maintenance will be provided for these Python versions.) (Pull #29)

Added

  • Add official support for Python 3.9 through 3.13. (Pull #29)

1.1.0 - 2021-10-26

Added

  • Support custom encoding/decoding implementation via the packb=... and unpackb=... optional parameters, allowing the use of alternative msgpack libraries. (Pull #20)

Fixed

  • Properly re-write request Content-Type to application/json. (Pull #24)

1.0.0 - 2020-03-26

First production/stable release.

Changed

  • Switch to private module naming. Components should now be imported from the root package, e.g. from msgpack_asgi import MessagePackMiddleware. (Pull #5)

Fixed

  • Add missing MANIFEST.in. (Pull #4)

0.1.0 - 2019-11-04

Initial release.

Added

  • Add the MessagePackMiddleware ASGI middleware.
  • Add the MessagePackResponse ASGI response class.

Metadata

Release files for msgpack-asgi 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for msgpack-asgi 3.0.0
File Size Uploaded Provenance
msgpack_asgi-3.0.0.tar.gz 26.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for msgpack-asgi 3.0.0
File Interpreter ABI Platform
msgpack_asgi-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.7 kB

Release files / msgpack_asgi-3.0.0.tar.gz

Download URL msgpack_asgi-3.0.0.tar.gz
Size 26.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d7c89a1491883730b999f1ad70453f5ebf51663561f80aa90cfb7aa438440b7b
BLAKE2b-256 checksum
How to use checksums
2eb72a94926667cb5a07d6034c236b181279063496778e1e8235fcb596dea345
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / msgpack_asgi-3.0.0-py3-none-any.whl

Download URL msgpack_asgi-3.0.0-py3-none-any.whl
Size 8.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c5900e237695cd1508d5641fb2c16828d6a3f5d3abfb77375e4ba0715b0a74c1
BLAKE2b-256 checksum
How to use checksums
155245483b67fdb583fae3061ca97353ce4de118ab39d3c9db59ae3d1ef7f3d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Security for msgpack-asgi 3.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page