Skip to content

2. Setup

Two surfaces, one install: the datavo CLI and the datavo_sdk Python client. Start with the CLI to prove you can reach a server, then build the client the rest of the guide uses.

Install

uv add datavo-cli
# or
pip install datavo-cli

datavo-cli depends on datavo-sdk[entra], so this installs the datavo command, the Python client and MSAL together — everything Entra sign-in needs. The chapters also use numpy for example payloads, and torch only where a DataLoader or a .pth key appears.

Sign in

datavo auth login

That is the whole setup. The CLI already points at https://prod.datavo.io, so there is nothing to configure first — auth login needs no flags either: against an Entra server it runs the interactive login and caches the refresh token in ~/.datavo/msal_cache.json.

Using a different instance Only if you have been told to. A profile stores a name and URL in `~/.datavo/config.json`:
datavo config set dev --url https://dev.datavo.io
datavo config use dev
Omit the profile name and it is the URL's hostname. `DATAVO_API_BASE_URL` overrides the profile for one command, and `DATAVO_PROFILE` selects a saved one. `config set` also caches the server's public config in `~/.datavo/server_config.json`.

Check connectivity

Three commands, in order — each fails differently, so together they say where a problem is:

datavo config show       # which server you point at, and the Entra settings it advertised
datavo auth status       # whether a credential is in place locally
datavo sample-store list # the first authorized round trip to the server

The first two read local state; sample-store list is the one that actually calls the server, so it tests reachability, authentication and your role at once. A 403 there means you got through and your role is the limit.

Your role

Access is a role, resolved outside Datavo and enforced on every route:

Role Can
reader browse, read, download
contributor reader, plus create stores, import, attach, build datasets

client.get_auth_status() reports your user_id and roles from the server — datavo auth status only reports local credential state. A 403 anywhere is this table, not your setup.

The Python client

Everything from chapter 4 on is Python. Constructing a client is all the authentication you do: it discovers the tenant, client id and audience from the server's /config and reuses the MSAL cache the CLI just wrote, so it refreshes silently.

from datavo_sdk import DatavoClient

client = DatavoClient()

It defaults to https://prod.datavo.io; pass server_url= only to reach a different instance. Two variations:

# headless — device code instead of a browser
from datavo_sdk import login_entra
client = DatavoClient(token_provider=login_entra(device_flow=True))

# CI — a token obtained outside the client
client = DatavoClient(auth_token="<token>")

Use it as a context manager (with DatavoClient(...) as client:) in a short script, and keep it alive for as long as you iterate data — iteration is lazy and streams through it.

Reads can also build their own client: omit client= from SampleStream.from_dataset(...) and it falls back to DATAVO_API_BASE_URL / DATAVO_AUTH_TOKEN, or to the active CLI profile. That is what makes a script portable between your machine and CI.

The tokens involved

Every request reaches the server as a token. There are two kinds: your identity token, and the short-lived stream ticket issued from it while you iterate. Authority narrows — a ticket can do less than the identity behind it — and both are short-lived, refreshed or reissued as you work.

Token Authorizes Obtained by Lifetime
identity token everything your role allows (above) datavo auth login, or constructing DatavoClient() ≈1 hour, refreshed silently
stream ticket one shard, read once issued by the SDK while you iterate ≈30 minutes

Identity token — who you are. datavo auth login authenticates you through Entra and caches the credential; DatavoClient() reuses that cache and refreshes it silently, so constructing the client is the whole of authentication. Each Entra access token lasts about an hour, and MSAL renews it from the cached refresh token, so interactive use never encounters the limit. In CI, pass a token acquired elsewhere as auth_token=. This credential backs every CLI command and client method and carries your role — a 403 reflects that role, not a missing token.

Stream ticket — one shard, once. Iterating a workset or downloading a dataset transfers shards over plain HTTP. The SDK requests a short-lived signed URL for each shard and uses it on your behalf, so the download path carries no session. You handle a ticket directly only to pass its download_url to a non-SDK client.

Run the examples

Each chapter from here has a script. They take the server from DATAVO_SERVER, then the active CLI profile, then a local server — deliberately not the production default the client uses, since every script creates and deletes a store. Name the server you mean:

DATAVO_SERVER=https://dev.datavo.io python examples/01_ingest_source.py

Every script creates its own throwaway store, prints what it does, and deletes what it created, so they are safe to run repeatedly against a shared server.

Pitfalls

  • A profile pointing somewhere else. Commands target whichever profile is active. Check datavo config list before anything that writes, or scope one command with DATAVO_PROFILE=<name> datavo ….
  • Skipping the CLI login. The Python client can log in interactively too, but doing it once through the CLI keeps scripts non-interactive afterwards.

Next: 3. Download data — get existing data onto your disk.