Repository navigation
Req.mojo 0.2.0
Req is a synchronous HTTP client for Mojo. Version 0.2.0 adds HTTP/2,
file and multipart uploads, proxies, connection pool limits, and more ways to
stream responses and test HTTP integrations.
What's new
- Use opt-in HTTP/2 with connection reuse and overlapping response streams,
with HTTP/1.1 fallback enabled by default. - Upload files incrementally, send finite byte chunks, and combine multipart
files with ordinary form fields. - Route requests through HTTP/HTTPS proxies, including authenticated proxies,
or opt in to proxy and CA environment settings. - Limit physical connections and keepalive retention; configure capacity waits
withTimeout.pooland handlePoolTimeoutseparately. - Read response streams as decoded bytes, original encoded bytes, text, or lines.
- Add request/response hooks and supply mock or custom transports for tests.
- Inspect redirect history, the next prepared request, per-response cookies,
and elapsed time.
Install with Pixi
From a Pixi workspace configured for Mojo,
add the official Modular Community channel and install or upgrade Req:
pixi workspace channel add --prepend https://repo.prefix.dev/modular-community
pixi add "req==0.2.0"The community package
is awaiting publication. The version-pinned command becomes available once
0.2.0 is published to the channel. Until then, use the precompiled downloads
or source build below.
Req uses Mojo 1.1.0 on Linux x86-64, Linux ARM64, and macOS ARM64.
Pixi installs the matching compiler and native dependencies. The package includes
Req's precompiled module, CPU JSON modules, and native shared library; no C build
or extra linker flags are needed.
Send your first request
Save this as main.mojo in your workspace root:
import req
def main() raises:
var response = req.get("https://example.com")
response.raise_for_status()
print(response.status_code)
print(response.headers["Content-Type"])
print(response.text())Run it directly with pixi run mojo main.mojo, or compile and run it:
pixi run mojo build main.mojo -o main
pixi run ./mainHTTP/2, proxies, and pool limits
import req
def main() raises:
var owner = req.Client(
http2=True,
limits=req.Limits(max_connections=10, max_keepalive_connections=5),
timeout=req.Timeout(connect=3.0, read=10.0, write=10.0, pool=2.0),
)
with owner.context() as client:
var response = client.get("https://example.com")
response.raise_for_status()
print(response.http_version)HTTP/2 is opt-in and requires libcurl with HTTP/2 support; HTTP/1.1 fallback
remains enabled. HTTP/2-only mode (http1=False, http2=True) requires libcurl
8.10 or later. Add proxy="http://127.0.0.1:8080" for an explicit HTTP/HTTPS
proxy, or trust_env=True to read proxy/CA environment configuration.
Pool waits use Timeout.pool and raise PoolTimeout.
See HTTP/2 and
proxies.
File and multipart uploads
Send a file incrementally with
body=req.RequestBody.from_file("report.csv"), or combine multipart
files and ordinary fields:
import req
def main() raises:
var files = List[req.UploadFile]()
files.append(req.UploadFile.from_bytes(
"file", req.encode_utf8("hello\n"),
filename="hello.txt", content_type="text/plain",
))
var response = req.post(
"https://httpbin.org/post",
files=files,
data=req.QueryParams("tag=mojo&tag=http"),
)
response.raise_for_status()
print(response.status_code)Files and byte bodies are replayable. Finite RequestBody.from_chunks(...)
sources are one-shot by default; resending one after consumption raises
StreamConsumed. See uploads
for body combinations and redirect behavior.
Stream bytes, text, and lines
import req
def main() raises:
with req.stream("GET", "https://example.com") as response:
response.raise_for_status()
for line in response.iter_lines():
print(line)
print(response.elapsed())Use iter_bytes() for decoded bytes, iter_raw() for original content-encoded
bytes without HTTP transfer framing, and iter_text() for incremental text
decoding. Context exit closes partially consumed responses too.
See streaming.
Hooks, transports, and response metadata
- EventHooks run request and
response callbacks in order, including each followed redirect. - MockTransport and custom transports
let tests supply responses without a network server. response.historyretains closed intermediate responses.
response.next_requestexposes the next prepared request for an unfollowed
redirect.response.cookiesis a per-response snapshot.response.elapsed()reports seconds from sending until reading or closing
completes; accessing it earlier raisesStreamNotRead.
Defaults and upgrading from 0.1.0
Existing basic request calls keep their defaults: verified TLS, HTTP/1.1,
no followed redirects, and five seconds per timeout phase.
Timeout(seconds) and Timeout.disabled() now include the pool phase.
Environment routing remains off unless trust_env=True.
HTTP 4xx/5xx requires raise_for_status() to become an error.
Use a precompiled download
Release assets are provided for Linux x86-64, Linux ARM64, and
macOS ARM64, all built with Mojo 1.1.0. Download the archive matching
your machine and verify it against SHA256SUMS. Each archive includes
req.mojoc, the native transport, CPU JSON modules, licenses, and pinned
Pixi environment files.
Use an existing Mojo 1.1.0 environment with libcurl 7.85+ and zlib. Point Mojo's
-I option at the extracted directory and set REQ_NATIVE_LIB to the absolute
path of its libreq_curl.so (Linux) or libreq_curl.dylib (macOS).
See the archive instructions
for complete run and build commands.
Build from source
Source builds require Pixi, a C compiler, libcurl 7.85+ development headers
with TLS support, and zlib development headers. Install Command Line Tools
on macOS, or build-essential libcurl4-openssl-dev zlib1g-dev openssl on
Debian/Ubuntu, then:
git clone --branch v0.2.0 --depth 1 https://github.com/mojoto/req.mojo.git
cd req.mojo
pixi install
make buildSave the first example as main.mojo in the repository root and run
pixi run mojo -I . main.mojo. Req finds the native transport in build/.
Learn more
Clients remain single-threaded. There is no Async API, overall request deadline,
or configurable application retry policy. Keep one Client per worker and
consume or close responses before releasing its context.