Skip to main content

schemabound-sdk

Python SDK for the OAM (Object Agent Mapping) framework. Connects Python applications to the OAM runtime over gRPC with SQLAlchemy model registration and all three schema modes.

Installation

pip install schemabound-sdk
# or with uv
uv add schemabound-sdk

Quick Start

from schemabound_sdk import SchemaboundClient
from schemabound_sdk.v1.agent import service_pb2

client = SchemaboundClient(address="localhost:50051", api_key="your-api-key")
client.connect()

# Register as a DATA_FIRST agent (read-only, DB introspection)
client.register("my-agent", "1.0.0", service_pb2.SchemaMode.DATA_FIRST)

# Execute a query
response = client.execute_query("SELECT * FROM organizations LIMIT 10")

client.close()

Schema Modes

from schemabound_sdk.v1.agent import service_pb2

# DATA_FIRST — Discovery mode. Read-only. Backend introspects DB schema.
client.register("agent", "1.0", service_pb2.SchemaMode.DATA_FIRST)

# CODE_FIRST — App extension mode. Only registered models are queryable. Read-write.
client.register("agent", "1.0", service_pb2.SchemaMode.CODE_FIRST)

# HYBRID — Registered models first, introspection fallback. Read-only.
client.register("agent", "1.0", service_pb2.SchemaMode.HYBRID)
Mode Description Access
DATA_FIRST DB introspection — no model registration needed Read-only
CODE_FIRST Registered models only — code-defined validation Read-write
HYBRID Registered models + introspection fallback Read-only

SQLAlchemy Model Registration

Use SchemaboundDeclarativeBase as the base for your SQLAlchemy models to enable CODE_FIRST or HYBRID registration:

from sqlalchemy.orm import DeclarativeBase
from schemabound_sdk import SchemaboundClient, SchemaboundDeclarativeBase
from schemabound_sdk.v1.agent import service_pb2

class Base(SchemaboundDeclarativeBase, DeclarativeBase):
    pass

class Organization(Base):
    """Tenant organization model."""
    __tablename__ = "organizations"

    id: int
    name: str
    slug: str

client = SchemaboundClient(address="localhost:50051")
client.connect()
client.register("my-agent", "1.0.0", service_pb2.SchemaMode.CODE_FIRST)
client.register_model(Organization)

# Only registered tables are queryable in CODE_FIRST mode
response = client.execute_query("SELECT * FROM organizations")

Schema Constraint Mapping

SchemaboundDeclarativeBase.to_roam_schema() translates SQLAlchemy column constraints into restrictive JSON Schema rules for LLM tool calls.

SQLAlchemy constraint JSON Schema effect
primary_key=True Description annotated "Primary Key — auto-generated; omit on INSERT"; excluded from required
ForeignKey("table.col") Description annotated "Foreign Key → table.col"
unique=True Description annotated "UNIQUE — value must be unique across all rows"
Enum("a", "b", ...) Property emits "enum": ["a", "b", ...]
— "additionalProperties": False on every table schema
from sqlalchemy import Enum, ForeignKey, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from schemabound_sdk import SchemaboundDeclarativeBase

class Base(DeclarativeBase, SchemaboundDeclarativeBase):
    pass

class Department(Base):
    __tablename__ = "departments"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String, unique=True)

class Employee(Base):
    __tablename__ = "employees"
    id: Mapped[int] = mapped_column(primary_key=True)
    department_id: Mapped[int] = mapped_column(ForeignKey("departments.id"))
    role: Mapped[str] = mapped_column(Enum("engineer", "manager", name="role_enum"))

schema = Employee.to_roam_schema()
# schema["parameters"]["additionalProperties"] == False
# schema["parameters"]["properties"]["department_id"]["description"] contains "departments.id"
# schema["parameters"]["properties"]["role"]["enum"] == ["engineer", "manager"]

Runtime Context Headers

Attach request context before calling execute_query:

client.query_context = {
    "organization_id": "org-123",
    "user_id": "user-456",
    "tool_name": "data-explorer",
    "tool_intent": "read",
    "domain_tags": ["identity"],
    "table_names": ["organizations"],
}

These map to the standard SCHEMABOUND runtime headers (x-schemabound-organization-id, x-schemabound-user-id, etc.) and are forwarded on every gRPC call.

Testing

# Unit tests (no backend required)
pytest tests/unit/

# Integration tests (requires running OAM backend)
make grpc-start   # from repo root
pytest tests/integration/

Related Packages

Package Description
schemabound-sdk This package
schemabound Rust core runtime
schemabound-proto Shared protobuf definitions

License

Licensed under either of Apache License 2.0 or MIT License at your option.

Release files for schemabound-sdk 0.1.0

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

Source distribution (sdist)

Source distribution for schemabound-sdk 0.1.0
File Size Uploaded
schemabound_sdk-0.1.0.tar.gz 97.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for schemabound-sdk 0.1.0
File Interpreter ABI Platform
schemabound_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 112.1 kB

Release files / schemabound_sdk-0.1.0.tar.gz

Download URL schemabound_sdk-0.1.0.tar.gz
Size 97.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8fe0c2eb401370f4820fb5d6607113c17a9f8d1c0f40ef66c722973ca5ba2585
BLAKE2b-256 checksum
How to use checksums
7553ba1144e0c2af2a4b9a2f7a636a7e35b3e700cac7ab6b8182a69d94001fae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / schemabound_sdk-0.1.0-py3-none-any.whl

Download URL schemabound_sdk-0.1.0-py3-none-any.whl
Size 14.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b41790a0801ea5eb27a8f0dcef470a3879e6e468a2bd0fc843e26ac4e6af56aa
BLAKE2b-256 checksum
How to use checksums
35698ac0705da830007a54ae5922cfe1634f65b6000e04a0cf15b271a5dbd9ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.0 This release

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