Tests¶
client.tests: /api/v1/tests/...
Bases: Resource
Tests: fitness assessments with structured results (thresholds, VO2max, critical power).
app_metadata
cached
property
¶
This app's metadata on tests: set(test_id, data=...) and delete.
create(*, sport, start, title=None, end=None, results=None, tags=None)
¶
Creates a test.
Endpoint: POST /api/v1/tests/
Parameters:
-
sport(Sport | str) –The sport.
-
start(datetime) –When the test started. Must be timezone-aware.
-
title(str | None, default:None) –A title.
-
end(datetime | None, default:None) –When the test ended. Must be timezone-aware. Defaults to
startplus three hours, server-side. -
results(TestResults | None, default:None) –Structured results: thresholds, capacities, and so on.
-
tags(list[str] | None, default:None) –Tags.
Returns:
-
TestSummary(TestSummary) –The created test.
Raises:
-
ValueError–If
startorendis timezone-naive. -
SweatStackAPIError–If the API request fails.
Examples:
from datetime import datetime, timezone
from sweatstack import Client, Marker, TestResults
client = Client()
test = client.tests.create(
sport="cycling",
start=datetime(2026, 5, 1, 9, 0, tzinfo=timezone.utc),
title="Lactate step test",
results=TestResults(lt1=Marker(power=210), lt2=Marker(power=285)),
)
delete(test_id)
¶
Deletes a test.
Endpoint: DELETE /api/v1/tests/{test_id}
Parameters:
-
test_id(str) –The test's ID.
Raises:
-
SweatStackNotFoundError–If the test does not exist.
-
SweatStackAPIError–If the API request fails for any other reason.
Examples:
from sweatstack import Client
client = Client()
client.tests.delete("test_123")
list(*, start=None, end=None, sport=None, tags=None, created_by=None, limit=50, offset=0, output=None)
¶
list(*, start: date | None = None, end: date | None = None, sport: SportParam | None = None, tags: TagParam | None = None, created_by: str | None = None, limit: int = 50, offset: int = 0, output: Literal['models'] | None = None) -> builtins.list[TestSummary]
list(*, start: date | None = None, end: date | None = None, sport: SportParam | None = None, tags: TagParam | None = None, created_by: str | None = None, limit: int = 50, offset: int = 0, output: Literal['pandas']) -> pd.DataFrame
list(*, start: date | None = None, end: date | None = None, sport: SportParam | None = None, tags: TagParam | None = None, created_by: str | None = None, limit: int = 50, offset: int = 0, output: Literal['polars']) -> pl.DataFrame
list(*, start: date | None = None, end: date | None = None, sport: SportParam | None = None, tags: TagParam | None = None, created_by: str | None = None, limit: int = 50, offset: int = 0, output: Literal['arrow']) -> pa.Table
Lists tests, newest first.
Endpoint: GET /api/v1/tests/
Parameters:
-
start(date | None, default:None) –Only tests on or after this date.
-
end(date | None, default:None) –Only tests on or before this date.
-
sport(SportParam | None, default:None) –One sport or a list; a test matches any of them.
-
tags(TagParam | None, default:None) –One tag or a list; a test must have all of them.
-
created_by(str | None, default:None) –Only tests created by this app (client ID).
-
limit(int, default:50) –How many tests to return. The client pages through the endpoint until it has this many or there are no more.
-
offset(int, default:0) –How many of the newest matching tests to skip.
-
output(ListOutput | None, default:None) –"models"(default),"pandas","polars"or"arrow".
Returns:
-
list[TestSummary] | DataFrame | DataFrame | Table–TestSummary objects, or a frame with one row per test;
resultsis flattened to -
list[TestSummary] | DataFrame | DataFrame | Table–dotted columns in pandas and a struct in Polars and Arrow.
Raises:
-
SweatStackAPIError–If the API request fails.
Examples:
from sweatstack import Client
client = Client()
tests = client.tests.list(sport="cycling", output="pandas")
replace(test_id, *, sport, start, title=None, end=None, results=None, tags=None)
¶
Replaces every field of a test.
Endpoint: PUT /api/v1/tests/{test_id}
Every field you leave out is cleared. To change one field, retrieve the test first and pass all its fields back.
Parameters:
-
test_id(str) –The test's ID.
-
sport(Sport | str) –The sport.
-
start(datetime) –When the test started. Must be timezone-aware.
-
title(str | None, default:None) –A title.
-
end(datetime | None, default:None) –When the test ended. Must be timezone-aware.
-
results(TestResults | None, default:None) –Structured results.
-
tags(list[str] | None, default:None) –Tags.
Raises:
-
ValueError–If
startorendis timezone-naive. -
SweatStackNotFoundError–If the test does not exist.
-
SweatStackAPIError–If the API request fails for any other reason.
Examples:
from sweatstack import Client
client = Client()
test = client.tests.retrieve("test_123")
client.tests.replace(
test.id, sport=test.sport, start=test.start, end=test.end,
title="Renamed", results=test.results, tags=test.tags,
)
retrieve(test_id, *, trace_resolution=TraceResolution.auto)
¶
Retrieves a test with its traces and the activities it overlaps.
Endpoint: GET /api/v1/tests/{test_id}
Parameters:
-
test_id(str) –The test's ID.
-
trace_resolution(TraceResolution | str, default:auto) –Which traces the
traceslist holds (activitiesis always matched by time overlap). Sent as thetracesquery parameter."auto"(default): traces inside the test's time range, plus traces linked to this test, minus traces linked to another test."linked": only traces linked to this test, whatever their timestamp.
Returns:
-
TestDetails(TestDetails) –The test with its traces and activities.
Raises:
-
SweatStackNotFoundError–If the test does not exist.
-
SweatStackAPIError–If the API request fails for any other reason.
Examples:
from sweatstack import Client
client = Client()
test = client.tests.retrieve("test_123", trace_resolution="linked")
print([trace.lactate for trace in test.traces])
Bases: _RecordAppMetadata
This app's metadata on tests. Requires an app token.
delete(test_id)
¶
Deletes this app's metadata from a test.
Endpoint: DELETE /api/v1/tests/{test_id}/app-metadata
Parameters:
-
test_id(str) –The test's ID.
Raises:
-
SweatStackAuthError–If the client does not hold an app token (403).
-
SweatStackAPIError–If the API request fails for any other reason.
Examples:
from sweatstack import Client
client = Client(api_key="app-user-token")
client.tests.app_metadata.delete("test_123")
set(test_id, *, data)
¶
Replaces this app's metadata on a test.
Endpoint: PUT /api/v1/tests/{test_id}/app-metadata
The whole dict is replaced; there is no merge. Each app sees only its own metadata,
and it appears as app_metadata on the test when read with an app token.
Parameters:
-
test_id(str) –The test's ID.
-
data(dict[str, Any]) –Any JSON-serialisable dict, at most 1 KB and 32 levels deep.
Raises:
-
SweatStackAuthError–If the client does not hold an app token (403). A personal token, from
authenticate()or an API key, never qualifies. -
SweatStackBadRequestError–If
datais too large (413) or too deep (422). -
SweatStackNotFoundError–If the test does not exist.
-
SweatStackAPIError–If the API request fails for any other reason.
Examples:
from sweatstack import Client
client = Client(api_key="app-user-token") # e.g. user.client in FastAPI
client.tests.app_metadata.set("test_123", data={"reviewed": True})