flashforge-python-api 1.0.2__py3-none-any.whl → 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flashforge/__init__.py +70 -29
- flashforge/api/__init__.py +1 -0
- flashforge/api/constants/__init__.py +1 -0
- flashforge/api/constants/commands.py +1 -0
- flashforge/api/constants/endpoints.py +7 -0
- flashforge/api/controls/__init__.py +1 -0
- flashforge/api/controls/control.py +64 -61
- flashforge/api/controls/files.py +28 -26
- flashforge/api/controls/info.py +84 -85
- flashforge/api/controls/job_control.py +120 -82
- flashforge/api/controls/temp_control.py +14 -11
- flashforge/api/misc/__init__.py +1 -1
- flashforge/api/network/__init__.py +2 -1
- flashforge/api/network/utils.py +7 -8
- flashforge/client.py +185 -64
- flashforge/discovery/__init__.py +30 -3
- flashforge/discovery/discovery.py +641 -308
- flashforge/models/__init__.py +11 -10
- flashforge/models/machine_info.py +225 -100
- flashforge/models/responses.py +103 -43
- flashforge/tcp/__init__.py +30 -17
- flashforge/tcp/a3_client.py +408 -0
- flashforge/tcp/a4_client.py +300 -0
- flashforge/tcp/ff_client.py +93 -90
- flashforge/tcp/gcode/__init__.py +4 -2
- flashforge/tcp/gcode/a3_gcode_controller.py +109 -0
- flashforge/tcp/gcode/gcode_controller.py +48 -36
- flashforge/tcp/gcode/gcodes.py +7 -1
- flashforge/tcp/parsers/__init__.py +11 -11
- flashforge/tcp/parsers/endstop_status.py +103 -132
- flashforge/tcp/parsers/location_info.py +26 -13
- flashforge/tcp/parsers/print_status.py +49 -56
- flashforge/tcp/parsers/printer_info.py +38 -48
- flashforge/tcp/parsers/temp_info.py +46 -47
- flashforge/tcp/parsers/thumbnail_info.py +65 -40
- flashforge/tcp/tcp_client.py +296 -293
- flashforge_python_api-1.2.0.dist-info/METADATA +133 -0
- flashforge_python_api-1.2.0.dist-info/RECORD +46 -0
- {flashforge_python_api-1.0.2.dist-info → flashforge_python_api-1.2.0.dist-info}/WHEEL +1 -1
- flashforge_python_api-1.0.2.dist-info/METADATA +0 -284
- flashforge_python_api-1.0.2.dist-info/RECORD +0 -43
- {flashforge_python_api-1.0.2.dist-info → flashforge_python_api-1.2.0.dist-info}/entry_points.txt +0 -0
- {flashforge_python_api-1.0.2.dist-info → flashforge_python_api-1.2.0.dist-info}/licenses/LICENSE +0 -0
flashforge/models/responses.py
CHANGED
|
@@ -2,122 +2,182 @@
|
|
|
2
2
|
FlashForge Python API - Response Models
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from pydantic import BaseModel, Field
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
7
6
|
|
|
8
|
-
from .machine_info import
|
|
7
|
+
from .machine_info import FFGcodeFileEntry, FFPrinterDetail
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
class GenericResponse(BaseModel):
|
|
12
11
|
"""Represents a generic response from the printer's API."""
|
|
12
|
+
|
|
13
|
+
model_config = ConfigDict(extra="forbid")
|
|
14
|
+
|
|
13
15
|
code: int
|
|
14
16
|
message: str = ""
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class DetailResponse(GenericResponse):
|
|
18
20
|
"""Represents the structure of the response from the printer's detail endpoint."""
|
|
21
|
+
|
|
22
|
+
model_config = ConfigDict(extra="forbid")
|
|
23
|
+
|
|
19
24
|
detail: FFPrinterDetail
|
|
20
25
|
|
|
21
26
|
|
|
22
27
|
class Product(BaseModel):
|
|
23
28
|
"""
|
|
24
29
|
Defines the structure of the `product` object nested within a `ProductResponse`.
|
|
25
|
-
|
|
30
|
+
|
|
26
31
|
This contains various control state flags reported by the printer,
|
|
27
32
|
indicating the status or availability of certain features like temperature controls,
|
|
28
33
|
fan controls, and light controls. A state of 0 often means off/unavailable,
|
|
29
34
|
while other numbers (typically 1) mean on/available or a specific mode.
|
|
30
|
-
|
|
35
|
+
|
|
31
36
|
Field names match the actual camelCase format returned by the printer.
|
|
32
37
|
"""
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
model_config = ConfigDict(extra="forbid")
|
|
40
|
+
|
|
41
|
+
chamberTempCtrlState: int # noqa: N815 - field must match API camelCase response format
|
|
42
|
+
externalFanCtrlState: int # noqa: N815 - field must match API camelCase response format
|
|
43
|
+
internalFanCtrlState: int # noqa: N815 - field must match API camelCase response format
|
|
44
|
+
lightCtrlState: int # noqa: N815 - field must match API camelCase response format
|
|
45
|
+
nozzleTempCtrlState: int # noqa: N815 - field must match API camelCase response format
|
|
46
|
+
platformTempCtrlState: int # noqa: N815 - field must match API camelCase response format
|
|
39
47
|
|
|
40
48
|
|
|
41
49
|
class ProductResponse(GenericResponse):
|
|
42
50
|
"""
|
|
43
51
|
Represents the expected structure of the response from the "product command"
|
|
44
52
|
sent to the printer (typically to the `/product` endpoint).
|
|
45
|
-
|
|
53
|
+
|
|
46
54
|
This response includes general status information (via `GenericResponse`)
|
|
47
55
|
and a nested `product` object containing specific control states.
|
|
48
56
|
"""
|
|
57
|
+
|
|
58
|
+
model_config = ConfigDict(extra="forbid")
|
|
59
|
+
|
|
49
60
|
product: Product
|
|
50
61
|
|
|
51
62
|
|
|
52
63
|
class FilamentArgs(BaseModel):
|
|
53
64
|
"""Represents the arguments for controlling the printer's filtration system."""
|
|
54
|
-
internal: str
|
|
55
|
-
external: str
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
model_config = ConfigDict(extra="forbid")
|
|
67
|
+
|
|
68
|
+
internal: str = Field(description="Internal filtration state ('open' or 'close')")
|
|
69
|
+
external: str = Field(description="External filtration state ('open' or 'close')")
|
|
70
|
+
|
|
71
|
+
@field_validator("internal", "external")
|
|
72
|
+
@classmethod
|
|
73
|
+
def validate_filtration_state(cls, v: str) -> str:
|
|
74
|
+
"""Validate that the state is either 'open' or 'close'."""
|
|
75
|
+
if v not in {"open", "close"}:
|
|
76
|
+
raise ValueError(f"Filtration state must be 'open' or 'close', got: {v}")
|
|
77
|
+
return v
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def create(cls, internal_on: bool, external_on: bool) -> "FilamentArgs":
|
|
81
|
+
"""
|
|
82
|
+
Create FilamentArgs from boolean states.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
internal_on: Whether internal filtration should be open (True) or closed (False)
|
|
86
|
+
external_on: Whether external filtration should be open (True) or closed (False)
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
FilamentArgs instance with proper string states
|
|
90
|
+
"""
|
|
91
|
+
return cls(
|
|
92
|
+
internal="open" if internal_on else "close", external="open" if external_on else "close"
|
|
61
93
|
)
|
|
62
94
|
|
|
63
95
|
|
|
64
96
|
class AD5XMaterialMapping(BaseModel):
|
|
65
97
|
"""Represents a material mapping for AD5X multi-color printing. Maps a tool (extruder) to a specific material station slot."""
|
|
98
|
+
|
|
99
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
100
|
+
|
|
66
101
|
tool_id: int = Field(ge=0, le=3, description="Tool ID (0-based: 0, 1, 2, 3)")
|
|
67
102
|
slot_id: int = Field(ge=1, le=4, description="Slot ID (1-based: 1, 2, 3, 4)")
|
|
68
103
|
material_name: str = Field(description="Name of the material (e.g., 'PLA', 'SILK')")
|
|
69
|
-
tool_material_color: str = Field(
|
|
70
|
-
|
|
104
|
+
tool_material_color: str = Field(
|
|
105
|
+
description="Hex color code for the tool material (e.g., '#FFFFFF')"
|
|
106
|
+
)
|
|
107
|
+
slot_material_color: str = Field(
|
|
108
|
+
description="Hex color code for the slot material (e.g., '#46328E')"
|
|
109
|
+
)
|
|
71
110
|
|
|
72
|
-
|
|
73
|
-
|
|
111
|
+
@field_validator("tool_material_color", "slot_material_color")
|
|
112
|
+
@classmethod
|
|
113
|
+
def validate_hex_color(cls, v: str) -> str:
|
|
114
|
+
"""Validate that the color is a valid hex color code."""
|
|
115
|
+
import re
|
|
116
|
+
|
|
117
|
+
if not re.match(r"^#[0-9A-Fa-f]{6}$", v):
|
|
118
|
+
raise ValueError(f"Invalid hex color format: {v}")
|
|
119
|
+
return v
|
|
74
120
|
|
|
75
121
|
|
|
76
122
|
class AD5XLocalJobParams(BaseModel):
|
|
77
123
|
"""Parameters for starting an AD5X local job with material mappings. Used for multi-color prints that utilize the material station."""
|
|
78
|
-
file_name: str = Field(description="Name of the file on the printer to start")
|
|
79
|
-
leveling_before_print: bool = Field(description="Whether to perform bed leveling before printing")
|
|
80
|
-
material_mappings: list[AD5XMaterialMapping] = Field(description="Array of material mappings (1-4 items)")
|
|
81
124
|
|
|
82
|
-
|
|
83
|
-
|
|
125
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
126
|
+
|
|
127
|
+
file_name: str = Field(description="Name of the file on the printer to start")
|
|
128
|
+
leveling_before_print: bool = Field(
|
|
129
|
+
description="Whether to perform bed leveling before printing"
|
|
130
|
+
)
|
|
131
|
+
material_mappings: list[AD5XMaterialMapping] = Field(
|
|
132
|
+
min_length=1, max_length=4, description="Array of material mappings (1-4 items)"
|
|
133
|
+
)
|
|
84
134
|
|
|
85
135
|
|
|
86
136
|
class AD5XSingleColorJobParams(BaseModel):
|
|
87
137
|
"""Parameters for starting an AD5X single-color local job. Used for single-color prints that do not require the material station."""
|
|
88
|
-
file_name: str = Field(description="Name of the file on the printer to start")
|
|
89
|
-
leveling_before_print: bool = Field(description="Whether to perform bed leveling before printing")
|
|
90
138
|
|
|
91
|
-
|
|
92
|
-
|
|
139
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
140
|
+
|
|
141
|
+
file_name: str = Field(description="Name of the file on the printer to start")
|
|
142
|
+
leveling_before_print: bool = Field(
|
|
143
|
+
description="Whether to perform bed leveling before printing"
|
|
144
|
+
)
|
|
93
145
|
|
|
94
146
|
|
|
95
147
|
class AD5XUploadParams(BaseModel):
|
|
96
148
|
"""Parameters for uploading a file to AD5X printer with material station support. Extends basic upload functionality with AD5X-specific features."""
|
|
149
|
+
|
|
150
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
151
|
+
|
|
97
152
|
file_path: str = Field(description="Local file path to upload")
|
|
98
153
|
start_print: bool = Field(description="Whether to start printing immediately after upload")
|
|
99
|
-
leveling_before_print: bool = Field(
|
|
154
|
+
leveling_before_print: bool = Field(
|
|
155
|
+
description="Whether to perform bed leveling before printing"
|
|
156
|
+
)
|
|
100
157
|
flow_calibration: bool = Field(description="Whether to enable flow calibration")
|
|
101
158
|
first_layer_inspection: bool = Field(description="Whether to enable first layer inspection")
|
|
102
159
|
time_lapse_video: bool = Field(description="Whether to enable time lapse video recording")
|
|
103
|
-
material_mappings: list[AD5XMaterialMapping] = Field(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
160
|
+
material_mappings: list[AD5XMaterialMapping] = Field(
|
|
161
|
+
min_length=1,
|
|
162
|
+
max_length=4,
|
|
163
|
+
description="Array of material mappings for the material station (1-4 items)",
|
|
164
|
+
)
|
|
107
165
|
|
|
108
166
|
|
|
109
167
|
class GCodeListResponse(GenericResponse):
|
|
110
168
|
"""Represents the response structure for a G-code file list request."""
|
|
111
|
-
gcode_list: Optional[Union[list[str], list[FFGcodeFileEntry]]] = Field(default=None, alias="gcodeList")
|
|
112
|
-
gcode_list_detail: Optional[list[FFGcodeFileEntry]] = Field(default=None, alias="gcodeListDetail")
|
|
113
169
|
|
|
114
|
-
|
|
115
|
-
|
|
170
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
171
|
+
|
|
172
|
+
gcode_list: list[str] | list[FFGcodeFileEntry] | None = Field(default=None, alias="gcodeList")
|
|
173
|
+
gcode_list_detail: list[FFGcodeFileEntry] | None = Field(default=None, alias="gcodeListDetail")
|
|
116
174
|
|
|
117
175
|
|
|
118
176
|
class ThumbnailResponse(GenericResponse):
|
|
119
177
|
"""Represents the response structure for a G-code thumbnail request."""
|
|
120
|
-
image_data: str = Field(alias="imageData", description="The thumbnail image data encoded as a base64 string")
|
|
121
178
|
|
|
122
|
-
|
|
123
|
-
|
|
179
|
+
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
|
180
|
+
|
|
181
|
+
image_data: str = Field(
|
|
182
|
+
alias="imageData", description="The thumbnail image data encoded as a base64 string"
|
|
183
|
+
)
|
flashforge/tcp/__init__.py
CHANGED
|
@@ -5,8 +5,10 @@ This module provides low-level TCP socket communication and high-level G-code in
|
|
|
5
5
|
for controlling FlashForge printers via their TCP API.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from .a3_client import A3BuildVolume, A3FileEntry, A3PrinterInfo, A3Thumbnail, FlashForgeA3Client
|
|
9
|
+
from .a4_client import A4BuildVolume, A4FileEntry, A4PrinterInfo, FlashForgeA4Client
|
|
8
10
|
from .ff_client import FlashForgeClient
|
|
9
|
-
from .gcode import GCodeController, GCodes
|
|
11
|
+
from .gcode import A3GCodeController, GCodeController, GCodes
|
|
10
12
|
from .parsers import (
|
|
11
13
|
Endstop,
|
|
12
14
|
EndstopStatus,
|
|
@@ -20,22 +22,33 @@ from .parsers import (
|
|
|
20
22
|
TempInfo,
|
|
21
23
|
ThumbnailInfo,
|
|
22
24
|
)
|
|
23
|
-
from .tcp_client import FlashForgeTcpClient
|
|
25
|
+
from .tcp_client import FlashForgeTcpClient, FlashForgeTcpClientOptions
|
|
24
26
|
|
|
25
27
|
__all__ = [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
28
|
+
"FlashForgeTcpClient",
|
|
29
|
+
"FlashForgeTcpClientOptions",
|
|
30
|
+
"FlashForgeClient",
|
|
31
|
+
"FlashForgeA3Client",
|
|
32
|
+
"FlashForgeA4Client",
|
|
33
|
+
"GCodes",
|
|
34
|
+
"GCodeController",
|
|
35
|
+
"A3GCodeController",
|
|
36
|
+
"A3BuildVolume",
|
|
37
|
+
"A3PrinterInfo",
|
|
38
|
+
"A3FileEntry",
|
|
39
|
+
"A3Thumbnail",
|
|
40
|
+
"A4BuildVolume",
|
|
41
|
+
"A4PrinterInfo",
|
|
42
|
+
"A4FileEntry",
|
|
43
|
+
"PrinterInfo",
|
|
44
|
+
"TempInfo",
|
|
45
|
+
"TempData",
|
|
46
|
+
"LocationInfo",
|
|
47
|
+
"EndstopStatus",
|
|
48
|
+
"MachineStatus",
|
|
49
|
+
"MoveMode",
|
|
50
|
+
"Status",
|
|
51
|
+
"Endstop",
|
|
52
|
+
"PrintStatus",
|
|
53
|
+
"ThumbnailInfo",
|
|
41
54
|
]
|