SDK & shared models
Type-safe async Python SDK and the shared Pydantic models for the
youSleep sleep-analysis platform. Published to PyPI as
yousleep-common.
Analyze a sleep recording in three lines:
from yousleep_common.client import AsyncClient
async with AsyncClient(base_url="https://api.yousleep.ai", token="...") as client:
result = await client.workflows.analyze_file(
file="night.edf", analysis_config_id="u-sleep-research-v1"
)
print(result.biomarkers.biomarkers.tst_min, len(result.events))
What it covers
| Area | Detail |
|---|---|
| Workflows | client.workflows runs upload → submit → poll → fetch in one call; the _temporary variants delete what they created on block exit, including on exception |
| Multi-file batches | analyze_files submits and polls through the server's batch endpoints; per-file outcomes are returned rather than raised, so one bad file does not abort the batch. The server caps a batch at 500 items |
| Endpoint namespaces | admin, analyses, auth, batch, billing, legal, projects, recordings, report_exports, reports, status, studies, user, workflows — checked against the server's OpenAPI spec in CI (make verify-routes) |
| Uploads | Presigned S3 PUT, streamed in 64 KiB chunks with an optional progress callback, so the file is not held in memory |
| Typing | Pydantic v2 request/response models, py.typed, mypy strict |
| Presentation models | Server-computed tables and charts (formatted values, units, curated summary flags, status tokens, hover descriptions) so every renderer draws the same thing |
| Auth and errors | JWT with automatic refresh, retry with exponential backoff on rate limits, and one exception per failure mode (see below) |
Installation
pip install yousleep-common
Requires Python 3.12+.
Quick start
Authenticate
from yousleep_common.client import AsyncClient
from yousleep_common.models import UserAuthentication
client = await AsyncClient.from_credentials(
base_url="https://api.yousleep.ai",
credentials=UserAuthentication(email="you@example.com", password="..."),
)
Or pass a JWT directly: AsyncClient(base_url=..., token=...).
Analyze a file end-to-end
result = await client.workflows.analyze_file(
file="night.edf",
analysis_config_id="u-sleep-research-v1",
study_name="Subject 001", # optional; inferred from filename if omitted
age=35, sex="male", # optional subject metadata
)
result.events # list[Event] | None
result.biomarkers # AnalysisBiomarkersResponse | None
result.biomarkers.biomarkers # Biomarkers: tst_min, tib_min, sleep_efficiency_pct, …
result.biomarkers.table # TableModel | None — the server-defined presentation table
analyze_file_temporary is the ephemeral variant: it deletes everything it
created when the block exits, including on error.
async with client.workflows.analyze_file_temporary(
file="night.edf", analysis_config_id="u-sleep-research-v1"
) as result:
export(result.biomarkers)
# project, study, recording, and analysis no longer exist
Score many files at once
result = await client.workflows.analyze_files(
files=["sub-01.edf", "sub-02.edf", "sub-03.edf"],
analysis_config_id="u-sleep-research-v1",
)
for ok in result.succeeded:
print(ok.file, ok.result.biomarkers)
for bad in result.failed:
print(bad.file, bad.status, bad.error) # per-file; never aborts the batch
Use the low-level client
Every REST resource is a typed namespace on the client:
from pathlib import Path
from yousleep_common.models import ProjectCreate, StudyCreate, AnalysisRequest
project = await client.projects.create(ProjectCreate(name="My Study 2026"))
study = await client.studies.create(project.id, StudyCreate(name="Subject 001"))
# `upload` takes a Path or an open binary file — not a str path.
recording = await client.recordings.upload(study.id, Path("night.edf"))
analysis = await client.analyses.submit(
recording.id, AnalysisRequest(analysis_config_id="u-sleep-research-v1")
)
analysis = await client.analyses.wait_for(analysis.id, timeout=3600)
events = await client.analyses.get_events(analysis.id)
wait_for raises ClientTimeoutError — not the builtin TimeoutError — when
timeout elapses before a terminal status.
Error handling & usage limits
All SDK errors derive from YouSleepClientError:
from yousleep_common.client import (
AnalysisWorkflowError, # analysis ended failed/cancelled (carries logs)
AuthenticationError, # 401
InsufficientCreditsError, # 402 — not enough credits
NotFoundError, # 404
QuotaExceededError, # usage quota hit (projects/studies/analyses/hours)
RateLimitError, # 429 throttling (retried automatically first)
ValidationError, # 422
)
Quota errors are raised immediately rather than retried. Check limits and current consumption up front:
limits = await client.user.usage_limits() # your account's usage limits (None = unlimited)
usage = await client.user.usage_detailed() # your current usage
print(usage.storage.active, "/", limits.storage.active, "bytes")
In multi-file workflows, a quota hit on one file fails only that file's outcome — the rest of the batch continues.
Shared models
yousleep_common.models and yousleep_common.types are the platform's shared
contract — the same Pydantic models and enums used by the youSleep API server.
Import them for type-safe request building and response handling:
from yousleep_common.models import AnalysisRequest, Event, StudyCreate
from yousleep_common.types import AnalysisStatus, AnalysisType, EventLabel
Documentation
- Integration guide — the end-to-end path for an external system: credentials, ingestion, submission, polling, results, and the limits that shape all four
- SDK guide — installing, authenticating, the shape of the client
- Workflows guide — the high-level helpers in depth
Those three pages live in the source repository and are not shipped in the
package, so the links above resolve on GitHub and not from PyPI. The generated
API reference is served from docs.yousleep.ai. Both that site and the
repository are access-restricted: if you are integrating against the platform
and cannot reach them, ask support rather than assuming the links are broken.
What does travel with the package is the code and its docstrings, so help()
and an IDE resolve every signature offline without any of the above.
Development
make install # uv sync
make check # ruff, mypy (strict), deptry, lock check
make test # pytest
make verify-routes # SDK ↔ OpenAPI spec coverage check (every unimplemented route is listed by name in tests/test_sdk_routes.py)
make update-openapi URL=https://api.yousleep.ai # refresh the committed fixture; a weekly workflow opens a PR when the deployed API is newer
Releases are automated with python-semantic-release (Angular commit convention).
License
Support
- support@yousleep.ai — the channel for everyone, and the only one if you reached this package from PyPI
- GitHub Issues — requires access
to the
yousleep-aiorganisation
Release files for yousleep-common 28.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| yousleep_common-28.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / yousleep_common-28.2.0-py3-none-any.whl
| Download URL | yousleep_common-28.2.0-py3-none-any.whl |
|---|---|
| Size | 243.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4c2ad9933f517b244e2700e6071ea25b36c42e8e0e8167086fe2eebe2946f083
|
|
BLAKE2b-256 checksum How to use checksums |
7400faa7fc65387b269462ecb0000ccd1847b85f15ff253c4ddd5ba033a719ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency log