ViperHTTP IPC Bridge (MicroPython)
This bridge connects Core 0 (C server) with Core 1 (MicroPython) using the IPC queues. It polls incoming requests, dispatches them via the ViperHTTP app, serializes responses, and sends them back through IPC.
For normal applications, you do not need to import this module directly.
app.run(...) starts bridge runtime automatically.
Optional Manual Example
import viperhttp
import viperhttp_bridge
app = viperhttp.ViperHTTP()
@app.get("/hello")
def hello():
return {"msg": "ok"}
@app.get("/plain")
def plain():
return "hello"
viperhttp_bridge.run(app, port=8080, wifi=False)
Wi-Fi + app.run()
app.run() uses the bridge and starts the C server automatically, but it does not connect to Wi-Fi.
Connect first, then run:
import network
import viperhttp
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("SSID", "PASSWORD")
while not wlan.isconnected():
pass
app = viperhttp.ViperHTTP()
@app.get("/hello")
def hello():
return {"message": "ok"}
app.run(port=8080, wifi=False)
IPC Request Payload Layout
The request IPC message carries offsets and lengths for a contiguous blob in the ring buffer:
buffer_offset: start of the bloburi_len: length of the raw URI (path + optional?query)query_len: length of the query string (no leading?)headers_len: length of the headers blobheaders_offset: start of the headers blobbody_len: length of the raw body
Blob layout:
[URI][HEADERS][BODY]
Headers blob encoding:
name\0value\0name\0value\0...
IPC Response Payload Layout
Responses use the same ring buffer for headers and body:
headers_len+headers_offset: header blob (Name: value\r\nlines).body_len+buffer_offset: response body bytes.total_len: total body length for streamed responses (Content-Length).flags:VHTTP_IPC_FLAG_STREAM+VHTTP_IPC_FLAG_FINALmark streaming chunks.
Streaming behavior:
- The first response for a request includes headers and total_len.
- Subsequent chunks include only body_len and buffer_offset.
- The final chunk sets VHTTP_IPC_FLAG_FINAL.
Notes
serialize_response()converts dict/list to JSON usingujson.- Body sent over IPC must be
str,bytes, orbytearray. - This bridge is intentionally minimal and will evolve alongside IPC.
viperhttp.poll_request()now includes arequestobject with headers, query params, and body bytes.- The bridge passes
requestintoapp.dispatch(method, path, request)and exposes it viaviperhttp.current_request(). - Query params are parsed from the URL and passed to handlers as kwargs.
- Typed query params are supported via
Query()andquery={...}in decorators. - Query strings are not URL-decoded.
- Async handlers and async middleware are awaited in the bridge loop.
- Async stream responses are supported (
async forbody chunks over IPC stream frames). - Bridge worker tuning is available in
viperhttp_bridge.run(...): bridge_min_workers,bridge_max_workers,bridge_queue_sizebridge_autoscale(optional; defaults toTruewhenbridge_max_workers > bridge_min_workers)bridge_enqueue_wait_ms(bounded wait when queue is full before returning overload)bridge_worker_yield_every(worker cooperative-yield cadence for better throughput/fairness balance)bridge_scale_up_max_burst(max workers spawned in one scale-up cycle)min_workers,max_workers(C runtime worker limits API)- Bridge dispatcher behavior:
- If
bridge_min_workers == bridge_max_workers, bridge workers stay fixed. - If
bridge_min_workers < bridge_max_workers, bridge can scale up under queue pressure and scale back tobridge_min_workersafter idle periods. - Queue size is clamped to at least
bridge_max_workers. - Background tasks are lazy-allocated in the bridge hot path, so requests that do not use
background_tasks.add_task(...)avoid unnecessary object allocation overhead. - Under load, the C event-loop runtime may defer request queue push and retry asynchronously
before returning
503 Queue Full(reduces burst-time drops without blocking the event-loop).
Startup Hook (ESP32S3_N16R8)
For the custom board build, a frozen main.py is included. It attempts to import
viperhttp_app and start the bridge automatically if an app object is present.
Create viperhttp_app.py on the device with: