Skip to content

Models

Pydantic models for Prusa Connect API responses.

This module defines the data structures used by the client to parse API responses into typed objects.

MODULE DESCRIPTION
cameras

Camera models for Prusa Connect SDK.

common

Common models for Prusa Connect SDK.

config

Models for the /app/config endpoint.

files

File models for Prusa Connect SDK.

jobs

Job models for Prusa Connect SDK.

printers

Printer models for Prusa Connect SDK.

stats

Stats models for Prusa Connect SDK.

teams

Team models for Prusa Connect SDK.

AppConfig

Bases: WarnExtraFieldsModel

Application configuration returned by /app/config.

Source code in src/prusa/connect/client/models/config.py
21
22
23
24
class AppConfig(WarnExtraFieldsModel):
    """Application configuration returned by /app/config."""

    auth: AuthConfig

AuthConfig

Bases: WarnExtraFieldsModel

Authentication configuration.

Source code in src/prusa/connect/client/models/config.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class AuthConfig(WarnExtraFieldsModel):
    """Authentication configuration."""

    backends: list[str]
    server_url: str
    client_id: str
    redirect_url: str
    avatar_server_url: str
    max_upload_size: int
    max_snapshot_size: int
    max_preview_size: int
    afs_enabled: bool
    afs_group_id: int

BaseFile

Bases: WarnExtraFieldsModel

Common fields for all file types.

Source code in src/prusa/connect/client/models/files.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class BaseFile(WarnExtraFieldsModel):
    """Common fields for all file types."""

    type: str  # Discriminator field
    name: str
    display_name: str | None = None
    size: pydantic.ByteSize | None = None
    hash: str | None = None

    team_id: int | None = None
    upload_id: int | None = None
    uploaded: datetime.datetime | None = None

    path: str | None = None
    display_path: str | None = None
    read_only: bool = False
    m_timestamp: int | None = None

    sync: SyncInfo | None = None
    owner: Owner | None = None

    model_config = pydantic.ConfigDict(extra="allow")

Camera

Bases: WarnExtraFieldsModel

Camera information.

Source code in src/prusa/connect/client/models/cameras.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class Camera(WarnExtraFieldsModel):
    """Camera information."""

    id: int | None = None  # Numeric ID for snapshots
    token: str | None = None  # Alphanumeric token/id in some contexts?
    name: str | None = None
    origin: str | None = None
    resolution: str | None = None
    snapshot_url: str | None = None

    config: CameraConfig | None = None
    options: CameraOptions | None = None
    capabilities: list[str] | None = None
    features: list[str] | None = None
    sort_order: int | None = None
    registered: bool | None = None
    team_id: int | None = None
    printer_uuid: str | None = None

    snapshots: list[str] | None = None

CameraConfig

Bases: WarnExtraFieldsModel

Camera internal configuration snapshot.

Source code in src/prusa/connect/client/models/cameras.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class CameraConfig(WarnExtraFieldsModel):
    """Camera internal configuration snapshot."""

    name: str | None = None
    path: str | None = None
    model: str | None = None
    driver: str | None = None
    firmware: str | None = None
    rotation: int | None = None
    camera_id: str | None = None
    resolution: CameraResolution | None = None
    manufacturer: str | None = None
    network_info: CameraNetworkInfo | None = None
    trigger_scheme: str | None = None

CameraNetworkInfo

Bases: WarnExtraFieldsModel

Camera network configuration.

Source code in src/prusa/connect/client/models/cameras.py
13
14
15
16
17
18
class CameraNetworkInfo(WarnExtraFieldsModel):
    """Camera network configuration."""

    wifi_mac: str | None = None
    wifi_ipv4: str | None = None
    wifi_ssid: str | None = None

CameraOptions

Bases: WarnExtraFieldsModel

Available options/capabilities for the camera.

Source code in src/prusa/connect/client/models/cameras.py
37
38
39
40
class CameraOptions(WarnExtraFieldsModel):
    """Available options/capabilities for the camera."""

    available_resolutions: list[CameraResolution] | None = None

CameraResolution

Bases: WarnExtraFieldsModel

Camera resolution details.

Source code in src/prusa/connect/client/models/cameras.py
 6
 7
 8
 9
10
class CameraResolution(WarnExtraFieldsModel):
    """Camera resolution details."""

    width: int
    height: int

CancelableObject

Bases: WarnExtraFieldsModel

Represents an object that can be cancelled during print.

Source code in src/prusa/connect/client/models/jobs.py
56
57
58
59
60
61
62
class CancelableObject(WarnExtraFieldsModel):
    """Represents an object that can be cancelled during print."""

    id: int
    name: str
    polygon: list[list[float]] | None = None
    canceled: bool = False

FirmwareFile

Bases: BaseFile

Represents a firmware file on the printer.

Source code in src/prusa/connect/client/models/files.py
108
109
110
111
112
113
114
class FirmwareFile(BaseFile):
    """Represents a firmware file on the printer."""

    type: typing.Literal["FIRMWARE"] = "FIRMWARE"  # pyrefly: ignore[bad-override]
    printer_type: str | None = None
    release_url: pydantic.HttpUrl | None = None
    meta: FirmwareFileMeta | None = None

FirmwareFileMeta

Bases: WarnExtraFieldsModel

Metadata associated with a firmware file.

Source code in src/prusa/connect/client/models/files.py
58
59
60
61
62
63
64
65
66
class FirmwareFileMeta(WarnExtraFieldsModel):
    """Metadata associated with a firmware file."""

    device_type_id: str | None = None
    version: str | None = None
    sem_ver: str | None = None
    build_no: int | None = None
    bbf_version: int | None = None
    printer_model: str | None = None

FirmwareSupport

Bases: WarnExtraFieldsModel

Firmware version information.

Source code in src/prusa/connect/client/models/printers.py
81
82
83
84
85
86
87
88
89
90
class FirmwareSupport(WarnExtraFieldsModel):
    """Firmware version information."""

    latest: str | None = None
    current: str | None = None
    release_url: str | None = None
    stable: str | None = None
    prerelease: str | None = None
    release: str | None = None
    state: str | None = None

Job

Bases: WarnExtraFieldsModel

A planned or history job.

Source code in src/prusa/connect/client/models/jobs.py
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
class Job(WarnExtraFieldsModel):
    """A planned or history job."""

    id: int
    lifetime_id: str | None = None
    printer_uuid: str | None = None
    team_id: int | None = None
    origin_id: int | None = None
    source: str | None = None
    source_info: SourceInfo | None = None

    state: JobStatus

    cameras: list[Camera] | None = None
    hash: str | None = None
    time_printing: int | None = None
    start: int | None = None
    end: int | None = None
    progress: float | None = None
    planned: dict | None = None

    print_height: float | None = None

    file: File | None = None
    path: str | None = None

    reason: JobFailureReason | None = None

    cancelable_objects: list[CancelableObject] | None = pydantic.Field(
        None, validation_alias=AliasChoices("cancelable_objects", AliasPath("cancelable", "objects"))
    )
    cancelable_time: datetime.datetime | None = None

JobFailureReason

Bases: WarnExtraFieldsModel

Details about a job failure.

Source code in src/prusa/connect/client/models/jobs.py
65
66
67
68
69
class JobFailureReason(WarnExtraFieldsModel):
    """Details about a job failure."""

    tag: list[JobFailureTag] = pydantic.Field(default_factory=list)
    other: str | None = None

JobFailureTag

Bases: StrEnum

Enum representing reasons for job failure/cancellation.

Source code in src/prusa/connect/client/models/jobs.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class JobFailureTag(StrEnum):
    """Enum representing reasons for job failure/cancellation."""

    IGNORED = "IGNORED"
    CLOGGED_NOZZLE = "CLOGGED_NOZZLE"
    NON_ADHERENT_BED = "NON_ADHERENT_BED"
    UNDER_EXTRUSION = "UNDER_EXTRUSION"
    OVER_EXTRUSION = "OVER_EXTRUSION"
    STRINGING_OR_OOZING = "STRINGING_OR_OOZING"
    GAPS_IN_THIN_WALLS = "GAPS_IN_THIN_WALLS"
    OVERHEATING = "OVERHEATING"
    LAYER_SHIFTING = "LAYER_SHIFTING"
    SPAGHETTI_MONSTER = "SPAGHETTI_MONSTER"
    LAYER_SEPARATION = "LAYER_SEPARATION"
    WARPING = "WARPING"
    POOR_BRIDGING = "POOR_BRIDGING"
    OTHER = "OTHER"

JobInfo

Bases: WarnExtraFieldsModel

Snapshot of a job currently on a printer.

Source code in src/prusa/connect/client/models/jobs.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class JobInfo(WarnExtraFieldsModel):
    """Snapshot of a job currently on a printer."""

    id: int | None = None
    origin_id: int | None = None
    path: str | None = None
    state: str | None = None
    progress: float | None = None
    time_printing: datetime.timedelta | None = None
    time_remaining: datetime.timedelta | None = None
    display_name: str | None = None
    start: datetime.datetime | None = None
    end: datetime.datetime | None = None
    hash: str | None = None
    preview_url: str | None = None
    model_weight: float | None = None
    weight_remaining: float | None = None
    print_height: float | None = None
    total_height: float | None = None
    lifetime_id: str | None = None

JobStatus

Bases: StrEnum

Enum representing the status of a job.

METHOD DESCRIPTION
__lt__

Compare two JobStatus members by order of declaration.

get_order

Get the index of the member in the order of declaration.

Source code in src/prusa/connect/client/models/stats.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@functools.total_ordering
class JobStatus(StrEnum):
    """Enum representing the status of a job."""

    PRINTING = "PRINTING"
    FINISHED = "FINISHED"

    OK = "FIN_OK"
    STOPPED = "FIN_STOPPED"
    ERROR = "FIN_ERROR"
    UNKNOWN = "FIN_UNKNOWN"

    @classmethod
    def _missing_(cls, value: object) -> typing.Any:
        return cls.UNKNOWN

    @classmethod
    def get_order(cls, member: "JobStatus") -> int:
        """Get the index of the member in the order of declaration."""
        global _job_status_order_map
        if _job_status_order_map is None:
            _job_status_order_map = {m: i for i, m in enumerate(cls)}
        return _job_status_order_map[member]

    def __lt__(self, other):
        """Compare two JobStatus members by order of declaration."""
        if self.__class__ is other.__class__:
            return self.get_order(self) < self.get_order(other)
        return NotImplemented

__lt__(other)

Compare two JobStatus members by order of declaration.

Source code in src/prusa/connect/client/models/stats.py
39
40
41
42
43
def __lt__(self, other):
    """Compare two JobStatus members by order of declaration."""
    if self.__class__ is other.__class__:
        return self.get_order(self) < self.get_order(other)
    return NotImplemented

get_order(member) classmethod

Get the index of the member in the order of declaration.

Source code in src/prusa/connect/client/models/stats.py
31
32
33
34
35
36
37
@classmethod
def get_order(cls, member: "JobStatus") -> int:
    """Get the index of the member in the order of declaration."""
    global _job_status_order_map
    if _job_status_order_map is None:
        _job_status_order_map = {m: i for i, m in enumerate(cls)}
    return _job_status_order_map[member]

JobsSuccess

Bases: StatsModel

Printer usage statistics: job success history.

Source code in src/prusa/connect/client/models/stats.py
107
108
109
110
111
112
113
114
115
116
class JobsSuccess(StatsModel):
    """Printer usage statistics: job success history."""

    date_axis: list[str] = pydantic.Field(
        ..., alias="xAxis", validation_alias=pydantic.AliasChoices("xAxis", "date_axis"), description="Date axis"
    )
    printer_name: str = pydantic.Field(..., alias="name")
    printer_uuid: str = pydantic.Field(..., alias="uuid")
    series: list[JobsSuccessSeries]
    time_shift: str

JobsSuccessSeries

Bases: WarnExtraFieldsModel

Series data for job success stats.

Source code in src/prusa/connect/client/models/stats.py
100
101
102
103
104
class JobsSuccessSeries(WarnExtraFieldsModel):
    """Series data for job success stats."""

    status: JobStatus = pydantic.Field(..., alias="name")
    data: list[int]

MaterialQuantity

Bases: StatsModel

Printer usage statistics: material quantity used.

Source code in src/prusa/connect/client/models/stats.py
75
76
77
78
79
80
class MaterialQuantity(StatsModel):
    """Printer usage statistics: material quantity used."""

    printer_name: str = pydantic.Field(..., alias="name")
    printer_uuid: str = pydantic.Field(..., alias="uuid")
    data: list[typing.Any]

NetworkInfo

Bases: WarnExtraFieldsModel

Network configuration details.

Source code in src/prusa/connect/client/models/common.py
30
31
32
33
34
35
36
37
38
39
class NetworkInfo(WarnExtraFieldsModel):
    """Network configuration details."""

    hostname: str | None = None
    ipv4: str | None = None
    ipv6: str | None = None
    mac: str | None = None
    wifi_ssid: str | None = None
    lan_ipv4: str | None = None
    lan_mac: str | None = None

Owner

Bases: SourceInfo

Represents the owner of a resource (same fields as SourceInfo).

Source code in src/prusa/connect/client/models/common.py
60
61
62
63
class Owner(SourceInfo):
    """Represents the owner of a resource (same fields as SourceInfo)."""

    pass

PlannedTasks

Bases: StatsModel

Printer usage statistics: planned tasks.

Source code in src/prusa/connect/client/models/stats.py
91
92
93
94
95
96
97
class PlannedTasks(StatsModel):
    """Printer usage statistics: planned tasks."""

    time_axis: list[int] = pydantic.Field(
        ..., alias="xAxis", validation_alias=pydantic.AliasChoices("xAxis", "time_axis"), description="Time axis"
    )
    series: PlannedTasksSeries

PlannedTasksSeries

Bases: WarnExtraFieldsModel

Series data for planned tasks.

Source code in src/prusa/connect/client/models/stats.py
83
84
85
86
87
88
class PlannedTasksSeries(WarnExtraFieldsModel):
    """Series data for planned tasks."""

    printer_uuid: str = pydantic.Field(..., alias="uuid")
    printer_name: str = pydantic.Field(..., alias="name")
    data: list[tuple[int, int]]

PrintFile

Bases: BaseFile

Represents a print file (G-code, BG-code).

Source code in src/prusa/connect/client/models/files.py
 99
100
101
102
103
104
105
class PrintFile(BaseFile):
    """Represents a print file (G-code, BG-code)."""

    type: typing.Literal["PRINT_FILE"] = "PRINT_FILE"  # pyrefly: ignore[bad-override]
    preview_url: str | None = None
    preview_mimetype: str | None = None
    meta: PrintFileMeta | None = None

PrintFileMeta

Bases: WarnExtraFieldsModel

Metadata associated with a print file (statistics parse from G-code).

Source code in src/prusa/connect/client/models/files.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class PrintFileMeta(WarnExtraFieldsModel):
    """Metadata associated with a print file (statistics parse from G-code)."""

    model_config = pydantic.ConfigDict(extra="allow")

    extruder_colour: str | None = None
    filament_abrasive: bool | None = None
    temperature: int | None = None
    brim_width: int | None = None
    bed_temperature: int | None = None
    ironing: bool | None = None
    nozzle_high_flow: bool | None = None
    support_material: bool | None = None
    filament_type: str | None = None
    filament_cost: float | None = None
    total_height: float | None = None
    max_layer_z: float | None = None
    filament_used_m: float | None = None
    filament_used_mm: float | None = None
    filament_used_g: float | None = None
    filament_used_cm3: float | None = None
    filament_used_mm3: float | None = None
    nozzle_diameter: float | None = None
    fill_density: str | None = None
    printer_model: str | None = None
    estimated_print_time: datetime.timedelta | None = None
    estimated_printing_time_normal_mode: str | None = None
    layer_height: float | None = None
    producer: str | None = None
    slots: list[dict[str, typing.Any]] | None = None
    objects_info: dict[str, typing.Any] | None = None

Printer

Bases: WarnExtraFieldsModel

Detailed Printer Object.

Matches structure in printers.error.response.json and printer_details.json.

Source code in src/prusa/connect/client/models/printers.py
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
class Printer(WarnExtraFieldsModel):
    """Detailed Printer Object.

    Matches structure in `printers.error.response.json` and `printer_details.json`.
    """

    uuid: str | None = None  # UUID might not be in the detail root, but often is
    name: str | None = None
    printer_state: PrinterState | None = pydantic.Field(
        None, validation_alias=pydantic.AliasChoices("printer_state", "state")
    )  # API uses 'state' or 'printer_state'
    disabled: dict[str, bool] | None = None
    printer_model: str | None = None
    firmware_version: str | None = pydantic.Field(None, alias="firmware")
    last_online: float | None = None

    network_info: NetworkInfo | None = None

    support: FirmwareSupport | None = None
    tools: dict[str, Tool] | None = None
    slot: SlotInfo | None = None
    location: str | None = None
    team_name: str | None = None
    appendix: bool | None = None
    state: PrinterState | None = None
    state_reason: str | None = None
    time_delta: int | None = None
    prusalink_api_key: pydantic.SecretStr | None = None
    api_key: pydantic.SecretStr | None = None
    sheet_settings: typing.Any | None = None
    inaccurate_estimates: bool | None = None
    enclosure: typing.Any | None = None
    slots: int | None = None
    mmu: dict[str, typing.Any] | None = None
    supported_printer_models: list[str] | None = None
    printer_type_compatible: list[str] | None = None
    connect_state: str | None = None
    allowed_functionalities: list[str] | None = None
    decision_maker: typing.Any | None = None
    printer_type: str | None = None
    fw_printer_type: str | None = None
    printer_type_name: str | None = None
    flags: dict[str, typing.Any] | None = None
    max_filename: int | None = None
    printable_extension: list[str] | None = None
    created: datetime.datetime | None = None
    sn: str | None = None
    team_id: int | None = None
    is_beta: bool | None = None
    filament: dict[str, typing.Any] | None = None
    organization_id: uuid_pkg.UUID | None = None
    rights_r: bool | None = None
    rights_w: bool | None = None
    rights_u: bool | None = None
    prusaconnect_api_key: pydantic.SecretStr | None = None
    groups: list[typing.Any] | None = None
    owner: Owner | None = None

    # Nested info
    telemetry: Temperatures | None = pydantic.Field(None, alias="temp")
    job: JobInfo | None = pydantic.Field(None, alias="job_info")
    cameras: list[Camera] | None = None

    # Capabilities
    nozzle_diameter: float | None = None
    speed: int | None = None
    flow: int | None = None
    axis_x: float | None = None
    axis_y: float | None = None
    axis_z: float | None = None

    model_config = pydantic.ConfigDict(extra="allow")

PrinterCommand

Bases: StrEnum

Enum representing known commands for a printer.

NOTE: These commands are the subset of commands on a MK4S printer that do not require any additional parameters.

TODO(dcode): Add support for commands that require additional parameters. TODO(dcode): Consider dynamic command generation from the printer's capabilities.

Source code in src/prusa/connect/client/models/printers.py
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
67
68
69
class PrinterCommand(StrEnum):
    """Enum representing known commands for a printer.

    NOTE: These commands are the subset of commands on a
    MK4S printer that do not require any additional parameters.

    TODO(dcode): Add support for commands that require additional parameters.
    TODO(dcode): Consider dynamic command generation from the printer's capabilities.
    """

    SET_PRINTER_READY = "SET_PRINTER_READY"
    CANCEL_PRINTER_READY = "CANCEL_PRINTER_READY"
    PAUSE_PRINT = "PAUSE_PRINT"
    RESUME_PRINT = "RESUME_PRINT"
    STOP_PRINT = "STOP_PRINT"
    RESET_PRINTER = "RESET_PRINTER"
    UNLOAD_FILAMENT = "UNLOAD_FILAMENT"
    SEND_INFO = "SEND_INFO"
    STOP_TRANSFER = "STOP_TRANSFER"
    SEND_STATE_INFO = "SEND_STATE_INFO"
    RESET = "RESET"
    DISABLE_STEPPERS = "DISABLE_STEPPERS"
    BEEP = "BEEP"
    # Fallback for unknown states
    UNKNOWN = "UNKNOWN"

    @classmethod
    def _missing_(cls, value: object) -> typing.Any:
        return cls.UNKNOWN

PrinterListResponse

Bases: WarnExtraFieldsModel

Response model for the /printers endpoint.

Source code in src/prusa/connect/client/models/printers.py
190
191
192
193
class PrinterListResponse(WarnExtraFieldsModel):
    """Response model for the /printers endpoint."""

    printers: list[Printer]

PrinterState

Bases: StrEnum

Enum representing the possible states of a printer.

Source code in src/prusa/connect/client/models/printers.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class PrinterState(StrEnum):
    """Enum representing the possible states of a printer."""

    READY = "READY"
    IDLE = "IDLE"

    BUSY = "BUSY"
    MANIPULATING = "MANIPULATING"
    PRINTING = "PRINTING"

    PAUSED = "PAUSED"
    FINISHED = "FINISHED"
    STOPPED = "STOPPED"

    ATTENTION = "ATTENTION"
    ERROR = "ERROR"
    OFFLINE = "OFFLINE"

    # Fallback for unknown states
    UNKNOWN = "UNKNOWN"

    @classmethod
    def _missing_(cls, value: object) -> typing.Any:
        return cls.UNKNOWN

PrintingNotPrinting

Bases: StatsModel

Printer usage statistics: printing vs not printing.

Source code in src/prusa/connect/client/models/stats.py
67
68
69
70
71
72
class PrintingNotPrinting(StatsModel):
    """Printer usage statistics: printing vs not printing."""

    printer_name: str = pydantic.Field(..., alias="name")
    printer_uuid: str = pydantic.Field(..., alias="uuid")
    data: list[PrintingNotPrintingEntry]

PrintingNotPrintingEntry

Bases: WarnExtraFieldsModel

Represents a single entry in printing vs not printing stats.

Source code in src/prusa/connect/client/models/stats.py
60
61
62
63
64
class PrintingNotPrintingEntry(WarnExtraFieldsModel):
    """Represents a single entry in printing vs not printing stats."""

    name: str
    duration: datetime.timedelta = pydantic.Field(..., alias="value")

RegularFile

Bases: BaseFile

Represents a generic file.

Source code in src/prusa/connect/client/models/files.py
93
94
95
96
class RegularFile(BaseFile):
    """Represents a generic file."""

    type: typing.Literal["FILE"] = "FILE"  # pyrefly: ignore[bad-override]

SlotInfo

Bases: WarnExtraFieldsModel

MMU Slot information.

Source code in src/prusa/connect/client/models/printers.py
107
108
109
110
111
112
113
class SlotInfo(WarnExtraFieldsModel):
    """MMU Slot information."""

    active: int | None = None
    slots: dict[str, Tool] | None = None
    state: str | None = None
    command: str | None = None

SourceInfo

Bases: WarnExtraFieldsModel

Information about the source of an action or object (e.g., user).

METHOD DESCRIPTION
resolve_avatar_url

Automatically prepend MEDIA_BASE_URL if missing.

Source code in src/prusa/connect/client/models/common.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class SourceInfo(WarnExtraFieldsModel):
    """Information about the source of an action or object (e.g., user)."""

    id: int | None = None
    first_name: str | None = None
    last_name: str | None = None
    public_name: str | None = None
    avatar: str | None = None

    @pydantic.field_validator("avatar")
    @classmethod
    def resolve_avatar_url(cls, v: typing.Any) -> typing.Any:
        """Automatically prepend MEDIA_BASE_URL if missing."""
        if isinstance(v, str) and v and not v.startswith(("http://", "https://")):
            return f"{consts.MEDIA_BASE_URL}{v.lstrip('/')}"
        return v

resolve_avatar_url(v) classmethod

Automatically prepend MEDIA_BASE_URL if missing.

Source code in src/prusa/connect/client/models/common.py
51
52
53
54
55
56
57
@pydantic.field_validator("avatar")
@classmethod
def resolve_avatar_url(cls, v: typing.Any) -> typing.Any:
    """Automatically prepend MEDIA_BASE_URL if missing."""
    if isinstance(v, str) and v and not v.startswith(("http://", "https://")):
        return f"{consts.MEDIA_BASE_URL}{v.lstrip('/')}"
    return v

StatsModel

Bases: WarnExtraFieldsModel

Base model for statistics with date validation.

Source code in src/prusa/connect/client/models/stats.py
46
47
48
49
50
51
52
53
54
55
56
57
class StatsModel(WarnExtraFieldsModel):
    """Base model for statistics with date validation."""

    from_time: datetime.date = pydantic.Field(..., alias="from")
    to_time: datetime.date = pydantic.Field(..., alias="to")

    @pydantic.field_validator("from_time", "to_time", mode="before")
    @classmethod
    def _validate_date(cls, v):
        if isinstance(v, (int, float)):
            return datetime.datetime.fromtimestamp(v, datetime.UTC).date()
        return v

Storage

Bases: WarnExtraFieldsModel

Represents a storage device on the printer.

Source code in src/prusa/connect/client/models/files.py
11
12
13
14
15
16
17
18
19
20
21
22
class Storage(WarnExtraFieldsModel):
    """Represents a storage device on the printer."""

    type: str
    path: str
    mountpoint: str | None = None
    name: str
    read_only: bool = False
    is_sfn: bool | None = None
    file_count: int | None = None
    free_space: int | None = None
    total_space: int | None = None

SyncInfo

Bases: WarnExtraFieldsModel

Synchronization details for a resource.

Source code in src/prusa/connect/client/models/common.py
66
67
68
69
70
71
class SyncInfo(WarnExtraFieldsModel):
    """Synchronization details for a resource."""

    synced_by: dict[str, typing.Any] | None = None
    synced: datetime.datetime | None = None
    source: str | None = None

Team

Bases: WarnExtraFieldsModel

Team information.

Source code in src/prusa/connect/client/models/teams.py
24
25
26
27
28
29
30
31
32
33
34
35
36
class Team(WarnExtraFieldsModel):
    """Team information."""

    id: int
    name: str
    role: str | None = None
    description: str | None = None
    capacity: int | None = None
    organization_id: uuid_pkg.UUID | None = None
    prusaconnect_api_key: pydantic.SecretStr | None = None
    user_count: int | None = None
    users: list[TeamUser] | None = None
    invitees: list[typing.Any] | None = None

TeamUser

Bases: WarnExtraFieldsModel

User in a team.

Source code in src/prusa/connect/client/models/teams.py
11
12
13
14
15
16
17
18
19
20
21
class TeamUser(WarnExtraFieldsModel):
    """User in a team."""

    id: int
    first_name: str | None = None
    last_name: str | None = None
    public_name: str | None = None
    avatar: str | None = None
    rights_ro: bool | None = None
    rights_rw: bool | None = None
    rights_use: bool | None = None

Temperatures

Bases: WarnExtraFieldsModel

Printer temperatures.

Source code in src/prusa/connect/client/models/printers.py
72
73
74
75
76
77
78
class Temperatures(WarnExtraFieldsModel):
    """Printer temperatures."""

    temp_nozzle: float | None = None
    temp_bed: float | None = None
    target_nozzle: float | None = None
    target_bed: float | None = None

Tool

Bases: WarnExtraFieldsModel

Tool/Head information.

Source code in src/prusa/connect/client/models/printers.py
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
class Tool(WarnExtraFieldsModel):
    """Tool/Head information."""

    material: str | None = None
    temp: float | None = None
    nozzle_diameter: float | None = None
    fan_hotend: float | None = None
    fan_print: float | None = None
    mmu: dict[str, typing.Any] | None = None
    hardened: bool | None = None
    high_flow: bool | None = None
    active: bool | None = None

UploadStatus

Bases: WarnExtraFieldsModel

Status of a file upload to Prusa Connect.

Source code in src/prusa/connect/client/models/files.py
120
121
122
123
124
125
126
127
128
129
class UploadStatus(WarnExtraFieldsModel):
    """Status of a file upload to Prusa Connect."""

    id: int
    team_id: int
    name: str
    size: int
    hash: str | None = None
    state: str
    source: str | None = None

WarnExtraFieldsModel

Bases: BaseModel

Base model that logs a warning if extra fields are present.

METHOD DESCRIPTION
__init__

Initialize the model.

Source code in src/prusa/connect/client/models/common.py
15
16
17
18
19
20
21
22
23
24
25
26
27
class WarnExtraFieldsModel(pydantic.BaseModel):
    """Base model that logs a warning if extra fields are present."""

    model_config = pydantic.ConfigDict(extra="allow")

    def __init__(self, **data: typing.Any):
        """Initialize the model."""
        super().__init__(**data)
        if self.__pydantic_extra__:
            logger.warning(
                f"Model {self.__class__.__name__} received unknown fields: {list(self.__pydantic_extra__.keys())}"
            )
            logger.debug("Full JSON", json=json.dumps(data, default=str))

__init__(**data)

Initialize the model.

Source code in src/prusa/connect/client/models/common.py
20
21
22
23
24
25
26
27
def __init__(self, **data: typing.Any):
    """Initialize the model."""
    super().__init__(**data)
    if self.__pydantic_extra__:
        logger.warning(
            f"Model {self.__class__.__name__} received unknown fields: {list(self.__pydantic_extra__.keys())}"
        )
        logger.debug("Full JSON", json=json.dumps(data, default=str))

cameras

Camera models for Prusa Connect SDK.

Camera

Bases: WarnExtraFieldsModel

Camera information.

Source code in src/prusa/connect/client/models/cameras.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class Camera(WarnExtraFieldsModel):
    """Camera information."""

    id: int | None = None  # Numeric ID for snapshots
    token: str | None = None  # Alphanumeric token/id in some contexts?
    name: str | None = None
    origin: str | None = None
    resolution: str | None = None
    snapshot_url: str | None = None

    config: CameraConfig | None = None
    options: CameraOptions | None = None
    capabilities: list[str] | None = None
    features: list[str] | None = None
    sort_order: int | None = None
    registered: bool | None = None
    team_id: int | None = None
    printer_uuid: str | None = None

    snapshots: list[str] | None = None

CameraConfig

Bases: WarnExtraFieldsModel

Camera internal configuration snapshot.

Source code in src/prusa/connect/client/models/cameras.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class CameraConfig(WarnExtraFieldsModel):
    """Camera internal configuration snapshot."""

    name: str | None = None
    path: str | None = None
    model: str | None = None
    driver: str | None = None
    firmware: str | None = None
    rotation: int | None = None
    camera_id: str | None = None
    resolution: CameraResolution | None = None
    manufacturer: str | None = None
    network_info: CameraNetworkInfo | None = None
    trigger_scheme: str | None = None

CameraNetworkInfo

Bases: WarnExtraFieldsModel

Camera network configuration.

Source code in src/prusa/connect/client/models/cameras.py
13
14
15
16
17
18
class CameraNetworkInfo(WarnExtraFieldsModel):
    """Camera network configuration."""

    wifi_mac: str | None = None
    wifi_ipv4: str | None = None
    wifi_ssid: str | None = None

CameraOptions

Bases: WarnExtraFieldsModel

Available options/capabilities for the camera.

Source code in src/prusa/connect/client/models/cameras.py
37
38
39
40
class CameraOptions(WarnExtraFieldsModel):
    """Available options/capabilities for the camera."""

    available_resolutions: list[CameraResolution] | None = None

CameraResolution

Bases: WarnExtraFieldsModel

Camera resolution details.

Source code in src/prusa/connect/client/models/cameras.py
 6
 7
 8
 9
10
class CameraResolution(WarnExtraFieldsModel):
    """Camera resolution details."""

    width: int
    height: int

common

Common models for Prusa Connect SDK.

NetworkInfo

Bases: WarnExtraFieldsModel

Network configuration details.

Source code in src/prusa/connect/client/models/common.py
30
31
32
33
34
35
36
37
38
39
class NetworkInfo(WarnExtraFieldsModel):
    """Network configuration details."""

    hostname: str | None = None
    ipv4: str | None = None
    ipv6: str | None = None
    mac: str | None = None
    wifi_ssid: str | None = None
    lan_ipv4: str | None = None
    lan_mac: str | None = None

Owner

Bases: SourceInfo

Represents the owner of a resource (same fields as SourceInfo).

Source code in src/prusa/connect/client/models/common.py
60
61
62
63
class Owner(SourceInfo):
    """Represents the owner of a resource (same fields as SourceInfo)."""

    pass

SourceInfo

Bases: WarnExtraFieldsModel

Information about the source of an action or object (e.g., user).

METHOD DESCRIPTION
resolve_avatar_url

Automatically prepend MEDIA_BASE_URL if missing.

Source code in src/prusa/connect/client/models/common.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class SourceInfo(WarnExtraFieldsModel):
    """Information about the source of an action or object (e.g., user)."""

    id: int | None = None
    first_name: str | None = None
    last_name: str | None = None
    public_name: str | None = None
    avatar: str | None = None

    @pydantic.field_validator("avatar")
    @classmethod
    def resolve_avatar_url(cls, v: typing.Any) -> typing.Any:
        """Automatically prepend MEDIA_BASE_URL if missing."""
        if isinstance(v, str) and v and not v.startswith(("http://", "https://")):
            return f"{consts.MEDIA_BASE_URL}{v.lstrip('/')}"
        return v

resolve_avatar_url(v) classmethod

Automatically prepend MEDIA_BASE_URL if missing.

Source code in src/prusa/connect/client/models/common.py
51
52
53
54
55
56
57
@pydantic.field_validator("avatar")
@classmethod
def resolve_avatar_url(cls, v: typing.Any) -> typing.Any:
    """Automatically prepend MEDIA_BASE_URL if missing."""
    if isinstance(v, str) and v and not v.startswith(("http://", "https://")):
        return f"{consts.MEDIA_BASE_URL}{v.lstrip('/')}"
    return v

SyncInfo

Bases: WarnExtraFieldsModel

Synchronization details for a resource.

Source code in src/prusa/connect/client/models/common.py
66
67
68
69
70
71
class SyncInfo(WarnExtraFieldsModel):
    """Synchronization details for a resource."""

    synced_by: dict[str, typing.Any] | None = None
    synced: datetime.datetime | None = None
    source: str | None = None

WarnExtraFieldsModel

Bases: BaseModel

Base model that logs a warning if extra fields are present.

METHOD DESCRIPTION
__init__

Initialize the model.

Source code in src/prusa/connect/client/models/common.py
15
16
17
18
19
20
21
22
23
24
25
26
27
class WarnExtraFieldsModel(pydantic.BaseModel):
    """Base model that logs a warning if extra fields are present."""

    model_config = pydantic.ConfigDict(extra="allow")

    def __init__(self, **data: typing.Any):
        """Initialize the model."""
        super().__init__(**data)
        if self.__pydantic_extra__:
            logger.warning(
                f"Model {self.__class__.__name__} received unknown fields: {list(self.__pydantic_extra__.keys())}"
            )
            logger.debug("Full JSON", json=json.dumps(data, default=str))

__init__(**data)

Initialize the model.

Source code in src/prusa/connect/client/models/common.py
20
21
22
23
24
25
26
27
def __init__(self, **data: typing.Any):
    """Initialize the model."""
    super().__init__(**data)
    if self.__pydantic_extra__:
        logger.warning(
            f"Model {self.__class__.__name__} received unknown fields: {list(self.__pydantic_extra__.keys())}"
        )
        logger.debug("Full JSON", json=json.dumps(data, default=str))

config

Models for the /app/config endpoint.

AppConfig

Bases: WarnExtraFieldsModel

Application configuration returned by /app/config.

Source code in src/prusa/connect/client/models/config.py
21
22
23
24
class AppConfig(WarnExtraFieldsModel):
    """Application configuration returned by /app/config."""

    auth: AuthConfig

AuthConfig

Bases: WarnExtraFieldsModel

Authentication configuration.

Source code in src/prusa/connect/client/models/config.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class AuthConfig(WarnExtraFieldsModel):
    """Authentication configuration."""

    backends: list[str]
    server_url: str
    client_id: str
    redirect_url: str
    avatar_server_url: str
    max_upload_size: int
    max_snapshot_size: int
    max_preview_size: int
    afs_enabled: bool
    afs_group_id: int

files

File models for Prusa Connect SDK.

BaseFile

Bases: WarnExtraFieldsModel

Common fields for all file types.

Source code in src/prusa/connect/client/models/files.py
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class BaseFile(WarnExtraFieldsModel):
    """Common fields for all file types."""

    type: str  # Discriminator field
    name: str
    display_name: str | None = None
    size: pydantic.ByteSize | None = None
    hash: str | None = None

    team_id: int | None = None
    upload_id: int | None = None
    uploaded: datetime.datetime | None = None

    path: str | None = None
    display_path: str | None = None
    read_only: bool = False
    m_timestamp: int | None = None

    sync: SyncInfo | None = None
    owner: Owner | None = None

    model_config = pydantic.ConfigDict(extra="allow")

FirmwareFile

Bases: BaseFile

Represents a firmware file on the printer.

Source code in src/prusa/connect/client/models/files.py
108
109
110
111
112
113
114
class FirmwareFile(BaseFile):
    """Represents a firmware file on the printer."""

    type: typing.Literal["FIRMWARE"] = "FIRMWARE"  # pyrefly: ignore[bad-override]
    printer_type: str | None = None
    release_url: pydantic.HttpUrl | None = None
    meta: FirmwareFileMeta | None = None

FirmwareFileMeta

Bases: WarnExtraFieldsModel

Metadata associated with a firmware file.

Source code in src/prusa/connect/client/models/files.py
58
59
60
61
62
63
64
65
66
class FirmwareFileMeta(WarnExtraFieldsModel):
    """Metadata associated with a firmware file."""

    device_type_id: str | None = None
    version: str | None = None
    sem_ver: str | None = None
    build_no: int | None = None
    bbf_version: int | None = None
    printer_model: str | None = None

PrintFile

Bases: BaseFile

Represents a print file (G-code, BG-code).

Source code in src/prusa/connect/client/models/files.py
 99
100
101
102
103
104
105
class PrintFile(BaseFile):
    """Represents a print file (G-code, BG-code)."""

    type: typing.Literal["PRINT_FILE"] = "PRINT_FILE"  # pyrefly: ignore[bad-override]
    preview_url: str | None = None
    preview_mimetype: str | None = None
    meta: PrintFileMeta | None = None

PrintFileMeta

Bases: WarnExtraFieldsModel

Metadata associated with a print file (statistics parse from G-code).

Source code in src/prusa/connect/client/models/files.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class PrintFileMeta(WarnExtraFieldsModel):
    """Metadata associated with a print file (statistics parse from G-code)."""

    model_config = pydantic.ConfigDict(extra="allow")

    extruder_colour: str | None = None
    filament_abrasive: bool | None = None
    temperature: int | None = None
    brim_width: int | None = None
    bed_temperature: int | None = None
    ironing: bool | None = None
    nozzle_high_flow: bool | None = None
    support_material: bool | None = None
    filament_type: str | None = None
    filament_cost: float | None = None
    total_height: float | None = None
    max_layer_z: float | None = None
    filament_used_m: float | None = None
    filament_used_mm: float | None = None
    filament_used_g: float | None = None
    filament_used_cm3: float | None = None
    filament_used_mm3: float | None = None
    nozzle_diameter: float | None = None
    fill_density: str | None = None
    printer_model: str | None = None
    estimated_print_time: datetime.timedelta | None = None
    estimated_printing_time_normal_mode: str | None = None
    layer_height: float | None = None
    producer: str | None = None
    slots: list[dict[str, typing.Any]] | None = None
    objects_info: dict[str, typing.Any] | None = None

RegularFile

Bases: BaseFile

Represents a generic file.

Source code in src/prusa/connect/client/models/files.py
93
94
95
96
class RegularFile(BaseFile):
    """Represents a generic file."""

    type: typing.Literal["FILE"] = "FILE"  # pyrefly: ignore[bad-override]

Storage

Bases: WarnExtraFieldsModel

Represents a storage device on the printer.

Source code in src/prusa/connect/client/models/files.py
11
12
13
14
15
16
17
18
19
20
21
22
class Storage(WarnExtraFieldsModel):
    """Represents a storage device on the printer."""

    type: str
    path: str
    mountpoint: str | None = None
    name: str
    read_only: bool = False
    is_sfn: bool | None = None
    file_count: int | None = None
    free_space: int | None = None
    total_space: int | None = None

UploadStatus

Bases: WarnExtraFieldsModel

Status of a file upload to Prusa Connect.

Source code in src/prusa/connect/client/models/files.py
120
121
122
123
124
125
126
127
128
129
class UploadStatus(WarnExtraFieldsModel):
    """Status of a file upload to Prusa Connect."""

    id: int
    team_id: int
    name: str
    size: int
    hash: str | None = None
    state: str
    source: str | None = None

jobs

Job models for Prusa Connect SDK.

CancelableObject

Bases: WarnExtraFieldsModel

Represents an object that can be cancelled during print.

Source code in src/prusa/connect/client/models/jobs.py
56
57
58
59
60
61
62
class CancelableObject(WarnExtraFieldsModel):
    """Represents an object that can be cancelled during print."""

    id: int
    name: str
    polygon: list[list[float]] | None = None
    canceled: bool = False

Job

Bases: WarnExtraFieldsModel

A planned or history job.

Source code in src/prusa/connect/client/models/jobs.py
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
class Job(WarnExtraFieldsModel):
    """A planned or history job."""

    id: int
    lifetime_id: str | None = None
    printer_uuid: str | None = None
    team_id: int | None = None
    origin_id: int | None = None
    source: str | None = None
    source_info: SourceInfo | None = None

    state: JobStatus

    cameras: list[Camera] | None = None
    hash: str | None = None
    time_printing: int | None = None
    start: int | None = None
    end: int | None = None
    progress: float | None = None
    planned: dict | None = None

    print_height: float | None = None

    file: File | None = None
    path: str | None = None

    reason: JobFailureReason | None = None

    cancelable_objects: list[CancelableObject] | None = pydantic.Field(
        None, validation_alias=AliasChoices("cancelable_objects", AliasPath("cancelable", "objects"))
    )
    cancelable_time: datetime.datetime | None = None

JobFailureReason

Bases: WarnExtraFieldsModel

Details about a job failure.

Source code in src/prusa/connect/client/models/jobs.py
65
66
67
68
69
class JobFailureReason(WarnExtraFieldsModel):
    """Details about a job failure."""

    tag: list[JobFailureTag] = pydantic.Field(default_factory=list)
    other: str | None = None

JobFailureTag

Bases: StrEnum

Enum representing reasons for job failure/cancellation.

Source code in src/prusa/connect/client/models/jobs.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class JobFailureTag(StrEnum):
    """Enum representing reasons for job failure/cancellation."""

    IGNORED = "IGNORED"
    CLOGGED_NOZZLE = "CLOGGED_NOZZLE"
    NON_ADHERENT_BED = "NON_ADHERENT_BED"
    UNDER_EXTRUSION = "UNDER_EXTRUSION"
    OVER_EXTRUSION = "OVER_EXTRUSION"
    STRINGING_OR_OOZING = "STRINGING_OR_OOZING"
    GAPS_IN_THIN_WALLS = "GAPS_IN_THIN_WALLS"
    OVERHEATING = "OVERHEATING"
    LAYER_SHIFTING = "LAYER_SHIFTING"
    SPAGHETTI_MONSTER = "SPAGHETTI_MONSTER"
    LAYER_SEPARATION = "LAYER_SEPARATION"
    WARPING = "WARPING"
    POOR_BRIDGING = "POOR_BRIDGING"
    OTHER = "OTHER"

JobInfo

Bases: WarnExtraFieldsModel

Snapshot of a job currently on a printer.

Source code in src/prusa/connect/client/models/jobs.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class JobInfo(WarnExtraFieldsModel):
    """Snapshot of a job currently on a printer."""

    id: int | None = None
    origin_id: int | None = None
    path: str | None = None
    state: str | None = None
    progress: float | None = None
    time_printing: datetime.timedelta | None = None
    time_remaining: datetime.timedelta | None = None
    display_name: str | None = None
    start: datetime.datetime | None = None
    end: datetime.datetime | None = None
    hash: str | None = None
    preview_url: str | None = None
    model_weight: float | None = None
    weight_remaining: float | None = None
    print_height: float | None = None
    total_height: float | None = None
    lifetime_id: str | None = None

printers

Printer models for Prusa Connect SDK.

FirmwareSupport

Bases: WarnExtraFieldsModel

Firmware version information.

Source code in src/prusa/connect/client/models/printers.py
81
82
83
84
85
86
87
88
89
90
class FirmwareSupport(WarnExtraFieldsModel):
    """Firmware version information."""

    latest: str | None = None
    current: str | None = None
    release_url: str | None = None
    stable: str | None = None
    prerelease: str | None = None
    release: str | None = None
    state: str | None = None

Printer

Bases: WarnExtraFieldsModel

Detailed Printer Object.

Matches structure in printers.error.response.json and printer_details.json.

Source code in src/prusa/connect/client/models/printers.py
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
class Printer(WarnExtraFieldsModel):
    """Detailed Printer Object.

    Matches structure in `printers.error.response.json` and `printer_details.json`.
    """

    uuid: str | None = None  # UUID might not be in the detail root, but often is
    name: str | None = None
    printer_state: PrinterState | None = pydantic.Field(
        None, validation_alias=pydantic.AliasChoices("printer_state", "state")
    )  # API uses 'state' or 'printer_state'
    disabled: dict[str, bool] | None = None
    printer_model: str | None = None
    firmware_version: str | None = pydantic.Field(None, alias="firmware")
    last_online: float | None = None

    network_info: NetworkInfo | None = None

    support: FirmwareSupport | None = None
    tools: dict[str, Tool] | None = None
    slot: SlotInfo | None = None
    location: str | None = None
    team_name: str | None = None
    appendix: bool | None = None
    state: PrinterState | None = None
    state_reason: str | None = None
    time_delta: int | None = None
    prusalink_api_key: pydantic.SecretStr | None = None
    api_key: pydantic.SecretStr | None = None
    sheet_settings: typing.Any | None = None
    inaccurate_estimates: bool | None = None
    enclosure: typing.Any | None = None
    slots: int | None = None
    mmu: dict[str, typing.Any] | None = None
    supported_printer_models: list[str] | None = None
    printer_type_compatible: list[str] | None = None
    connect_state: str | None = None
    allowed_functionalities: list[str] | None = None
    decision_maker: typing.Any | None = None
    printer_type: str | None = None
    fw_printer_type: str | None = None
    printer_type_name: str | None = None
    flags: dict[str, typing.Any] | None = None
    max_filename: int | None = None
    printable_extension: list[str] | None = None
    created: datetime.datetime | None = None
    sn: str | None = None
    team_id: int | None = None
    is_beta: bool | None = None
    filament: dict[str, typing.Any] | None = None
    organization_id: uuid_pkg.UUID | None = None
    rights_r: bool | None = None
    rights_w: bool | None = None
    rights_u: bool | None = None
    prusaconnect_api_key: pydantic.SecretStr | None = None
    groups: list[typing.Any] | None = None
    owner: Owner | None = None

    # Nested info
    telemetry: Temperatures | None = pydantic.Field(None, alias="temp")
    job: JobInfo | None = pydantic.Field(None, alias="job_info")
    cameras: list[Camera] | None = None

    # Capabilities
    nozzle_diameter: float | None = None
    speed: int | None = None
    flow: int | None = None
    axis_x: float | None = None
    axis_y: float | None = None
    axis_z: float | None = None

    model_config = pydantic.ConfigDict(extra="allow")

PrinterCommand

Bases: StrEnum

Enum representing known commands for a printer.

NOTE: These commands are the subset of commands on a MK4S printer that do not require any additional parameters.

TODO(dcode): Add support for commands that require additional parameters. TODO(dcode): Consider dynamic command generation from the printer's capabilities.

Source code in src/prusa/connect/client/models/printers.py
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
67
68
69
class PrinterCommand(StrEnum):
    """Enum representing known commands for a printer.

    NOTE: These commands are the subset of commands on a
    MK4S printer that do not require any additional parameters.

    TODO(dcode): Add support for commands that require additional parameters.
    TODO(dcode): Consider dynamic command generation from the printer's capabilities.
    """

    SET_PRINTER_READY = "SET_PRINTER_READY"
    CANCEL_PRINTER_READY = "CANCEL_PRINTER_READY"
    PAUSE_PRINT = "PAUSE_PRINT"
    RESUME_PRINT = "RESUME_PRINT"
    STOP_PRINT = "STOP_PRINT"
    RESET_PRINTER = "RESET_PRINTER"
    UNLOAD_FILAMENT = "UNLOAD_FILAMENT"
    SEND_INFO = "SEND_INFO"
    STOP_TRANSFER = "STOP_TRANSFER"
    SEND_STATE_INFO = "SEND_STATE_INFO"
    RESET = "RESET"
    DISABLE_STEPPERS = "DISABLE_STEPPERS"
    BEEP = "BEEP"
    # Fallback for unknown states
    UNKNOWN = "UNKNOWN"

    @classmethod
    def _missing_(cls, value: object) -> typing.Any:
        return cls.UNKNOWN

PrinterListResponse

Bases: WarnExtraFieldsModel

Response model for the /printers endpoint.

Source code in src/prusa/connect/client/models/printers.py
190
191
192
193
class PrinterListResponse(WarnExtraFieldsModel):
    """Response model for the /printers endpoint."""

    printers: list[Printer]

PrinterState

Bases: StrEnum

Enum representing the possible states of a printer.

Source code in src/prusa/connect/client/models/printers.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class PrinterState(StrEnum):
    """Enum representing the possible states of a printer."""

    READY = "READY"
    IDLE = "IDLE"

    BUSY = "BUSY"
    MANIPULATING = "MANIPULATING"
    PRINTING = "PRINTING"

    PAUSED = "PAUSED"
    FINISHED = "FINISHED"
    STOPPED = "STOPPED"

    ATTENTION = "ATTENTION"
    ERROR = "ERROR"
    OFFLINE = "OFFLINE"

    # Fallback for unknown states
    UNKNOWN = "UNKNOWN"

    @classmethod
    def _missing_(cls, value: object) -> typing.Any:
        return cls.UNKNOWN

SlotInfo

Bases: WarnExtraFieldsModel

MMU Slot information.

Source code in src/prusa/connect/client/models/printers.py
107
108
109
110
111
112
113
class SlotInfo(WarnExtraFieldsModel):
    """MMU Slot information."""

    active: int | None = None
    slots: dict[str, Tool] | None = None
    state: str | None = None
    command: str | None = None

Temperatures

Bases: WarnExtraFieldsModel

Printer temperatures.

Source code in src/prusa/connect/client/models/printers.py
72
73
74
75
76
77
78
class Temperatures(WarnExtraFieldsModel):
    """Printer temperatures."""

    temp_nozzle: float | None = None
    temp_bed: float | None = None
    target_nozzle: float | None = None
    target_bed: float | None = None

Tool

Bases: WarnExtraFieldsModel

Tool/Head information.

Source code in src/prusa/connect/client/models/printers.py
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
class Tool(WarnExtraFieldsModel):
    """Tool/Head information."""

    material: str | None = None
    temp: float | None = None
    nozzle_diameter: float | None = None
    fan_hotend: float | None = None
    fan_print: float | None = None
    mmu: dict[str, typing.Any] | None = None
    hardened: bool | None = None
    high_flow: bool | None = None
    active: bool | None = None

stats

Stats models for Prusa Connect SDK.

JobStatus

Bases: StrEnum

Enum representing the status of a job.

METHOD DESCRIPTION
__lt__

Compare two JobStatus members by order of declaration.

get_order

Get the index of the member in the order of declaration.

Source code in src/prusa/connect/client/models/stats.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@functools.total_ordering
class JobStatus(StrEnum):
    """Enum representing the status of a job."""

    PRINTING = "PRINTING"
    FINISHED = "FINISHED"

    OK = "FIN_OK"
    STOPPED = "FIN_STOPPED"
    ERROR = "FIN_ERROR"
    UNKNOWN = "FIN_UNKNOWN"

    @classmethod
    def _missing_(cls, value: object) -> typing.Any:
        return cls.UNKNOWN

    @classmethod
    def get_order(cls, member: "JobStatus") -> int:
        """Get the index of the member in the order of declaration."""
        global _job_status_order_map
        if _job_status_order_map is None:
            _job_status_order_map = {m: i for i, m in enumerate(cls)}
        return _job_status_order_map[member]

    def __lt__(self, other):
        """Compare two JobStatus members by order of declaration."""
        if self.__class__ is other.__class__:
            return self.get_order(self) < self.get_order(other)
        return NotImplemented

__lt__(other)

Compare two JobStatus members by order of declaration.

Source code in src/prusa/connect/client/models/stats.py
39
40
41
42
43
def __lt__(self, other):
    """Compare two JobStatus members by order of declaration."""
    if self.__class__ is other.__class__:
        return self.get_order(self) < self.get_order(other)
    return NotImplemented

get_order(member) classmethod

Get the index of the member in the order of declaration.

Source code in src/prusa/connect/client/models/stats.py
31
32
33
34
35
36
37
@classmethod
def get_order(cls, member: "JobStatus") -> int:
    """Get the index of the member in the order of declaration."""
    global _job_status_order_map
    if _job_status_order_map is None:
        _job_status_order_map = {m: i for i, m in enumerate(cls)}
    return _job_status_order_map[member]

JobsSuccess

Bases: StatsModel

Printer usage statistics: job success history.

Source code in src/prusa/connect/client/models/stats.py
107
108
109
110
111
112
113
114
115
116
class JobsSuccess(StatsModel):
    """Printer usage statistics: job success history."""

    date_axis: list[str] = pydantic.Field(
        ..., alias="xAxis", validation_alias=pydantic.AliasChoices("xAxis", "date_axis"), description="Date axis"
    )
    printer_name: str = pydantic.Field(..., alias="name")
    printer_uuid: str = pydantic.Field(..., alias="uuid")
    series: list[JobsSuccessSeries]
    time_shift: str

JobsSuccessSeries

Bases: WarnExtraFieldsModel

Series data for job success stats.

Source code in src/prusa/connect/client/models/stats.py
100
101
102
103
104
class JobsSuccessSeries(WarnExtraFieldsModel):
    """Series data for job success stats."""

    status: JobStatus = pydantic.Field(..., alias="name")
    data: list[int]

MaterialQuantity

Bases: StatsModel

Printer usage statistics: material quantity used.

Source code in src/prusa/connect/client/models/stats.py
75
76
77
78
79
80
class MaterialQuantity(StatsModel):
    """Printer usage statistics: material quantity used."""

    printer_name: str = pydantic.Field(..., alias="name")
    printer_uuid: str = pydantic.Field(..., alias="uuid")
    data: list[typing.Any]

PlannedTasks

Bases: StatsModel

Printer usage statistics: planned tasks.

Source code in src/prusa/connect/client/models/stats.py
91
92
93
94
95
96
97
class PlannedTasks(StatsModel):
    """Printer usage statistics: planned tasks."""

    time_axis: list[int] = pydantic.Field(
        ..., alias="xAxis", validation_alias=pydantic.AliasChoices("xAxis", "time_axis"), description="Time axis"
    )
    series: PlannedTasksSeries

PlannedTasksSeries

Bases: WarnExtraFieldsModel

Series data for planned tasks.

Source code in src/prusa/connect/client/models/stats.py
83
84
85
86
87
88
class PlannedTasksSeries(WarnExtraFieldsModel):
    """Series data for planned tasks."""

    printer_uuid: str = pydantic.Field(..., alias="uuid")
    printer_name: str = pydantic.Field(..., alias="name")
    data: list[tuple[int, int]]

PrintingNotPrinting

Bases: StatsModel

Printer usage statistics: printing vs not printing.

Source code in src/prusa/connect/client/models/stats.py
67
68
69
70
71
72
class PrintingNotPrinting(StatsModel):
    """Printer usage statistics: printing vs not printing."""

    printer_name: str = pydantic.Field(..., alias="name")
    printer_uuid: str = pydantic.Field(..., alias="uuid")
    data: list[PrintingNotPrintingEntry]

PrintingNotPrintingEntry

Bases: WarnExtraFieldsModel

Represents a single entry in printing vs not printing stats.

Source code in src/prusa/connect/client/models/stats.py
60
61
62
63
64
class PrintingNotPrintingEntry(WarnExtraFieldsModel):
    """Represents a single entry in printing vs not printing stats."""

    name: str
    duration: datetime.timedelta = pydantic.Field(..., alias="value")

StatsModel

Bases: WarnExtraFieldsModel

Base model for statistics with date validation.

Source code in src/prusa/connect/client/models/stats.py
46
47
48
49
50
51
52
53
54
55
56
57
class StatsModel(WarnExtraFieldsModel):
    """Base model for statistics with date validation."""

    from_time: datetime.date = pydantic.Field(..., alias="from")
    to_time: datetime.date = pydantic.Field(..., alias="to")

    @pydantic.field_validator("from_time", "to_time", mode="before")
    @classmethod
    def _validate_date(cls, v):
        if isinstance(v, (int, float)):
            return datetime.datetime.fromtimestamp(v, datetime.UTC).date()
        return v

teams

Team models for Prusa Connect SDK.

Team

Bases: WarnExtraFieldsModel

Team information.

Source code in src/prusa/connect/client/models/teams.py
24
25
26
27
28
29
30
31
32
33
34
35
36
class Team(WarnExtraFieldsModel):
    """Team information."""

    id: int
    name: str
    role: str | None = None
    description: str | None = None
    capacity: int | None = None
    organization_id: uuid_pkg.UUID | None = None
    prusaconnect_api_key: pydantic.SecretStr | None = None
    user_count: int | None = None
    users: list[TeamUser] | None = None
    invitees: list[typing.Any] | None = None

TeamUser

Bases: WarnExtraFieldsModel

User in a team.

Source code in src/prusa/connect/client/models/teams.py
11
12
13
14
15
16
17
18
19
20
21
class TeamUser(WarnExtraFieldsModel):
    """User in a team."""

    id: int
    first_name: str | None = None
    last_name: str | None = None
    public_name: str | None = None
    avatar: str | None = None
    rights_ro: bool | None = None
    rights_rw: bool | None = None
    rights_use: bool | None = None