Skip to main content
Version: 0.10

SDK

The Marmot SDK is a typed client for the REST API, available in Python, Go and TypeScript. Authentication resolves automatically from environment variables, cached OAuth tokens or workload identity.

Install​

pip install marmot-sdk

Requires Python 3.10+. Package name is marmot-sdk, import name is marmot.

Authenticate​

Every SDK resolves credentials from the same priority chain, so the same code runs locally, in CI and in production without branching on environment:

  1. Explicit arguments. api_key / token passed to connect() or NewClient().
  2. Environment variables. MARMOT_API_KEY, MARMOT_TOKEN, MARMOT_HOST, MARMOT_CONTEXT.
  3. Cached OAuth token. Written to ~/.config/marmot/credentials.json by marmot login.
  4. Workload identity. GitHub Actions OIDC, GCP metadata or a Kubernetes service-account token. No API key needed.

If no credential resolves, the SDK raises an AuthError so misconfiguration fails fast.

Log in for local use:

marmot login http://localhost:5173

Then construct a client:

import marmot

# Resolves from the chain
client = marmot.connect()

# Or pass an API key explicitly
client = marmot.connect(base_url="https://marmot.example.com", api_key="...")

# Context manager closes the underlying httpx client on exit
with marmot.connect() as client:
me = client.users.me()

The following sections all assume client (and ctx for Go) is already constructed as shown above.

client.search(query) is the unified search across assets, glossary terms, teams and data products. Returns a typed SearchResponse with facets, results and pagination.

import marmot

client = marmot.connect()

results = client.search("orders", types=["Table", "Topic"], limit=20)
for hit in results.results:
print(hit.name, hit.metadata.get("mrn"))

Marmot accepts both free-text queries and a structured query language (@type: "Table" AND @provider: "postgres"). See the Query Language guide for the full grammar.

Assets​

Every catalog entry is an Asset. The Assets resource covers CRUD, lookup by natural key, search, summary aggregates and tag management.

Fetch by ID​

import marmot

client = marmot.connect()

asset = client.assets.get("01HX...")
print(asset.name, asset.mrn)

Lookup by natural key​

When you know an asset by (type, service, name) but not its ID, lookup resolves it. find does the same but returns nil / None instead of raising on a miss.

import marmot

client = marmot.connect()

asset = client.assets.lookup(type="Table", service="postgres", name="orders")
maybe = client.assets.find(type="Table", service="postgres", name="orders") # None on 404

Search and summary​

import marmot

client = marmot.connect()

hits = client.assets.search(
query="customer",
types=["Table"],
providers=["postgres"],
tags=["pii"],
limit=50,
)
summary = client.assets.summary() # totals by type, provider, tag

Create, update, delete​

import marmot

client = marmot.connect()

created = client.assets.create({
"name": "orders",
"type": "Table",
"providers": ["postgres"],
"metadata": {"owner": "data-eng"},
})

updated = client.assets.update(created.id, {"description": "Customer orders"})
client.assets.delete(created.id)

Tag management​

import marmot

client = marmot.connect()

client.assets.add_tag(asset_id, "pii")
client.assets.remove_tag(asset_id, "pii")

Lineage​

Lineage edges identify endpoints by MRN (<type>://<service>/<name>). Read the graph from any node; write one edge or many at a time.

Read the graph​

import marmot

client = marmot.connect()

graph = client.lineage.get(asset_id, direction="both", limit=50)
upstream = client.lineage.upstream(asset_id, limit=10)

Write edges​

Prefer /lineage/direct and /lineage/batch for new integrations. They accept simple (source, target) pairs and de-duplicate server-side.

import marmot

client = marmot.connect()

# Single edge
client.lineage.write(
source="postgres://prod/sales/orders",
target="kafka://prod/orders.events",
)

# Batched: one HTTP call, many edges
client.lineage.batch([
("postgres://prod/sales/orders", "kafka://prod/orders.events"),
("kafka://prod/orders.events", "s3://prod/orders-archive"),
])

Leave Type empty (DIRECT is the default) for code-derived edges; set it explicitly ("writes", "AGENT_LOOKUP", …) when you want to distinguish causes in the lineage graph.

Glossary​

Business glossary terms with definitions, descriptions and hierarchies via parent_term_id.

import marmot

client = marmot.connect()

page = client.glossary.list(limit=50)
hits = client.glossary.search(query="customer")

term = client.glossary.create(
name="PII",
definition="Personally Identifiable Information",
description="Data that can identify an individual.",
)

client.glossary.update(term.id, name="Personally Identifiable Information")
client.glossary.delete(term.id)

Users & Teams​

import marmot

client = marmot.connect()

me = client.users.me()
user = client.users.get(user_id)
users = client.users.list(active=True, limit=100)

teams = client.teams.list()
team = client.teams.get(team_id)
members = client.teams.members(team_id)

API Keys​

Manage personal API keys for the authenticated user. The full key token is only readable from the create response, so store it immediately.

import marmot

client = marmot.connect()

keys = client.api_keys.list()
created = client.api_keys.create(name="ci-deploy", expires_in_days=30)
print(created.key) # only readable here
client.api_keys.delete(created.id)

Runs​

Read pipeline-ingestion run history. Useful when wiring up alerts on failed ingests or audit dashboards.

import marmot

client = marmot.connect()

recent = client.runs.list(statuses="failed,running", limit=20)
run = client.runs.get(run_id)
entities = client.runs.entities(run_id, status="failed")

Metrics​

Catalog usage and breakdown metrics. top_assets and top_queries take an inclusive [start, end] window of RFC3339 timestamps.

import marmot

client = marmot.connect()

total = client.metrics.total_assets()
by_type = client.metrics.assets_by_type()
by_provider = client.metrics.assets_by_provider()

top = client.metrics.top_assets(
start="2025-01-01T00:00:00Z",
end="2025-02-01T00:00:00Z",
limit=10,
)
queries = client.metrics.top_queries(
start="2025-01-01T00:00:00Z",
end="2025-02-01T00:00:00Z",
limit=10,
)

Owners​

Search the catalog for asset owners (users and teams).

import marmot

client = marmot.connect()

hits = client.owners.search("alice", limit=10)

Admin​

Trigger or poll a full search reindex. Requires admin permissions.

import marmot

client = marmot.connect()

accepted = client.admin.reindex()
status = client.admin.reindex_status()
print(status.running, status.es_configured)

Building an agent?

Marmot for Agents builds on the SDK to give LLM agents the catalog as tools and writes their lineage automatically.

Read the guide