Runtime SDK for the Caravan application-definition compiler.
Project description
caravan-rpc (Python)
Runtime SDK for the Caravan application-definition compiler.
Status: 0.1.1. Functional runtime with @wagon, provide, client, CARAVAN_RPC_PEERS env-var dispatch (inproc / HTTP / Lambda Function URL via SigV4), peer-mode self-call guard, base64-encoded bytes over the wire, and Caravan-shipped resource adapters (BlobStore, MessageQueue) for S3 / Redis / RabbitMQ / SQS.
What is Caravan?
Caravan is an application-definition compiler. The same source code deploys across packaging (inproc / container / lambda) × placement (compose / Fargate / Lambda) × composition (oss-local / cloud-managed) axes by yaml-line changes alone — no source-code edits.
Read the thesis and the PoC RPC SDK spec.
Install
pip install caravan-rpc>=0.1.1
Optional extras (each pulls in its backend client only when needed):
pip install "caravan-rpc[aws,redis,rabbit,lambda]>=0.1.1"
# aws — boto3 for S3BlobStore + SqsQueue.
# redis — redis-py for RedisStreamQueue.
# rabbit — pika for RabbitMQQueue.
# lambda — botocore SigV4 signer for Lambda Function URL client dispatch.
# all — convenience meta-extra.
Three-point structural contract
User code interacts with Caravan through three SDK entry points; everything else is compiler-managed:
from caravan_rpc import wagon, provide, client
# 1. @wagon declares an interface as a Caravan seam — a synchronous
# abstraction boundary that yaml can flip between inproc / HTTP /
# Lambda dispatch per target.
@wagon
class LLMExtraction:
def extract(self, ocr_text: str, file_bytes: bytes) -> InvoiceExtraction: ...
# 2. provide() registers a concrete impl at process startup.
class GeminiExtractor:
def extract(self, ocr_text, file_bytes):
...
provide(LLMExtraction, GeminiExtractor())
# 3. client() dispatches a call — inproc, HTTP, or Lambda per the
# `CARAVAN_RPC_PEERS` env var the compiler emits per target.
def run(pdf_bytes: bytes, ocr_text: str):
extractor = client(LLMExtraction)
return extractor.extract(ocr_text, pdf_bytes)
bytes arguments are JSON-encoded as base64 over the wire (set via pydantic.ConfigDict(ser_json_bytes="base64") on the codec's TypeAdapter). Binary payloads — PDFs, images — cross HTTP / Lambda cleanly without UTF-8 decode failures.
Dispatch modes
CARAVAN_RPC_PEERS is a per-deploy-unit JSON map the compiler emits:
{
"LLMExtraction": {"mode": "http", "url": "http://llm-extractor:8080"},
"OCRText": {"mode": "inproc"},
"ValidateExtraction": {"mode": "lambda", "function_url": "https://...lambda-url.ap-southeast-1.on.aws/"}
}
inproc→client(I).methodreturns the registered impl's bound method directly (zero overhead, no-config-inert).http→ returns a callable that POSTs to/_caravan/rpc/<iface>/<method>with a Bearer token.lambda→ SigV4-signed POST to the Lambda Function URL (requires[lambda]extra).
Peer-mode self-call guard: when CARAVAN_RPC_ROLE=peer-<Interface> matches the served interface, client(I) falls through to the local impl instead of an HTTP dispatcher pointing back at this same container. Peer containers share the consumer's CARAVAN_RPC_PEERS, so without the guard requests would loop.
Peer-mode entry: python -m caravan_rpc.serve
Caravan emits compose peer services that invoke this module:
python -m caravan_rpc.serve --interface LLMExtraction \
--impl invoice_processing.extraction:GeminiExtractor \
--port 8080
The CLI imports the impl, calls provide(), then serves @wagon methods on /_caravan/rpc/<iface>/<method>. Same wire contract the client(I) HTTP dispatcher targets.
Resource adapters
Caravan-shipped impls of common resource seams (BlobStore, MessageQueue):
from caravan_rpc.resources import auto_register_resources, BlobStore
from caravan_rpc import client
def main():
with open("config/app.yaml") as f:
cfg = yaml.safe_load(f)
auto_register_resources(yaml_fallback=cfg)
blob = client(BlobStore)
blob.put("input.pdf", pdf_bytes)
Backend selection is driven by explicit Caravan-emitted markers:
CARAVAN_BLOB_BACKEND=s3+S3_BUCKETset →S3BlobStore(real AWS or MinIO viaS3_ENDPOINT_URL).CARAVAN_BLOB_BACKEND=local-fs→LocalFsBlobStorerooted at the path fromyaml_fallback.blob_storage.base_path(default/data/blobs).- Marker unset → consult
yaml_fallback. Non-caravan local-dev path.
CARAVAN_BLOB_BACKEND=s3 with no S3_BUCKET loud-fails at startup (catches the "user forgot to populate .env.hybrid from tofu output" footgun).
MessageQueue selects on QUEUE_URL scheme: redis:// → RedisStreamQueue, amqp:// → RabbitMQQueue, https:// → SqsQueue.
Versions
- 0.1.1: peer-mode self-call guard;
CARAVAN_BLOB_BACKENDexplicit marker; bytes serialized as base64 (was utf-8 default in pydantic, which crashed on binary payloads). SDK version bumped alongside Rust 0.1.1 for matching wire-protocol semantics. - 0.1.0: first functional release.
@wagon/provide/clientwithCARAVAN_RPC_PEERSenv-var dispatch; HTTP + Lambda SigV4 client dispatchers;caravan_rpc.servepeer CLI;caravan_rpc.lambda_handlerfor Function URL event v2.0; resource adapters. - 0.0.1: PyPI name reservation placeholder.
See development_plan.md for the full milestone history.
License
Apache-2.0. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file caravan_rpc-0.1.1.tar.gz.
File metadata
- Download URL: caravan_rpc-0.1.1.tar.gz
- Upload date:
- Size: 25.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51e175945b87311c7592513da9438083eee8a97dfc5c24ed03dbed78c2e3ed2e
|
|
| MD5 |
052d8f1561ec03607e4807bdc1ce9a2b
|
|
| BLAKE2b-256 |
36e10236090c4565175c49f4acb96b7060f151972f587dd7443be004d4df5045
|
Provenance
The following attestation bundles were made for caravan_rpc-0.1.1.tar.gz:
Publisher:
publish-py-sdk.yml on paulxiep/caravan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
caravan_rpc-0.1.1.tar.gz -
Subject digest:
51e175945b87311c7592513da9438083eee8a97dfc5c24ed03dbed78c2e3ed2e - Sigstore transparency entry: 1639157726
- Sigstore integration time:
-
Permalink:
paulxiep/caravan@1929ce91e5821fe187598d29ebd39f3f6ff61f96 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/paulxiep
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-py-sdk.yml@1929ce91e5821fe187598d29ebd39f3f6ff61f96 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file caravan_rpc-0.1.1-py3-none-any.whl.
File metadata
- Download URL: caravan_rpc-0.1.1-py3-none-any.whl
- Upload date:
- Size: 31.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1801867f8d1c9f8737b7ea601dabe2c9356aafe92b94bf1a36ffa55c4b3744ad
|
|
| MD5 |
7bd6fb1222d97625f9d89a4f7fbd78e5
|
|
| BLAKE2b-256 |
b80d8472f97843a144cd30f57aa365e4b4fe794ac4f2d416337d5babba5eb090
|
Provenance
The following attestation bundles were made for caravan_rpc-0.1.1-py3-none-any.whl:
Publisher:
publish-py-sdk.yml on paulxiep/caravan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
caravan_rpc-0.1.1-py3-none-any.whl -
Subject digest:
1801867f8d1c9f8737b7ea601dabe2c9356aafe92b94bf1a36ffa55c4b3744ad - Sigstore transparency entry: 1639157915
- Sigstore integration time:
-
Permalink:
paulxiep/caravan@1929ce91e5821fe187598d29ebd39f3f6ff61f96 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/paulxiep
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-py-sdk.yml@1929ce91e5821fe187598d29ebd39f3f6ff61f96 -
Trigger Event:
workflow_dispatch
-
Statement type: