pkg flare
flare: A foundational networking library for Mojoπ₯.
flare: A foundational networking library for Mojoπ₯.
Under development. APIs may change.
A foundational networking library for Mojoπ₯, from raw socket primitives up to HTTP/1.1 and WebSockets. Written entirely in Mojo with minimal FFI surface.
Principles
- Correctness above all: typed errors everywhere; no silent failures
- Security by default: TLS 1.2+, injection-safe parsing, DoS limits baked in
- Zero unnecessary C deps: only libc (always present) and OpenSSL for TLS
- Layered architecture: each layer imports only from layers below it
Layer Architecture
flare.io - BufReader (Readable trait)
|
flare.ws - WebSocket client (RFC 6455)
flare.http - HTTP/1.1 client + HeaderMap + URL
|
flare.tls - TLS 1.2/1.3 via OpenSSL FFI
|
flare.tcp - TcpStream + TcpListener
flare.udp - UdpSocket
|
flare.dns - getaddrinfo(3) FFI
|
flare.net - IpAddr, SocketAddr, RawSocket, errors
Quick Start: High-Level API
One-shot HTTP helpers
No client object needed for simple requests. post with a String body sets
Content-Type: application/json automatically, no format parameter needed:
from flare.http import get, post
def main() raises:
var resp = get("https://httpbin.org/get")
print(resp.status, resp.ok()) # 200 True
print(resp.text()[:80])
# String body sets Content-Type: application/json automatically
var r = post("https://httpbin.org/post", '{"hello": "flare"}')
r.raise_for_status()
print(r.json()["json"]["hello"].string_value())
HttpClient: base URL, authentication, JSON
HttpClient takes base URL and auth as positional arguments, the most
natural call-site syntax:
from flare.http import HttpClient, BasicAuth, BearerAuth, HttpError
def main() raises:
# Base URL as first positional arg, relative paths resolved automatically
var client = HttpClient("https://api.example.com")
client.post("/items", '{"name": "flare"}').raise_for_status()
# HTTP Basic authentication (RFC 7617), auth as first positional
var auth_client = HttpClient(BasicAuth("alice", "s3cr3t"))
auth_client.get("https://httpbin.org/basic-auth/alice/s3cr3t").raise_for_status()
# Base URL + Bearer token, both positional
with HttpClient("https://api.example.com", BearerAuth("tok_abc123")) as c:
c.post("/items", '{"name": "new"}').raise_for_status()
Context managers
All connection types implement __enter__ / __exit__ for automatic cleanup:
from flare.http import HttpClient
from flare.tcp import TcpStream
from flare.tls import TlsStream, TlsConfig
from flare.ws import WsClient
def main() raises:
with HttpClient() as c:
print(c.get("https://httpbin.org/get").status)
with TcpStream.connect("localhost", 9000) as stream:
_ = stream.write("hello\n".as_bytes())
with WsClient.connect("ws://echo.websocket.events") as ws:
ws.send_text("hello!")
print(ws.recv().text_payload())
WebSocket with WsMessage
recv_message() returns a typed WsMessage wrapper, no raw opcode checks:
from flare.ws import WsClient, WsMessage
def main() raises:
with WsClient.connect("ws://echo.websocket.events") as ws:
ws.send_text("hello, flare!")
var msg = ws.recv_message()
if msg.is_text:
print(msg.as_text())
Buffered I/O: BufReader
BufReader[S: Readable] wraps any readable stream for efficient line reads:
from flare.tls import TlsStream, TlsConfig
from flare.io import BufReader
def main() raises:
var stream = TlsStream.connect("example.com", 443, TlsConfig())
_ = stream.write(
"GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n"
.as_bytes()
)
var reader = BufReader[TlsStream](stream^, capacity=4096)
while True:
var line = reader.readline()
if line == "" or line == "\r\n":
break
print(line, end="")
Quick Start: Low-Level API
IP addresses and DNS
from flare.net import IpAddr, SocketAddr
from flare.dns import resolve_v4
def main() raises:
var ip = IpAddr.parse("192.168.1.100")
print(ip.is_private()) # True
var addr = SocketAddr.parse("127.0.0.1:8080")
print(addr.port) # 8080
var addrs = resolve_v4("example.com")
print(addrs[0]) # 93.184.216.34
TCP
from flare.tcp import TcpStream
def main() raises:
var conn = TcpStream.connect("localhost", 8080)
_ = conn.write("Hello\n".as_bytes())
var buf = List[UInt8](capacity=4096)
buf.resize(4096, 0)
var n = conn.read(buf.unsafe_ptr(), len(buf))
conn.close()
TLS
from flare.tls import TlsStream, TlsConfig
def main() raises:
# TLS 1.2/1.3, cert verified against pixi CA bundle by default
var tls = TlsStream.connect("example.com", 443, TlsConfig())
_ = tls.write("GET / HTTP/1.0\r\nHost: example.com\r\n\r\n".as_bytes())
tls.close()
# Skip cert verification (testing only)
var insecure = TlsStream.connect("localhost", 8443, TlsConfig.insecure())
HTTP/1.1: response details
from flare.http import HttpClient, Status, Url
def main() raises:
var client = HttpClient()
var resp = client.get("http://httpbin.org/get")
if resp.status == Status.OK:
print(resp.text()[:80])
var ct = resp.headers.get("content-type") # case-insensitive lookup
var u = Url.parse("https://api.example.com:8443/v1/users?page=2")
print(u.host, u.port, u.path)
WebSocket: raw frame API
from flare.ws import WsClient, WsFrame
def main() raises:
var ws = WsClient.connect("ws://echo.websocket.events")
ws.send_text("Hello, flare WebSocket!")
var frame = ws.recv()
print(frame.text_payload())
ws.close()
flare.net
An IP address: either IPv4 or IPv6.
from .net.addressA socket address: an IP address combined with a port number.
from .net.addressA thin, owning wrapper around a POSIX socket file descriptor.
from .net.socketGeneric network error β a catch-all for OS errors without a more specific typed variant.
from .net.errorRaised when a TCP ``connect()`` fails with ``ECONNREFUSED``.
from .net.errorRaised when a TCP ``connect()`` times out (``ETIMEDOUT``).
from .net.errorRaised when the peer forcibly closes a connection (``ECONNRESET``).
from .net.errorRaised when ``bind()`` fails because the port is in use (``EADDRINUSE``).
from .net.errorRaised when an address string cannot be parsed.
from .net.errorRaised on write to a connection whose read end is closed (``EPIPE``).
from .net.errorRaised when DNS resolution fails.
from .net.errorRaised when a blocking I/O operation exceeds its timeout.
from .net.errorflare.dns
flare.tcp
flare.udp
flare.tls
Configuration for a TLS connection.
from .tls.configPeer certificate verification mode constants.
from .tls.configAn encrypted TCP stream using TLS (via OpenSSL FFI).
from .tls.streamThe TLS handshake failed (generic failure not covered by cert errors).
from .tls.errorThe server certificate has passed its ``notAfter`` date.
from .tls.errorThe server certificate's CN/SAN does not match the target hostname.
from .tls.errorThe server certificate is not trusted by any CA in the bundle.
from .tls.errorflare.http
An ordered, case-insensitive HTTP header collection.
from .http.headersRaised when a header key or value contains CR or LF bytes.
from .http.headersA parsed HTTP/HTTPS URL.
from .http.urlRaised when a URL string cannot be parsed.
from .http.urlAn HTTP/1.1 request.
from .http.requestHTTP request method string constants (RFC 7231 Β§4).
from .http.requestAn HTTP/1.1 response.
from .http.responseCommon HTTP status code constants (RFC 7231 Β§6).
from .http.responseHTTP ``Content-Encoding`` / ``Accept-Encoding`` token constants.
from .http.encodingRaised by ``Response.raise_for_status()`` on non-2xx responses.
from .http.errorRaised when a redirect chain exceeds the configured maximum.
from .http.errorHTTP Basic authentication (RFC 7617).
from .http.authHTTP Bearer token authentication (RFC 6750).
from .http.authA blocking HTTP/1.1 client.
from .http.clientPerform a one-shot HTTP GET request.
from .http.clientPerform a one-shot HTTP POST with a JSON string body.
from .http.clientPerform a one-shot HTTP PUT with a JSON string body.
from .http.clientPerform a one-shot HTTP DELETE request.
from .http.clientPerform a one-shot HTTP HEAD request.
from .http.clientA blocking HTTP/1.1 server that calls a handler for each request.
from .http.serverflare.ws
A single WebSocket frame.
from .ws.frameWebSocket opcode byte constants (RFC 6455 Β§5.2).
from .ws.frameWebSocket close status code constants (RFC 6455 Β§7.4.1).
from .ws.frameRaised when an incoming frame violates RFC 6455.
from .ws.frameA WebSocket client connection established via HTTP Upgrade.
from .ws.clientRaised when the WebSocket opening handshake fails.
from .ws.clientA high-level WebSocket message (Text or Binary).
from .ws.clientA WebSocket server that upgrades incoming HTTP connections.
from .ws.server