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.