Skip to content

Clients

How to create clients, when the module-level interface is safe to use, and how to act as another user.

Create one client per user

A Client holds one user's credentials and settings, and its own connection pool. In an app that serves several users, create one client per user, or use the one the Streamlit or FastAPI helper gives you:

from sweatstack import Client

client = Client(api_key="your-api-key", timeout=30.0)
activities = client.activities.list(limit=10)

A client reuses its connections across requests. To release them at a known point, use the client as a context manager or call close():

from sweatstack import Client

with Client(api_key="your-api-key") as client:
    activities = client.activities.list()

A client is safe to share between threads. If its access token expires, one thread refreshes it and the others wait.

Use the module-level interface in scripts and notebooks

The sweatstack module mirrors the client: sweatstack.activities.list() calls activities.list() on one shared client.

import sweatstack

sweatstack.authenticate()
activities = sweatstack.activities.list(limit=10)

The shared client is one per Python process. That's convenient in a script or a notebook. In an app that serves several users, it would send every user's requests with the same credentials, so the app could show one user's data to another. Don't use the module-level interface in apps.

Act as another user

If you have access to other people's data, as a coach or a team member, delegated_client() returns a new client that acts as one of them. The original client doesn't change.

from sweatstack import Client

coach = Client()
athletes = coach.users.list(include_managed=False)
for athlete in athletes:
    athlete_client = coach.delegated_client(athlete)
    latest = athlete_client.activities.latest()
    print(athlete.display_name, latest.start_local if latest else "no activities")

users.list() returns everyone you can access, yourself included. To find one user by name, pass name. It returns every user whose display name contains the text, ignoring case, so check how many you got before you pick one:

from sweatstack import Client

coach = Client()
matches = coach.users.list(name="carla")
if len(matches) != 1:
    raise ValueError(f"Expected one user matching 'carla', found {len(matches)}")
carla = coach.delegated_client(matches[0])

To act as a user through a team's access, pass team_id: coach.delegated_client(athlete, team_id=team.id). List a team's users with coach.teams.users(team.id).

A delegated client keeps the original's settings (output, timeout, max_retries and the app credentials). To get back to the signed-in user from a delegated client, call principal_client().

Configure a client

Argument Default Meaning
api_key, refresh_token from the environment or a saved sign-in See Authentication.
output None The default container for collections. See Data output.
timeout 60.0 Seconds to wait for a connection and for each read.
max_retries 2 How often to retry a failed GET, PUT or DELETE. See Errors.
url https://app.sweatstack.no The SweatStack instance.
client_id, client_secret the SDK's own app Your app's credentials, for the Portal and the token exchange.

See Configuration for the environment variables.