Docs menu
Python SDK
Install the SDK, connect with an API key and learn how its client works.
In short
The Python SDK lets your code register and govern resources in Northstar: storage systems, sources, datasets, document collections, KPIs, dashboards, teams. It authenticates with the API key of an integration account and calls the platform API, never your warehouse. Everything it does respects the account's roles and teams.
Install
The SDK needs Python 3.13 or later.
pip install northstar-sdk
# or
uv add northstar-sdkThe package ships type hints: your editor completes the arguments of every method.
Configure
The SDK reads two environment variables:
| Variable | Value | Example |
|---|---|---|
NORTHSTAR_API_URL | The address of your platform, followed by /api | https://data.example.com/api |
NORTHSTAR_API_KEY | The integration account's API key | northstar_… |
You can also pass them in code, for example when you read the key from a secret manager:
from northstar_sdk import Client
client = Client(
api_url="https://data.example.com/api",
api_key=secrets["northstar-api-key"],
timeout=120, # seconds, the default
)Client() raises a ValueError if the URL or the key is missing.
The client
Client is the single entry point. It talks only to the platform API: your warehouse credentials, when you register a storage system, go to Northstar, which encrypts them.
The organization comes from the key. The first call that needs it asks the platform once, then keeps it:
client = Client()
print(client.resolve_organization()) # the organization id of the keyNamespaces
Each kind of resource has a namespace on the client:
| Namespace | Read | Write |
|---|---|---|
client.storage_systems | — | create, upsert, update, delete |
client.data_source_categories | — | create, upsert, update, delete |
client.data_sources | list, get | create, upsert, update, delete |
client.datasets | list, get, find_by_name | create, upsert, update, delete |
client.document_collections | — | create, upsert, update, delete, then ingest() |
client.kpis | list, get, find_by_name | create, upsert, update, delete |
client.figures | list, get | create, upsert, update, delete |
client.dashboards | browse, get, find_by_title | create, upsert, update, delete, create_folder |
client.dashboard_folders | browse, list, get, find_by_name | create, upsert, update, delete |
client.teams | list, find_by_name, find_by_slug | create, upsert, update, delete |
client.users | resolve | create, upsert, update |
client.organisations | — | create, upsert, update, delete |
client.search | global search | — |
Reads only return what the account's teams can see:
list(search=…, page=1, limit=20)returns aPagewithitems,total,total_pagesandhas_next.list_all()fetches every page.get(id)returnsNonewhen the resource does not exist or the account cannot see it.get_or_raise(id)raisesNotFoundErrorinstead.find_by_name(name)raisesNotFoundErrorwhen nothing matches andAmbiguousLookupErrorwhen several resources match.
Create, update, upsert, delete
| Method | Use it to | When the resource already exists |
|---|---|---|
create(...) | Add a resource that must not exist yet | Fails with 409 Conflict, giving the existing id |
update(id, ...) | Change a resource you know the id of | Updates it; fails with 404 if it is missing |
upsert(...) | Provision idempotently, for example at each pipeline run | Updates it instead of failing |
delete(id) | Remove a resource | Deletes it; fails with 404 if it is missing |
Each resource is identified by a business key: the slug of a storage system or a data source, the storage system and location of a dataset, the embed URL of a dashboard. upsert uses that key to find the existing resource.
Write methods return a handle: an object that knows the resource's id and offers its actions. for_id(id) gives the handle of an existing resource.
dataset = client.datasets.upsert(
location={"schema": "marts", "table": "orders"},
name="Orders",
type="TABLE",
layer="GOLD",
storage_system_slug="warehouse",
)
dataset.analyze()
same_dataset = client.datasets.for_id(dataset.dataset_id)Governance
Handles of datasets, KPIs, dashboards and figures carry the governance actions of teams and resources:
dataset.assign_to_team("sales") # default rights for the resource type
dataset.assign_to_team("finance", permissions=["view", "ask_ai"])
dataset.assign_owner("owner@example.com")
dataset.assign_editors(["editor@example.com"])assign_to_teamtakes the team's slug. An unknown slug assigns nothing: the result then carries a warning instead of raising an error.- Without
permissions, the team gets the default rights of the resource type. - The owner and the editors must belong to a team the resource is shared with: assign the team first.
- Figures have no owner: call
assign_editorson them, notassign_owner. Document collections are assigned to teams in the app. - A new dataset is only visible to platform administrators until a team gets access to it. Assign a team right after creating it.
Errors
| Error | When |
|---|---|
ValueError | NORTHSTAR_API_URL or NORTHSTAR_API_KEY is missing, or the key has no organization |
PermissionError | The key is missing, unknown or revoked (401) |
httpx.HTTPStatusError | Any other error answer: 400 invalid input, 403 missing right, 404 not found, 409 conflict. The response body explains it. |
NotFoundError, AmbiguousLookupError | A lookup by id or name found nothing, or more than one resource |
See the error answers for their content.
FAQ
Does the SDK read data from my warehouse? No. It registers and governs resources; Northstar reads the warehouse with the credentials of the storage system.
Can I use the SDK from a notebook? Yes, with an integration account's key in the environment. Use a dedicated key, and revoke it when the notebook is done.
Which resources can the SDK not manage yet? Validation rules, alerts, transformations and dashboards built in Northstar are managed in the app. The SDK registers dashboards embedded from other tools.