Skip to content

Run scripts unattended

Run a Python script on a schedule, on a server or in CI, with no browser to sign in. The example exports the past week's activities to a parquet file every night.

1. Get the tokens

On your own machine, sign in once:

from sweatstack import Client

client = Client()
client.authenticate()
print(client.api_key.get_secret_value())
print(client.refresh_token.get_secret_value())

The access token expires. The refresh token lets the SDK get a new access token without a browser. Treat both like passwords.

For a script that only ever reads your own data, an API key from Settings → API works too.

2. Set them in the environment

On the server, set both as environment variables, for example as secrets in your CI or scheduler:

export SWEATSTACK_API_KEY="..."
export SWEATSTACK_REFRESH_TOKEN="..."

Don't call authenticate() in the script. Client() reads both variables. When the access token expires, the SDK refreshes it and keeps the new one for the rest of the run; the variables are not changed.

3. Write the script

from datetime import date, timedelta

from sweatstack import Client

with Client(max_retries=4) as client:
    week = client.activities.list(start=date.today() - timedelta(days=7), output="polars")
week.write_parquet(f"activities-{date.today()}.parquet")

max_retries=4 makes the script retry a failed read four times instead of twice, so a short outage doesn't fail the nightly run. See Errors.

4. Fail loudly

A scheduled script has no one watching it. Exit with a clear message and a non-zero status when the sign-in fails:

import sys

from sweatstack import Client, SweatStackAuthError, SweatStackTokenRefreshError

try:
    with Client() as client:
        print(client.whoami().display_name)
except (SweatStackAuthError, SweatStackTokenRefreshError) as error:
    sys.exit(f"SweatStack sign-in failed, get new tokens: {error}")

SweatStackTokenRefreshError means the refresh token is expired or revoked. Repeat step 1 to get new tokens.

Complete script
# /// script
# requires-python = ">=3.10"
# dependencies = ["sweatstack[polars]"]
# ///
import sys
from datetime import date, timedelta

from sweatstack import Client, SweatStackAuthError, SweatStackTokenRefreshError

try:
    with Client(max_retries=4) as client:
        week = client.activities.list(
            start=date.today() - timedelta(days=7), output="polars"
        )
except (SweatStackAuthError, SweatStackTokenRefreshError) as error:
    sys.exit(f"SweatStack sign-in failed, get new tokens: {error}")

week.write_parquet(f"activities-{date.today()}.parquet")
print(f"Exported {week.height} activities")

Run it with uv run export.py.