flashforge-python-api 1.2.1__py3-none-any.whl → 1.2.2__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 CHANGED
@@ -127,7 +127,7 @@ from .tcp import (
127
127
  )
128
128
 
129
129
  FiveMClient = FlashForgeClient
130
- __version__ = "1.1.1"
130
+ __version__ = "1.2.2"
131
131
  __author__ = "FlashForge Python API Contributors"
132
132
  __email__ = "notghosttypes@gmail.com"
133
133
  __description__ = "Python library for controlling FlashForge 3D printers"
@@ -12,7 +12,7 @@ from dataclasses import dataclass, field
12
12
  from enum import IntEnum, StrEnum
13
13
  from typing import Any
14
14
 
15
- import netifaces
15
+ import ifaddr
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
@@ -535,26 +535,27 @@ class PrinterDiscovery:
535
535
  broadcast_addresses: list[str] = []
536
536
 
537
537
  try:
538
- for interface_name in netifaces.interfaces():
539
- try:
540
- addresses = netifaces.ifaddresses(interface_name)
541
- if netifaces.AF_INET not in addresses:
538
+ for adapter in ifaddr.get_adapters():
539
+ for ip in adapter.ips:
540
+ if not ip.is_IPv4:
541
+ continue
542
+
543
+ ip_addr = ip.ip
544
+ if not isinstance(ip_addr, str) or ip_addr.startswith("127."):
542
545
  continue
543
546
 
544
- for addr_info in addresses[netifaces.AF_INET]:
545
- if addr_info.get("addr", "").startswith("127."):
546
- continue
547
+ prefix = ip.network_prefix
548
+ if not isinstance(prefix, int) or not 0 < prefix <= 32:
549
+ continue
547
550
 
548
- ip_addr = addr_info.get("addr")
549
- netmask = addr_info.get("netmask")
550
- if not ip_addr or not netmask:
551
- continue
551
+ mask_int = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF
552
+ netmask = ".".join(
553
+ str((mask_int >> (8 * (3 - i))) & 0xFF) for i in range(4)
554
+ )
552
555
 
553
- broadcast = self.calculate_broadcast_address(ip_addr, netmask)
554
- if broadcast and broadcast not in broadcast_addresses:
555
- broadcast_addresses.append(broadcast)
556
- except Exception as error:
557
- logger.warning("Error processing interface %s: %s", interface_name, error)
556
+ broadcast = self.calculate_broadcast_address(ip_addr, netmask)
557
+ if broadcast and broadcast not in broadcast_addresses:
558
+ broadcast_addresses.append(broadcast)
558
559
  except Exception as error:
559
560
  logger.error("Error getting network interfaces: %s", error)
560
561
  broadcast_addresses = ["255.255.255.255", "192.168.1.255", "192.168.0.255"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flashforge-python-api
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: A comprehensive Python library for controlling FlashForge 3D printers
5
5
  Project-URL: Homepage, https://github.com/GhostTypes/ff-5mp-api-py
6
6
  Project-URL: Documentation, https://github.com/GhostTypes/ff-5mp-api-py#readme
@@ -16,12 +16,13 @@ Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
19
20
  Classifier: Topic :: Scientific/Engineering
20
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
22
  Classifier: Topic :: System :: Hardware :: Hardware Drivers
22
23
  Requires-Python: >=3.11
23
24
  Requires-Dist: aiohttp>=3.8.0
24
- Requires-Dist: netifaces>=0.11.0
25
+ Requires-Dist: ifaddr>=0.2.0
25
26
  Requires-Dist: pydantic>=2.0.0
26
27
  Requires-Dist: requests>=2.31.0
27
28
  Provides-Extra: all
@@ -70,14 +71,20 @@ Modern LAN-mode HTTP printers require:
70
71
 
71
72
  - printer IP address
72
73
  - serial number
73
- - check code
74
+ - check code (per-printer credential, not returned by discovery)
74
75
 
75
76
  ```python
76
77
  import asyncio
77
- from flashforge import FlashForgeClient, PrinterDiscovery
78
+ import os
79
+ from flashforge import FlashForgeClient, FiveMClientConnectionOptions, PrinterDiscovery
78
80
 
79
81
 
80
82
  async def main():
83
+ check_code = os.getenv("FLASHFORGE_CHECK_CODE", "").strip()
84
+ if not check_code:
85
+ print("Set FLASHFORGE_CHECK_CODE before running this example")
86
+ return
87
+
81
88
  discovery = PrinterDiscovery()
82
89
  printers = await discovery.discover()
83
90
 
@@ -86,13 +93,23 @@ async def main():
86
93
  return
87
94
 
88
95
  printer = printers[0]
96
+ if not printer.serial_number:
97
+ print("Discovered printer did not report a serial number")
98
+ return
99
+
100
+ options = FiveMClientConnectionOptions(
101
+ http_port=printer.event_port,
102
+ tcp_port=printer.command_port,
103
+ )
89
104
 
90
105
  async with FlashForgeClient(
91
106
  printer.ip_address,
92
- printer.serial_number or "SERIAL_NUMBER",
93
- "CHECK_CODE",
107
+ printer.serial_number,
108
+ check_code,
109
+ options=options,
94
110
  ) as client:
95
- if not await client.initialize():
111
+ status = await client.get_printer_status()
112
+ if not status:
96
113
  return
97
114
 
98
115
  await client.init_control()
@@ -1,4 +1,4 @@
1
- flashforge/__init__.py,sha256=3fmBeEJ4vFJDSsOQV0Yixb1yLyUw8nHDZKQHbXIbtmo,5336
1
+ flashforge/__init__.py,sha256=NjSFURsQlavWjvD6CikOj01SXqpdmGF-PlAHyLXtc-4,5336
2
2
  flashforge/client.py,sha256=lplKJxNOLhUJMusm025cj7rZvWRAiv2j5qENdBIctuA,16920
3
3
  flashforge/api/__init__.py,sha256=vQz-DkG6LTH39bI4fyiUc0D9jQzemLh45pORLptSOlg,335
4
4
  flashforge/api/constants/__init__.py,sha256=Q0HL2tqSBYPd4Oz49VHLS3qUvRuv__GCvTGecaLrQ-Y,163
@@ -19,7 +19,7 @@ flashforge/api/network/__init__.py,sha256=G5fBoAlq-NQPDkWp579mFIqsj0v7B1Lb2TAzO6
19
19
  flashforge/api/network/fnet_code.py,sha256=BR2niVKKk4ZfXtizUDIMXzDhlCxPHzqWg5AQQIcoj3g,402
20
20
  flashforge/api/network/utils.py,sha256=hh-9SGI61ii0CRkLVnAp-Eq2E0a9PAKPyNLMGaYPNsI,2065
21
21
  flashforge/discovery/__init__.py,sha256=G0WiP70EhfHdjXR1RNlv6xjhyHOdo-HWyOm9J0ds4SM,828
22
- flashforge/discovery/discovery.py,sha256=lNyD-nDDdYKV23kUOQpuA5ZX4r9T7_Zk3SzXoUwgMPI,26163
22
+ flashforge/discovery/discovery.py,sha256=ka75bIXnn2a14DEpzpmJxUGajF-tpLHUR2EHA88NIGc,26073
23
23
  flashforge/models/__init__.py,sha256=MNpnXdS6Yah5kSwBB7cbA2Hd-8azffE62pgUrrKSZk4,984
24
24
  flashforge/models/machine_info.py,sha256=t7TJk03PG8kf-g6XnWd3NiWuCVLY1Wuod-aI4zdXu4Y,14976
25
25
  flashforge/models/responses.py,sha256=befMeXAc7XXiK7emF8Ep2cd1GuhZ-zyYPbbPqS2lcQI,7214
@@ -39,8 +39,8 @@ flashforge/tcp/parsers/print_status.py,sha256=4q9ZlJfO0c7_t1o15tgxbguMxpDjEW9pMy
39
39
  flashforge/tcp/parsers/printer_info.py,sha256=QY6LECfcOhVHSIdsvQZwJago0OjXroUwiX0H-uQaH2A,5411
40
40
  flashforge/tcp/parsers/temp_info.py,sha256=9Waf68tt-4QBcChyUwfMHDwWdIzM4mmDpZAKeAzklgs,7908
41
41
  flashforge/tcp/parsers/thumbnail_info.py,sha256=ZmxdEbVFOzqR1AfhXXZyjENVI66BdRdE7Q8LQ8an9FY,10201
42
- flashforge_python_api-1.2.1.dist-info/METADATA,sha256=eMFS4ENMi13-7DADIKwTNTSQyBoFjHrGrLMb_gw4dZw,4194
43
- flashforge_python_api-1.2.1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
44
- flashforge_python_api-1.2.1.dist-info/entry_points.txt,sha256=AkOxlsLvQ7cvMLxn7tlzfKp_DCH2hXhbVceHIXxawpU,66
45
- flashforge_python_api-1.2.1.dist-info/licenses/LICENSE,sha256=-cTA-hrmvlb3pqlQrBZQXUnKayhUjsLJMPb7TD91frM,1067
46
- flashforge_python_api-1.2.1.dist-info/RECORD,,
42
+ flashforge_python_api-1.2.2.dist-info/METADATA,sha256=fgIgmb7nLlupuynCJcbY5V-fF_g4hNI48e9d61Qym0s,4787
43
+ flashforge_python_api-1.2.2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
44
+ flashforge_python_api-1.2.2.dist-info/entry_points.txt,sha256=AkOxlsLvQ7cvMLxn7tlzfKp_DCH2hXhbVceHIXxawpU,66
45
+ flashforge_python_api-1.2.2.dist-info/licenses/LICENSE,sha256=-cTA-hrmvlb3pqlQrBZQXUnKayhUjsLJMPb7TD91frM,1067
46
+ flashforge_python_api-1.2.2.dist-info/RECORD,,