HTTP Transport¶
HTTP transport using Falcon (server) and httpx (client). Requires pip install vgi-rpc[http].
Quick Start¶
Server¶
Create a WSGI app and serve it with any WSGI server (waitress, gunicorn, etc.):
from vgi_rpc import RpcServer, make_wsgi_app
server = RpcServer(MyService, MyServiceImpl())
app = make_wsgi_app(server)
# serve `app` with waitress, gunicorn, etc.
Client¶
from vgi_rpc import http_connect
with http_connect(MyService, "http://localhost:8080") as proxy:
result = proxy.echo(message="hello") # proxy is typed as MyService
Testing (no real server)¶
make_sync_client wraps a Falcon TestClient so you can test the full HTTP stack in-process:
from vgi_rpc import RpcServer
from vgi_rpc.http import http_connect, make_sync_client
server = RpcServer(MyService, MyServiceImpl())
client = make_sync_client(server)
with http_connect(MyService, client=client) as proxy:
assert proxy.echo(message="hello") == "hello"
API Reference¶
Server¶
make_wsgi_app
¶
make_wsgi_app(
server: RpcServer,
*,
prefix: str = "/vgi",
signing_key: bytes | None = None,
max_stream_response_bytes: int | None = None,
max_request_bytes: int | None = None,
authenticate: (
Callable[[Request], AuthContext] | None
) = None,
cors_origins: str | Iterable[str] | None = None,
upload_url_provider: UploadUrlProvider | None = None,
max_upload_bytes: int | None = None,
otel_config: object | None = None,
token_ttl: int = 3600
) -> App[Request, Response]
Create a Falcon WSGI app that serves RPC requests over HTTP.
| PARAMETER | DESCRIPTION |
|---|---|
server
|
The RpcServer instance to serve.
TYPE:
|
prefix
|
URL prefix for all RPC endpoints (default
TYPE:
|
signing_key
|
HMAC key for signing state tokens. When
TYPE:
|
max_stream_response_bytes
|
When set, producer stream responses are
broken into multiple HTTP exchanges once the response body
exceeds this size. The client transparently resumes via
TYPE:
|
max_request_bytes
|
When set, the value is advertised via the
TYPE:
|
authenticate
|
Optional callback that extracts an :class:
TYPE:
|
cors_origins
|
Allowed origins for CORS. Pass
TYPE:
|
upload_url_provider
|
Optional provider for generating pre-signed
upload URLs. When set, the
TYPE:
|
max_upload_bytes
|
When set (and
TYPE:
|
otel_config
|
Optional
TYPE:
|
token_ttl
|
Maximum age of stream state tokens in seconds. Tokens
older than this are rejected with HTTP 400. Default is 3600
(1 hour). Set to
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
App[Request, Response]
|
A Falcon application with routes for unary and stream RPC calls. |
Source code in vgi_rpc/http/_server.py
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 | |
Client¶
http_connect
¶
http_connect(
protocol: type[P],
base_url: str | None = None,
*,
prefix: str = "/vgi",
on_log: Callable[[Message], None] | None = None,
client: Client | _SyncTestClient | None = None,
external_location: ExternalLocationConfig | None = None,
ipc_validation: IpcValidation = FULL,
retry: HttpRetryConfig | None = None
) -> Iterator[P]
Connect to an HTTP RPC server and yield a typed proxy.
| PARAMETER | DESCRIPTION |
|---|---|
protocol
|
The Protocol class defining the RPC interface.
TYPE:
|
base_url
|
Base URL of the server (e.g.
TYPE:
|
prefix
|
URL prefix matching the server's prefix (default
TYPE:
|
on_log
|
Optional callback for log messages from the server.
TYPE:
|
client
|
Optional HTTP client —
TYPE:
|
external_location
|
Optional ExternalLocationConfig for resolving and producing externalized batches.
TYPE:
|
ipc_validation
|
Validation level for incoming IPC batches.
TYPE:
|
retry
|
Optional retry configuration for transient HTTP failures.
When
TYPE:
|
| YIELDS | DESCRIPTION |
|---|---|
P
|
A typed RPC proxy supporting all methods defined on protocol. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If base_url is |
Source code in vgi_rpc/http/_client.py
http_introspect
¶
http_introspect(
base_url: str | None = None,
*,
prefix: str = "/vgi",
client: Client | _SyncTestClient | None = None,
ipc_validation: IpcValidation = FULL,
retry: HttpRetryConfig | None = None
) -> ServiceDescription
Send a __describe__ request over HTTP and return a ServiceDescription.
| PARAMETER | DESCRIPTION |
|---|---|
base_url
|
Base URL of the server (e.g.
TYPE:
|
prefix
|
URL prefix matching the server's prefix (default
TYPE:
|
client
|
Optional HTTP client (
TYPE:
|
ipc_validation
|
Validation level for incoming IPC batches.
TYPE:
|
retry
|
Optional retry configuration for transient HTTP failures.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ServiceDescription
|
A |
| RAISES | DESCRIPTION |
|---|---|
RpcError
|
If the server does not support introspection or returns an error. |
ValueError
|
If base_url is |
Source code in vgi_rpc/http/_client.py
http_capabilities
¶
http_capabilities(
base_url: str | None = None,
*,
prefix: str = "/vgi",
client: Client | _SyncTestClient | None = None,
retry: HttpRetryConfig | None = None
) -> HttpServerCapabilities
Discover server capabilities via an OPTIONS request.
Sends OPTIONS {prefix}/__capabilities__ and reads capability
headers (VGI-Max-Request-Bytes, VGI-Upload-URL-Support,
VGI-Max-Upload-Bytes) from the response.
| PARAMETER | DESCRIPTION |
|---|---|
base_url
|
Base URL of the server (e.g.
TYPE:
|
prefix
|
URL prefix matching the server's prefix (default
TYPE:
|
client
|
Optional HTTP client (
TYPE:
|
retry
|
Optional retry configuration for transient HTTP failures.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
HttpServerCapabilities
|
An |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If base_url is |
Source code in vgi_rpc/http/_client.py
request_upload_urls
¶
request_upload_urls(
base_url: str | None = None,
*,
count: int = 1,
prefix: str = "/vgi",
client: Client | _SyncTestClient | None = None,
retry: HttpRetryConfig | None = None
) -> list[UploadUrl]
Request pre-signed upload URLs from the server's __upload_url__ endpoint.
The server must have been configured with an upload_url_provider
in make_wsgi_app().
| PARAMETER | DESCRIPTION |
|---|---|
base_url
|
Base URL of the server (e.g.
TYPE:
|
count
|
Number of upload URLs to request (default 1, max 100).
TYPE:
|
prefix
|
URL prefix matching the server's prefix (default
TYPE:
|
client
|
Optional HTTP client (
TYPE:
|
retry
|
Optional retry configuration for transient HTTP failures.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[UploadUrl]
|
A list of |
| RAISES | DESCRIPTION |
|---|---|
RpcError
|
If the server does not support upload URLs (404) or returns an error. |
ValueError
|
If base_url is |
Source code in vgi_rpc/http/_client.py
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 | |
Capabilities¶
HttpServerCapabilities
dataclass
¶
HttpServerCapabilities(
max_request_bytes: int | None = None,
upload_url_support: bool = False,
max_upload_bytes: int | None = None,
)
Capabilities advertised by an HTTP RPC server.
| ATTRIBUTE | DESCRIPTION |
|---|---|
max_request_bytes |
Maximum request body size the server advertises,
or
TYPE:
|
upload_url_support |
Whether the server supports the
TYPE:
|
max_upload_bytes |
Maximum upload size the server advertises for
client-vended URLs, or
TYPE:
|
Stream Session¶
HttpStreamSession
¶
HttpStreamSession(
client: Client | _SyncTestClient,
url_prefix: str,
method: str,
state_bytes: bytes | None,
output_schema: Schema,
on_log: Callable[[Message], None] | None = None,
*,
external_config: ExternalLocationConfig | None = None,
ipc_validation: IpcValidation = FULL,
pending_batches: list[AnnotatedBatch] | None = None,
finished: bool = False,
header: object | None = None,
retry_config: HttpRetryConfig | None = None
)
Client-side handle for a stream over HTTP (both producer and exchange patterns).
For producer streams, use __iter__() — yields batches from batched
responses and follows continuation tokens transparently.
For exchange streams, use exchange() — sends an input batch and
receives an output batch.
Supports context manager protocol for convenience.
Initialize with HTTP client, method details, and initial state.
Source code in vgi_rpc/http/_client.py
typed_header
¶
Return the stream header narrowed to the expected type.
| PARAMETER | DESCRIPTION |
|---|---|
header_type
|
The expected header dataclass type.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
H
|
The header, typed as header_type. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the header is |
Source code in vgi_rpc/http/_client.py
exchange
¶
exchange(input_batch: AnnotatedBatch) -> AnnotatedBatch
Send an input batch and receive the output batch.
| PARAMETER | DESCRIPTION |
|---|---|
input_batch
|
The input batch to send.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
AnnotatedBatch
|
The output batch from the server. |
| RAISES | DESCRIPTION |
|---|---|
RpcError
|
If the server reports an error or the stream has finished. |
Source code in vgi_rpc/http/_client.py
__iter__
¶
__iter__() -> Iterator[AnnotatedBatch]
Iterate over output batches from a producer stream.
Yields pre-loaded batches from init, then follows continuation tokens.
Source code in vgi_rpc/http/_client.py
close
¶
__enter__
¶
__enter__() -> HttpStreamSession
__exit__
¶
Testing¶
make_sync_client
¶
make_sync_client(
server: RpcServer,
*,
prefix: str = "/vgi",
signing_key: bytes | None = None,
max_stream_response_bytes: int | None = None,
max_request_bytes: int | None = None,
authenticate: (
Callable[[Request], AuthContext] | None
) = None,
default_headers: dict[str, str] | None = None,
upload_url_provider: UploadUrlProvider | None = None,
max_upload_bytes: int | None = None,
otel_config: object | None = None,
token_ttl: int = 3600
) -> _SyncTestClient
Create a synchronous test client for an RpcServer.
Uses falcon.testing.TestClient internally — no real HTTP server needed.
| PARAMETER | DESCRIPTION |
|---|---|
server
|
The RpcServer to test.
TYPE:
|
prefix
|
URL prefix for RPC endpoints (default
TYPE:
|
signing_key
|
HMAC key for signing state tokens (see
TYPE:
|
max_stream_response_bytes
|
See
TYPE:
|
max_request_bytes
|
See
TYPE:
|
authenticate
|
See
TYPE:
|
default_headers
|
Headers merged into every request (e.g. auth tokens).
TYPE:
|
upload_url_provider
|
See
TYPE:
|
max_upload_bytes
|
See
TYPE:
|
otel_config
|
See
TYPE:
|
token_ttl
|
See
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
_SyncTestClient
|
A sync client that can be passed to |