Skip to main content

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/"}
}
  • inprocclient(I).method returns 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_BUCKET set → S3BlobStore (real AWS or MinIO via S3_ENDPOINT_URL).
  • CARAVAN_BLOB_BACKEND=local-fsLocalFsBlobStore rooted at the path from yaml_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_BACKEND explicit 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 / client with CARAVAN_RPC_PEERS env-var dispatch; HTTP + Lambda SigV4 client dispatchers; caravan_rpc.serve peer CLI; caravan_rpc.lambda_handler for 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.

Release files for caravan-rpc 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for caravan-rpc 0.1.1
File Size Uploaded
caravan_rpc-0.1.1.tar.gz 25.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for caravan-rpc 0.1.1
File Interpreter ABI Platform
caravan_rpc-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 57.0 kB

Release files / caravan_rpc-0.1.1.tar.gz

Download URL caravan_rpc-0.1.1.tar.gz
Size 25.5 kB
Tags Source
SHA-256 checksum
How to use checksums
51e175945b87311c7592513da9438083eee8a97dfc5c24ed03dbed78c2e3ed2e
BLAKE2b-256 checksum
How to use checksums
36e10236090c4565175c49f4acb96b7060f151972f587dd7443be004d4df5045
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 27, 2026.

Transparency log

Release files / caravan_rpc-0.1.1-py3-none-any.whl

Download URL caravan_rpc-0.1.1-py3-none-any.whl
Size 31.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1801867f8d1c9f8737b7ea601dabe2c9356aafe92b94bf1a36ffa55c4b3744ad
BLAKE2b-256 checksum
How to use checksums
b80d8472f97843a144cd30f57aa365e4b4fe794ac4f2d416337d5babba5eb090
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page