mm-web
MetaMessage protocol integrations for Python web frameworks — framework adapters for FastAPI, Flask, and Django, plus a framework-agnostic HTTP client SDK.
Install from PyPI.
The wheel ships all adapter code — you only need to install the web framework itself as a runtime dependency. Use extras for a one-command install, or install them separately:
# --- pip ---
pip install "mm-web[fastapi]" # mm-web + FastAPI (一条命令)
pip install "mm-web[flask]" # mm-web + Flask
pip install "mm-web[django]" # mm-web + Django
pip install "mm-web[dev]" # mm-web + 全部框架 + 开发工具
# pip 两条命令(wheel 已包含适配器代码,仅缺框架运行时):
pip install mm-web
pip install fastapi # 或 flask / django
# --- uv ---
uv add "mm-web[fastapi]" # mm-web + FastAPI (一条命令)
uv add "mm-web[flask]"
uv add "mm-web[django]"
# uv 两条命令:
uv add mm-web
uv add fastapi # 或 flask / django
What is MetaMessage?
MetaMessage is a binary serialization protocol that provides efficient encoding/decoding of structured data. It follows the convention:
- GET/DELETE requests: Parameters are hex-encoded as
?data=<hex>query parameter - POST/PUT/PATCH requests: Body is binary MetaMessage
- Responses: Always binary MetaMessage
Packages
mm-core
Shared framework-agnostic code:
CONTENT_TYPE_METAMESSAGE- Content type constant (application/metamessage)MMEncoderError/MMDecoderError- Encoding/decoding error classesMMClient/AsyncMMClient- Synchronous and asynchronous HTTP clients
mm-fastapi
from fastapi import FastAPI
from mm_fastapi import MMRouter
app = FastAPI()
router = MMRouter(app)
@router.get("/users")
async def list_users(req: User) -> User:
return User(name=req.name, age=req.age)
@router.post("/users")
async def create_user(req: User) -> User:
return User(name=req.name, age=req.age)
mm-flask
from flask import Flask
from mm_flask import MMFlask, MMMiddleware
app = Flask(__name__)
MMMiddleware(app)
mm = MMFlask(app)
@mm.get("/users")
def list_users(req: User) -> User:
return User(name=req.name, age=req.age)
@mm.post("/users")
def create_user(req: User) -> User:
return User(name=req.name, age=req.age)
mm-django
from django.http import HttpResponse
from mm_django import mm_view
@mm_view()
def create_user(request, req: User) -> User:
return User(name=req.name, age=req.age)
Schema discovery & validation
Every route automatically exposes an OPTIONS endpoint that returns the request
schema encoded as binary MetaMessage, along with two headers:
Access-Control-Max-Age: 86400Schema-Md5: <md5 of the example-encoded schema>
The mm_core.MMClient uses these: it sends an OPTIONS preflight, caches the
Schema-Md5, and sends it back on each request. The server validates the incoming
Schema-Md5 header and rejects mismatches with a {"error": "Schema-Md5 mismatch: ..."}
response, so clients can detect an out-of-date schema before sending data.
Quick start (end-to-end)
A complete, runnable walkthrough lives in
examples/mm-fastapi/run.py. It spins up the FastAPI
app in-process and exercises health, OPTIONS schema discovery, GET query
encoding, POST/PUT/DELETE body encoding, and Schema-Md5 validation:
cd examples/mm-fastapi
python run.py
You can also run a real server + client (in two terminals):
# terminal 1
cd examples/mm-fastapi
python server_example.py
# terminal 2
cd examples/mm-fastapi
python client_example.py
Testing
pip install "mm-web[dev]"
pytest tests/ -v
Project Structure
src/
├── mm_core/ # Shared types, errors, client SDK
├── mm_fastapi/ # FastAPI integration
├── mm_flask/ # Flask integration
└── mm_django/ # Django integration
tests/
├── test_mm_django.py
├── test_mm_fastapi.py
└── test_mm_flask.py
examples/
├── mm-fastapi/ # FastAPI examples (server_example, client_example, run.py)
├── mm-flask/ # Flask examples
└── mm_django/ # Django examples
License
MIT License
Release files for mm-web 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mm_web-0.1.1.tar.gz | 100.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mm_web-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 133.7 kB
Release files / mm_web-0.1.1.tar.gz
| Download URL | mm_web-0.1.1.tar.gz |
|---|---|
| Size | 100.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
efdb38efbf8f347a8b294f1a6d643f652c7c0efa6b47b1994c87a65188055af5
|
|
BLAKE2b-256 checksum How to use checksums |
cf5984d96b26c44c470593fc30a36a41e0b71fbe4abdde0079973bd327b83667
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Release files / mm_web-0.1.1-py3-none-any.whl
| Download URL | mm_web-0.1.1-py3-none-any.whl |
|---|---|
| Size | 33.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
55d17212275cc61b3e93e4aa120876549e33459fca987c8140be598185ecf995
|
|
BLAKE2b-256 checksum How to use checksums |
35b323fa877d3ab2892b9581c7fa8889aa53b304369dfaf32dd11fd89d10af2e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|