{"id":13424688,"url":"https://github.com/florimondmanca/msgpack-asgi","last_synced_at":"2025-04-05T21:07:47.070Z","repository":{"id":46803396,"uuid":"219042240","full_name":"florimondmanca/msgpack-asgi","owner":"florimondmanca","description":"Drop-in MessagePack support for ASGI applications and frameworks","archived":false,"fork":false,"pushed_at":"2024-03-20T16:17:33.000Z","size":79,"stargazers_count":165,"open_issues_count":4,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T20:08:32.242Z","etag":null,"topics":["asgi","fastapi","json","messagepack","middleware","msgpack","python","starlette"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/msgpack-asgi","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/florimondmanca.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-01T18:36:11.000Z","updated_at":"2025-01-27T20:29:12.000Z","dependencies_parsed_at":"2024-06-11T19:09:30.826Z","dependency_job_id":"c596fd57-c0a9-426e-aba1-5f2508e24a96","html_url":"https://github.com/florimondmanca/msgpack-asgi","commit_stats":{"total_commits":47,"total_committers":4,"mean_commits":11.75,"dds":"0.12765957446808507","last_synced_commit":"6261b1e22b3689551f68038ee00adda5fbc04670"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florimondmanca%2Fmsgpack-asgi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florimondmanca%2Fmsgpack-asgi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florimondmanca%2Fmsgpack-asgi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florimondmanca%2Fmsgpack-asgi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/florimondmanca","download_url":"https://codeload.github.com/florimondmanca/msgpack-asgi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399877,"owners_count":20932876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asgi","fastapi","json","messagepack","middleware","msgpack","python","starlette"],"created_at":"2024-07-31T00:00:57.873Z","updated_at":"2025-04-05T21:07:47.044Z","avatar_url":"https://github.com/florimondmanca.png","language":"Python","readme":"# msgpack-asgi\n\n[![Build Status](https://dev.azure.com/florimondmanca/public/_apis/build/status/florimondmanca.msgpack-asgi?branchName=master)](https://dev.azure.com/florimondmanca/public/_build/latest?definitionId=5\u0026branchName=master)\n[![Coverage](https://codecov.io/gh/florimondmanca/msgpack-asgi/branch/master/graph/badge.svg)](https://codecov.io/gh/florimondmanca/msgpack-asgi)\n[![Package version](https://badge.fury.io/py/msgpack-asgi.svg)](https://pypi.org/project/msgpack-asgi)\n\n`msgpack-asgi` allows you to add automatic [MessagePack](https://msgpack.org/) content negotiation to ASGI applications (Starlette, FastAPI, Quart, etc.), with a single line of code:\n\n```python\napp.add_middleware(MessagePackMiddleware)\n```\n\n_(You may want to adapt this snippet to your framework-specific middleware API.)_\n\nThis gives you the bandwitdth usage reduction benefits of MessagePack without having to change existing code.\n\n**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](#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.\n\n## Installation\n\nInstall with pip:\n\n```bash\npip install \"msgpack-asgi==1.*\"\n```\n\n## Quickstart\n\nFirst, you'll need an ASGI application. Let's use this sample application, which exposes an endpoint that returns JSON data:\n\n```python\n# For convenience, we use some ASGI components from Starlette.\n# Install with: `$ pip install starlette`.\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\n\n\nasync def get_response(request):\n    if request.method == \"POST\":\n        data = await request.json()\n        return JSONResponse({\"data\": data}, status_code=201)\n    else:\n        return JSONResponse({\"message\": \"Hello, msgpack!\"})\n\n\nasync def app(scope, receive, send):\n    assert scope[\"type\"] == \"http\"\n    request = Request(scope=scope, receive=receive)\n    response = await get_response(request)\n    await response(scope, receive, send)\n```\n\nThen, wrap your application around `MessagePackMiddleware`:\n\n```python\nfrom msgpack_asgi import MessagePackMiddleware\n\napp = MessagePackMiddleware(app)\n```\n\nServe your application using an ASGI server, for example with [Uvicorn](https://www.uvicorn.org):\n\n```bash\nuvicorn app:app\n```\n\nNow, let's make a request that accepts MessagePack data in response:\n\n```bash\ncurl -i http://localhost:8000 -H \"Accept: application/x-msgpack\"\n```\n\nYou should get the following output:\n\n```http\nHTTP/1.1 200 OK\ndate: Fri, 01 Nov 2019 17:40:14 GMT\nserver: uvicorn\ncontent-length: 25\ncontent-type: application/x-msgpack\n\n��message�Hello, msgpack!\n```\n\nWhat 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.\n\nWe can make sure the response contains valid MessagePack data by making the request again in Python, and decoding the response content:\n\n```python\n\u003e\u003e\u003e import requests\n\u003e\u003e\u003e import msgpack\n\u003e\u003e\u003e url = \"http://localhost:8000\"\n\u003e\u003e\u003e headers = {\"accept\": \"application/x-msgpack\"}\n\u003e\u003e\u003e r = requests.get(url, headers=headers)\n\u003e\u003e\u003e r.content\nb'\\x81\\xa7message\\xafHello, msgpack!'\n\u003e\u003e\u003e msgpack.unpackb(r.content, raw=False)\n{'message': 'Hello, msgpack!'}\n```\n\n`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:\n\n```python\n\u003e\u003e\u003e import requests\n\u003e\u003e\u003e import msgpack\n\u003e\u003e\u003e url = \"http://localhost:8000\"\n\u003e\u003e\u003e data = msgpack.packb({\"message\": \"Hi, there!\"})\n\u003e\u003e\u003e headers = {\"content-type\": \"application/x-msgpack\"}\n\u003e\u003e\u003e r = requests.post(url, data=data, headers=headers)\n\u003e\u003e\u003e r.json()\n{'data': {'message': 'Hi, there!'}}\n```\n\nThat's all there is to it! You can now go reduce the size of your payloads.\n\n## Advanced usage\n\n### Custom implementations\n\n`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.\n\nTo do so, use the following arguments:\n\n* `packb` - _(Optional, type: `(obj: Any) -\u003e bytes`, default: `msgpack.packb`)_ - Used to encode outgoing data.\n* `unpackb` - _(Optional, type: `(data: bytes) -\u003e Any`, default: `msgpack.unpackb`)_ - Used to decode incoming data.\n\nFor example, to use the [`ormsgpack`](https://pypi.org/project/ormsgpack/) library for encoding:\n\n```python\nimport ormsgpack  # Installed separately.\nfrom msgpack_asgi import MessagePackMiddleware\n\ndef packb(obj):\n    option = ...  # See `ormsgpack` options.\n    return ormsgpack.packb(obj, option=option)\n\napp = MessagePackMiddleware(..., packb=packb)\n```\n\n## Limitations\n\n`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.\n\n## How it works\n\n![](https://github.com/florimondmanca/msgpack-asgi/blob/master/img/msgpack-asgi.png)\n\nAn ASGI application wrapped around `MessagePackMiddleware` will perform automatic content negotiation based on the client's capabilities. More precisely:\n\n- If the client sends MessagePack-encoded data with the `application/x-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.)\n- If the client sent the `Accept: application/x-msgpack` header, `msgpack-asgi` will automatically re-encode any JSON response data to MessagePack for the client to consume.\n\n(In other cases, `msgpack-asgi` won't intervene at all.)\n\n## License\n\nMIT\n","funding_links":[],"categories":["Third-Party Extensions","Serialization"],"sub_categories":["Developer Tools","Tutorials"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflorimondmanca%2Fmsgpack-asgi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflorimondmanca%2Fmsgpack-asgi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflorimondmanca%2Fmsgpack-asgi/lists"}