flare_mlake · API · grpc

flare.grpc.client

The gRPC unary client over the HTTP/2 HttpClient path.

Composes on the existing :class:flare.http.HttpClient HTTP/2 surface rather than introducing a new transport: a unary call is one POST whose body is the length-prefix-message (LPM) request frame and whose response body is the LPM reply frame, with grpc-status / grpc-message read from the response header set. The flare H2 client appends trailing HEADERS into the same header list as the initial response HEADERS, so a real gRPC server's status trailer is read transparently here.

Scope: unary (one request frame, one reply frame). Server-streaming, client-streaming, and bidi are future phases on the same H2 stream machinery; this module ships the unary path so the common request/reply RPC works end to end today.

from flare.grpc import GrpcClient

var ch = GrpcClient("http://127.0.0.1:50051")  # h2c cleartext
var reply = ch.call("/echo.EchoService/Echo", "hello".as_bytes())
if reply.is_ok():
    print(len(reply.message), "bytes back")

Structs

GrpcCallResult

struct GrpcCallResult

The outcome of a unary call.

Fields: status: the RPC :class:GrpcStatus (code + message), read from grpc-status / grpc-message in the response headers. message: the LPM-unwrapped reply payload bytes (empty on a non-OK status or a trailers-only response). http_status: the HTTP/2 :status (200 for a well-formed gRPC response regardless of the RPC status code). headers: the full response header set (initial HEADERS + merged trailing HEADERS), for reading response metadata.

Implements Movable

Fields
status: GrpcStatus
message: List[UInt8]
http_status: Int
headers: HeaderMap

is_ok

def is_ok(self) -> Bool

True iff the RPC status code is OK (0).

GrpcClient

struct GrpcClient

A blocking gRPC unary client over HTTP/2.

Wraps an :class:HttpClient configured for HTTP/2: cleartext h2c via prior knowledge (cleartext=True, the default, for an http:// base) or HTTP/2 over TLS via ALPN (cleartext=False for an https:// base). Response auto-decompression is disabled because gRPC carries its own grpc-encoding independent of HTTP Content-Encoding.

Implements Movable

__init__

def __init__(out self, base_url: String, *, cleartext: Bool = True)

Create a channel to base_url (origin only, e.g. http://host:port). cleartext selects h2c prior knowledge vs HTTP/2 over TLS.

__enter__

def __enter__(var self) -> Self

call

def call(self, service_method: String, request: Span[UInt8], metadata: GrpcMetadata = GrpcMetadata(), timeout_ms: Int = Int(0)) -> GrpcCallResult

Invoke a unary RPC.

Args
service_method: The fully-qualified method path (/package.Service/Method); a leading / is added if missing.
request: The serialised request message bytes (LPM-wrapped here; the caller passes raw protobuf / codec bytes).
metadata: Optional initial metadata. Text entries become request headers verbatim; binary -bin entries are base64-encoded onto their -bin header per the gRPC wire format.
timeout_ms: Optional call deadline in milliseconds. When > 0 it is emitted as the grpc-timeout header (<n>m millisecond form) so a deadline-aware server can abort the RPC and reply DEADLINE_EXCEEDED.

Raises NetworkError: on transport failure (connection / H2 error).

call_server_streaming

def call_server_streaming(self, service_method: String, request: Span[UInt8], metadata: GrpcMetadata = GrpcMetadata()) -> GrpcServerStream

Open a server-streaming RPC: send one request message, then receive N reply messages.

The returned :class:GrpcServerStream yields reply payloads one at a time via recv() (None at end of stream) as the server's DATA frames arrive -- only one message plus the partial-frame reassembly buffer are ever held in memory. Read the final grpc-status with status() after recv() returns None.

Args
service_method: /package.Service/Method (leading / added if missing).
request: The single request message bytes (LPM-framed here).
metadata: Optional initial metadata (text entries only).

call_client_streaming

def call_client_streaming(self, service_method: String, metadata: GrpcMetadata = GrpcMetadata()) -> GrpcBidiStream

Open a client-streaming RPC: the request stream stays OPEN so the caller pumps request messages with send() then half-closes with close_send(), after which recv() drains the (typically single) reply message and status() the final status.

Implemented on the same OPEN-stream machinery as :meth:call_bidi (a client-streaming RPC is a bidi RPC the server answers only after the request half-closes).

call_bidi

def call_bidi(self, service_method: String, metadata: GrpcMetadata = GrpcMetadata()) -> GrpcBidiStream

Open a bidirectional-streaming RPC. The returned :class:GrpcBidiStream keeps the request side OPEN: pump request messages with send(), half-close with close_send(), and drain replies with recv() (then status()).

Args
service_method: /package.Service/Method (leading / added if missing).
metadata: Optional initial metadata (text entries only).