Index
API endpoint handlers for the YouSleep client.
AdminEndpoint
¶
Bases: BaseEndpoint
Handle admin-specific API endpoints.
Provide methods for accounts, organizations (their limits and credits), and platform statistics. All methods require admin role.
adjust_organization_credits(org_id, adjustment)
async
¶
Add to or deduct from an organization's purchased credits.
A deduction never takes credits held for running analyses, so less than requested may be deducted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
adjustment
|
CreditAdjustment
|
The signed amount and the reason, kept on the ledger. |
required |
Returns:
| Type | Description |
|---|---|
AdminOrganizationDetailOut
|
The organization with its new balance |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the organization does not exist |
ForbiddenError
|
If not an admin user |
approve_capability_request(request_id)
async
¶
Approve a request for a capability, which turns the capability on.
Refused unless the organization's owner has accepted the latest published site agreement, or the platform operates the organization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
UUID | str
|
The request id. |
required |
approve_credit_request(request_id, approval=None)
async
¶
Approve a grant or extension request, as asked or with changes.
Approving a grant request makes the grant; approving an extension moves the grant's expiry. The requester is emailed the decision.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
UUID | str
|
The request id. |
required |
approval
|
AdminCreditRequestApprove | None
|
A different amount or term, and a note for administrators; the request's own when omitted. |
None
|
approve_runner(runner_id, fingerprint)
async
¶
Approve a pending runner, with the fingerprint read on its host.
The runner prints its key's fingerprint when it enrols. Compare it with the one on the host, not one passed along by someone else: the platform refuses an approval whose fingerprint differs from the enrolled key's.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runner_id
|
UUID | str
|
The runner to approve. |
required |
fingerprint
|
str
|
The whole fingerprint, |
required |
Returns:
| Type | Description |
|---|---|
RunnerOut
|
The runner, now active. |
Raises:
| Type | Description |
|---|---|
YouSleepClientError
|
If the fingerprint differs or the runner is not pending (409) |
NotFoundError
|
If the runner does not exist |
ForbiddenError
|
If not an admin user |
approve_user(user_id)
async
¶
Approve a pending request-access account so its owner can log in.
Idempotent — approving an already-approved account is a no-op.
To decline a request instead, use :meth:reject_user.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the pending user to approve |
required |
Returns:
| Type | Description |
|---|---|
AdminUserOut
|
The approved user ( |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If user does not exist |
ForbiddenError
|
If not an admin user |
cancel_analyses(request)
async
¶
Cancel analyses across accounts, one bounded page per call.
Address them by explicit ids, by a filter (an account, a set of live
states, or both) with the count seen on the listing, or by all
with that count. A live-set selector whose count moved since it was
previewed is refused with a conflict. Each call handles at most the
server's per-request cap; loop on summary.remaining.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
AdminCancelAnalysesRequest
|
The selector and, for a live set, the expected count |
required |
Returns:
| Type | Description |
|---|---|
AdminCancelAnalysesResponse
|
Per-item results and the page summary, including what remains |
Raises:
| Type | Description |
|---|---|
ConflictError
|
If a live set's count moved since it was previewed |
ForbiddenError
|
If not an admin user |
Example
page = await client.admin.list_analyses(user_id=user_id,
status_any=[AnalysisStatus.PENDING])
request = AdminCancelAnalysesRequest(
selector={"filter": {"user_id": user_id,
"status_any": [AnalysisStatus.PENDING]}},
expected_count=page.total,
)
result = await client.admin.cancel_analyses(request)
while result.summary.remaining and result.summary.cancelled:
request.expected_count = result.summary.remaining
result = await client.admin.cancel_analyses(request)
clear_control(name)
async
¶
Clear a control's override; the configured value applies again at once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
PlatformControlName | str
|
The control |
required |
Returns:
| Type | Description |
|---|---|
PlatformControlOut
|
The control as it now reads |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
create_demo_dataset(dataset)
async
¶
Register a new demo dataset (or replace an existing one by name).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset
|
AdminDemoDatasetCreate
|
Demo dataset definition including studies and S3 keys |
required |
Returns:
| Type | Description |
|---|---|
AdminDemoDatasetOut
|
The created/updated demo dataset with study and recording counts |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
create_enrolment_token(pool_id)
async
¶
Create a single-use token a runner enrols into a pool with.
The token is in this answer only and is never shown again. Give it to the runner's installer, who passes it on standard input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pool_id
|
UUID | str
|
The pool the runner joins. |
required |
Returns:
| Type | Description |
|---|---|
EnrolmentTokenOut
|
The token and when it expires. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the pool does not exist |
ForbiddenError
|
If not an admin user |
create_user(user)
async
¶
Provision a new user.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user
|
AdminUserCreate
|
User creation data (email, password, subscription level, etc.) |
required |
Returns:
| Type | Description |
|---|---|
AdminUserOut
|
The newly created user |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If user data is invalid |
ForbiddenError
|
If not an admin user |
decline_capability_request(request_id, decline)
async
¶
Decline a request for a capability, with the reason the organization is shown.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
UUID | str
|
The request id. |
required |
decline
|
AdminCapabilityRequestDecline
|
The reason. |
required |
decline_credit_request(request_id, decline)
async
¶
Decline a grant or extension request with a reason the requester is sent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
UUID | str
|
The request id. |
required |
decline
|
AdminCreditRequestDecline
|
The reason, a note for administrators, and whether to email the requester. |
required |
delete_demo_dataset(dataset_id)
async
¶
Delete a demo dataset catalog entry. Does not delete S3 files.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_id
|
UUID | str
|
UUID of the demo dataset to delete |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming deletion |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If dataset does not exist |
ForbiddenError
|
If not an admin user |
delete_project(project_id)
async
¶
Delete any account's project, with everything in it, in the background.
The deletion runs as the project's owner would run it and is written to the audit trail under your account. A second call while one is still running starts nothing new.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message saying the deletion started, or is already running |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the project does not exist |
ForbiddenError
|
If not an admin user |
delete_user(user_id)
async
¶
Delete a user.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the user to delete |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming deletion |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If user does not exist |
ForbiddenError
|
If not an admin, or if attempting to delete own account |
export_audit_events(filters=None, *, org_id=None, actor=None, email=None)
async
¶
Return the audit trail as CSV text, oldest first, under the same filters.
get_health()
async
¶
Read the API's health, dependency by dependency.
The public health check reports only the overall status; this is the breakdown behind it. The call answers even when a dependency is down, so read the fields rather than expecting an error.
Returns:
| Type | Description |
|---|---|
AdminHealthDetail
|
The overall status and one field per dependency |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
get_organization(org_id)
async
¶
Return one organization with its members, as the operators see it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the organization does not exist |
ForbiddenError
|
If not an admin user |
get_organization_credit_totals(org_id)
async
¶
Get an organization's all-time net credit movement per ledger reason.
Signed sums keyed by the CreditReason wire value (grants positive,
charges negative): what the organization received and spent, by kind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id |
required |
Returns:
| Type | Description |
|---|---|
dict[str, int]
|
Mapping of reason -> net credits, e.g. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the organization does not exist |
ForbiddenError
|
If not an admin user |
get_platform_stats()
async
¶
Get platform-wide statistics.
Returns:
| Type | Description |
|---|---|
PlatformStats
|
Statistics including user counts, resource counts, |
PlatformStats
|
and subscription level breakdown |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
get_storage_reconciliation()
async
¶
Read the last storage reconciliation report.
The reconciliation compares each data bucket's objects with the
storage records that reference them, both ways. It runs on a
schedule, and :meth:run_storage_reconciliation starts one now.
Returns:
| Type | Description |
|---|---|
StorageReconciliationReport | None
|
The last report, or None when no report is stored: none has run |
StorageReconciliationReport | None
|
yet, or the last one has expired |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
get_user(user_id)
async
¶
Get detailed information about a specific user.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the user to retrieve |
required |
Returns:
| Type | Description |
|---|---|
AdminUserOut
|
The account's details, permissions and admin fields |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If user does not exist |
ForbiddenError
|
If not an admin user |
get_user_organization(user_id)
async
¶
Return the organization an account belongs to, as that member sees it.
Every account belongs to exactly one organization; this is how an operator finds its id and the member's role before acting on it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the account |
required |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the account does not exist |
ForbiddenError
|
If not an admin user |
get_user_usage(user_id)
async
¶
Get resource usage statistics for a specific user.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the user to retrieve usage for |
required |
Returns:
| Type | Description |
|---|---|
ResourceUsage
|
Resource usage including projects, studies, recordings, |
ResourceUsage
|
analyses, reports, analysis hours, and storage |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If user does not exist |
ForbiddenError
|
If not an admin user |
grant_credits(org_id, grant)
async
¶
Grant an organization research credits directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
grant
|
AdminGrantCreate
|
The amount, the term (none for a grant that never expires) and the reason, kept with the grant. |
required |
Returns:
| Type | Description |
|---|---|
CreditGrant
|
The new grant. |
list_analyses(*, status_any=None, user_id=None, user_email=None, org_id=None, analysis_config_id=None, failure_code=None, since=None, until=None, include_deleted=False, offset=0, limit=50)
async
¶
List analyses across every account, newest first.
The operator's view of the queue and of recent outcomes: each row is the analysis as its owner sees it plus the owner's account and email, the credits charged or held, and the process exit code. Filters combine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
status_any
|
list[AnalysisStatus] | None
|
Only analyses in at least one of these states |
None
|
user_id
|
UUID | str | None
|
Only analyses owned by this account |
None
|
user_email
|
str | None
|
Only analyses owned by the account with exactly this email |
None
|
org_id
|
UUID | str | None
|
Only analyses of this organization |
None
|
analysis_config_id
|
str | None
|
Only analyses of this configuration (string identity); an unknown identity matches nothing |
None
|
failure_code
|
ErrorCode | None
|
Only failed analyses with this failure code |
None
|
since
|
datetime | None
|
Only analyses enqueued at or after this time |
None
|
until
|
datetime | None
|
Only analyses enqueued before this time |
None
|
include_deleted
|
bool
|
Also list soft-deleted analyses, with their deletion time |
False
|
offset
|
int
|
Pagination offset (default: 0) |
0
|
limit
|
int
|
Maximum analyses to return (default: 50, max: 200) |
50
|
Returns:
| Type | Description |
|---|---|
AdminAnalysisListResponse
|
One page and the total the filters match |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_analysis_configs()
async
¶
List every registered analysis and who it is offered to.
Includes private analyses of every organization and withdrawn ones, each with the reason a promotion would be refused, if it would be.
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_audit_events(filters=None, *, user_id=None, org_id=None, action=None, actor=None, email=None, since=None, until=None, offset=0, limit=50)
async
¶
Read the whole audit trail, newest first.
Every privileged or automated action on an account or its data, as recorded. Read-only: nothing writes to the trail through the API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filters
|
AuditFilters | None
|
The views' filters (event types, time window, person, item) |
None
|
user_id
|
UUID | str | None
|
Only events concerning this account |
None
|
org_id
|
UUID | str | None
|
Only events concerning this organization |
None
|
action
|
str | None
|
Only events recording this action (the vocabulary:
|
None
|
actor
|
str | None
|
Only events by exactly this actor, e.g. |
None
|
email
|
str | None
|
Only events concerning the account with this email — the one it has now, or the one it had before it was deleted |
None
|
since
|
datetime | None
|
Only events at or after this time |
None
|
until
|
datetime | None
|
Only events before this time |
None
|
offset
|
int
|
Pagination offset (default: 0) |
0
|
limit
|
int
|
Maximum events to return (default: 50, max: 200) |
50
|
Returns:
| Type | Description |
|---|---|
AuditEventListResponse
|
One page of events and the total the filters match |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_capability_requests(status=None, limit=50, offset=0)
async
¶
Return requests for capabilities across organizations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
status
|
CapabilityRequestStatus | None
|
Only requests in this state; all when omitted. |
None
|
limit
|
int
|
Maximum requests to return. |
50
|
offset
|
int
|
Requests to skip. |
0
|
Returns:
| Type | Description |
|---|---|
AdminCapabilityRequestPage
|
The page: pending requests first, oldest first. |
list_compute_pools(*, offset=0, limit=50)
async
¶
List the compute pools, with the lease period and queue timeout in force.
The platform's own pool is named platform and has no organization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
offset
|
int
|
Pagination offset (default: 0). |
0
|
limit
|
int
|
Maximum pools to return (default: 50, max: 200). |
50
|
Returns:
| Type | Description |
|---|---|
ComputePoolListResponse
|
One page of pools, with the total. |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_controls()
async
¶
Read every operator control.
For each: the configured default, the live override if any, and the effective value.
Returns:
| Type | Description |
|---|---|
PlatformControlsOut
|
Every known control |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_credit_requests(status=None, limit=50, offset=0)
async
¶
Return grant and extension requests across organizations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
status
|
CreditRequestStatus | None
|
Only requests in this state; all when omitted. |
None
|
limit
|
int
|
Maximum requests to return. |
50
|
offset
|
int
|
Requests to skip. |
0
|
Returns:
| Type | Description |
|---|---|
AdminCreditRequestPage
|
The page: pending requests first, oldest first. |
list_demo_datasets()
async
¶
List all registered demo datasets.
Returns:
| Type | Description |
|---|---|
list[AdminDemoDatasetOut]
|
List of demo datasets with study and recording counts |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_organizations(*, search=None, include_retired=False, offset=0, limit=50)
async
¶
List organizations with their owner, seats, projects, storage and credits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
search
|
str | None
|
Filter by organization name or owner email substring (case-insensitive). |
None
|
include_retired
|
bool
|
Also list organizations that were retired (soft-deleted); off by default. |
False
|
offset
|
int
|
Pagination offset (default: 0). |
0
|
limit
|
int
|
Maximum organizations to return (default: 50, max: 200). |
50
|
Returns:
| Type | Description |
|---|---|
AdminOrganizationListResponse
|
One page of organizations, newest first, with the total. |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_run_records(*, kind=None, analysis_id=None, runner_id=None, offset=0, limit=50)
async
¶
List where jobs ran and on what, as their runners attested it, newest first.
A record is written when the platform accepts a job's result, for every kind of job: its subject, the runner and pool, the runner's version, the image digest it ran, the inputs it read and the output it uploaded, its peak memory and its run length.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
LeaseKind | None
|
Only this kind of job's records. |
None
|
analysis_id
|
UUID | str | None
|
Only this analysis's records. |
None
|
runner_id
|
UUID | str | None
|
Only this runner's records. |
None
|
offset
|
int
|
Pagination offset (default: 0). |
0
|
limit
|
int
|
Maximum records to return (default: 50, max: 200). |
50
|
Returns:
| Type | Description |
|---|---|
RunRecordListResponse
|
One page of run records, with the total. |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_runners(*, pool_id=None, offset=0, limit=50)
async
¶
List runners, newest first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pool_id
|
UUID | str | None
|
Only this pool's runners. |
None
|
offset
|
int
|
Pagination offset (default: 0). |
0
|
limit
|
int
|
Maximum runners to return (default: 50, max: 200). |
50
|
Returns:
| Type | Description |
|---|---|
RunnerListResponse
|
One page of runners, with the total. |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
list_site_exceptions(org_id, limit=50, offset=0)
async
¶
Return an organization's exception records, newest first.
An exception lets the organization run an analysis its configuration keeps on the platform at its site. Records only grow: a revocation is a record of its own, and the latest per analysis is its state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
limit
|
int
|
Maximum records to return. |
50
|
offset
|
int
|
Records to skip from the newest. |
0
|
list_user_api_keys(user_id)
async
¶
List another account's API keys — never the secret.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the account |
required |
Returns:
| Type | Description |
|---|---|
list[ApiKeyOut]
|
The account's keys, newest first |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the account does not exist |
ForbiddenError
|
If not an admin |
list_users(*, search=None, disabled=None, pending=None, organization_id=None, offset=0, limit=50, sort=None)
async
¶
List users with optional filtering, ordering and pagination.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
search
|
str | None
|
Filter by email substring (case-insensitive) |
None
|
disabled
|
bool | None
|
Filter by disabled status |
None
|
pending
|
bool | None
|
Filter by request-access approval. True returns only accounts awaiting approval (the approval queue). |
None
|
organization_id
|
UUID | str | None
|
Only the members of this organization. |
None
|
offset
|
int
|
Pagination offset (default: 0) |
0
|
limit
|
int
|
Maximum number of users to return (default: 50, max: 200) |
50
|
sort
|
AdminUserSort | None
|
Ordering — newest first by default, most recent sign-in first (never signed in last), or by email |
None
|
Returns:
| Type | Description |
|---|---|
AdminUserListResponse
|
Paginated user list with total count |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
queue()
async
¶
Read the queue in one call.
Live counts by status, the oldest wait, and the accounts holding the most live analyses.
Returns:
| Type | Description |
|---|---|
AdminQueueSummary
|
The queue summary, with the time it was sampled |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
record_site_exception(org_id, exception)
async
¶
Let an organization run a platform-only analysis at its site, until an expiry.
It covers every version of the analysis. Recording one for an analysis that already has one in force replaces it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
exception
|
SiteExceptionCreate
|
The analysis, the agreement it rests on, and the expiry. |
required |
Returns:
| Type | Description |
|---|---|
SiteExceptionOut
|
The record. |
reject_user(user_id, rejection)
async
¶
Decline a pending access request and tell the applicant why.
The reason is chosen from a fixed list, and the applicant is emailed
it in the platform's own wording unless notify is false. The
reviewer's note is kept in the audit record and is never sent.
The account is disabled at once and erased in the background, which
frees the address, so an applicant declined for a fixable reason can
apply again.
Only a pending account can be declined. An approved account is a
conflict; disable or delete it with :meth:update_user or
:meth:delete_user instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the pending user to decline |
required |
rejection
|
AdminUserReject
|
The reason, the reviewer's note and whether to notify |
required |
Returns:
| Type | Description |
|---|---|
AdminUserOut
|
The account as it stands at the moment of the decision |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If user does not exist |
ForbiddenError
|
If not an admin user |
YouSleepClientError
|
If the account has already been approved (409) |
release_runner(runner_id)
async
¶
Release a quarantined runner, so it leases work again.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runner_id
|
UUID | str
|
The runner to release. |
required |
Returns:
| Type | Description |
|---|---|
RunnerOut
|
The runner. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the runner does not exist |
ForbiddenError
|
If not an admin user |
revoke_runner(runner_id)
async
¶
Revoke a runner; it is refused from its next request on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runner_id
|
UUID | str
|
The runner to revoke. |
required |
Returns:
| Type | Description |
|---|---|
RunnerOut
|
The runner, now revoked. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the runner does not exist |
ForbiddenError
|
If not an admin user |
revoke_site_exception(org_id, analysis_config_id, revoke)
async
¶
End an organization's exception for an analysis before it expires.
Analyses already queued at the site are then failed when a runner would take them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
analysis_config_id
|
str
|
The analysis, by its machine-readable id. |
required |
revoke
|
SiteExceptionRevoke
|
Why it ends. |
required |
Returns:
| Type | Description |
|---|---|
SiteExceptionOut
|
The revocation record. |
revoke_user_api_key(user_id, key_id)
async
¶
Revoke another account's API key; recorded against the administrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the account |
required |
key_id
|
UUID | str
|
UUID of the key |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
A confirmation message |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the account or the key does not exist |
ForbiddenError
|
If not an admin |
run_storage_reconciliation()
async
¶
Start a storage reconciliation now, in the background.
Read the result with :meth:get_storage_reconciliation once it has
finished.
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message saying the reconciliation was queued |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If not an admin user |
set_control(name, update)
async
¶
Set a control's override, replacing any existing one.
The override applies immediately, must carry a reason, and must expire within the server's maximum override length; setting it again with a later expiry is how it is extended.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
PlatformControlName | str
|
The control |
required |
update
|
PlatformControlUpdate
|
The value, the reason and the expiry |
required |
Returns:
| Type | Description |
|---|---|
PlatformControlOut
|
The control as it now reads |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If the expiry lies outside the allowed window |
ForbiddenError
|
If not an admin user |
set_entitlement(org_id, capability, change)
async
¶
Turn one of an organization's capabilities on or off.
On needs the owner's acceptance of the latest published site agreement, unless the platform operates the organization. Off stops new work at the organization's site; nothing already there is touched.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
capability
|
SiteCapability | str
|
The capability to change, or its value. |
required |
change
|
AdminEntitlementChange
|
On or off, and why. |
required |
Returns:
| Type | Description |
|---|---|
OrganizationCapabilities
|
The organization's capabilities after the change. |
transfer_organization_ownership(org_id, request)
async
¶
Hand an organization to one of its members (administrator).
The recovery path when an organization's owner is unreachable. The current owner becomes an admin; both are told by email.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
UUID of the organization |
required |
request
|
AdminOwnershipTransfer
|
The member who becomes the owner |
required |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the organization or member does not exist |
ForbiddenError
|
If not an admin user |
update_analysis_config(analysis_config_id, update)
async
¶
Assign an analysis to an organization, promote it, or withdraw it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_config_id
|
str
|
The analysis configuration's id |
required |
update
|
AdminAnalysisConfigUpdate
|
Only the fields provided change |
required |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If no analysis has this id |
YouSleepClientError
|
If the change is not allowed (409), with the reason |
ForbiddenError
|
If not an admin user |
update_organization(org_id, update)
async
¶
Set or clear an organization's limits and settings (only provided fields change).
The settings are whether the platform operates the organization, whether its analyses run at its site, and its own site-compute factor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
update
|
AdminOrganizationUpdate
|
The overrides to set; an explicit |
required |
Returns:
| Type | Description |
|---|---|
AdminOrganizationDetailOut
|
The organization with the limits now in force |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the organization does not exist |
ValidationError
|
If a study limit passes the platform's ceiling |
ForbiddenError
|
If not an admin user |
update_user(user_id, update)
async
¶
Update a user's properties.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the user to update |
required |
update
|
AdminUserUpdate
|
Fields to update (only provided fields are changed) |
required |
Returns:
| Type | Description |
|---|---|
AdminUserOut
|
The updated user |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If user does not exist |
ForbiddenError
|
If not an admin, or if attempting self-demotion/self-disable |
verify_user_email(user_id)
async
¶
Mark a user's email address as verified, in place of the emailed link.
Idempotent: verifying an already-verified address is a no-op.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
UUID | str
|
UUID of the user |
required |
Returns:
| Type | Description |
|---|---|
AdminUserOut
|
The user, with |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If user does not exist |
ForbiddenError
|
If not an admin user |
AnalysesEndpoint
¶
Bases: BaseEndpoint
Handles analysis-related API endpoints.
Analyses are sleep analysis jobs (staging, REM detection, etc.) run on recordings.
cancel(analysis_id)
async
¶
Cancel a running or pending analysis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis to cancel |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming cancellation |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
ValidationError
|
If analysis cannot be cancelled |
AuthenticationError
|
If not authenticated |
count_for_project(project_id, *, status_any=None, analysis_config_id=None)
async
¶
Count the analyses a filter resolves to, without fetching them.
This is the expected_count a live-set analysis operation (e.g.
a filtered batch delete) must present — the server re-resolves
with the SAME predicate and rejects on drift.
delete(analysis_id)
async
¶
Delete an analysis and its results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis to delete |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming deletion |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
AuthenticationError
|
If not authenticated |
download_events_json(analysis_id)
async
¶
Download an analysis and its events as one document.
This is the downloadable events file, validated: the analysis as
analysis and its events as events. The server records the
download in the project's access log.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
Returns:
| Type | Description |
|---|---|
AnnotatedAnalysisEvents
|
The analysis and its events |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
AuthenticationError
|
If not authenticated |
get(analysis_id)
async
¶
Get detailed information about an analysis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
Returns:
| Type | Description |
|---|---|
AnalysisOut
|
Detailed analysis information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
AuthenticationError
|
If not authenticated |
get_biomarkers(analysis_id, soremp_threshold_min=15.0, statistics_window_start_ms=None, statistics_window_end_ms=None)
async
¶
Compute biomarkers for a completed staging analysis.
Returns 13 standard sleep biomarkers (TST, TIB, SE, SOL, WASO, etc.) plus quality metrics. The statistics window defaults to study lights off/on events, then full recording length.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
soremp_threshold_min
|
float
|
Max minutes from sleep onset to the first REM epoch for a SOREMP |
15.0
|
statistics_window_start_ms
|
int | None
|
Optional window start override (ms) |
None
|
statistics_window_end_ms
|
int | None
|
Optional window end override (ms) |
None
|
Returns:
| Type | Description |
|---|---|
AnalysisBiomarkersResponse
|
AnalysisBiomarkersResponse with biomarkers, QC metrics, |
AnalysisBiomarkersResponse
|
metadata, and the server-defined presentation |
AnalysisBiomarkersResponse
|
(None when the server predates the field) |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
AuthenticationError
|
If not authenticated |
get_config(analysis_config_id, *, expand_licence=False)
async
¶
Get detailed information about an analysis configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_config_id
|
str
|
ID of the analysis configuration |
required |
expand_licence
|
bool
|
Return the |
False
|
Returns:
| Type | Description |
|---|---|
AnalysisConfigOut
|
Detailed analysis configuration information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If configuration doesn't exist |
AuthenticationError
|
If not authenticated |
get_event_blocks(analysis_id)
async
¶
Get analysis results as one document of event blocks.
The bulk companion to :meth:get_events. A block is a run of
consecutive equal-duration slots with per-slot attributes as parallel
arrays, so a full night of 1 Hz sleep staging is a handful of blocks
rather than tens of thousands of events. Prefer this whenever you are
reading dense output at scale; get_events stays the convenient
form for a single analysis you intend to iterate.
The document is returned whole — there is no server-side filtering, so fetch once and slice locally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
Returns:
| Type | Description |
|---|---|
EventBlocksDocument
|
The analysis's events in block form. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the analysis doesn't exist or has no results |
AuthenticationError
|
If not authenticated |
get_events(analysis_id, *, window_start_time_ms=None, window_end_time_ms=None, window_mode=None, label=None, analysis_type=None, match_mode=None, offset=None, limit=None)
async
¶
Get analysis results as a list of events.
Called with the analysis id alone, this returns every event. The server can narrow the list in two independent stages:
- A time window, given in milliseconds from the start of the
recording.
window_modedecides how an event must sit in the window to be kept; the server's default isSTART. - A label filter, which names one
label, the labels of oneanalysis_type, or both.match_modekeeps the matching events (INCLUDE, the default) or removes them (EXCLUDE).
offset and limit page through what the filters leave, in the
stored event order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
window_start_time_ms
|
int | None
|
Start of the time window |
None
|
window_end_time_ms
|
int | None
|
End of the time window |
None
|
window_mode
|
WindowFilterModes | None
|
How an event is matched against the window |
None
|
label
|
EventLabel | None
|
One event label to match |
None
|
analysis_type
|
AnalysisType | None
|
Match every label of this analysis type |
None
|
match_mode
|
MatchModes | None
|
Keep or remove the events the labels match |
None
|
offset
|
int | None
|
Events to skip, after the filters |
None
|
limit
|
int | None
|
Maximum events to return |
None
|
Returns:
| Type | Description |
|---|---|
list[Event]
|
List of events from the analysis |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist or has no results |
ValidationError
|
If the window is invalid |
AuthenticationError
|
If not authenticated |
get_logs(analysis_id)
async
¶
Get analysis execution logs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
Returns:
| Type | Description |
|---|---|
AnalysisLogs | None
|
Analysis logs, or None if no logs are available |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
AuthenticationError
|
If not authenticated |
get_run(analysis_id)
async
¶
Get where an analysis runs or ran, and on what.
The place is known from submission; the image digest and the inputs' SHA-256 once the run's result is accepted. The runner's name is shown to the organization's owners and admins only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
Returns:
| Type | Description |
|---|---|
AnalysisRunOut
|
The analysis's run |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
AuthenticationError
|
If not authenticated |
list(recording_id, status=None, analysis_type=None, *, offset=None, limit=None)
async
¶
List analyses for a specific recording.
With neither offset nor limit every matching analysis is
returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
status
|
AnalysisStatus | None
|
Optional analysis status to filter by |
None
|
analysis_type
|
AnalysisType | None
|
Optional analysis type to filter by |
None
|
offset
|
int | None
|
Analyses to skip |
None
|
limit
|
int | None
|
Maximum analyses to return (1-500) |
None
|
Returns:
| Type | Description |
|---|---|
list[AnalysisOut]
|
List of analyses |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording doesn't exist |
AuthenticationError
|
If not authenticated |
list_configs(*, expand_licence=False)
async
¶
List all available analysis configurations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expand_licence
|
bool
|
Return each |
False
|
Returns:
| Type | Description |
|---|---|
list[AnalysisConfigOut]
|
List of available analysis configurations |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
list_for_project(project_id, *, status_any=None, analysis_config_id=None, skip=0, limit=100)
async
¶
List one page of a project's analyses, newest first.
status_any and analysis_config_id are the analysis
selector's filter vocabulary: this listing previews exactly what a
live-set batch operation with the same filter will address. An
unknown analysis_config_id raises NotFoundError rather
than returning an empty page.
list_publications()
async
¶
List the publications behind the analyses on offer to the caller.
The evidence of every analysis the caller may run, with the analysis families it is grouped by, as the portal's publications page shows it.
Returns:
| Type | Description |
|---|---|
PublicationListing
|
The publications and their families. |
quote(recording_id, request)
async
¶
Quote what an analysis would cost, without submitting it.
The quote runs the same validation and pricing as :meth:submit, so
for the same request it equals the charge the submission would
settle. It also says which balance pays for it (research analyses
from grants, commercial ones from purchased credits) and whether that
balance covers it. Nothing is created and no credits are reserved;
the submission itself remains the gate.
A request that could not be submitted fails here in the same way, so a quote also checks a request before it is sent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording to analyze |
required |
request
|
AnalysisRequest
|
The same request you would pass to :meth: |
required |
Returns:
| Type | Description |
|---|---|
BillingQuote
|
The estimated credits, the current balances and, when the |
BillingQuote
|
submission would be refused, |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If configuration or parameters are invalid |
NotFoundError
|
If recording or configuration doesn't exist |
AuthenticationError
|
If not authenticated |
stream_status(analysis_id, poll_interval=5.0, timeout=None)
async
¶
Stream analysis status updates until completion or timeout.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
poll_interval
|
float
|
Seconds between status checks |
5.0
|
timeout
|
float | None
|
Maximum total seconds to poll before raising ClientTimeoutError. None = no limit. |
None
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[AnalysisOut]
|
Analysis status updates |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
AuthenticationError
|
If not authenticated |
ClientTimeoutError
|
If timeout is reached before terminal status |
submit(recording_id, request)
async
¶
Submit a new analysis job.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording to analyze |
required |
request
|
AnalysisRequest
|
Analysis request with config ID and optional parameters |
required |
Returns:
| Type | Description |
|---|---|
AnalysisOut
|
Information about the submitted analysis |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If configuration is invalid |
NotFoundError
|
If recording doesn't exist |
AuthenticationError
|
If not authenticated |
Example
from yousleep_common.models import AnalysisRequest
# Submit with config ID
request = AnalysisRequest(
analysis_config_id="u-sleep-research-v1",
channels=["EEG Fpz-Cz", "EOG horizontal"],
parameters=[["data-per-prediction", 3840]]
)
analysis = await client.analyses.submit(
recording_id=recording.id,
request=request
)
wait_for(analysis_id, poll_interval=5.0, timeout=None)
async
¶
Poll an analysis until it reaches a terminal status and return it.
Convenience wrapper over stream_status for the common case where only
the final state matters: it consumes the status stream and returns the
last (terminal) AnalysisOut. Terminal statuses are COMPLETED,
FAILED, CANCELLED, REJECTED and REVIEW — inspect
.status on the return value to distinguish success from failure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_id
|
UUID | str
|
UUID of the analysis |
required |
poll_interval
|
float
|
Seconds between status checks |
5.0
|
timeout
|
float | None
|
Maximum total seconds to poll before raising ClientTimeoutError. None = no limit. |
None
|
Returns:
| Type | Description |
|---|---|
AnalysisOut
|
The analysis in its terminal status. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If analysis doesn't exist |
AuthenticationError
|
If not authenticated |
ClientTimeoutError
|
If timeout is reached before a terminal status |
AnalysisWorkflowResult
dataclass
¶
AuthEndpoint
¶
Bases: BaseEndpoint
Handles authentication-related API endpoints.
Provides methods for login, registration, token refresh, and user management.
login(credentials)
async
¶
Authenticate with email and password.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
credentials
|
UserAuthentication
|
User authentication credentials (email and password) |
required |
Returns:
| Type | Description |
|---|---|
TokenPair
|
Token information including access_token and refresh_token |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If credentials are invalid |
refresh(refresh_token)
async
¶
Refresh access token using refresh token.
The server reads the refresh token only from the bearer header, so this request sends it there in place of the client's own credential.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_token
|
str
|
Valid refresh token |
required |
Returns:
| Type | Description |
|---|---|
AccessToken
|
New access token information |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If refresh token is invalid or expired |
register(registration)
async
¶
Register a new user account.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registration
|
UserRegistration
|
User registration information |
required |
Returns:
| Type | Description |
|---|---|
UserOut
|
Created user information |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If registration data is invalid |
Example
from yousleep_common.models import UserRegistration
from yousleep_common.types import UsageType
registration = UserRegistration(
email="user@example.com",
password="secure_password",
name="Jane Ríos",
organization="My Lab", # or "Independent"
usage_type=UsageType.RESEARCH,
purpose="Sleep-staging research on our EEG cohort",
position="Researcher", # optional
)
user = await client.auth.register(registration)
request_password_reset(request)
async
¶
Request a password reset email.
The answer is the same whether or not an account with the address exists. No authentication is needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
PasswordResetEmailRequest
|
The address of the account |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming the request |
resend_confirmation_email(request)
async
¶
Resend the email confirmation link to an address.
The answer is the same whether or not an account with that address exists, or is already confirmed, so the call cannot be used to probe for accounts. No authentication is needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
VerificationEmailRequest
|
The address of the account to confirm |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message saying a link was sent if the account exists |
reset_password(token, request)
async
¶
Set a new password with the token from a reset or setup link.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
Password reset token from the email |
required |
request
|
ResetPasswordRequest
|
The new password. The server's password policy decides whether it is accepted. |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming the password change |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the token is invalid, expired or already used |
YouSleepClientError
|
With status 400 if the password does not meet the policy, or the account is disabled or unconfirmed |
verify_email(token)
async
¶
Verify email address using verification token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
Email verification token from email |
required |
Returns:
| Type | Description |
|---|---|
UserOut
|
Verified user information |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If token is invalid or expired |
BatchAnalysisWorkflowResult
dataclass
¶
Everything a multi-file analyze_files run produced.
Per-file failures never raise (mirroring the platform's 207-style batch
semantics); inspect :attr:failed for files that did not complete.
BatchEndpoint
¶
Bases: BaseEndpoint
Handles batch operation API endpoints.
Batch endpoints allow bulk operations across multiple resources in a single request. All endpoints are project-scoped.
cancel_analyses(project_id, request)
async
¶
Batch cancel multiple analyses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project |
required |
request
|
BatchCancelAnalysesRequest
|
Batch cancellation request with analysis IDs |
required |
Returns:
| Type | Description |
|---|---|
BatchCancelAnalysesResponse
|
Response with per-item results and summary counts |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
create_studies(project_id, request)
async
¶
Batch create multiple studies in a project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project |
required |
request
|
BatchCreateStudiesRequest
|
Batch study creation request with list of studies |
required |
Returns:
| Type | Description |
|---|---|
BatchCreateStudiesResponse
|
Response with per-item results and summary counts |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
Example
from yousleep_common.models import BatchCreateStudiesRequest, BatchStudyItem
request = BatchCreateStudiesRequest(
studies=[
BatchStudyItem(name="Subject 001", age=35),
BatchStudyItem(name="Subject 002", age=42),
]
)
result = await client.batch.create_studies(project_id, request)
print(f"Created: {result.summary.created}, Errors: {result.summary.errors}")
delete_analyses(project_id, request)
async
¶
Delete analyses by selector — e.g. clear failed runs by status.
delete_recordings(project_id, request)
async
¶
Delete recordings by selector (ids | all); same contract.
delete_studies(project_id, request)
async
¶
Delete studies by selector (background cascade; returns on acceptance).
The selector addresses the set with exactly one mode — ids,
filter or all. Live-set selectors (filter/all) must carry
expected_count: the count previewed via the filtered study list;
a drifted set is rejected with a conflict error.
Example
from yousleep_common.models import (
DeleteStudiesRequest, StudyFilter, StudySelector,
)
# Delete every study tagged "pilot" (previewed as 12 studies).
accepted = await client.batch.delete_studies(
project_id,
DeleteStudiesRequest(
selector=StudySelector(filter=StudyFilter(tags_any=["pilot"])),
expected_count=12,
),
)
print(f"{accepted.count} studies scheduled for deletion")
edit_study_tags(project_id, request)
async
¶
Add/remove tags across the selected studies, set-based.
Example
from yousleep_common.models import (
EditStudyTagsRequest, StudyFilter, StudySelector,
)
# Remove the tag "pilot" from every study carrying it.
result = await client.batch.edit_study_tags(
project_id,
EditStudyTagsRequest(
selector=StudySelector(filter=StudyFilter(tags_any=["pilot"])),
remove=["pilot"],
expected_count=12,
),
)
print(f"{result.count} studies updated")
get_analyses_status(project_id, request)
async
¶
Batch poll analysis status for multiple analyses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project |
required |
request
|
BatchGetAnalysesStatusRequest
|
Batch status request with analysis IDs |
required |
Returns:
| Type | Description |
|---|---|
BatchGetAnalysesStatusResponse
|
Response with per-analysis status results and summary counts |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
get_event_blocks(project_id, request)
async
¶
Batch retrieve event blocks for multiple analyses.
The block-shaped counterpart to :meth:get_events: the same analyses,
as one block document each rather than expanded event lists. Prefer it
when reading dense per-epoch output across many analyses — the saving
is in parse cost and object count (a night of staging decodes to one
block rather than tens of thousands of events) rather than in
compressed bytes.
There is no filter, matching the single-analysis block endpoint: a
document is fetched once and sliced locally. Filtered access stays on
:meth:get_events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project |
required |
request
|
BatchGetEventBlocksRequest
|
Batch request with the analysis IDs |
required |
Returns:
| Type | Description |
|---|---|
BatchGetEventBlocksResponse
|
Response with a block document per analysis and summary counts. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
Example
from yousleep_common.models import BatchGetEventBlocksRequest
from yousleep_common.utils.event_blocks import blocks_to_events
response = await client.batch.get_event_blocks(
project.id,
BatchGetEventBlocksRequest(analysis_ids=[a.id, b.id]),
)
for entry in response.results.values():
if entry.status == "ok" and entry.document is not None:
events = blocks_to_events(entry.document.blocks)
get_events(project_id, request)
async
¶
Batch retrieve events for multiple analyses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project |
required |
request
|
BatchGetEventsRequest
|
Batch event retrieval request with analysis IDs and optional filter |
required |
Returns:
| Type | Description |
|---|---|
BatchGetEventsResponse
|
Response with per-analysis event results and summary counts |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
get_recordings_by_studies(project_id, request)
async
¶
Fetch the recordings of many studies in one request, keyed by study.
get_recordings_details(project_id, request)
async
¶
Batch fetch recording details for multiple recordings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project |
required |
request
|
BatchGetRecordingsDetailsRequest
|
Batch details request with recording IDs |
required |
Returns:
| Type | Description |
|---|---|
BatchGetRecordingsDetailsResponse
|
Response with per-recording detail results and summary counts |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
get_studies_by_ids(project_id, request)
async
¶
Fetch many studies by id in one request (per-item results).
patch_channels(project_id, request)
async
¶
Bulk-edit channel metadata (type/unit/name) across a project.
patch_studies_metadata(project_id, request)
async
¶
Apply subject-metadata patches (age/sex/BMI) across many studies.
Rows address studies by exact name or id. Field PRESENCE is the
PATCH semantics — this method serializes with exclude_unset so
an absent field leaves the study unchanged and an explicit None
clears it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project. |
required |
request
|
BatchPatchStudiesMetadataRequest
|
The metadata patch rows. |
required |
Returns:
| Type | Description |
|---|---|
BatchPatchStudiesMetadataResponse
|
Per-item 207 results plus a summary. |
quote_analyses(project_id, request)
async
¶
Pre-flight cost quote for a batch submission (same request body).
Runs the submission's own validation/pricing per (target, step) and returns per-step costs plus the batch total against the org balance. Advisory: the real submission's reserve remains the gate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
The project the targets belong to. |
required |
request
|
BatchSubmitAnalysesRequest
|
The same pipeline/targets body you would submit. |
required |
Returns:
| Type | Description |
|---|---|
BatchAnalysesQuote
|
BatchAnalysesQuote with per-step results, the total, and the |
BatchAnalysesQuote
|
drain-order preview / blocked_reason for the batch total. |
set_study_lights(project_id, request)
async
¶
Assign lights-off/on markers across many studies.
Each marker takes exactly one spelling: clock ("23:15", resolved
per study with overnight wrap — only while the study's recording
span is ≤ 24 h), datetime (read in the recording's wall-clock
frame), or elapsed_ms. Existing markers win unless
replace_existing; an explicit None deletes a marker
(exclude_unset serialization, as for the metadata patch).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project. |
required |
request
|
BatchSetStudyLightsRequest
|
The lights assignment rows. |
required |
Returns:
| Type | Description |
|---|---|
BatchSetStudyLightsResponse
|
Per-item 207 results (resolved instants echoed as elapsed ms). |
submit_analyses(project_id, request)
async
¶
Batch submit analyses for multiple recordings with pipeline support.
Each pipeline step can depend on earlier steps via step_ids. If a step fails for a target, downstream steps auto-fail.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID or name of the project |
required |
request
|
BatchSubmitAnalysesRequest
|
Batch analysis submission request with pipeline and targets |
required |
Returns:
| Type | Description |
|---|---|
BatchSubmitAnalysesResponse
|
Response with per-item results and summary counts |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
ValidationError
|
If pipeline structure is invalid |
AuthenticationError
|
If not authenticated |
Example
from yousleep_common.models import (
BatchSubmitAnalysesRequest,
BatchAnalysisPipelineStep,
BatchAnalysisTarget,
)
request = BatchSubmitAnalysesRequest(
pipeline=[
BatchAnalysisPipelineStep(
step_id="staging",
analysis_config_id="u-sleep-research-v1",
),
],
targets=[
BatchAnalysisTarget(study_id=study_id, recording_id=rec_id),
],
)
result = await client.batch.submit_analyses(project_id, request)
BillingEndpoint
¶
Bases: BaseEndpoint
Handles billing and payment-related API endpoints.
Provides methods for the credit balance and credit purchases via Stripe.
create_checkout_session(request)
async
¶
Create a Stripe checkout session for one or more credit packages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
StripeCheckoutSessionCreate
|
The Stripe price ids to purchase (from
:meth: |
required |
Returns:
| Type | Description |
|---|---|
StripeCheckoutSession
|
Stripe checkout session with a URL to complete payment. |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If the price IDs or redirect URLs are invalid. |
AuthenticationError
|
If not authenticated. |
Example
from yousleep_common.models import StripeCheckoutSessionCreate
packages = await client.billing.credit_packages()
session = await client.billing.create_checkout_session(
StripeCheckoutSessionCreate(
price_ids=[packages[0].price_id],
success_url="https://app.example.com/account",
cancel_url="https://app.example.com/account",
)
)
print(f"Complete payment at: {session.url}")
create_portal_session(request=None)
async
¶
Open the Stripe customer portal (purchase history, invoices, receipts).
Only meaningful after at least one purchase (a Stripe customer exists) — the server responds 409 otherwise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
StripePortalSessionCreate | None
|
Where Stripe sends the user when they leave the portal. Omit it to use Stripe's default. |
None
|
Returns:
| Type | Description |
|---|---|
StripePortalSession
|
The portal session; redirect the browser to its |
credit_entries(limit=50, offset=0)
async
¶
Return a page of the org's credit ledger, newest first.
Every balance change is a ledger entry: grants, purchases, analysis charges, storage debits, what remained of a grant at its expiry and administrators' adjustments. An entry in the grants balance names its grant.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int
|
Maximum entries to return (page size). |
50
|
offset
|
int
|
Entries to skip from the newest. |
0
|
Returns:
| Type | Description |
|---|---|
CreditLedgerPage
|
The page of entries plus the total entry count. |
credit_packages()
async
¶
Get the purchasable credit packages (live Stripe prices).
Amounts come straight from Stripe, so what is displayed always
matches what checkout charges. Pass a package's price_id to the
checkout-session endpoint to purchase it.
Returns:
| Type | Description |
|---|---|
list[CreditPackage]
|
The packages, sorted by credits ascending. |
credits()
async
¶
Return the caller's organization's credits: research grants and purchased credits.
Research analyses are paid from grants, commercial analyses and storage above the free ceiling from purchased credits. Each balance reports what is held for running analyses and what is available.
Returns:
| Type | Description |
|---|---|
OrgCredits
|
The organization's two balances. |
FileAnalysisOutcome
dataclass
¶
Outcome for a single input file of :meth:WorkflowsEndpoint.analyze_files.
status is "completed" when the file's analysis finished successfully
(result is set), "failed" when any stage failed for this file
(error describes it; analysis is attached when one was submitted),
and "timeout" when the analysis was still running when the batch wait
expired.
LegalEndpoint
¶
Bases: BaseEndpoint
Handles legal document and license-related API endpoints.
Provides access to terms, privacy policies, and licenses.
commercial_license(version=None)
async
¶
Get the commercial license text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
int | None
|
The document version to return; the latest when omitted |
None
|
Returns:
| Type | Description |
|---|---|
LegalDocument
|
Commercial license document |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
licenses(version=None)
async
¶
Get all available licenses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
int | None
|
The version to return for every licence; the latest when omitted |
None
|
Returns:
| Type | Description |
|---|---|
list[LegalDocumentShort]
|
List of available licenses (short form) |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
non_commercial_license(version=None)
async
¶
Get the non-commercial license text.
Covers research, education, and personal use.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
int | None
|
The document version to return; the latest when omitted |
None
|
Returns:
| Type | Description |
|---|---|
LegalDocument
|
Non-commercial license document |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
privacy_policy_standard(version=None)
async
¶
Get the standard privacy policy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
int | None
|
The document version to return; the latest when omitted |
None
|
Returns:
| Type | Description |
|---|---|
LegalDocument
|
Privacy policy document for standard users |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
site_agreement(version=None)
async
¶
Get the site agreement an organization's owner accepts before using its own hardware.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
int | None
|
The document version to return; the latest when omitted |
None
|
Returns:
| Type | Description |
|---|---|
LegalDocument
|
The site agreement |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
While no version is published, or for an unknown version |
terms_and_conditions_standard(version=None)
async
¶
Get the standard terms and conditions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
int | None
|
The document version to return; the latest when omitted |
None
|
Returns:
| Type | Description |
|---|---|
LegalDocument
|
Terms and conditions document for standard users |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
OrganizationsEndpoint
¶
Bases: BaseEndpoint
Handles organization-related API endpoints.
Every account belongs to exactly one organization: the one created for it
at sign-up, or the one it joined by invitation. These methods manage that
organization and who belongs to it; client.user.get_organization
returns it.
accept_invitation(request)
async
¶
Accept an invitation as the signed-in account and join the organization.
The account's verified email must match the invited address. The account's own organization of one is retired; what joining means is in the Terms and Conditions, which every account has accepted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
InvitationToken
|
The token from the invitation link. |
required |
Returns:
| Type | Description |
|---|---|
UserOrganizationOut
|
The organization joined. |
accept_site_agreement(org_id, version)
async
¶
Accept the site agreement on the organization's behalf.
The owner only, and only the latest published version
(client.legal.site_agreement()). The acceptance is recorded and
never changed; a later version is accepted anew.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
version
|
int
|
The version read and accepted. |
required |
Returns:
| Type | Description |
|---|---|
SiteAgreementAcceptance
|
The acceptance as recorded. |
approve_runner(org_id, runner_id, fingerprint)
async
¶
Approve a pending runner of the organization's site pool.
Compare the fingerprint with the one the runner's host prints; the platform refuses an approval whose fingerprint differs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
runner_id
|
UUID | str
|
The runner to approve. |
required |
fingerprint
|
str
|
The whole fingerprint, |
required |
create_enrolment_token(org_id)
async
¶
Create a single-use token a runner enrols into the organization's site pool with.
The first token creates the pool. Owners and admins, while the organization holds site compute. The token is in this answer only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
Returns:
| Type | Description |
|---|---|
EnrolmentTokenOut
|
The token, its pool, and when it expires. |
create_invitation(org_id, request)
async
¶
Invite an email address into the organization (owner or admin).
The invitee's own organization must be empty when they accept: it is retired, and they join this one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
request
|
InvitationCreate
|
The address and the role to join with. |
required |
Returns:
| Type | Description |
|---|---|
InvitationOut
|
The pending invitation. The token is only ever sent by email. |
estimate_credits(org_id, request)
async
¶
Price a plan of analyses as its runs would be priced.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
request
|
CreditEstimateRequest
|
The plan (studies, average recording length, analyses with their runs per study) and the margin to add. |
required |
Returns:
| Type | Description |
|---|---|
CreditEstimate
|
The cost per analysis, the total, and the total with the margin. |
export_audit(org_id, filters=None)
async
¶
Return the same events as CSV text, oldest first.
get(org_id)
async
¶
Get one of the caller's organizations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
Returns:
| Type | Description |
|---|---|
UserOrganizationOut
|
The organization as the caller sees it. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the caller is not a member of it. |
get_capabilities(org_id)
async
¶
Return the organization's capabilities on its own hardware.
Running analyses on its own hardware and keeping recordings at its site are each off until a platform administrator turns them on. The answer also says which version of the site agreement is published and which the organization accepted. Any member.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
get_compute_pool(org_id)
async
¶
Return the organization's site pool, or None before it has one.
An organization has at most one site pool, created with its first enrolment token. Owners and admins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
get_usage(org_id)
async
¶
Return the organization's usage against its ceilings, member by member.
Owner and admins only. Storage and projects against their ceilings, then one row per member: the bytes and projects they hold (private ones included, without naming them), their analyses and the credits those cost.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
Returns:
| Type | Description |
|---|---|
OrganizationUsageOut
|
The organization's totals and one row per member, largest first. |
list_audit(org_id, filters=None, *, offset=0, limit=50)
async
¶
Return the organisation's audit trail (its owner and admins).
Its members, invitations and roles, its storage and credits, and every
event about a project the organisation could see when it happened.
Newest first; filters narrows by event types, a time window, a
person or an item.
Returns:
| Type | Description |
|---|---|
AuditEventListResponse
|
One page of events ( |
list_capability_requests(org_id, limit=50, offset=0)
async
¶
Return the organization's requests for capabilities, newest first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
limit
|
int
|
Maximum requests to return. |
50
|
offset
|
int
|
Requests to skip from the newest. |
0
|
list_credit_requests(org_id, limit=50, offset=0)
async
¶
Return the organization's grant and extension requests, newest first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
limit
|
int
|
Maximum requests to return. |
50
|
offset
|
int
|
Requests to skip from the newest. |
0
|
list_grants(org_id)
async
¶
Return the organization's research grants, soonest to expire first.
Each with what remains of it; the starter grant, which never expires, comes last.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
list_invitations(org_id)
async
¶
List an organization's open invitations: pending, and recently expired.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
Returns:
| Type | Description |
|---|---|
list[InvitationOut]
|
The invitations, newest first. |
list_members(org_id)
async
¶
List an organization's members.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
Returns:
| Type | Description |
|---|---|
list[MemberOut]
|
The members with their roles, owner first. |
list_runners(org_id, *, offset=0, limit=50)
async
¶
List the runners of the organization's site pool, newest first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
offset
|
int
|
Pagination offset (default: 0). |
0
|
limit
|
int
|
Maximum runners to return (default: 50, max: 200). |
50
|
lookup_invitation(request)
async
¶
Describe the invitation behind a link, before accepting it.
No authentication is required: the token itself is the credential.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
InvitationToken
|
The token from the invitation link. |
required |
Returns:
| Type | Description |
|---|---|
InvitationPreview
|
The organization, inviter and invited address. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the token is unknown, expired or revoked. |
release_runner(org_id, runner_id)
async
¶
Release a quarantined runner of the organization's site pool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
runner_id
|
UUID | str
|
The runner to release. |
required |
remove_member(membership_id)
async
¶
Remove a member from the organization, or leave it by removing yourself.
Projects the member owned pass to the organization's owner, and the member receives a fresh organization of their own. The owner cannot be removed; ownership is transferred first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
membership_id
|
UUID | str
|
The membership to end. The caller's own membership id
is on |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
A message confirming the removal. |
request_capability(org_id, request)
async
¶
Ask the platform's administrators to turn a capability on.
The owner only, one request per capability at a time, and none for a capability that is already on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
request
|
CapabilityRequestCreate
|
The capability, and what it is for. |
required |
Returns:
| Type | Description |
|---|---|
CapabilityRequestOut
|
The pending request. |
request_extension(org_id, grant_id, request)
async
¶
Ask for more time on a grant before it expires.
Owner and admins only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
grant_id
|
UUID | str
|
The grant to extend. |
required |
request
|
ExtensionRequestCreate
|
The extra time asked for, and why. |
required |
Returns:
| Type | Description |
|---|---|
CreditRequestOut
|
The pending request. |
request_grant(org_id, request)
async
¶
Ask for a research grant for a planned piece of work.
Owner and admins only. An administrator reviews the plan, the computed cost and the amount asked for, and approves or declines it; the requester is emailed the decision.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
request
|
GrantRequestCreate
|
The plan, the margin, the amount asked for, the term and what the research is. |
required |
Returns:
| Type | Description |
|---|---|
CreditRequestOut
|
The pending request. |
revoke_invitation(invitation_id)
async
¶
Withdraw a pending invitation (owner or admin).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
invitation_id
|
UUID | str
|
The invitation id. |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
A message confirming the revocation. |
revoke_runner(org_id, runner_id)
async
¶
Revoke a runner of the organization's site pool; it is refused from its next request on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
runner_id
|
UUID | str
|
The runner to revoke. |
required |
transfer_ownership(org_id, request)
async
¶
Hand the organization to another member (owner only).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
request
|
OwnershipTransfer
|
The new owner and the caller's password. |
required |
Returns:
| Type | Description |
|---|---|
UserOrganizationOut
|
The organization, with the caller's new role (admin). |
update(org_id, request)
async
¶
Rename an organization (owner or admin).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
org_id
|
UUID | str
|
The organization id. |
required |
request
|
OrganizationUpdate
|
The new name. |
required |
Returns:
| Type | Description |
|---|---|
UserOrganizationOut
|
The updated organization. |
update_member_role(membership_id, request)
async
¶
Change a member's role between admin and member.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
membership_id
|
UUID | str
|
The membership to change (from |
required |
request
|
MemberRoleUpdate
|
The new role. |
required |
Returns:
| Type | Description |
|---|---|
MemberOut
|
The updated member. |
ProjectsEndpoint
¶
Bases: BaseEndpoint
Handles project-related API endpoints.
Projects are the top-level organizational unit in YouSleep.
bucket_files(project_id, prefix='')
async
¶
Return every file under prefix in a bucket project's bucket that can be registered where it is.
The platform signs each page of the listing, and this client sends it
to the bucket, which answers only where the organisation's network
reaches it. Files under youSleep/, where youSleep writes, and
files that are not EDF files are left out. Register each with
client.recordings.register_in_place.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
A project whose recordings are in its organisation's bucket. |
required |
prefix
|
str
|
The folder to list, as its keys start; empty lists the whole bucket. |
''
|
Returns:
| Type | Description |
|---|---|
list[BucketFile]
|
The files, with their keys and sizes. |
Raises:
| Type | Description |
|---|---|
ClientConnectionError
|
If the bucket does not answer, or refuses. |
YouSleepClientError
|
If the project's recordings are not in its
organisation's bucket ( |
bucket_folders(project_id)
async
¶
Return the folders a bucket project registered files from: where to look for new files.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
A project whose recordings are in its organisation's bucket. |
required |
Returns:
| Type | Description |
|---|---|
BucketFolders
|
Each folder, ending in |
BucketFolders
|
folder inside another is left out. |
create(project)
async
¶
Create a new project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project
|
ProjectCreate
|
Project data (name is required; description, tags optional) |
required |
Returns:
| Type | Description |
|---|---|
ProjectOut
|
Created project information |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If project data is invalid |
AuthenticationError
|
If not authenticated |
delete(project_id)
async
¶
Delete a project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project to delete |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming deletion |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
export_audit(project_id, filters=None)
async
¶
Return the same events as CSV text, oldest first.
get(project_id)
async
¶
Get a specific project by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
Returns:
| Type | Description |
|---|---|
ProjectOut
|
Project information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
get_report(project_id, by_group=False, groups=None, analysis_configs=None, stratify_by=None, stratify_edges=None, longitudinal=False, longitudinal_basis=None, calendar_granularity='month', subjects=None, include_biomarkers=False, soremp_threshold_min=15.0, statistics_window_start_ms=None, statistics_window_end_ms=None)
async
¶
Get a report for the project.
Aggregates event statistics across all completed analyses in every study of the project. The report can optionally be grouped by study tags, computed longitudinally, and carry aggregated biomarker summary statistics (with their tables and charts).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
by_group
|
bool
|
Group the statistics by study tags. Off by default — note
that :class: |
False
|
groups
|
list[str] | None
|
With |
None
|
analysis_configs
|
list[str] | None
|
Only these analysis configurations contribute;
default: every completed analysis does. The project's own
vocabulary comes from |
None
|
stratify_by
|
MetadataType | None
|
Group the statistics by a subject-metadata factor
(age, sex or BMI) instead of tags. Each study lands in exactly
one stratum; studies missing the factor form a "Not set"
stratum. Mutually exclusive with |
None
|
stratify_edges
|
list[float] | None
|
Bin edges overriding the server's configured defaults; numeric factors (age, bmi) only. Strictly increasing; bins are half-open intervals [a, b). |
None
|
longitudinal
|
bool
|
Compute the longitudinal section — the flat boxplot with time bins as rows, one chart per metric |
False
|
longitudinal_basis
|
LongitudinalBasis | None
|
What a bin is: |
None
|
calendar_granularity
|
CalendarGranularity
|
|
'month'
|
subjects
|
list[str] | None
|
Draw these subjects as lines beside the bins, one series each; keys are compared case- and whitespace-insensitively |
None
|
include_biomarkers
|
bool
|
Whether to compute biomarkers for staging analyses |
False
|
soremp_threshold_min
|
float
|
Max minutes from sleep onset to the first REM epoch for a SOREMP |
15.0
|
statistics_window_start_ms
|
int | None
|
Optional window start override (ms); must be given together with the end |
None
|
statistics_window_end_ms
|
int | None
|
Optional window end override (ms); must be given together with the start |
None
|
Returns:
| Type | Description |
|---|---|
ProjectReportResponse
|
Project report envelope with aggregated event stats and optional |
ProjectReportResponse
|
biomarker summaries across all studies in the project. Large |
ProjectReportResponse
|
reports carry shared per-study origins lists once, referenced per |
ProjectReportResponse
|
entry — read an entry's origins through |
ProjectReportResponse
|
|
ProjectReportResponse
|
directly. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
ValidationError
|
If the requested report mode is invalid —
|
AuthenticationError
|
If not authenticated |
list(*, visibility=None, name_contains=None, skip=None, limit=None, order=None)
async
¶
List the projects the authenticated user can open.
Projects are ordered by creation time, oldest first unless order
is "desc". With neither skip nor limit every project is
returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
visibility
|
Visibility | None
|
Only projects with this visibility (private, org or shared), among the accessible ones — a filter, never a widening. |
None
|
name_contains
|
str | None
|
Only projects whose name contains this text (case-insensitive). |
None
|
skip
|
int | None
|
Projects to skip |
None
|
limit
|
int | None
|
Maximum projects to return (1-500) |
None
|
order
|
Literal['asc', 'desc'] | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
list[ProjectOut]
|
List of projects |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
list_analysis_configs(project_id)
async
¶
List the analysis configurations the project has results from.
The project's own vocabulary, with how much each configuration
produced — what a report's analysis_configs selection can name,
which the report itself cannot say once a selection narrows it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
Returns:
| Type | Description |
|---|---|
list[ProjectAnalysisConfig]
|
One entry per configuration with completed analyses, by name. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the project doesn't exist |
AuthenticationError
|
If not authenticated |
list_audit(project_id, filters=None, *, offset=0, limit=50)
async
¶
Return a project's audit trail (the project's owner).
Every event about the project, whoever caused it.
Newest first; filters narrows by event types, a time window, a
person or an item.
Returns:
| Type | Description |
|---|---|
AuditEventListResponse
|
One page of events ( |
list_demo_datasets()
async
¶
List available public demo datasets.
Returns:
| Type | Description |
|---|---|
list[DemoDatasetDescription]
|
List of demo dataset descriptions |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
list_shares(project_id)
async
¶
List the members a shared project is open to (project owner only).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
The project id. |
required |
Returns:
| Type | Description |
|---|---|
list[ProjectShareOut]
|
The shares, one per member. |
new_bucket_files(project_id)
async
¶
Look for new files: the files a bucket project has not registered, in the folders it registered files from.
Each folder is listed again through requests the platform signs, as
bucket_files lists it, and what the listing found is reported. A
folder reported whole is judged too: a recording whose file is gone
from its key, or changed there, is missing at the site
(RecordingOut.missing_since), and one whose file is back is not.
Register each new file with client.recordings.register_in_place,
naming its folder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
A project whose recordings are in its organisation's bucket. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[BucketFile]]
|
Each folder's new files. |
Raises:
| Type | Description |
|---|---|
ClientConnectionError
|
If the bucket does not answer, or refuses. |
register_demo_dataset(dataset, project_name)
async
¶
Register a public demo dataset as a new project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset
|
str
|
Name of the demo dataset to register (e.g. "sleep-edfx") |
required |
project_name
|
str
|
Name for the created project |
required |
Returns:
| Type | Description |
|---|---|
ProjectOut
|
Created project with demo data |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If dataset doesn't exist |
AuthenticationError
|
If not authenticated |
report_found(project_id, files, *, folder=None)
async
¶
Report files a listing of a bucket project's bucket found; learn which are new.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
A project whose recordings are in its organisation's bucket. |
required |
files
|
list[BucketFile]
|
Up to 5,000 files, as |
required |
folder
|
str | None
|
The folder |
None
|
Returns:
| Type | Description |
|---|---|
BucketFoundOut
|
The keys of those the project can register and has not |
BucketFoundOut
|
registered, and of those missing at the site. |
share(project_id, request)
async
¶
Share a project with one member of its organization (project owner only).
The project's visibility must be shared; set it with update.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
The project id. |
required |
request
|
ProjectShareCreate
|
The member to share with. |
required |
Returns:
| Type | Description |
|---|---|
ProjectShareOut
|
The share granted. |
sign_bucket_listing(project_id, listing)
async
¶
Sign one page of a bucket project's bucket listing, for this client to send.
bucket_files sends every page and reads them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
A project whose recordings are in its organisation's bucket. |
required |
listing
|
BucketListing
|
The prefix, whether to list folders, and the page's token. |
required |
Returns:
| Type | Description |
|---|---|
SignedRequest
|
The bucket's GET, valid for a few minutes. |
unshare(share_id)
async
¶
Withdraw a share (project owner only).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
share_id
|
UUID | str
|
The share id, from |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
A message confirming the withdrawal. |
update(project_id, project)
async
¶
Update an existing project (PATCH).
Universal field semantics:
- Omit a field to leave it unchanged.
- Include a field with a value to update it.
- Include a field with
Noneto clear it (where nullable in storage —description,tags).
name cannot be cleared; sending name=None raises a validation
error. Omit name to leave it unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project to update |
required |
project
|
ProjectUpdate
|
Partial update (only included fields are modified) |
required |
Returns:
| Type | Description |
|---|---|
ProjectOut
|
Updated project information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
ValidationError
|
If update data is invalid (e.g., |
AuthenticationError
|
If not authenticated |
RecordingsEndpoint
¶
Bases: BaseEndpoint
Handles recording-related API endpoints.
Recordings are sleep study files (EDF, EDF+, etc.) associated with studies.
__init__(client)
¶
Hold the parent client, and the policies of the studies uploaded to.
add_in_place(project_id, key, header_bytes, full_file_size, filename, *, folder=None)
async
¶
Add the bucket's file at key as a recording, from its cleaned header.
register_in_place reads and cleans the header first; send only a
header cleaned by the project's rule.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
A project whose recordings are in its organisation's bucket. |
required |
key
|
str
|
The file's key in the bucket. |
required |
header_bytes
|
bytes
|
The file's EDF header, cleaned by the project's rule. |
required |
full_file_size
|
int
|
The file's size in bytes. |
required |
filename
|
str
|
The name the recording carries; its study takes it without its extension. |
required |
folder
|
str | None
|
The folder the file was chosen from; the file's own folder if not given. |
None
|
Returns:
| Type | Description |
|---|---|
RecordingOut
|
The registered recording. |
delete(recording_id)
async
¶
Delete a recording.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording to delete |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming deletion |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording doesn't exist |
AuthenticationError
|
If not authenticated |
download_url(recording_id)
async
¶
Get a pre-signed download URL for a recording file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
Returns:
| Type | Description |
|---|---|
PreSignedDownloadUrl
|
Pre-signed download URL with expiry information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording doesn't exist |
AuthenticationError
|
If not authenticated |
finalize(recording_id)
async
¶
Finalize a recording after upload.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
Returns:
| Type | Description |
|---|---|
RecordingOut
|
Finalized recording information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording doesn't exist |
ValidationError
|
If recording cannot be finalized |
AuthenticationError
|
If not authenticated |
get(recording_id)
async
¶
Get detailed information about a recording.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
Returns:
| Type | Description |
|---|---|
RecordingOut
|
Detailed recording information including header data |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording doesn't exist |
AuthenticationError
|
If not authenticated |
get_channel(recording_id, channel_index)
async
¶
Get a specific channel by index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
channel_index
|
int
|
Index of the channel |
required |
Returns:
| Type | Description |
|---|---|
ChannelOut
|
Channel information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording or channel doesn't exist |
AuthenticationError
|
If not authenticated |
get_events(recording_id)
async
¶
Get all events for a recording across all analyses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
Returns:
| Type | Description |
|---|---|
list[Event]
|
List of events from all analyses on this recording |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording doesn't exist |
AuthenticationError
|
If not authenticated |
list(study_id, *, offset=None, limit=None)
async
¶
List the recordings of a study.
With neither offset nor limit every recording is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
offset
|
int | None
|
Recordings to skip |
None
|
limit
|
int | None
|
Maximum recordings to return (1-500) |
None
|
Returns:
| Type | Description |
|---|---|
list[RecordingOut]
|
List of recordings |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If study doesn't exist |
AuthenticationError
|
If not authenticated |
list_channels(recording_id)
async
¶
List all channels in a recording.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
Returns:
| Type | Description |
|---|---|
list[ChannelOut]
|
List of channels with metadata |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording doesn't exist |
AuthenticationError
|
If not authenticated |
list_for_project(project_id, *, offset=0, limit=50)
async
¶
List one page of a project's recordings across all of its studies.
Each recording carries its study's id and name and a summary of its analyses, so a project overview needs no request per study.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
offset
|
int
|
Recordings to skip (default: 0) |
0
|
limit
|
int
|
Maximum recordings to return (default: 50, max: 200) |
50
|
Returns:
| Type | Description |
|---|---|
PaginatedRecordingsResponse
|
One page of recordings with the total across all pages |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
pre_register(study_id, header_bytes, full_file_size, filename)
async
¶
Pre-register a recording before upload.
Sends the EDF file header for server-side validation and receives a presigned PUT URL for the file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
header_bytes
|
bytes
|
EDF header bytes (extracted from the file) |
required |
full_file_size
|
int
|
Total size of the file in bytes |
required |
filename
|
str
|
Name of the recording file |
required |
Returns:
| Type | Description |
|---|---|
PreRegistrationResponse
|
Pre-registration response with recording info and presigned PUT URL |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If study doesn't exist |
AuthenticationError
|
If not authenticated |
register_in_place(project_id, key, *, name=None, folder=None)
async
¶
Register a file a bucket project's bucket already stores, where it is.
Nothing is uploaded or copied: the file stays in the organisation's bucket, and deleting its recording only unregisters it. It: 1. Reads the file's header through a ranged GET the platform signs; the bucket answers only where the organisation's network reaches it, so run this from there. 2. Applies the project's pseudonymisation rule to the header, as an upload's is cleaned. The file in the bucket is not changed. 3. Registers the file with the cleaned header and its size, in a study of its own named after the file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
A project whose recordings are in its organisation's bucket. |
required |
key
|
str
|
The file's key in the bucket, as |
required |
name
|
str | None
|
The name the recording and its study carry; the file's own name if not given. A project that codes file names requires it: pass the code your own records map to the file. |
None
|
folder
|
str | None
|
The folder the file was chosen from, ending in |
None
|
Returns:
| Type | Description |
|---|---|
RecordingOut
|
The registered recording. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the file does not start with an EDF header, or the
project codes file names and no |
ClientConnectionError
|
If the bucket does not answer, or refuses. |
ValidationError
|
If the file cannot be registered: it is under
|
YouSleepClientError
|
If the project already has the file
( |
set_channel_identity(recording_id, channel_index, patch)
async
¶
Set or clear what a channel is: the side it records and its canonical name.
A field included with a value sets it, a field included as None
clears it, and a field left out keeps its value. A value set here is
recorded as a person's correction, and re-reading the file's label
never overwrites it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
channel_index
|
int
|
Index of the channel |
required |
patch
|
ChannelIdentityPatch
|
The correction (at least one field must be included) |
required |
Returns:
| Type | Description |
|---|---|
ChannelOut
|
The channel as it now stands |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording or channel doesn't exist |
ValidationError
|
If the canonical name or side is invalid |
AuthenticationError
|
If not authenticated |
sign_bucket_reads(project_id, keys)
async
¶
Sign a ranged GET of each file's header in a bucket project's bucket.
register_in_place sends it, cleans the header and registers the
file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
A project whose recordings are in its organisation's bucket. |
required |
keys
|
list[str]
|
The files' keys, at most 100. |
required |
Returns:
| Type | Description |
|---|---|
BucketReadsOut
|
Each key's GET of its first 64 KiB, valid for a few minutes. |
update_channel_type(recording_id, channel_index, type)
async
¶
Update the type of a specific channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
channel_index
|
int
|
Index of the channel |
required |
type
|
str
|
New channel type |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming update |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording or channel doesn't exist |
ValidationError
|
If channel type is invalid |
AuthenticationError
|
If not authenticated |
update_channel_unit(recording_id, channel_index, unit)
async
¶
Update the unit of a specific channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recording_id
|
UUID | str
|
UUID of the recording |
required |
channel_index
|
int
|
Index of the channel |
required |
unit
|
str
|
New unit |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming update |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If recording or channel doesn't exist |
ValidationError
|
If unit is invalid |
AuthenticationError
|
If not authenticated |
upload(study_id, file, on_progress=None, *, name=None)
async
¶
Upload a recording file, pseudonymised by its project's policy.
It: 1. Applies the pseudonymisation rule to the file's EDF header: the patient and recording identification fields are blanked, and the start date becomes EDF+'s unknown date if the project removes dates. Your file is not changed; only the uploaded copy is. 2. Pre-registers the recording with the API (sends the cleaned header) 3. Uploads the file, with the cleaned header, via presigned PUT 4. Finalizes the recording
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
file
|
BinaryIO | Path
|
File-like object or path to recording file |
required |
on_progress
|
Callable[[int], None] | None
|
Optional callback for upload progress (percentage 0-100) |
None
|
name
|
str | None
|
The name the recording carries on the platform; the file's own name if not given. A project that codes file names requires it: pass the code your own records map to the file. The file's extension is added if the name has none. |
None
|
Returns:
| Type | Description |
|---|---|
RecordingOut
|
Information about the uploaded recording |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the file does not start with an EDF header, or the
project codes file names and no |
ValidationError
|
If file is invalid or unsupported format |
NotFoundError
|
If study doesn't exist |
AuthenticationError
|
If not authenticated |
ReportExportsEndpoint
¶
Bases: BaseEndpoint
Handles report export API endpoints.
An export renders a study or project report server-side into a downloadable artifact (a branded PDF, or a markdown bundle). Exports are created against the project or study whose report they render, then polled and downloaded through the user-scoped export lifecycle:
import asyncio
from yousleep_common.models import ReportExportCreate
export = await client.report_exports.create_for_study(
study_id=study.id,
export=ReportExportCreate(format="pdf"),
)
while export.status in ("queued", "running"):
await asyncio.sleep(2)
export = await client.report_exports.get(export.id)
print(export.download_url)
Creation is idempotent: an identical export that is still live is returned
as-is rather than re-rendered, so a fresh create can already be
completed with its download_url set. Check status before
polling — see the note on each create method.
create_for_project(project_id, export)
async
¶
Create an export of a project's report.
The export renders asynchronously: the returned record is normally
queued, and :meth:get is the poll target for its status and
download URL. Creation is idempotent — when an identical export is
still live, that existing export is returned instead of a new one, and
it comes back already completed with its download_url set. Check
status before polling rather than polling unconditionally.
The artifact carries the audit appendix (which studies and analyses the
numbers came from) and expires after a few days, at which point
status becomes expired and the download URL is withheld.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
export
|
ReportExportCreate
|
Export request (format, optional section layout, optional
project report mode via |
required |
Returns:
| Type | Description |
|---|---|
ReportExportOut
|
The export record — queued, or an identical live export already |
ReportExportOut
|
completed with its download URL |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
ValidationError
|
If the export request is invalid |
AuthenticationError
|
If not authenticated |
Example
from yousleep_common.models import (
ReportExportCreate,
ReportExportProjectParams,
)
export = await client.report_exports.create_for_project(
project_id=project.id,
export=ReportExportCreate(
format="pdf",
project_params=ReportExportProjectParams(by_group=True),
),
)
if export.status == "completed":
print(export.download_url) # reused an existing export
create_for_study(study_id, export)
async
¶
Create an export of a study's report.
The export renders asynchronously: the returned record is normally
queued, and :meth:get is the poll target for its status and
download URL. Creation is idempotent — when an identical export is
still live, that existing export is returned instead of a new one, and
it comes back already completed with its download_url set. Check
status before polling rather than polling unconditionally.
The artifact expires after a few days, at which point status becomes
expired and the download URL is withheld.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
export
|
ReportExportCreate
|
Export request (format and optional section layout;
|
required |
Returns:
| Type | Description |
|---|---|
ReportExportOut
|
The export record — queued, or an identical live export already |
ReportExportOut
|
completed with its download URL |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If study doesn't exist |
ValidationError
|
If the export request is invalid |
AuthenticationError
|
If not authenticated |
get(export_id)
async
¶
Get one report export — the poll target for a created export.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
export_id
|
UUID | str
|
UUID of the export |
required |
Returns:
| Type | Description |
|---|---|
ReportExportOut
|
The export record; |
ReportExportOut
|
export is completed and its artifact has not expired |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the export doesn't exist or belongs to another user |
AuthenticationError
|
If not authenticated |
list(limit=20, offset=0, kind=None, format=None)
async
¶
List a page of the authenticated user's report exports, newest first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int
|
Maximum exports to return; the server clamps it to 1-100 |
20
|
offset
|
int
|
How many exports to skip, for paging past the first page |
0
|
kind
|
ReportExportKind | None
|
Only study or only project exports; None for both |
None
|
format
|
ReportExportFormat | None
|
Only exports of this artifact format; None for every one |
None
|
Returns:
| Type | Description |
|---|---|
ReportExportListResponse
|
One page of exports, each with a fresh download URL while |
ReportExportListResponse
|
completed and not expired, and |
ReportExportListResponse
|
— narrowed by the filters, so a filtered history pages correctly |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
ReportsEndpoint
¶
Bases: BaseEndpoint
Handles report generation API endpoints.
Provides methods for generating aggregated reports across recordings and analyses.
download_project_audit_csv(project_id, *, groups=None, statistics_window_start_ms=None, statistics_window_end_ms=None)
async
¶
Download the complete report audit table as CSV text.
The full counterpart of the report payload's capped audit appendix:
one row per completed analysis, streamed from metadata (no
statistics are computed). groups narrows to the report's
by-group cohort; the window override must set both bounds or
neither.
Returns:
| Type | Description |
|---|---|
str
|
The CSV document (header + rows) as text. |
get_unique_channels(project_id)
async
¶
Get unique channels across all recordings in all studies.
Returns a list of unique channel names with their locations across recordings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
Returns:
| Type | Description |
|---|---|
list[UniqueChannel]
|
List of unique channels with their locations |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
StatusEndpoint
¶
Bases: BaseEndpoint
Handles status-related API endpoints.
Provides health checks and system status information.
analyses(limit=None)
async
¶
Get recent analyses across all projects, newest first.
The server bounds the list by default so that polling it stays cheap
during large batches. :meth:analyses_counts carries the full totals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
limit
|
int | None
|
Maximum analyses to return (1-500); the server's default when omitted |
None
|
Returns:
| Type | Description |
|---|---|
list[AnalysisOut]
|
List of recent analyses with parent project/study info |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
analyses_counts()
async
¶
Get counts of recent analyses by status.
Returns:
| Type | Description |
|---|---|
dict[str, int]
|
Dictionary mapping analysis status to count |
Example
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
audit_actions()
async
¶
Get the audit action vocabulary: each action's name and readers.
Public. An audit view offers as filters the actions whose readers
include its own, and reads each event's action by name.
Returns:
| Type | Description |
|---|---|
list[AuditActionInfo]
|
Every action the server records, in the server's order |
billing_rates()
async
¶
Get the public billing rates (platform pricing in credits).
Clients must display these rather than hardcoding prices, so the UI always matches what the server actually charges.
Returns:
| Type | Description |
|---|---|
BillingRates
|
The current billing rates. |
enabled_features()
async
¶
Get server features that are currently enabled.
Returns:
| Type | Description |
|---|---|
ServerFeaturesEnabled
|
Server feature flags |
Example
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
health()
async
¶
limits()
async
¶
Get the server's client-relevant request limits.
Currently exposes the per-request item caps for the batch endpoints
(deployment-configurable; e.g. the max number of files one batch
analysis submission may target). Distinct from per-user usage quotas,
which are available via client.user.usage_limits().
Returns:
| Type | Description |
|---|---|
ServerLimits
|
The server's configured limits. |
permissions()
async
¶
Get the permission vocabulary, with what an API key may be scoped to.
Public. The one list a permission editor renders and a key dialog
offers from; key_scopeable is the server's decision.
Returns:
| Type | Description |
|---|---|
list[PermissionInfo]
|
Every permission, in the server's order |
study_import_columns()
async
¶
Get the recognised column vocabulary for bulk study-data imports.
The server's authoritative copy of STUDY_IMPORT_COLUMNS (keys,
aliases, units) — clients building a mapping UI fetch it from here
instead of mirroring the constant, so new columns arrive without a
package upgrade. Public, no authentication required.
version()
async
¶
Get API server and common module version information.
Returns:
| Type | Description |
|---|---|
ServerVersionInfo
|
ServerVersionInfo with api_version and common_version |
StudiesEndpoint
¶
Bases: BaseEndpoint
Handles study-related API endpoints.
Studies represent individual subjects or participants within a project.
count(project_id, *, tags_any=None, name_contains=None, subject_key=None, missing_metadata_any=None)
async
¶
Count the studies a filter resolves to, without fetching them.
This is the expected_count a live-set selector write must
present (the server re-resolves with the SAME predicate).
create(project_id, study)
async
¶
Create a new study in a project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
study
|
StudyCreate
|
Study data (name is required; description, tags, metadata optional) |
required |
Returns:
| Type | Description |
|---|---|
StudyOut
|
Created study information |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If study data is invalid |
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
create_events(study_id, request)
async
¶
Create study-level events (e.g. lights off/on).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
request
|
CreateStudyEventsRequest
|
Request containing list of study events to create |
required |
Returns:
| Type | Description |
|---|---|
list[StudyEvent]
|
List of created study events |
Raises:
| Type | Description |
|---|---|
ValidationError
|
If event data is invalid |
NotFoundError
|
If study doesn't exist |
AuthenticationError
|
If not authenticated |
delete(study_id)
async
¶
Delete a study.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study to delete |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming deletion |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If study doesn't exist |
AuthenticationError
|
If not authenticated |
delete_event(study_id, event_id)
async
¶
Delete a study-level event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
event_id
|
UUID | str
|
UUID of the study event to delete |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming deletion |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If event doesn't exist |
AuthenticationError
|
If not authenticated |
get(study_id)
async
¶
Get a specific study by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
Returns:
| Type | Description |
|---|---|
StudyOut
|
Study information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If study doesn't exist |
AuthenticationError
|
If not authenticated |
get_report(study_id, include_biomarkers=False, soremp_threshold_min=15.0, statistics_window_start_ms=None, statistics_window_end_ms=None)
async
¶
Get a report for the study.
Returns event statistics for all completed analyses, optionally including biomarkers for staging analyses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
include_biomarkers
|
bool
|
Whether to compute biomarkers for staging analyses |
False
|
soremp_threshold_min
|
float
|
Max minutes from sleep onset to the first REM epoch for a SOREMP |
15.0
|
statistics_window_start_ms
|
int | None
|
Optional window start override (ms) |
None
|
statistics_window_end_ms
|
int | None
|
Optional window end override (ms) |
None
|
Returns:
| Type | Description |
|---|---|
StudyReportResponse
|
StudyReportResponse with event stats, optional biomarkers, and window |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If study doesn't exist |
AuthenticationError
|
If not authenticated |
list(project_id, *, skip=None, limit=None, tags_any=None, name_contains=None, subject_key=None, missing_metadata_any=None, order_by=None)
async
¶
List the (optionally filtered) studies in a project.
tags_any/name_contains/subject_key are the selector
filter vocabulary — this filtered listing is the preview of what a
batch selector write addresses (see the Bulk Operations with
Selectors guide).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
skip
|
int | None
|
Pagination offset |
None
|
limit
|
int | None
|
Maximum studies to return (1-10,000). Without it the whole list is read, a project of up to 10,000 studies in one request |
None
|
tags_any
|
list[str] | None
|
Only studies carrying at least one of these tags |
None
|
name_contains
|
str | None
|
Only studies whose name contains this text |
None
|
subject_key
|
str | None
|
Only the studies of one subject — the key is compared case- and whitespace-insensitively |
None
|
missing_metadata_any
|
list[MetadataType] | None
|
Only studies that do not record at least one of these subject values |
None
|
order_by
|
StudyOrder | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
list[StudyOut]
|
List of matching studies in the project |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
list_events(study_id)
async
¶
List all study-level events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study |
required |
Returns:
| Type | Description |
|---|---|
list[StudyEvent]
|
List of study events |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If study doesn't exist |
AuthenticationError
|
If not authenticated |
summary(project_id, *, tags_any=None, preview=None)
async
¶
Summarise a project's studies without listing them.
Every tag and every subject with its count, the studies carrying no tag, and the first studies of each set. One small answer at any project size, for pickers and breakdowns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_id
|
UUID | str
|
UUID of the project |
required |
tags_any
|
list[str] | None
|
The tags a selection keeps; the summary then also
counts the studies carrying none of them ( |
None
|
preview
|
int | None
|
How many studies each set names (0-100, default 20) |
None
|
Returns:
| Type | Description |
|---|---|
StudySummary
|
The project's study summary |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If project doesn't exist |
AuthenticationError
|
If not authenticated |
update(study_id, study)
async
¶
Update an existing study (PATCH).
Universal field semantics:
- Omit a field to leave it unchanged.
- Include a field with a value to update it.
- Include a field with
Noneto clear it (where nullable in storage —description,tags,age,bmi,sex).
name cannot be cleared; sending name=None raises a validation
error. Omit name to leave it unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
study_id
|
UUID | str
|
UUID of the study to update |
required |
study
|
StudyUpdate
|
Partial update (only included fields are modified) |
required |
Returns:
| Type | Description |
|---|---|
StudyOut
|
Updated study information |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If study doesn't exist |
ValidationError
|
If update data is invalid (e.g., |
AuthenticationError
|
If not authenticated |
UserEndpoint
¶
Bases: BaseEndpoint
Handles user-related API endpoints.
Provides access to user information, history, and usage statistics.
change_password(request)
async
¶
Change the authenticated user's password.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ChangePasswordRequest
|
Current password (for verification) and the new password |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming the password change |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
ValidationError
|
If the current password is wrong or the new one does not meet complexity requirements |
create_api_key(request)
async
¶
Create an API key; the response carries the secret exactly once.
The account must have been enabled for keys by an administrator, and the request carries the account password again.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ApiKeyCreate
|
Name, scopes, optional description and lifetime, password |
required |
Returns:
| Type | Description |
|---|---|
ApiKeyCreated
|
The key with its secret — store it now, it is not shown again |
Raises:
| Type | Description |
|---|---|
ForbiddenError
|
If the account may not create keys, or the client is itself authenticated with a key |
ValidationError
|
If a scope is refused or the lifetime exceeds the server's maximum |
Example
from yousleep_common.models import ApiKeyCreate
from yousleep_common.types import Permission
created = await client.user.create_api_key(
ApiKeyCreate(
name="Nightly pipeline",
scopes=[Permission.RECORDING_CREATE, Permission.ANALYSIS_CREATE],
expires_in_days=90,
password="…",
)
)
secret_manager.store("YOUSLEEP_API_KEY", created.secret)
delete()
async
¶
Delete the current user account.
This is a permanent action that deletes all user data.
Returns:
| Type | Description |
|---|---|
MessageResponse
|
Message confirming deletion |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
export_audit(filters=None)
async
¶
Return your own audit trail as CSV text, oldest first.
get_current()
async
¶
Get information about the currently authenticated user.
Returns:
| Type | Description |
|---|---|
UserOut
|
User information |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
get_organization()
async
¶
Get the caller's organization and their role in it.
Every project, credit balance and storage figure belongs to it.
Returns:
| Type | Description |
|---|---|
UserOrganizationOut
|
The organization overview. |
history(*, since_num_days=None, analysis_config_id=None, project_name=None, study_name=None, status=None, analysis_type=None, order=None, offset=None, limit=None)
async
¶
Get one page of the user's analysis history.
The history covers every analysis in every project the user can
open, deleted ones included, ordered by the time each was queued.
The server returns the newest first and a bounded page by default;
total on the response counts every match, so page with
offset until it is reached.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
since_num_days
|
int | None
|
Only analyses from the last |
None
|
analysis_config_id
|
str | None
|
Only analyses of this configuration |
None
|
project_name
|
str | None
|
Only analyses in the project with this name |
None
|
study_name
|
str | None
|
Only analyses in studies with this name |
None
|
status
|
AnalysisStatus | None
|
Only analyses in this status |
None
|
analysis_type
|
AnalysisType | None
|
Only analyses of this type |
None
|
order
|
Literal['asc', 'desc'] | None
|
|
None
|
offset
|
int | None
|
Analyses to skip |
None
|
limit
|
int | None
|
Maximum analyses to return; the server's default when omitted |
None
|
Returns:
| Type | Description |
|---|---|
HistoryResponse
|
Analysis history with list of analyses and total count |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
list_api_keys()
async
¶
List the account's API keys — everything except the secret.
Expired keys stay listed until deleted, so the owner can see what needs rotating.
Returns:
| Type | Description |
|---|---|
list[ApiKeyOut]
|
The keys, newest first |
list_audit(filters=None, *, offset=0, limit=50)
async
¶
Return your own audit trail, newest first.
Events about your account and membership, and what you did in
projects. filters narrows by event types, a time window or an item.
Returns:
| Type | Description |
|---|---|
AuditEventListResponse
|
One page of events ( |
revoke_api_key(key_id)
async
¶
Revoke an API key; it stops authenticating on its next request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_id
|
UUID | str
|
The key's id, from the listing |
required |
Returns:
| Type | Description |
|---|---|
MessageResponse
|
A confirmation message |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the account holds no such key |
update_profile(request)
async
¶
Update the authenticated user's own profile (name/position).
Omitted fields are left unchanged. Email/password changes go through
their dedicated flows; usage_type changes are admin-mediated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
UserProfileUpdate
|
The profile fields to change |
required |
Returns:
| Type | Description |
|---|---|
UserOut
|
The updated user |
usage(analysis_config_id, since_num_days=30)
async
¶
Get the user's analysis usage statistics for a specific analysis config.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
analysis_config_id
|
str
|
ID of the analysis configuration to get usage for |
required |
since_num_days
|
int
|
Number of days to look back (default: 30) |
30
|
Returns:
| Type | Description |
|---|---|
AnalysisUsage
|
Usage statistics including analysis count, credit cost, and signal hours |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
usage_detailed()
async
¶
Get detailed resource usage statistics.
Returns:
| Type | Description |
|---|---|
ResourceUsage
|
Resource usage with project, study, recording, and storage counts |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
usage_limits()
async
¶
Get usage limits for the current user.
Returns:
| Type | Description |
|---|---|
ResourceUsage
|
Resource usage limits |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If not authenticated |
WorkflowsEndpoint
¶
Bases: BaseEndpoint
High-level, end-to-end analysis workflows built on the resource endpoints.
analyze_file(*, file, analysis_config_id, project_id=None, study_id=None, project_name=None, study_name=None, age=None, bmi=None, sex=None, project=None, study=None, parameters=None, channels=None, fetch=('events', 'biomarkers'), poll_interval=5.0, timeout=3600.0, on_progress=None, _ctx=None)
async
¶
Analyze a file end-to-end and return the results.
Creates a project and study (unless existing IDs are supplied), uploads
the recording, submits an analysis with analysis_config_id, waits for
it to complete, and fetches the requested results. Resources are kept
— this method never deletes anything. Use
:meth:analyze_file_temporary when you want them cleaned up.
Naming: when study_name is omitted it is inferred from the filename
(night.edf -> study night). Metadata (age/bmi/sex) is
optional and passed as plain scalars. Power users may pass full
project/study models instead, mutually exclusively with the
corresponding scalar arguments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
str | Path | BinaryIO
|
Path (or open binary file) of the recording to upload. |
required |
analysis_config_id
|
str
|
ID of the analysis config to run. |
required |
project_id
|
UUID | str | None
|
Analyze into this existing project instead of creating one. |
None
|
study_id
|
UUID | str | None
|
Analyze into this existing study (requires |
None
|
project_name
|
str | None
|
Name for the project to create (else auto-generated). |
None
|
study_name
|
str | None
|
Name for the study to create (else inferred from filename). |
None
|
age
|
int | None
|
Optional subject age (years) for a created study. |
None
|
bmi
|
float | None
|
Optional subject BMI for a created study. |
None
|
sex
|
str | None
|
Optional subject sex ("male"/"female"/"other"/"unknown"). |
None
|
project
|
ProjectCreate | None
|
Full ProjectCreate model (instead of project_name). |
None
|
study
|
StudyCreate | None
|
Full StudyCreate model (instead of study_name + metadata). |
None
|
parameters
|
list[tuple[str, str | int | float | bool]] | None
|
Optional analysis parameters as (name, value) tuples. |
None
|
channels
|
list[str] | None
|
Optional explicit channel names for the analysis. |
None
|
fetch
|
tuple[FetchKind, ...]
|
Which results to return; defaults to events and biomarkers. |
('events', 'biomarkers')
|
poll_interval
|
float
|
Seconds between status checks while waiting. |
5.0
|
timeout
|
float | None
|
Max seconds to wait for the analysis before ClientTimeoutError. |
3600.0
|
on_progress
|
Callable[[int], None] | None
|
Optional upload-progress callback (percentage 0-100). |
None
|
_ctx
|
_RunContext | None
|
Internal run context (used by analyze_file_temporary); do not set. |
None
|
Returns:
| Type | Description |
|---|---|
AnalysisWorkflowResult
|
An AnalysisWorkflowResult with the recording, analysis, and results. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If targeting arguments are combined incorrectly. |
AnalysisWorkflowError
|
If the analysis ends in a non-completed state. |
ClientTimeoutError
|
If the analysis does not finish within |
YouSleepClientError
|
On any underlying API error. |
analyze_file_temporary(*, file, analysis_config_id, project_id=None, study_id=None, project_name=None, study_name=None, age=None, bmi=None, sex=None, project=None, study=None, parameters=None, channels=None, fetch=('events', 'biomarkers'), poll_interval=5.0, timeout=3600.0, on_progress=None)
async
¶
Run :meth:analyze_file, deleting created resources on exit.
Takes the same arguments as :meth:analyze_file. On exit — whether the
block completes normally or raises — this deletes whatever resources the
workflow created, relying on server-side cascade (deleting the created
project/study/recording removes its descendants and frees quota).
Caller-supplied project_id/study_id are never deleted.
Example
Yields:
| Type | Description |
|---|---|
AsyncIterator[AnalysisWorkflowResult]
|
The AnalysisWorkflowResult, valid for the duration of the block. |
analyze_files(*, files, analysis_config_id, project_id=None, project_name=None, project=None, study_id=None, parameters=None, channels=None, fetch=('events', 'biomarkers'), poll_interval=5.0, timeout=3600.0, max_concurrency=4, on_progress=None, _ctx=None)
async
¶
Analyze multiple files end-to-end and return per-file outcomes.
Creates one project (unless project_id is given) and one study per
file (names inferred from filenames), uploads the recordings with
bounded concurrency, submits all analyses in a single batch call, polls
the whole batch with single status calls, and fetches results for
completed analyses. Resources are kept — use
:meth:analyze_files_temporary for automatic cleanup.
Per-file failures never raise: each input file yields a
:class:FileAnalysisOutcome (completed/failed/timeout) and
the rest of the batch continues. Only argument errors and whole-batch
failures (e.g. the project cannot be created) raise.
One study per file. study_id targets an existing study and is
therefore only valid with a single file — a study holds exactly one
recording. Passing it with several files raises ValueError.
Multiple nights of one subject are several studies, one per night,
linked by a shared subject_key.
Per-file subject metadata is not supported here — create studies via the lower-level endpoints if needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
files
|
Sequence[str | Path | BinaryIO]
|
Paths (or open binary files) of the recordings, 1-500. |
required |
analysis_config_id
|
str
|
ID of the analysis config to run on every file. |
required |
project_id
|
UUID | str | None
|
Analyze into this existing project instead of creating one. |
None
|
project_name
|
str | None
|
Name for the project to create (else auto-generated). |
None
|
project
|
ProjectCreate | None
|
Full ProjectCreate model (instead of project_name). |
None
|
study_id
|
UUID | str | None
|
Existing study to upload into (requires project_id). Valid with a single file only — a study holds one recording. |
None
|
parameters
|
list[tuple[str, str | int | float | bool]] | None
|
Optional analysis parameters as (name, value) tuples. |
None
|
channels
|
list[str] | None
|
Optional explicit channel names for the analyses. |
None
|
fetch
|
tuple[FetchKind, ...]
|
Which results to return per file; defaults to events + biomarkers. |
('events', 'biomarkers')
|
poll_interval
|
float
|
Seconds between batch status polls while waiting. |
5.0
|
timeout
|
float | None
|
Max seconds to wait for the whole batch; analyses still
running afterwards yield |
3600.0
|
max_concurrency
|
int
|
Max parallel uploads / per-item result fetches. |
4
|
on_progress
|
Callable[[str | Path | BinaryIO, int], None] | None
|
Optional upload-progress callback receiving
|
None
|
_ctx
|
_BatchRunContext | None
|
Internal run context (used by analyze_files_temporary); do not set. |
None
|
Returns:
| Type | Description |
|---|---|
BatchAnalysisWorkflowResult
|
A BatchAnalysisWorkflowResult with one outcome per input file, in |
BatchAnalysisWorkflowResult
|
input order. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If arguments are combined incorrectly or out of range. |
YouSleepClientError
|
On whole-batch API failures (before any per-file work exists). |
analyze_files_temporary(*, files, analysis_config_id, project_id=None, project_name=None, project=None, study_id=None, parameters=None, channels=None, fetch=('events', 'biomarkers'), poll_interval=5.0, timeout=3600.0, max_concurrency=4, on_progress=None)
async
¶
Run :meth:analyze_files, deleting created resources on exit.
Takes the same arguments as :meth:analyze_files. On exit — whether the
block completes normally or raises — this deletes whatever the workflow
created: the created project (one cascade delete), or each created study
when the caller supplied the project, or each uploaded recording when
the caller supplied a shared study. Caller-supplied resources are never
deleted.
Yields:
| Type | Description |
|---|---|
AsyncIterator[BatchAnalysisWorkflowResult]
|
The BatchAnalysisWorkflowResult, valid for the duration of the block. |