Skip to main content

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/"}
}
  • 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

caravan_rpc-0.1.1.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

caravan_rpc-0.1.1-py3-none-any.whl (31.5 kB view details)

Uploaded Python 3

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

Hashes for caravan_rpc-0.1.1.tar.gz
Algorithm Hash digest
SHA256 51e175945b87311c7592513da9438083eee8a97dfc5c24ed03dbed78c2e3ed2e
MD5 052d8f1561ec03607e4807bdc1ce9a2b
BLAKE2b-256 36e10236090c4565175c49f4acb96b7060f151972f587dd7443be004d4df5045

See more details on using hashes here.

Provenance

The following attestation bundles were made for caravan_rpc-0.1.1.tar.gz:

Publisher: publish-py-sdk.yml on paulxiep/caravan

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for caravan_rpc-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1801867f8d1c9f8737b7ea601dabe2c9356aafe92b94bf1a36ffa55c4b3744ad
MD5 7bd6fb1222d97625f9d89a4f7fbd78e5
BLAKE2b-256 b80d8472f97843a144cd30f57aa365e4b4fe794ac4f2d416337d5babba5eb090

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page