Skip to content

chumicro-requests

Non-blocking HTTP/1.1 client for CircuitPython, MicroPython, and CPython.

An LED keeps blinking on the same board while a request is in flight, in a TLS handshake, or mid-timeout against a stalled peer. Built on chumicro-sockets and chumicro-timing.

Install

# CircuitPython (after `circup bundle-add ChuMicro/ChuMicro-Bundle`)
circup install chumicro_requests

# MicroPython
mpremote mip install github:ChuMicro/ChuMicro-Bundle/chumicro_requests

# CPython
pip install chumicro-requests

No board running yet? Start here goes from a new board to your own code running on it. Installing libraries covers registering the bundle, the experimental channel, and the pre-compiled .mpy packages.

Quick example

from chumicro_requests import HttpClient
from chumicro_sockets.sockets_factory import connector_factory
from chumicro_timing import ticks_ms
from chumicro_wifi import WifiConfig, WifiService

wifi = WifiService(WifiConfig(ssid="home-wifi", password="s3cret"))
client = HttpClient(transport_factory=connector_factory(radio=wifi.adapter.radio))
handle = client.get("http://api.example.com/now", timeout_ms=5000)

while not handle.done:
    now = ticks_ms()
    if client.check(now):
        client.handle(now)

response = handle.result   # raises HttpError on failure
print(response.status_code, response.headers["content-type"])
print(response.text)       # decoded str (charset sniffed from Content-Type)
print(response.json())     # parsed JSON when Content-Type is application/json

wifi.adapter.radio is the board radio on CircuitPython and None on MicroPython and CPython, where the connector needs no radio. Bringing your own socket instead of chumicro-sockets works too: transport_factory takes any (host, port, use_tls) callable.

On the runner, the same fetch is a generator that runs top to bottom while other services keep the CPU between yields:

from chumicro_requests.generators import get
from chumicro_runner import Runner


def fetch_once():
    response = yield from get(
        connector_factory(radio=wifi.adapter.radio),
        "http://api.example.com/now",
    )
    print(response.status_code, response.text)


runner = Runner()
handle = runner.add_generator(fetch_once())
while not handle.done:
    now = runner.tick()
    runner.wait(now)

Documentation

  • User Guide: generator flows and the HttpClient service, the POST / PUT / PATCH / DELETE verbs, redirects, body framing and decoding, streaming large bodies, bringing your own transport
  • API Reference: HttpClient, RequestHandle, and Response, plus the yield from generator helpers
  • Testing Helpers: using FakeHttpClient in your tests