Skip to content

projects

Project endpoint handlers.

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 (project_not_at_site).

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 /, or empty for the whole bucket; a

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

Example
from yousleep_common.models import ProjectCreate

project = ProjectCreate(
    name="My Study",
    description="Sleep analysis project",
)
created = await client.projects.create(project)

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:~yousleep_common.models.ReportExportProjectParams defaults by_group ON, so omitting it there means the opposite of omitting it here

False
groups list[str] | None

With by_group, only these study tags form the report's comparison groups; studies matching none are excluded (with a warning). Default: every tag becomes a group.

None
analysis_configs list[str] | None

Only these analysis configurations contribute; default: every completed analysis does. The project's own vocabulary comes from list_analysis_configs.

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 by_group, groups and longitudinal. The response's stratification block echoes the resolved bins and per-stratum study counts.

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: "session-index" (a study's position within its subject's series) or "calendar" (a week or month of recording starts). None lets the server choose: session-index when any study in scope carries a subject key, else calendar

None
calendar_granularity CalendarGranularity

"day", "week" or "month" — the span of one calendar bin; ignored on a session-index basis

'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

report.resolve_origins(entry) rather than entry.origins

ProjectReportResponse

directly.

Raises:

Type Description
NotFoundError

If project doesn't exist

ValidationError

If the requested report mode is invalid — groups without by_group, by_group together with longitudinal, or only one end of the statistics window

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

"asc" (the default) or "desc" for newest first

None

Returns:

Type Description
list[ProjectOut]

List of projects

Raises:

Type Description
AuthenticationError

If not authenticated

Example
recent = await client.projects.list(order="desc", limit=5)

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 (limit at most 200) and the total.

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.

Example
found = await client.projects.new_bucket_files(project.id)
for folder, files in found.items():
    for file in files:
        await client.recordings.register_in_place(
            project.id, file.key, folder=folder
        )

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 bucket_files lists them.

required
folder str | None

The folder files lists in full. The project's files registered from below it that the listing lacks, or names changed, are then missing at the site, and those it names are there again.

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 list_shares.

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 None to 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., name=None)

AuthenticationError

If not authenticated

Example
from yousleep_common.models import ProjectUpdate

# Clear the description, leave everything else alone
project_update = ProjectUpdate(description=None)
updated = await client.projects.update(project_id, project_update)