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¶
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¶
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`: 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.
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:
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 listbefore anything that writes, or scope one command withDATAVO_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.