A library for easily accessing dbt's Semantic Layer via Python.
To install the SDK, you'll need to specify optional dependencies depending on whether you want to use it synchronously (backed by requests) or via asyncio (backed by aiohttp).
# Sync installation
pip install "dbt-sl-sdk[sync]"
# Async installation
pip install "dbt-sl-sdk[async]"
To run operations against the Semantic Layer APIs, just instantiate a SemanticLayerClient with your specific connection parameters (learn more):
fromdbtslimportSemanticLayerClientclient=SemanticLayerClient(
environment_id=123,
auth_token="<your-semantic-layer-api-token>",
host="semantic-layer.cloud.getdbt.com",
)
# query the first metric by `metric_time`defmain():
withclient.session():
metrics=client.metrics()
table=client.query(
metrics=[metrics[0].name],
group_by=["metric_time"],
)
print(table)
main()Note that all method calls that will reach out to the APIs need to be within a client.session() context manager. By using a session, the client can connect to the APIs only once, and reuse the same connection between API calls.
If you're using asyncio, import AsyncSemanticLayerClient from dbtsl.asyncio. The APIs of SemanticLayerClient and AsyncSemanticLayerClient are the same. The only difference is that the asyncio version has async methods which need to be awaited.
That same sync example can be converted into asyncio code like so:
importasynciofromdbtsl.asyncioimportAsyncSemanticLayerClientclient=AsyncSemanticLayerClient(
environment_id=123,
auth_token="<your-semantic-layer-api-token>",
host="semantic-layer.cloud.getdbt.com",
)
asyncdefmain():
asyncwithclient.session():
metrics=awaitclient.metrics()
table=awaitclient.query(
metrics=[metrics[0].name],
group_by=["metric_time"],
)
print(table)
asyncio.run(main())By design, the SDK returns all query data as pyarrow tables. If you wish to use the data with libraries like pandas or polars, you need to manually download them and convert the data into their format.
If you're using pandas:
# ... initialize clientarrow_table=client.query(...)
pandas_df=arrow_table.to_pandas()If you're using polars:
importpolarsaspl# ... initialize clientarrow_table=client.query(...)
polars_df=pl.from_arrow(arrow_table)By default, the SDK will eagerly request for lists of nested objects. For example, in the list of Metric returned by client.metrics(), each metric will contain the list of its dimensions, entities and measures. This is convenient in most cases, but can make your returned data really large in case your project is really large, which can slow things down.
It is possible to set the client to lazy=True, which will make it skip populating nested object lists unless you explicitly load ask for it on a per-model basis. Check our lazy loading example to learn more.
Check out our usage examples to learn more.
By default, dbt the SDK sends some platform-related information to dbt Labs. If you'd like to opt out, do
fromdbtsl.envimportPLATFORMPLATFORM.anonymous=True# ... initialize clientIf you're interested in contributing to this project, check out our contribution guidelines.