pyoso SDK
pyoso is the Python client for querying the OSO data warehouse. It sends
read-only Trino SQL to the OSO API and returns results as pandas DataFrames,
with optional analytics metadata about how each table was built.
pyoso (from pyoso import Client) reads data out of the warehouse. It is a
different surface from the import oso / @oso.model SDK used to author
User-Defined Models (UDMs). Do not conflate them: use pyoso to run queries,
and the import oso SDK to define models. For authoring models, see the
Data modeling tutorial.
Install
pip install pyoso
For the optional semantic-modeling layer (see below), install the extra:
pip install pyoso[semantic]
Client
from pyoso import Client
client = Client()
Client() reads your API key from the OSO_API_KEY environment variable. You
can also pass it explicitly:
client = Client(api_key="your_api_key")
If no key is found in the environment or arguments, the constructor raises an
error. Point the client at a non-default API host with client_opts:
from pyoso import Client
from pyoso.client import ClientConfig
client = Client(client_opts=ClientConfig(base_url="https://api.oso.xyz/v1/"))
client.to_pandas(query)
Runs a single SQL statement and returns the result as a pandas.DataFrame. This
is the everyday method for pulling data.
df = client.to_pandas("SELECT * FROM oso.projects_v1 LIMIT 5")
print(df)
Only a single statement is supported per call — no semicolon-separated batches or multiple queries.
client.query(query) → QueryResponse
Runs a query and returns a QueryResponse object carrying both the data and
analytics metadata. Use it when you want to inspect data provenance and
freshness alongside the results.
response = client.query("SELECT * FROM oso.artifacts_v1 LIMIT 5")
df = response.to_pandas() # same DataFrame as to_pandas()
response.analytics # DataAnalytics for the query's dependency tree
response.data # raw QueryData (columns + rows)
QueryResponse members:
response.to_pandas()— convert the result rows to a DataFrame.response.analytics— aDataAnalyticsobject (see below).response.data— the rawQueryData(.columnsand.data).
response.analytics.print_tree()
response.analytics is a DataAnalytics object that models the dependency tree
of the tables your query touched — how each was constructed from upstream
sources and how fresh it is. print_tree() renders that tree to stdout.
response = client.query("SELECT * FROM oso.artifacts_v1 LIMIT 5")
response.analytics.print_tree()
Other useful members:
analytics.root_keys— top-level nodes in the dependency tree.analytics.sources— the leaf sources (nodes with no dependencies).analytics.get(key)— theDataStatus(materialization info) for one node.analytics.print_tree(key)— print the subtree rooted at a specific key.
Notebook helper: marimo_db
For marimo notebooks, pyoso ships a helper that returns a
database connection you can pass to mo.sql(...). Put this in a cell at the top
of your notebook:
from pyoso.notebook import marimo_db
pyoso_db_conn = marimo_db()
Then query with mo.sql(...) using that connection:
df = mo.sql("SELECT * FROM oso.projects_v1 LIMIT 10", engine=pyoso_db_conn)
Optional: semantic layer
When installed with the [semantic] extra, the client exposes a semantic
attribute — a registry for building queries against OSO's semantic models
(entities and their relationships) instead of writing raw SQL. This is optional
and off unless the oso_semantic package is present.
See also
- Querying OSO — first queries with pyoso and over MCP.
- Data model — the public
oso.*marts you'll query. - Notebooking — build and share notebooks on OSO data.
- Data modeling — author UDMs with the
import osoSDK (a different surface from this client).