Skip to content

Schemas

The slopit.schemas module contains Pydantic models for all data structures. These schemas mirror the TypeScript schemas in @slopit/core and provide validation and type safety.

Session Types

SlopitSession

The root container for a participant session. This is the primary data structure consumed by all analyzers.

slopit.schemas.session.SlopitSession

Bases: BaseModel

Root container for a participant session.

This is the primary data structure consumed by all analyzers. Platform adapters convert their native formats to this schema.

Attributes:

Name Type Description
schema_version Literal['1.0']

Schema version for forward compatibility. Current: "1.0".

session_id str

Unique session identifier.

participant_id str | None

Participant identifier from recruitment platform.

study_id str | None

Study identifier.

platform PlatformInfo

Platform information.

environment EnvironmentInfo

Client environment information.

timing SessionTiming

Session timing information.

trials list[SlopitTrial]

List of trial data.

global_events GlobalEvents

Events not tied to specific trials.

metadata dict[str, JsonValue] | None

Additional session metadata.

Examples:

Load a session from a JSON file:

>>> from slopit import load_session
>>> session = load_session("data/participant_001.json")
>>> print(f"Session {session.session_id} has {len(session.trials)} trials")

Validate raw data:

>>> from slopit.schemas import SlopitSession
>>> session = SlopitSession.model_validate(raw_dict)
Source code in src/slopit/schemas/session.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
class SlopitSession(BaseModel):
    """Root container for a participant session.

    This is the primary data structure consumed by all analyzers.
    Platform adapters convert their native formats to this schema.

    Attributes
    ----------
    schema_version
        Schema version for forward compatibility. Current: "1.0".
    session_id
        Unique session identifier.
    participant_id
        Participant identifier from recruitment platform.
    study_id
        Study identifier.
    platform
        Platform information.
    environment
        Client environment information.
    timing
        Session timing information.
    trials
        List of trial data.
    global_events
        Events not tied to specific trials.
    metadata
        Additional session metadata.

    Examples
    --------
    Load a session from a JSON file:

    >>> from slopit import load_session
    >>> session = load_session("data/participant_001.json")
    >>> print(f"Session {session.session_id} has {len(session.trials)} trials")

    Validate raw data:

    >>> from slopit.schemas import SlopitSession
    >>> session = SlopitSession.model_validate(raw_dict)
    """

    schema_version: Literal["1.0"] = "1.0"
    session_id: str
    participant_id: str | None = None
    study_id: str | None = None
    platform: PlatformInfo
    environment: EnvironmentInfo
    timing: SessionTiming
    trials: list[SlopitTrial] = Field(default_factory=lambda: list[SlopitTrial]())
    global_events: GlobalEvents
    metadata: dict[str, JsonValue] | None = None

Example

from slopit import load_session
from slopit.schemas import SlopitSession

# Load from file
session = load_session("data/participant_001.json")

# Validate raw data
raw_data = {"sessionId": "abc123", ...}
session = SlopitSession.model_validate(raw_data)

# Access attributes
print(f"Session: {session.session_id}")
print(f"Participant: {session.participant_id}")
print(f"Trials: {len(session.trials)}")

SlopitTrial

Data for a single trial within a session.

slopit.schemas.session.SlopitTrial

Bases: BaseModel

Data for a single trial.

Attributes:

Name Type Description
trial_id str

Unique trial identifier.

trial_index int

Zero-indexed position in the session.

trial_type str | None

Trial type identifier from the platform.

start_time int

Trial start as Unix timestamp in milliseconds.

end_time int

Trial end as Unix timestamp in milliseconds.

rt int | None

Response time in milliseconds.

stimulus StimulusInfo | None

Stimulus information.

response ResponseInfo | None

Participant response.

behavioral BehavioralData | None

Behavioral capture data.

platform_data dict[str, JsonValue] | None

Platform-specific trial data passed through.

capture_flags list[CaptureFlag] | None

Flags generated during capture.

Source code in src/slopit/schemas/session.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
class SlopitTrial(BaseModel):
    """Data for a single trial.

    Attributes
    ----------
    trial_id
        Unique trial identifier.
    trial_index
        Zero-indexed position in the session.
    trial_type
        Trial type identifier from the platform.
    start_time
        Trial start as Unix timestamp in milliseconds.
    end_time
        Trial end as Unix timestamp in milliseconds.
    rt
        Response time in milliseconds.
    stimulus
        Stimulus information.
    response
        Participant response.
    behavioral
        Behavioral capture data.
    platform_data
        Platform-specific trial data passed through.
    capture_flags
        Flags generated during capture.
    """

    trial_id: str
    trial_index: int
    trial_type: str | None = None
    start_time: int
    end_time: int
    rt: int | None = None
    stimulus: StimulusInfo | None = None
    response: ResponseInfo | None = None
    behavioral: BehavioralData | None = None
    platform_data: dict[str, JsonValue] | None = None
    capture_flags: list[CaptureFlag] | None = None

Example

for trial in session.trials:
    print(f"Trial {trial.trial_index}: {trial.trial_type}")

    if trial.response:
        print(f"  Response: {trial.response.value}")

    if trial.behavioral:
        print(f"  Keystrokes: {len(trial.behavioral.keystrokes)}")

SessionTiming

Session-level timing information.

slopit.schemas.session.SessionTiming

Bases: BaseModel

Session-level timing information.

Attributes:

Name Type Description
start_time int

Session start as Unix timestamp in milliseconds.

end_time int | None

Session end as Unix timestamp in milliseconds. None if session is incomplete.

duration int | None

Total duration in milliseconds.

Source code in src/slopit/schemas/session.py
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class SessionTiming(BaseModel):
    """Session-level timing information.

    Attributes
    ----------
    start_time
        Session start as Unix timestamp in milliseconds.
    end_time
        Session end as Unix timestamp in milliseconds.
        None if session is incomplete.
    duration
        Total duration in milliseconds.
    """

    start_time: int
    end_time: int | None = None
    duration: int | None = None

EnvironmentInfo

Client environment information captured at session start.

slopit.schemas.session.EnvironmentInfo

Bases: BaseModel

Client environment information captured at session start.

Attributes:

Name Type Description
user_agent str

Browser user agent string.

screen_resolution tuple[int, int]

Screen dimensions as (width, height) in pixels.

viewport_size tuple[int, int]

Viewport dimensions as (width, height) in pixels.

device_pixel_ratio float

Device pixel ratio for high-DPI displays.

timezone str

IANA timezone identifier (e.g., "America/New_York").

language str

Browser language setting (e.g., "en-US").

touch_capable bool

Whether touch input is available.

connection_type str | None

Estimated connection type from Navigator.connection API.

Source code in src/slopit/schemas/session.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class EnvironmentInfo(BaseModel):
    """Client environment information captured at session start.

    Attributes
    ----------
    user_agent
        Browser user agent string.
    screen_resolution
        Screen dimensions as (width, height) in pixels.
    viewport_size
        Viewport dimensions as (width, height) in pixels.
    device_pixel_ratio
        Device pixel ratio for high-DPI displays.
    timezone
        IANA timezone identifier (e.g., "America/New_York").
    language
        Browser language setting (e.g., "en-US").
    touch_capable
        Whether touch input is available.
    connection_type
        Estimated connection type from Navigator.connection API.
    """

    user_agent: str
    screen_resolution: tuple[int, int]
    viewport_size: tuple[int, int]
    device_pixel_ratio: float
    timezone: str
    language: str
    touch_capable: bool
    connection_type: str | None = None

PlatformInfo

Information about the experiment platform (jsPsych, lab.js, etc.).

slopit.schemas.session.PlatformInfo

Bases: BaseModel

Information about the experiment platform.

Attributes:

Name Type Description
name str

Platform identifier. Known values include "jspsych", "labjs", "psychojs", "gorilla", "qualtrics", and "custom".

version str | None

Platform version string.

adapter_version str | None

Version of the slopit adapter used.

Source code in src/slopit/schemas/session.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class PlatformInfo(BaseModel):
    """Information about the experiment platform.

    Attributes
    ----------
    name
        Platform identifier. Known values include "jspsych", "labjs",
        "psychojs", "gorilla", "qualtrics", and "custom".
    version
        Platform version string.
    adapter_version
        Version of the slopit adapter used.
    """

    name: str
    version: str | None = None
    adapter_version: str | None = None

StimulusInfo

Information about a trial stimulus.

slopit.schemas.session.StimulusInfo

Bases: BaseModel

Information about a trial stimulus.

Attributes:

Name Type Description
type Literal['text', 'image', 'audio', 'video', 'html', 'other']

Stimulus type category.

content str | None

Stimulus content. For text, the text content. For media, URL or data URI. For HTML, the HTML string.

content_hash str | None

SHA-256 hash of content for deduplication.

parameters dict[str, JsonValue] | None

Additional stimulus parameters.

Source code in src/slopit/schemas/session.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
class StimulusInfo(BaseModel):
    """Information about a trial stimulus.

    Attributes
    ----------
    type
        Stimulus type category.
    content
        Stimulus content. For text, the text content. For media,
        URL or data URI. For HTML, the HTML string.
    content_hash
        SHA-256 hash of content for deduplication.
    parameters
        Additional stimulus parameters.
    """

    type: Literal["text", "image", "audio", "video", "html", "other"]
    content: str | None = None
    content_hash: str | None = None
    parameters: dict[str, JsonValue] | None = None

ResponseInfo

Participant response information.

slopit.schemas.session.ResponseInfo

Bases: BaseModel

Participant response information.

Attributes:

Name Type Description
type Literal['text', 'choice', 'multi-choice', 'slider', 'likert', 'annotation', 'other']

Response type category.

value JsonValue

Response value. Type depends on response type.

character_count int | None

For text responses, the character count.

word_count int | None

For text responses, the word count.

Source code in src/slopit/schemas/session.py
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
class ResponseInfo(BaseModel):
    """Participant response information.

    Attributes
    ----------
    type
        Response type category.
    value
        Response value. Type depends on response type.
    character_count
        For text responses, the character count.
    word_count
        For text responses, the word count.
    """

    type: Literal["text", "choice", "multi-choice", "slider", "likert", "annotation", "other"]
    value: JsonValue
    character_count: int | None = None
    word_count: int | None = None

Behavioral Types

BehavioralData

Container for all behavioral capture data within a trial.

slopit.schemas.behavioral.BehavioralData

Bases: BaseModel

Container for all behavioral capture data.

Attributes:

Name Type Description
keystrokes list[KeystrokeEvent] | None

List of keystroke events.

focus list[FocusEvent] | None

List of focus/visibility events.

paste list[PasteEvent] | None

List of paste events.

mouse list[MouseEvent] | None

List of mouse events with kinematics data.

scroll list[ScrollEvent] | None

List of scroll events for reading pattern detection.

clipboard list[ClipboardCopyEvent] | None

List of clipboard copy/cut events.

input_duration list[InputDurationEvent] | None

List of input duration events for per-field tracking.

metrics BehavioralMetrics | None

Computed metrics from the behavioral data.

Source code in src/slopit/schemas/behavioral.py
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
class BehavioralData(BaseModel):
    """Container for all behavioral capture data.

    Attributes
    ----------
    keystrokes
        List of keystroke events.
    focus
        List of focus/visibility events.
    paste
        List of paste events.
    mouse
        List of mouse events with kinematics data.
    scroll
        List of scroll events for reading pattern detection.
    clipboard
        List of clipboard copy/cut events.
    input_duration
        List of input duration events for per-field tracking.
    metrics
        Computed metrics from the behavioral data.
    """

    keystrokes: list[KeystrokeEvent] | None = None
    focus: list[FocusEvent] | None = None
    paste: list[PasteEvent] | None = None
    mouse: list[MouseEvent] | None = None
    scroll: list[ScrollEvent] | None = None
    clipboard: list[ClipboardCopyEvent] | None = None
    input_duration: list[InputDurationEvent] | None = None
    metrics: BehavioralMetrics | None = None

Example

for trial in session.trials:
    if trial.behavioral is None:
        continue

    behavioral = trial.behavioral

    # Access keystroke data
    for ks in behavioral.keystrokes:
        if ks.event == "keydown":
            print(f"  {ks.time}ms: {ks.key}")

    # Access focus events
    for focus in behavioral.focus:
        print(f"  {focus.time}ms: {focus.event}")

    # Access paste events
    for paste in behavioral.paste:
        print(f"  {paste.time}ms: pasted {paste.text_length} chars")

KeystrokeEvent

A single keystroke event (keydown or keyup).

slopit.schemas.behavioral.KeystrokeEvent

Bases: BaseModel

A single keystroke event.

Attributes:

Name Type Description
time float

Time since trial start in milliseconds.

key str

Key value from KeyboardEvent.key (e.g., "a", "Enter").

code str

Physical key code from KeyboardEvent.code (e.g., "KeyA").

event Literal['keydown', 'keyup']

Event type, either "keydown" or "keyup".

text_length int | None

Current text length at this moment.

modifiers ModifierState | None

Modifier key states.

Source code in src/slopit/schemas/behavioral.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class KeystrokeEvent(BaseModel):
    """A single keystroke event.

    Attributes
    ----------
    time
        Time since trial start in milliseconds.
    key
        Key value from KeyboardEvent.key (e.g., "a", "Enter").
    code
        Physical key code from KeyboardEvent.code (e.g., "KeyA").
    event
        Event type, either "keydown" or "keyup".
    text_length
        Current text length at this moment.
    modifiers
        Modifier key states.
    """

    time: float
    key: str
    code: str
    event: Literal["keydown", "keyup"]
    text_length: int | None = None
    modifiers: ModifierState | None = None

Example

from slopit.schemas import KeystrokeEvent

# KeystrokeEvent fields
event = KeystrokeEvent(
    time=1234.5,           # ms since trial start
    key="a",               # KeyboardEvent.key
    code="KeyA",           # KeyboardEvent.code
    event="keydown",       # "keydown" or "keyup"
    text_length=42,        # current text length
    modifiers=None,        # modifier key states
)

FocusEvent

A focus or visibility change event.

slopit.schemas.behavioral.FocusEvent

Bases: BaseModel

A focus or visibility change event.

Attributes:

Name Type Description
time float

Time since trial start in milliseconds.

event Literal['focus', 'blur', 'visibilitychange']

Event type.

visibility Literal['visible', 'hidden'] | None

For visibilitychange events, the new visibility state.

blur_duration float | None

For blur events, duration until refocus in milliseconds.

Source code in src/slopit/schemas/behavioral.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class FocusEvent(BaseModel):
    """A focus or visibility change event.

    Attributes
    ----------
    time
        Time since trial start in milliseconds.
    event
        Event type.
    visibility
        For visibilitychange events, the new visibility state.
    blur_duration
        For blur events, duration until refocus in milliseconds.
    """

    time: float
    event: Literal["focus", "blur", "visibilitychange"]
    visibility: Literal["visible", "hidden"] | None = None
    blur_duration: float | None = None

PasteEvent

A paste event from clipboard.

slopit.schemas.behavioral.PasteEvent

Bases: BaseModel

A paste event.

Attributes:

Name Type Description
time float

Time since trial start in milliseconds.

text_length int

Length of pasted text in characters.

text_preview str | None

First N characters of pasted text.

text_hash str | None

SHA-256 hash of full pasted text.

preceding_keystrokes int

Number of keystrokes in preceding 2 seconds.

blocked bool

Whether paste was blocked by configuration.

Source code in src/slopit/schemas/behavioral.py
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
class PasteEvent(BaseModel):
    """A paste event.

    Attributes
    ----------
    time
        Time since trial start in milliseconds.
    text_length
        Length of pasted text in characters.
    text_preview
        First N characters of pasted text.
    text_hash
        SHA-256 hash of full pasted text.
    preceding_keystrokes
        Number of keystrokes in preceding 2 seconds.
    blocked
        Whether paste was blocked by configuration.
    """

    time: float
    text_length: int
    text_preview: str | None = None
    text_hash: str | None = None
    preceding_keystrokes: int
    blocked: bool

ModifierState

Modifier key states at the time of a keystroke.

slopit.schemas.behavioral.ModifierState

Bases: BaseModel

Modifier key states at the time of a keystroke.

Attributes:

Name Type Description
shift bool

Whether Shift was pressed.

ctrl bool

Whether Ctrl was pressed.

alt bool

Whether Alt was pressed.

meta bool

Whether Meta (Cmd on Mac, Win on Windows) was pressed.

Source code in src/slopit/schemas/behavioral.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class ModifierState(BaseModel):
    """Modifier key states at the time of a keystroke.

    Attributes
    ----------
    shift
        Whether Shift was pressed.
    ctrl
        Whether Ctrl was pressed.
    alt
        Whether Alt was pressed.
    meta
        Whether Meta (Cmd on Mac, Win on Windows) was pressed.
    """

    shift: bool
    ctrl: bool
    alt: bool
    meta: bool

Metric Types

KeystrokeMetrics

Computed metrics from keystroke data.

slopit.schemas.behavioral.KeystrokeMetrics

Bases: BaseModel

Computed metrics from keystroke data.

Attributes:

Name Type Description
total_keystrokes int

Total number of keystroke events.

printable_keystrokes int

Number of printable character keystrokes.

deletions int

Number of deletion keystrokes (Backspace, Delete).

mean_iki float

Mean inter-keystroke interval in milliseconds.

std_iki float

Standard deviation of inter-keystroke intervals.

median_iki float

Median inter-keystroke interval.

pause_count int

Number of pauses exceeding threshold.

product_process_ratio float

Ratio of final characters to total keystrokes.

Source code in src/slopit/schemas/behavioral.py
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
class KeystrokeMetrics(BaseModel):
    """Computed metrics from keystroke data.

    Attributes
    ----------
    total_keystrokes
        Total number of keystroke events.
    printable_keystrokes
        Number of printable character keystrokes.
    deletions
        Number of deletion keystrokes (Backspace, Delete).
    mean_iki
        Mean inter-keystroke interval in milliseconds.
    std_iki
        Standard deviation of inter-keystroke intervals.
    median_iki
        Median inter-keystroke interval.
    pause_count
        Number of pauses exceeding threshold.
    product_process_ratio
        Ratio of final characters to total keystrokes.
    """

    total_keystrokes: int
    printable_keystrokes: int
    deletions: int
    mean_iki: float
    std_iki: float
    median_iki: float
    pause_count: int
    product_process_ratio: float

FocusMetrics

Computed metrics from focus data.

slopit.schemas.behavioral.FocusMetrics

Bases: BaseModel

Computed metrics from focus data.

Attributes:

Name Type Description
blur_count int

Number of window blur events.

total_blur_duration float

Total time with window blurred in milliseconds.

hidden_count int

Number of visibility hidden events.

total_hidden_duration float

Total time with document hidden in milliseconds.

Source code in src/slopit/schemas/behavioral.py
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
class FocusMetrics(BaseModel):
    """Computed metrics from focus data.

    Attributes
    ----------
    blur_count
        Number of window blur events.
    total_blur_duration
        Total time with window blurred in milliseconds.
    hidden_count
        Number of visibility hidden events.
    total_hidden_duration
        Total time with document hidden in milliseconds.
    """

    blur_count: int
    total_blur_duration: float
    hidden_count: int
    total_hidden_duration: float

TimingMetrics

Timing metrics for a trial.

slopit.schemas.behavioral.TimingMetrics

Bases: BaseModel

Timing metrics for a trial.

Attributes:

Name Type Description
first_keystroke_latency float | None

Time from trial start to first keystroke in milliseconds.

total_response_time float

Time from trial start to submission in milliseconds.

characters_per_minute float | None

Typing speed in characters per minute.

Source code in src/slopit/schemas/behavioral.py
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
class TimingMetrics(BaseModel):
    """Timing metrics for a trial.

    Attributes
    ----------
    first_keystroke_latency
        Time from trial start to first keystroke in milliseconds.
    total_response_time
        Time from trial start to submission in milliseconds.
    characters_per_minute
        Typing speed in characters per minute.
    """

    first_keystroke_latency: float | None = None
    total_response_time: float
    characters_per_minute: float | None = None

BehavioralMetrics

Container for all computed behavioral metrics.

slopit.schemas.behavioral.BehavioralMetrics

Bases: BaseModel

Container for all computed behavioral metrics.

Attributes:

Name Type Description
keystroke KeystrokeMetrics | None

Keystroke-derived metrics.

focus FocusMetrics | None

Focus-derived metrics.

timing TimingMetrics | None

Timing metrics.

mouse MouseMetrics | None

Mouse movement and click metrics.

scroll ScrollMetrics | None

Scroll behavior metrics.

input_duration InputDurationMetrics | None

Per-field input duration metrics.

Source code in src/slopit/schemas/behavioral.py
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
class BehavioralMetrics(BaseModel):
    """Container for all computed behavioral metrics.

    Attributes
    ----------
    keystroke
        Keystroke-derived metrics.
    focus
        Focus-derived metrics.
    timing
        Timing metrics.
    mouse
        Mouse movement and click metrics.
    scroll
        Scroll behavior metrics.
    input_duration
        Per-field input duration metrics.
    """

    keystroke: KeystrokeMetrics | None = None
    focus: FocusMetrics | None = None
    timing: TimingMetrics | None = None
    mouse: MouseMetrics | None = None
    scroll: ScrollMetrics | None = None
    input_duration: InputDurationMetrics | None = None

Flag Types

AnalysisFlag

Flag generated during server-side analysis.

slopit.schemas.flags.AnalysisFlag

Bases: BaseModel

Flag generated during server-side analysis.

Attributes:

Name Type Description
type str

Flag type identifier.

analyzer str

Name of the analyzer that generated this flag.

severity Severity

Severity level of the flag.

message str

Human-readable description.

confidence float | None

Confidence score between 0.0 and 1.0.

evidence dict[str, JsonValue] | None

Evidence supporting this flag.

trial_ids list[str] | None

Related trial IDs if trial-specific.

Source code in src/slopit/schemas/flags.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
class AnalysisFlag(BaseModel):
    """Flag generated during server-side analysis.

    Attributes
    ----------
    type
        Flag type identifier.
    analyzer
        Name of the analyzer that generated this flag.
    severity
        Severity level of the flag.
    message
        Human-readable description.
    confidence
        Confidence score between 0.0 and 1.0.
    evidence
        Evidence supporting this flag.
    trial_ids
        Related trial IDs if trial-specific.
    """

    type: str
    analyzer: str
    severity: Severity
    message: str
    confidence: float | None = Field(default=None, ge=0.0, le=1.0)
    evidence: dict[str, JsonValue] | None = None
    trial_ids: list[str] | None = None

Example

from slopit.schemas.flags import AnalysisFlag

flag = AnalysisFlag(
    type="low_iki_variance",
    analyzer="keystroke",
    severity="medium",
    message="Keystroke timing unusually consistent",
    confidence=0.75,
    evidence={"std_iki": 45.2},
    trial_ids=["trial-0", "trial-1"],
)

CaptureFlag

Flag generated during client-side data capture.

slopit.schemas.flags.CaptureFlag

Bases: BaseModel

Flag generated during data capture.

Attributes:

Name Type Description
type str

Flag type identifier.

severity Severity

Severity level of the flag.

message str

Human-readable description.

timestamp int

Unix timestamp in milliseconds when flag was generated.

details dict[str, JsonValue] | None

Additional details about the flag.

Source code in src/slopit/schemas/flags.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class CaptureFlag(BaseModel):
    """Flag generated during data capture.

    Attributes
    ----------
    type
        Flag type identifier.
    severity
        Severity level of the flag.
    message
        Human-readable description.
    timestamp
        Unix timestamp in milliseconds when flag was generated.
    details
        Additional details about the flag.
    """

    type: str
    severity: Severity
    message: str
    timestamp: int
    details: dict[str, JsonValue] | None = None

Severity

Flag severity levels: "info", "low", "medium", "high".

Analysis Result Types

AnalysisResult

Result from a single analyzer.

slopit.schemas.analysis.AnalysisResult

Bases: BaseModel

Result from a single analyzer.

Attributes:

Name Type Description
analyzer str

Name of the analyzer that produced this result.

session_id str

ID of the analyzed session.

trials list[dict[str, JsonValue]]

Per-trial analysis results.

flags list[AnalysisFlag]

Flags generated by the analyzer.

session_summary dict[str, JsonValue]

Session-level summary statistics.

Source code in src/slopit/schemas/analysis.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class AnalysisResult(BaseModel):
    """Result from a single analyzer.

    Attributes
    ----------
    analyzer
        Name of the analyzer that produced this result.
    session_id
        ID of the analyzed session.
    trials
        Per-trial analysis results.
    flags
        Flags generated by the analyzer.
    session_summary
        Session-level summary statistics.
    """

    analyzer: str
    session_id: str
    trials: list[dict[str, JsonValue]] = Field(default_factory=lambda: list[dict[str, JsonValue]]())
    flags: list[AnalysisFlag] = Field(default_factory=lambda: list[AnalysisFlag]())
    session_summary: dict[str, JsonValue] = Field(default_factory=lambda: dict[str, JsonValue]())

SessionVerdict

Final verdict for a session.

slopit.schemas.analysis.SessionVerdict

Bases: BaseModel

Final verdict for a session.

Attributes:

Name Type Description
status Literal['clean', 'suspicious', 'flagged']

Overall status: "clean", "suspicious", or "flagged".

confidence float

Confidence in the verdict (0.0 to 1.0).

flags list[AnalysisFlag]

All flags contributing to the verdict.

summary str

Human-readable summary.

Source code in src/slopit/schemas/analysis.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class SessionVerdict(BaseModel):
    """Final verdict for a session.

    Attributes
    ----------
    status
        Overall status: "clean", "suspicious", or "flagged".
    confidence
        Confidence in the verdict (0.0 to 1.0).
    flags
        All flags contributing to the verdict.
    summary
        Human-readable summary.
    """

    status: Literal["clean", "suspicious", "flagged"]
    confidence: float = Field(ge=0.0, le=1.0)
    flags: list[AnalysisFlag] = Field(default_factory=lambda: list[AnalysisFlag]())
    summary: str

PipelineResult

Result from the analysis pipeline.

slopit.schemas.analysis.PipelineResult

Bases: BaseModel

Result from the analysis pipeline.

Attributes:

Name Type Description
sessions list[str]

List of analyzed session IDs.

analyzer_results dict[str, list[AnalysisResult]]

Results from each analyzer, keyed by analyzer name.

aggregated_flags dict[str, list[AnalysisFlag]]

Aggregated flags per session.

verdicts dict[str, SessionVerdict]

Final verdict per session.

Source code in src/slopit/schemas/analysis.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class PipelineResult(BaseModel):
    """Result from the analysis pipeline.

    Attributes
    ----------
    sessions
        List of analyzed session IDs.
    analyzer_results
        Results from each analyzer, keyed by analyzer name.
    aggregated_flags
        Aggregated flags per session.
    verdicts
        Final verdict per session.
    """

    sessions: list[str] = Field(default_factory=list)
    analyzer_results: dict[str, list[AnalysisResult]] = Field(default_factory=dict)
    aggregated_flags: dict[str, list[AnalysisFlag]] = Field(default_factory=dict)
    verdicts: dict[str, SessionVerdict] = Field(default_factory=dict)

    def to_dict(self) -> dict[str, JsonValue]:
        """Convert to dictionary for JSON serialization."""
        return self.model_dump()

Global Event Types

GlobalEvents

Container for session-level events not tied to specific trials.

slopit.schemas.behavioral.GlobalEvents

Bases: BaseModel

Container for session-level events.

Attributes:

Name Type Description
focus list[SessionFocusEvent]

Focus events at session level.

errors list[ErrorEvent]

Error events.

Source code in src/slopit/schemas/behavioral.py
501
502
503
504
505
506
507
508
509
510
511
512
513
class GlobalEvents(BaseModel):
    """Container for session-level events.

    Attributes
    ----------
    focus
        Focus events at session level.
    errors
        Error events.
    """

    focus: list[SessionFocusEvent] = Field(default_factory=lambda: list[SessionFocusEvent]())
    errors: list[ErrorEvent] = Field(default_factory=lambda: list[ErrorEvent]())

SessionFocusEvent

Session-level focus event.

slopit.schemas.behavioral.SessionFocusEvent

Bases: BaseModel

Session-level focus event (not tied to a specific trial).

Attributes:

Name Type Description
timestamp int

Unix timestamp in milliseconds.

event Literal['focus', 'blur', 'visibilitychange']

Event type.

visibility Literal['visible', 'hidden'] | None

Visibility state if applicable.

Source code in src/slopit/schemas/behavioral.py
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
class SessionFocusEvent(BaseModel):
    """Session-level focus event (not tied to a specific trial).

    Attributes
    ----------
    timestamp
        Unix timestamp in milliseconds.
    event
        Event type.
    visibility
        Visibility state if applicable.
    """

    timestamp: int
    event: Literal["focus", "blur", "visibilitychange"]
    visibility: Literal["visible", "hidden"] | None = None

Type Aliases

The slopit.schemas.types module defines type aliases used throughout the package:

from slopit.schemas.types import (
    JsonPrimitive,      # str | int | float | bool | None
    JsonValue,          # JSON-compatible value
    Severity,           # "info" | "low" | "medium" | "high"
    EventType,          # "keydown" | "keyup"
    FocusEventType,     # "focus" | "blur" | "visibilitychange"
    VisibilityState,    # "visible" | "hidden"
    VerdictStatus,      # "clean" | "suspicious" | "flagged"
    Milliseconds,       # float
    UnixTimestamp,      # int
    SessionId,          # str
    TrialId,            # str
    ParticipantId,      # str
    StudyId,            # str
)