Index
Pydantic models for the analysis configuration file.
This subpackage re-exports all public names so that existing imports like
from yousleep_common.models.analysis_config import AnalysisConfig continue to work.
AnalysisConfig
pydantic-model
¶
Bases: AnalysisConfigBase
The full analysis configuration: what is stored, hashed and run.
Adds what the catalogue does not serve: the image, the scheduling priority and the resources the analysis claims.
Config:
frozen:True
Fields:
-
identification(Identification) -
purpose(Purpose) -
provenance(Provenance) -
licence(Licence | LegalDocumentShort) -
evidence(Evidence) -
inputs(Inputs) -
outputs(Outputs) -
parameters(Parameters) -
cost(CostModel) -
runs_at(list[RunPlace]) -
docker(DockerSettings) -
priority(Priority) -
resources(ResourceRequirements)
Validators:
-
_provenance_written_before_it_existed -
runs_on_the_platform→runs_at -
the_declaration_covers_the_licence_class -
validated_regime_is_yousleeps_own_claim
priority
pydantic-field
¶
Scheduling priority. A platform decision; an author leaves it out.
compute_config_sha1()
¶
Compute the SHA1 hash of the analysis configuration JSON serialized.
load_validated_analysis_config(config_id, configs_dir)
classmethod
¶
Load and validate an analysis configuration from a YAML file by its filename.
:param config_id: ID of the analysis configuration file. :param configs_dir: Directory where the analysis configuration files are stored. :return: Validated analysis configuration.
AnalysisConfigBase
pydantic-model
¶
Bases: BaseModel
What an analysis configuration says that anyone may read.
The shared part of two models: AnalysisConfig, the full configuration
that is stored, hashed and run, and AnalysisConfigOut, what the
catalogue serves. What the platform knows about an analysis rather than
what the configuration says (whether its image is present, who it is
offered to) lives on the response model only, so it never enters a
configuration's identity.
Fields:
-
identification(Identification) -
purpose(Purpose) -
provenance(Provenance) -
licence(Licence | LegalDocumentShort) -
evidence(Evidence) -
inputs(Inputs) -
outputs(Outputs) -
parameters(Parameters) -
cost(CostModel) -
runs_at(list[RunPlace])
Validators:
-
_provenance_written_before_it_existed -
runs_on_the_platform→runs_at -
the_declaration_covers_the_licence_class -
validated_regime_is_yousleeps_own_claim
cost
pydantic-field
¶
Declarative pricing facts (work scaling + parameter surcharges). Defaults = flat per-signal-hour pricing; the quote endpoints always report the final figure.
evidence
pydantic-field
¶
What the analysis cites. An analysis with nothing to cite yet omits it.
identification
pydantic-field
¶
The identification object of the analysis configuration
licence
pydantic-field
¶
The licence of the analysis.
parameters
pydantic-field
¶
Parameters the analysis accepts. Omitted when it takes none.
provenance
pydantic-field
¶
Who developed the analysis, and what youSleep claims about it.
purpose
pydantic-field
¶
The purpose of the analysis.
runs_at
pydantic-field
¶
Where the analysis may run: on the platform, or on the platform and at an organisation's site. Its owner sets it, and a change applies to submissions made after it. Left out when it is the platform only. An organisation may run a platform-only analysis at its site only under an exception a platform administrator records.
runs_on_the_platform(runs_at)
pydantic-validator
¶
Require the platform among the places, and keep them in one order.
Every analysis runs on the platform; a site is the only addition. The order is fixed so two configurations that say the same thing hash the same.
the_declaration_covers_the_licence_class()
pydantic-validator
¶
Refuse a commercial licence class on a declaration that ticked non-commercial use.
The declaration is what the developer said the analysis may be offered for; the licence class is what the platform offers it for. The second cannot exceed the first.
validated_regime_is_yousleeps_own_claim()
pydantic-validator
¶
Refuse a validated regime on an analysis youSleep did not develop.
The regime says which values of a parameter the analysis was characterised
at, and the platform says it in its own voice: every other value is then
presented to the user as a research setting. That is a claim to make about
one's own work. A developer's published operating point for their own
analysis belongs under evidence, where a reader can see whose claim it
is, rather than being restated here as the platform's.
AnalysisConfigOut
pydantic-model
¶
Bases: AnalysisConfigBase
What the catalogue serves: the readable configuration and the platform's facts about it.
Fields:
-
identification(Identification) -
purpose(Purpose) -
provenance(Provenance) -
licence(Licence | LegalDocumentShort) -
evidence(Evidence) -
inputs(Inputs) -
outputs(Outputs) -
parameters(Parameters) -
cost(CostModel) -
runs_at(list[RunPlace]) -
available(bool) -
visibility(AnalysisVisibility) -
credits_per_signal_hour(float) -
site_allowance(SiteAllowance | None)
Validators:
-
_provenance_written_before_it_existed -
runs_on_the_platform→runs_at -
the_declaration_covers_the_licence_class -
validated_regime_is_yousleeps_own_claim
available = False
pydantic-field
¶
Whether the analysis's image is present in the registry, as the platform last checked.
credit
property
¶
Return the credit this analysis's results carry, wherever they are shown.
credits_per_signal_hour = 0
pydantic-field
¶
What the analysis costs per hour of recorded signal, before channel and parameter adjustments, as the platform charges it.
site_allowance = None
pydantic-field
¶
Where the caller's organisation may run the analysis, for a signed-in caller. Null for an anonymous caller, and from a server that predates it.
spend_class
property
¶
Return the spend class the analysis's licence gives it.
visibility = AnalysisVisibility.PUBLIC
pydantic-field
¶
Where the analysis is offered. A caller sees a private analysis only when it belongs to the caller's organization.
AnalysisCredit
pydantic-model
¶
Bases: BaseModel
Who to credit for an analysis's results, and what to cite.
Derived from the configuration's provenance and evidence, so every place a
result is shown or exported credits it the same way: the developer, with
"packaged by youSleep" for an analysis developed elsewhere, and the
publications to cite: by default those the developer wrote
(Publication.cite). Other publications are evidence about the
analysis, not what its users cite.
Config:
frozen:True
Fields:
-
developed_by(str) -
citations(list[Publication]) -
source_url(HttpUrl | None) -
source_licence(str | None)
citations
pydantic-field
¶
What to cite when using the analysis's results: by default the developer's own publications. Empty when there is none to cite.
developed_by
pydantic-field
¶
Who developed the analysis, as its results credit it: the developer, followed by '; packaged by youSleep' for an analysis developed elsewhere.
source_licence = None
pydantic-field
¶
That source's software licence, as an SPDX identifier.
source_url = None
pydantic-field
¶
Where an analysis developed elsewhere is published; null for youSleep's own.
of(provenance, evidence)
classmethod
¶
Return the credit a configuration's provenance and evidence give its results.
AnalysisParameter
pydantic-model
¶
Bases: BaseModel
Represents an analysis-specific parameter.
Analysis parameters are used to configure the analysis and can be of type 'str', 'int', or 'float'. Can be set by the user unless there is only a single choice in which case it is considered a hard coded parameters.
Fields:
-
name(ParameterNameStr) -
description(DescriptionStr) -
key(ParameterKeyStr) -
type(Literal['str', 'int', 'float', 'bool']) -
range(Range | None) -
choices(Choices | None) -
default(str | int | float | bool) -
validated_regime(list[str | int | float | bool] | None)
Validators:
-
_key_from_legacy_argument -
validate_range_choices -
validate_choices→choices -
validate_range→range -
validate_default -
validate_validated_regime
api_name
property
¶
Return the name a request uses for this parameter: its key.
Kept as a computed field so the API schema and every client keep the name they have always read; it is the key by another name.
choices = None
pydantic-field
¶
The list of choices for the parameter. If set, the parameter is considered a choice parameter and the user must select one of the choices. If choises is a length 1 list the parameter is considered a hard coded parameter and the user cannot change the value. Must be set if range is not set.
default
pydantic-field
¶
The default value of the parameter. Must be one of the choices if choices is set or must be in range if range is set. REQUIRED: All parameters must have a default for consistent hash computation.
description
pydantic-field
¶
A brief description of the parameter.
key
pydantic-field
¶
The machine key of the parameter, unique within the analysis: what a request names it by, the key it has in the analysis manifest's parameters, and the name the parameter hash is computed over. Lowercase letters, digits, hyphens and underscores.
name
pydantic-field
¶
The name of the parameter. Must be unique among all parameters of the analysis. The name must be a contain only lowercase alphabetical characters and underscores ('_') and be between 2 and 32 characters long.
range = None
pydantic-field
¶
The range of acceptable values for the parameter. Must be set if choices is not set.
type
pydantic-field
¶
The type of the parameter. Can be 'str', 'int', 'float', or 'bool'.
validated_regime = None
pydantic-field
¶
The value(s) of this parameter at which the analysis has been validated — its validated regime. Every other accepted value stays fully supported and runnable, but is a research setting: the analysis was not characterised there, so its outputs are exploratory and should be interpreted as such. This is a different statement from 'default', which only says which value is pre-selected for the user; an analysis may pre-select a value it was never validated at, or be validated at several values of which only one is pre-selected. List every validated value when more than one qualifies. Leave unset (null) when the validated regime is not declared, in which case no value is claimed to be a research setting and none is claimed to be validated. Each entry must be an accepted value of this parameter: one of 'choices', or inside 'range'.
get_validated_value_or_default(value)
¶
Return the value if it is not None, otherwise return the default value.
Every parameter declares a default, so a value is always returned.
is_research_mode(value)
¶
Return whether value falls outside this parameter's validated regime.
Always False when no validated regime is declared: an undeclared regime makes no claim about any value, so nothing is presented as research mode.
Pass a normalized value — the output of :meth:validate_value or
:meth:get_validated_value_or_default. A raw, uncoerced submission such as the
string "3840" does not match the integer 3840 and would be reported as research.
validate_choices(choices)
pydantic-validator
¶
Validate that all choices are unique and of the same type.
validate_default()
pydantic-validator
¶
Validate that the default value is one of the choices if choices is set.
validate_range(range)
pydantic-validator
¶
Validate that the range values are of the same type and either int or float.
validate_range_choices(data)
pydantic-validator
¶
Validate the range and choices fields.
Validate that only one of 'range' and 'choices' can be set and that at least one of them is set.
validate_validated_regime()
pydantic-validator
¶
Validate that every declared validated-regime value is an accepted value.
A validated regime that names a value the parameter does not accept could never be selected, so it would silently mark every selectable value as research mode.
validate_value(value)
¶
Validate the value of the parameter and return the value if it is valid.
ChannelRequirement
pydantic-model
¶
Bases: BaseModel
Base channel type & requirement spec used in e.g., ExactChannel and ChannelType.
Fields:
ChannelRequirements
pydantic-model
¶
Bases: BaseModel
Channel requirements for the analysis.
Fields:
-
sampling_rate(Range) -
quality(list[QualityRequirement])
ChannelTypeRequirement
pydantic-model
¶
Bases: ChannelRequirement
Represents a channel type (e.g., EEG or EOG) that the analysis expects.
Fields:
-
type(ChannelType) -
requirements(ChannelRequirements) -
number(Range) -
slots(list[ChannelSlot] | None)
Validators:
number
pydantic-field
¶
The minimum and maximum number of channels of the given type that the analysis expects.
slots = None
pydantic-field
¶
Optional ordered slots giving each expected channel of this type a labelled position (and optionally a required laterality). Only meaningful for fixed-count requirements: when set, 'number' must be exactly [len(slots), len(slots)]. Channels are passed to the analysis in slot order.
validate_slots()
pydantic-validator
¶
Slots imply a fixed count that matches the declared number range.
Choices
¶
Bases: RootModel
Represents a list of choices where all choises have the same type and are unique.
Each choice can be a string, integer, float, or boolean.
__getitem__(item)
¶
Return the choice at the given index.
__iter__()
¶
Return an iterator over the choices.
__len__()
¶
Return the number of choices.
validate_choices(values)
classmethod
¶
Validate the choices.
Validate the choises and ensure that all choices have the same type and handles specification as root or 'choices' key in the dictionary.
validate_unique_choices()
¶
Validate that all choices are unique.
CostModel
pydantic-model
¶
Bases: BaseModel
Declarative, INPUT-side pricing facts for one analysis config.
Pricing responds to what the user submits (hours, channels, chosen options) — never to how the analysis is implemented internally, so a predictor/algorithm change can never silently change prices. The api-server's single cost function computes::
rate = per_signal_hour or the global billing rate
multiplier = 1 + per_channel_slope * (n_channels - 1)
billed_h = signal_hours * multiplier * prod(surcharge multipliers)
cost = ceil(billed_h * rate) + global minimum
+ sum(surcharge credits)
The base duration cost is meant to dominate: keep per_channel_slope
well below 1 (default 0 = channel count does not affect price). All
defaults yield exactly the flat global per-signal-hour pricing.
Config:
frozen:True
Fields:
-
per_signal_hour(float | None) -
per_channel_slope(float) -
parameter_surcharges(list[ParameterSurcharge])
parameter_surcharges
pydantic-field
¶
Extra costs for specific user-chosen parameter values.
per_channel_slope = 0.0
pydantic-field
¶
Dampened premium per resolved channel beyond the first: multiplier = 1 + slope * (n_channels - 1). 0 (default) = channel count does not affect price; keep well below 1 so the duration cost dominates. The per-type channel caps bound the maximum.
per_signal_hour = None
pydantic-field
¶
Config-specific credit rate per billed hour; null uses the global billing.credit_cost.per_signal_hour. THE knob for pricing an expensive-to-run analysis (e.g. one that internally runs many inference passes).
DockerSettings
pydantic-model
¶
Bases: BaseModel
Docker settings for building the analysis image.
Fields:
-
image(str) -
tag(str) -
digest(str | None) -
base_command(str) -
relative_build_path(str | Path) -
remote_https_url(HttpUrl | None) -
ssh_key(str | None)
Validators:
base_command = ''
pydantic-field
¶
The base command without parameters to run the analysis in the Docker container. Defaults to an empty string assuming an entry is set in the Dockerfile.
digest = None
pydantic-field
¶
Optional content digest of the Docker image, e.g. 'sha256:abc…'. When set, the image reference used to run the analysis pins these exact bytes ('image:tag@sha256:…'): the tag remains the human-readable version label, while the digest is what the container runtime resolves — a re-pushed tag can no longer change what runs. When unset, the tag alone selects the image.
full_image_name
property
¶
Return the tag form of the image name ('image:tag').
Deliberately digest-free: registry APIs and humans address images by
tag. Use :attr:pinned_image_reference for the reference a container
runtime should run.
image
pydantic-field
¶
The name of the Docker image.
pinned_image_reference
property
¶
Return the reference to run, digest-pinned when a digest is declared.
'image:tag@digest' with a digest, else 'image:tag'. 'NAME:TAG@DIGEST' is valid for every mainstream runtime; the runtime resolves the digest and the tag rides along as documentation.
relative_build_path = '.'
pydantic-field
¶
The relative path to the Docker build context. This path is relative to the root of the repository. Default is the root of the repository.
remote_https_url = None
pydantic-field
¶
The HTTPS URL of the remote repository. This URL is used to clone the repository and build the Docker image. If the repository is private, the an SSH equivalent URL is used instead for which a valid SSH key must be registered with the ssh-agent.
ssh_key = None
pydantic-field
¶
The SSH key to use to clone the repository if the repository is private. The SSH key must be a valid private key in the OpenSSH format. If the repository is public, this field can be left empty.
ssh_url
property
¶
Return the SSH URL of the source repository, or None when none is declared.
tag
pydantic-field
¶
The tag of the Docker image, e.g. 'latest' or '1.0'.
validate_remote_https_url(v)
pydantic-validator
¶
Validate the remote, when one is declared, as a HTTPS URL.
The field is optional; an explicit null (which is what a stored or
author-facing configuration without a source repository carries) passes
through untouched.
Evidence
pydantic-model
¶
Bases: BaseModel
The published work a configuration cites for its analysis.
A citation list, not a census: it holds what the configuration chose to cite, and there may be further work that is not listed, not known here, or deliberately left out. Read a count off it as a floor — at least this many — never as a total, and present it that way.
Fields:
-
publications(list[Publication])
publications
pydantic-field
¶
What the analysis cites. Empty is allowed and is shown as such.
ExactChannelRequirement
pydantic-model
¶
Bases: ChannelRequirement
An exact channel (a montage such as C3-M2) that the analysis expects.
Matched by identity, not by string: the platform reads every recording
label into a canonical form, so C3-M2 here matches C3-A2, C3M2
and EEG C3-M2 in a file. any_of lists acceptable alternatives in
order of preference. A montage the file does not carry is prepared before
upload; the platform does not derive channels.
Fields:
-
type(ChannelType) -
requirements(ChannelRequirements) -
name(ChannelName) -
any_of(list[ChannelName])
Validators:
-
_alternatives_are_distinct
any_of
pydantic-field
¶
Alternatives accepted in place of name, in order of preference; the first one present in the recording is used, e.g. ['C4-M1'] for a requirement named 'C3-M2'.
name
pydantic-field
¶
The canonical name of the channel the analysis expects, e.g. 'C3-M2'. Matched against each recording channel's canonical identity.
Identification
pydantic-model
¶
Bases: BaseModel
Analysis identification information.
Config:
frozen:True
Fields:
-
name(AnalysisConfigNameStr) -
id(AnalysisConfigIdStr) -
family(str | None)
Validators:
-
_derive_id_from_name
family = None
pydantic-field
¶
The family the analysis belongs to: the versions and variants of one method share it (e.g. 'U-Sleep'), so clients can group and filter by it. Unset, the analysis is a family of its own, named by its name.
family_name
property
¶
The family to group the analysis under: its own name when it sets none.
id
pydantic-field
¶
The machine-readable identifier: one lineage of comparable results, never changed once registered. Derived from the name when omitted (lower case, spaces as hyphens); set it explicitly only to keep an existing id when the name changes.
Inputs
pydantic-model
¶
Bases: BaseModel
Represents the inputs of the analysis.
Fields:
-
recording(RecordingInput | None) -
events(list[EventType] | None) -
metadata(list[MetadataType] | None)
Validators:
events = None
pydantic-field
¶
The list of typed event that the analysis requires in the input.
metadata = None
pydantic-field
¶
Optional list of metadata type input for the analysis, e.g., 'age'.Can be None if the analysis does not require metadata.
recording
pydantic-field
¶
The recording input for the analysis. Can be None if the analysis does not require a recording input.
validate_at_least_one_input(data)
pydantic-validator
¶
Validate that at least one of 'recording', 'events' and 'metadata' is set.
Outputs
pydantic-model
¶
Bases: BaseModel
Defines the output of the analysis.
Fields:
-
supports_full_probabilistic_output(bool) -
events(list[EventType])
Validators:
events
pydantic-field
¶
The list of typed event that the analysis outputs.
supports_full_probabilistic_output = False
pydantic-field
¶
Whether the analysis supports outputting full probabilistic distributions (all class probabilities per prediction, not just argmax). When true, users can request overlapping events with probability scores for all classes.
validate_probabilistic_consistency()
pydantic-validator
¶
Validate probabilistic output consistency.
If supports_full_probabilistic_output is True, all event types must be probabilistic.
ParameterSurcharge
pydantic-model
¶
Bases: BaseModel
Extra cost when a parameter takes a specific (normalized) value.
Prices user-selected OPTIONS — e.g. a high-frequency-output mode that multiplies compute — without new server code. Matched against the submission's normalized parameter values (defaults filled in), so a default-valued surcharge applies even when the user omits the parameter.
Config:
frozen:True
Fields:
-
parameter(str) -
equals(str | int | float | bool) -
hours_multiplier(float) -
extra_credits(int)
equals
pydantic-field
¶
The value that triggers the surcharge (exact match on the normalized value).
extra_credits = 0
pydantic-field
¶
Flat credits added to the analysis cost when triggered.
hours_multiplier = 1.0
pydantic-field
¶
Multiplies the billed hours when triggered.
parameter
pydantic-field
¶
The parameter's api_name (must exist in parameters.custom).
Parameters
pydantic-model
¶
Bases: BaseModel
The analysis-specific parameters a configuration declares.
Every parameter reaches the container through the analysis manifest, keyed
by its key and typed as declared here; the platform passes nothing else.
Fields:
-
custom(list[AnalysisParameter])
Validators:
custom
pydantic-field
¶
Parameters the analysis accepts. Empty when it takes none.
research_parameters(submitted)
¶
Return the API names of parameters whose effective value is research mode.
The effective value of each custom parameter is the submitted value
(matched on :attr:AnalysisParameter.api_name) or, when absent, the
parameter's default — a default can itself lie outside the validated
regime. Parameters of configurations that declare no validated regime
never appear.
Raises:
| Type | Description |
|---|---|
ValueError
|
A submitted value does not resolve against this configuration (wrong type, not a choice, out of range). The caller decides whether that means "invalid submission" or, when classifying a historical analysis against a configuration that has since changed, "unknown". |
validate_unique_keys(custom)
pydantic-validator
¶
Keys and names are unique within one configuration.
Priority
pydantic-model
¶
Provenance
pydantic-model
¶
Bases: BaseModel
Who developed the analysis, and what youSleep claims about it.
A catalogue that lists what youSleep built beside what youSleep merely runs
owes the reader the difference, and this is where it is stated rather than
inferred from the absence of something else. Every field here is a fact
about where the analysis came from; what is known about how it performs is
evidence, and whether it carries a regulatory claim is neither.
For software developed elsewhere the upstream repository and its licence travel with the configuration. The attribution that licence requires is then rendered from the configuration that is actually deployed, and cannot drift from it.
Config:
frozen:True
Fields:
-
origin(Literal['yousleep', 'third-party']) -
developer(str) -
source_url(HttpUrl | None) -
source_licence(str | None) -
source_version(str | None) -
data_rights(DataRights | None)
Validators:
data_rights = None
pydantic-field
¶
On what basis the analysis may be offered under the licence class in 'licence': 'pending' while developing, or the developer's signed Analysis Declaration once it is on record. Required for a third-party analysis; the platform publishes one only with a declaration.
developer
pydantic-field
¶
The name to credit as the developer — an organisation, or the authors of the upstream software.
origin
pydantic-field
¶
Who developed the analysis: 'yousleep' for an analysis youSleep developed, 'third-party' for software developed elsewhere that youSleep packages and operates.
source_licence = None
pydantic-field
¶
The licence the source is published under, as an SPDX identifier (e.g. 'BSD-3-Clause'). This is the licence of the software itself, which is not the licence the platform grants for running it on the platform — that is 'licence'. Required for a third-party analysis.
source_url = None
pydantic-field
¶
Where the analysis' source is published. Required for a third-party analysis: its licence is a licence on that source, and a reader cannot check either without the location.
source_version = None
pydantic-field
¶
The upstream version this analysis runs, as its developers name it, with the version of any trained model when that is separate (e.g. 'YASA 0.7.0, classifiers 0.5.0'). Shown on the analysis page. A change here within one analysis id must leave its results comparable; otherwise it is a new id.
third_party_names_its_source()
pydantic-validator
¶
Require a third-party analysis to name its source, its licence and its data rights.
Publication
pydantic-model
¶
Bases: BaseModel
Represents information on a publication.
The optional fields are left out of the dump when unset: a configuration's hash is that of its dump, and a field it does not use must not change it.
Fields:
-
url(HttpUrl) -
title(str) -
name(str) -
by(Literal['developer', 'independent']) -
cite(bool | None) -
venue(str | None) -
year(int | None) -
summary(str | None)
by
pydantic-field
¶
Who produced this evidence, relative to the analysis' developer: 'developer' for work by the people who wrote the analysis, 'independent' for an evaluation by anyone else. This is a statement about authorship, not about quality — nothing here grades a study.
cite = None
pydantic-field
¶
Whether someone using the analysis should cite this publication. Unset, the developer's own publications are cited and independent ones are not; set it to false for the developer's own evaluation, which is evidence about the analysis rather than the work to cite, or to true for an independent publication that must be cited.
cited
property
¶
Whether a user of the analysis should cite this publication.
name
pydantic-field
¶
Short display name of the publication.
summary = None
pydantic-field
¶
One line on who or what was studied and what was found, as the publication reports it. A description, not an endorsement.
title
pydantic-field
¶
The title of the publication.
url
pydantic-field
¶
Persistent (e.g., doi) URL of the publication.
venue = None
pydantic-field
¶
Where it was published: the journal or proceedings.
year = None
pydantic-field
¶
The year of publication.
Purpose
pydantic-model
¶
Bases: BaseModel
Describes the analysis' type/outputs and purpose.
Fields:
-
analysis_types(list[AnalysisType]) -
description(DescriptionStr) -
tags(list[str])
analysis_types
pydantic-field
¶
The type(s) of analysis/anlyses (e.g., 'STAGING') that the analysis supports.
description
pydantic-field
¶
A brief description of the analysis.
tags
pydantic-field
¶
Optional free-form tags for categorising/sorting the analysis in clients (e.g. 'example' to mark demo configs, which clients sort last and badge).
QualityRequirement
pydantic-model
¶
Bases: BaseModel
Data quality requirements for a channel.
Fields:
method
pydantic-field
¶
The method used to calculate the quality metric. These methods are implemented by the platform and not by the individual analyses.
mode
pydantic-field
¶
The mode in which the quality metric is calculated and used. Modes can be 'global' or 'per_epoch'. If global, the channel cannot be passed to the analysis if the whole-recording quality is below the min_quality. If per_epoch, the channel can be passed to the analysis. If 'per_epoch', the analysis will receive the channel but the platform will indicate that any events within epochs with quality below min_quality should be considered uncertain.
score
pydantic-field
¶
The range of acceptable values for the quality metric.
Range
¶
Bases: RootModel
Represents a range between a minimum and maximum value.
Both values are inclusive and the minimum value is less than or equal to the maximum value. A maximum value of None indicates that there is no upper limit (+inf). A minimum value of None indicates that there is no lower limit (-inf). String literals "+inf" and "-inf" are also allowed.
__contains__(item)
¶
Check if the item is within the range.
__getitem__(item)
¶
Return the value at the given index.
__iter__()
¶
Return an iterator over the range values.
serialize_range()
¶
Convert float(+/-inf) to string (+/-inf) for JSON serialization.
validate_range(values)
classmethod
¶
Validate the range values.
Validate the range values and handles conversion of string inf literals to floats and specification as root or 'range' key in the dictionary.
RecordingInput
pydantic-model
¶
Bases: BaseModel
Defines a recording type input for the analysis.
Fields:
-
format(FileFormat) -
allow_multiple(bool) -
description(DescriptionStr | None) -
minimum_duration_seconds(PositiveInt) -
channels(list[ExactChannelRequirement] | None) -
channel_types(list[ChannelTypeRequirement] | None)
Validators:
allow_multiple = False
pydantic-field
¶
Whether the analysis supports multiple input files passed as a list of paths to 'argument' (see default parameters). Default is False, in which case a single path is passed.
channel_types = []
pydantic-field
¶
The list of channel types that the analysis expects and their requirements. Can be None if the analysis does not support general channels by types but requires exact channel deriviations only (see channels).
channels = []
pydantic-field
¶
The list of exact channels deriviations that the analysis expects and their requirements. Can be None if the analysis does not require any specific channels but any channels of certain types (see channel_types).
description = None
pydantic-field
¶
A brief description of the input.
format = FileFormat.EDF
pydantic-field
¶
The format of the input file, e.g., 'edf'.
minimum_duration_seconds = 1
pydantic-field
¶
The minimum duration of the input in seconds. Must be greater than 0.
validate_channels(data)
pydantic-validator
¶
Validate that at least one of 'channels' and 'channel_types' is set.
ResourceRequirements
pydantic-model
¶
Bases: BaseModel
Resource requirements for an analysis.
Memory needs are a sum of optional linear terms (all but base
default to 0, so each analysis opts into the terms matching how it loads
and holds signal data — no analysis is forced into another's shape):
peak_memory_mib =
base
+ per_hour * hours
+ per_hour_per_khz * hours * (max_sample_rate_hz / 1000)
+ per_hour_per_channel * hours * n_channels
+ per_hour_per_channel_per_khz
* hours * n_channels * (max_sample_rate_hz / 1000)
The per-channel term captures data at the analysis's fixed working rate
(one float32 full-signal copy at 128 Hz ~= 1.76 MiB/hour/channel); the
per-kHz term captures data held at the recording's native rate (one
float32 copy ~= 13.7 MiB/hour/channel/kHz) — e.g. the raw signal before an
analysis downsamples it. per_hour is for channel-independent buffers;
per_hour_per_khz for a channel-independent buffer at the native rate,
such as the working memory of resampling one channel at a time, which
every channel reuses.
The api-server uses :meth:estimate_peak_system_memory_mib /
:meth:estimate_peak_gpu_memory_mib at submission time to project the
expected memory consumption and passes it to the orchestrator as the
resource claim.
CPU is claimed in whole cores: cpu_cores is the parallelism the
analysis is written for. The platform reserves that many cores for the
run, passes the same number to the container as --cpus and as the
thread-count environment variables, and the container sizes its thread
pools to it. Thread pools do not look at cgroups, so a container that
starts more threads than it has cores is slower, not faster; the number
here is what keeps a full queue from over-subscribing the host. There is
no failure mode for too few cores, only a longer wall time, so no formula
or per-tier cap is needed.
Fields:
-
cpu_cores(PositiveInt) -
base_system_memory_mib(NonNegativeInt) -
per_hour_system_memory_mib(NonNegativeInt) -
per_hour_per_khz_system_memory_mib(NonNegativeInt) -
per_hour_per_channel_system_memory_mib(NonNegativeInt) -
per_hour_per_channel_per_khz_system_memory_mib(NonNegativeInt) -
base_gpu_memory_mib(NonNegativeInt) -
per_hour_gpu_memory_mib(NonNegativeInt) -
per_hour_per_channel_gpu_memory_mib(NonNegativeInt) -
per_hour_per_channel_per_khz_gpu_memory_mib(NonNegativeInt) -
artifacts_memory_mib(NonNegativeInt) -
per_hour_artifacts_memory_mib(NonNegativeInt) -
gpus(NonNegativeInt) -
wall_clock(WallClockCeiling | None) -
gpu_required(bool)
Validators:
-
_legacy_cpu_mhz
artifacts_memory_mib = 0
pydantic-field
¶
Disk space (in MiB) reserved for output artifacts. Added to the size of any input recording files to determine the total disk requirement.
base_gpu_memory_mib = 0
pydantic-field
¶
Constant term of the GPU-memory formula. Set to 0 if the analysis does not require a GPU.
base_system_memory_mib
pydantic-field
¶
Constant term of the system-memory formula: covers fixed overhead (model weights, ONNX runtime, Python, preprocessing libraries) before any signal data is loaded.
cpu_cores
pydantic-field
¶
Whole CPU cores the analysis is written to use in parallel. Reserved for the run and passed to the container as --cpus and as the thread-count environment variables; size thread pools to it.
gpu_required = False
pydantic-field
¶
Whether GPUs are mandatory or optional for the analysis.
gpus = 0
pydantic-field
¶
The number of GPUs required for the analysis. Set to 0 if the analysis does not require a GPU.
per_hour_artifacts_memory_mib = 0
pydantic-field
¶
Disk space (in MiB) added per signal hour for output artifacts.
per_hour_gpu_memory_mib = 0
pydantic-field
¶
GPU MiB per signal hour, independent of channel count. 0 if N/A.
per_hour_per_channel_gpu_memory_mib = 0
pydantic-field
¶
GPU MiB per signal hour per selected channel (at the working rate). 0 if the analysis needs no GPU or its GPU memory doesn't scale with length x channels.
per_hour_per_channel_per_khz_gpu_memory_mib = 0
pydantic-field
¶
GPU MiB per signal hour per channel per kHz of the native sample rate. 0 if the analysis doesn't hold native-rate signal on the GPU.
per_hour_per_channel_per_khz_system_memory_mib = 0
pydantic-field
¶
System MiB per signal hour per channel per kHz of the recording's NATIVE sample rate — data held at native rate before downsampling (a float32 copy is ~13.7 MiB/h/ch/kHz). 0 if the analysis doesn't hold native-rate signal.
per_hour_per_channel_system_memory_mib = 0
pydantic-field
¶
System MiB per signal hour per selected channel, at the analysis's fixed WORKING sample rate (a float32 full-signal copy at 128 Hz is ~1.76 MiB/h/ch). 0 if system memory does not scale with length x channels.
per_hour_per_khz_system_memory_mib = 0
pydantic-field
¶
System MiB per signal hour per kHz of the recording's NATIVE sample rate, independent of channel count: a buffer at native rate that the channels use one at a time, such as the working memory of resampling. 0 if not applicable.
per_hour_system_memory_mib = 0
pydantic-field
¶
System MiB per signal hour, independent of channel count (e.g. a channel-independent results/accumulator buffer). 0 if not applicable.
wall_clock = None
pydantic-field
¶
A wall-clock ceiling raised above the platform's default, with the reason. A platform decision made at registration; an author leaves it out.
estimate_peak_artifacts_memory_mib(hours)
¶
Project disk space (in MiB) for output artifacts.
estimate_peak_gpu_memory_mib(hours, n_channels, max_sample_rate_hz)
¶
Project peak GPU memory in MiB for an analysis of the given size.
Same optional-term structure as :meth:estimate_peak_system_memory_mib.
estimate_peak_system_memory_mib(hours, n_channels, max_sample_rate_hz)
¶
Project peak system memory in MiB for an analysis of the given size.
Sum of the optional linear terms (see the class docstring):
base + per_hour*h + per_hour_per_khz*h*(max_sample_rate_hz/1000)
+ per_hour_per_channel*h*c
+ per_hour_per_channel_per_khz*h*c*(max_sample_rate_hz/1000).
max_sample_rate_hz is the maximum native sample rate across the
selected channels (it only feeds the per-kHz terms). Rounded up so the
orchestrator never gets a value below the projection.
max_hours_within_system_memory(memory_mib, n_channels, max_sample_rate_hz)
¶
Return the longest recording whose projected peak fits memory_mib.
The inverse of :meth:estimate_peak_system_memory_mib for a given channel
count and native rate: (memory - base) / (the formula's per-hour
slope). None when nothing scales with length, so any length fits
once the base does; 0.0 when even the base does not fit.
SiteAllowance
pydantic-model
¶
Bases: BaseModel
Where the caller's organisation may run an analysis.
The platform runs every analysis. An organisation's own site runs one whose configuration allows a site, or one that an exception in force covers for the organisation. The quote and the submission apply the same rule; this says what it gives before either is asked.
Config:
frozen:True
Fields:
-
place(RunPlace) -
runs_there(bool) -
allowed_at_site(bool) -
by_exception(bool)
allowed_at_site
pydantic-field
¶
Whether the organisation may run the analysis at its own site: its configuration allows a site, or an exception in force covers it for the organisation.
by_exception
pydantic-field
¶
Whether only an exception in force allows it at the site: the configuration itself keeps the analysis on the platform.
place
pydantic-field
¶
Where the organisation's analyses run now: on the platform, or at its own site.
runs_there
pydantic-field
¶
Whether the analysis may run there. On the platform it always may; at the site, when allowed_at_site is true. Where it may not, the quote and the submission refuse it.
UserFriendlyNamedValue
pydantic-model
¶
Bases: BaseModel
Value with a user friendly name.
This is used to represent a value that can be presented to the user in a user-friendly way with a description of the value.
Fields:
-
value(str | int | float) -
description(str)
WallClockCeiling
pydantic-model
¶
Bases: BaseModel
A wall-clock ceiling raised above the platform's default, with the reason.
The platform bounds how long one run may take, scaling with the length of the recording, and stops a run that exceeds it. An author cannot predict their analysis's scaling reliably, so no configuration is asked to declare one; a configuration that genuinely needs more asks for it here, and the reason is part of the request. Set at registration.
Fields: