wifi-controller 0.1.0__tar.gz
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.
- wifi_controller-0.1.0/LICENSE +21 -0
- wifi_controller-0.1.0/PKG-INFO +199 -0
- wifi_controller-0.1.0/README.md +174 -0
- wifi_controller-0.1.0/pyproject.toml +48 -0
- wifi_controller-0.1.0/src/wifi_controller/__init__.py +357 -0
- wifi_controller-0.1.0/src/wifi_controller/_abc.py +66 -0
- wifi_controller-0.1.0/src/wifi_controller/_linux.py +170 -0
- wifi_controller-0.1.0/src/wifi_controller/_macos.py +164 -0
- wifi_controller-0.1.0/src/wifi_controller/_swift.py +197 -0
- wifi_controller-0.1.0/src/wifi_controller/_types.py +19 -0
- wifi_controller-0.1.0/src/wifi_controller/py.typed +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 jugglingbear
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: wifi-controller
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Cross-platform Wi-Fi controller with pluggable providers for macOS, Linux, and Windows.
|
|
5
|
+
License: MIT
|
|
6
|
+
Keywords: wifi,wireless,macos,linux,network
|
|
7
|
+
Author: jugglingbear
|
|
8
|
+
Requires-Python: >=3.10,<4.0
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: MacOS
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: System :: Networking
|
|
20
|
+
Requires-Dist: bear-tools (>=0.1.37,<0.2.0)
|
|
21
|
+
Project-URL: Homepage, https://github.com/jugglingbear/wifi_controller
|
|
22
|
+
Project-URL: Repository, https://github.com/jugglingbear/wifi_controller
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# wifi-controller
|
|
26
|
+
|
|
27
|
+
A cross-platform Wi-Fi controller for Python with pluggable provider architecture.
|
|
28
|
+
Supports macOS and Linux out of the box, with an optional Swift-based scanner for
|
|
29
|
+
macOS 15+ where Apple redacts SSIDs without Location Services authorization.
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- **Cross-platform** -- built-in providers for macOS (`networksetup`, `ipconfig`,
|
|
34
|
+
`system_profiler`) and Linux (`nmcli`, `iwgetid`)
|
|
35
|
+
- **Pluggable providers** -- register your own scan/connect/disconnect implementations
|
|
36
|
+
with priority-based resolution
|
|
37
|
+
- **macOS SSID redaction workaround** -- optional Swift scanner (`extras/ssid_scanner/`)
|
|
38
|
+
uses CoreWLAN + CoreLocation to return real SSIDs on macOS 15+
|
|
39
|
+
- **Zero dependencies** -- pure Python, stdlib only
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install wifi-controller
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or with Poetry:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
poetry add wifi-controller
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from wifi_controller import WiFiController
|
|
57
|
+
|
|
58
|
+
wifi = WiFiController()
|
|
59
|
+
|
|
60
|
+
# Get current network
|
|
61
|
+
ssid = wifi.get_current_ssid()
|
|
62
|
+
print(f"Connected to: {ssid}")
|
|
63
|
+
|
|
64
|
+
# Scan nearby networks
|
|
65
|
+
networks = wifi.scan()
|
|
66
|
+
for net in networks:
|
|
67
|
+
print(f" {net.ssid} (RSSI={net.rssi}, CH={net.channel})")
|
|
68
|
+
|
|
69
|
+
# Connect to a network
|
|
70
|
+
wifi.connect("MyNetwork", "hunter2")
|
|
71
|
+
|
|
72
|
+
# Poll for a specific SSID
|
|
73
|
+
found = wifi.scan_for_ssid("MyNetwork", timeout_sec=30)
|
|
74
|
+
|
|
75
|
+
# Disconnect
|
|
76
|
+
wifi.disconnect()
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## macOS 15+ SSID Redaction
|
|
80
|
+
|
|
81
|
+
Starting with macOS 15 (Sequoia), Apple redacts SSID information from
|
|
82
|
+
`system_profiler`, `CoreWLAN`, and other system APIs unless the calling process
|
|
83
|
+
has Location Services authorization via a signed app bundle.
|
|
84
|
+
|
|
85
|
+
The built-in Python providers **cannot** work around this limitation. To get
|
|
86
|
+
real SSIDs on macOS 15+, build the Swift scanner from `extras/ssid_scanner/`:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Prerequisites: Xcode Command Line Tools + Apple Development certificate
|
|
90
|
+
make -C extras/ssid_scanner check # verify prerequisites
|
|
91
|
+
make -C extras/ssid_scanner all # build and sign
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Then register the Swift providers:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from wifi_controller import WiFiController
|
|
98
|
+
from wifi_controller._swift import (
|
|
99
|
+
SwiftSsidScannerCurrentSSID,
|
|
100
|
+
SwiftSsidScannerScan,
|
|
101
|
+
SwiftSsidScannerConnect,
|
|
102
|
+
SwiftSsidScannerDisconnect,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
wifi = WiFiController()
|
|
106
|
+
binary = "extras/ssid_scanner/ssid_scanner" # path to built binary
|
|
107
|
+
|
|
108
|
+
wifi.register_scan_provider(SwiftSsidScannerScan(binary), priority=10)
|
|
109
|
+
wifi.register_current_ssid_provider(SwiftSsidScannerCurrentSSID(binary), priority=10)
|
|
110
|
+
wifi.register_connect_provider(SwiftSsidScannerConnect(binary), priority=10)
|
|
111
|
+
wifi.register_disconnect_provider(SwiftSsidScannerDisconnect(binary), priority=10)
|
|
112
|
+
|
|
113
|
+
# Now scan() returns real SSIDs on macOS 15+
|
|
114
|
+
networks = wifi.scan()
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Custom Providers
|
|
118
|
+
|
|
119
|
+
Implement any of the four provider ABCs to add support for additional tools:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from wifi_controller import WiFiController, SSIDScanProvider, SSIDInfo
|
|
123
|
+
|
|
124
|
+
class MyCustomScanner(SSIDScanProvider):
|
|
125
|
+
@property
|
|
126
|
+
def name(self) -> str:
|
|
127
|
+
return "my_scanner"
|
|
128
|
+
|
|
129
|
+
def is_available(self) -> bool:
|
|
130
|
+
return True # check if your tool is installed
|
|
131
|
+
|
|
132
|
+
def scan_ssids(self, interface: str, timeout: int = 15) -> list[SSIDInfo]:
|
|
133
|
+
# ... your implementation ...
|
|
134
|
+
return [SSIDInfo(ssid="Example", bssid="00:11:22:33:44:55", rssi=-42, channel=6)]
|
|
135
|
+
|
|
136
|
+
wifi = WiFiController()
|
|
137
|
+
wifi.register_scan_provider(MyCustomScanner(), priority=20)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Provider ABCs:
|
|
141
|
+
|
|
142
|
+
| ABC | Operation |
|
|
143
|
+
|-----|-----------|
|
|
144
|
+
| `CurrentSSIDProvider` | Get the currently-connected SSID |
|
|
145
|
+
| `SSIDScanProvider` | Scan for nearby networks |
|
|
146
|
+
| `SSIDConnectProvider` | Connect to a network (SSID + password) |
|
|
147
|
+
| `SSIDDisconnectProvider` | Disconnect from the current network |
|
|
148
|
+
|
|
149
|
+
Higher priority providers are tried first. The first provider whose
|
|
150
|
+
`is_available()` returns `True` is used and cached for subsequent calls.
|
|
151
|
+
|
|
152
|
+
## Project Layout
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
wifi_controller/
|
|
156
|
+
├── src/wifi_controller/ # Python package (ships on PyPI)
|
|
157
|
+
│ ├── __init__.py # WiFiController orchestrator
|
|
158
|
+
│ ├── _types.py # SSIDInfo, WiFiConnectionError
|
|
159
|
+
│ ├── _abc.py # Four provider ABCs
|
|
160
|
+
│ ├── _macos.py # Built-in macOS providers
|
|
161
|
+
│ ├── _linux.py # Built-in Linux providers
|
|
162
|
+
│ └── _swift.py # Python wrappers for Swift binary
|
|
163
|
+
├── extras/ssid_scanner/ # Swift source (not on PyPI, clone to use)
|
|
164
|
+
│ ├── scan.swift # CoreWLAN + CoreLocation scanner
|
|
165
|
+
│ ├── Makefile # Build, sign, test
|
|
166
|
+
│ └── *.plist # App bundle configuration
|
|
167
|
+
├── docs/ # Architecture diagrams (PlantUML)
|
|
168
|
+
└── tests/ # Unit tests
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Architecture
|
|
172
|
+
|
|
173
|
+
See [docs/](docs/) for PlantUML diagrams covering:
|
|
174
|
+
|
|
175
|
+
- **Class diagram** -- provider ABCs, WiFiController, built-in implementations
|
|
176
|
+
- **Sequence diagram** -- provider resolution and operation flow
|
|
177
|
+
- **Component diagram** -- package structure and platform boundaries
|
|
178
|
+
|
|
179
|
+
## Development
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Install dev dependencies
|
|
183
|
+
poetry install
|
|
184
|
+
|
|
185
|
+
# Run tests
|
|
186
|
+
poetry run pytest
|
|
187
|
+
|
|
188
|
+
# Lint
|
|
189
|
+
poetry run ruff check src/ tests/
|
|
190
|
+
|
|
191
|
+
# Format
|
|
192
|
+
poetry run ruff format src/ tests/
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT -- see [LICENSE](LICENSE).
|
|
198
|
+
|
|
199
|
+
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# wifi-controller
|
|
2
|
+
|
|
3
|
+
A cross-platform Wi-Fi controller for Python with pluggable provider architecture.
|
|
4
|
+
Supports macOS and Linux out of the box, with an optional Swift-based scanner for
|
|
5
|
+
macOS 15+ where Apple redacts SSIDs without Location Services authorization.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Cross-platform** -- built-in providers for macOS (`networksetup`, `ipconfig`,
|
|
10
|
+
`system_profiler`) and Linux (`nmcli`, `iwgetid`)
|
|
11
|
+
- **Pluggable providers** -- register your own scan/connect/disconnect implementations
|
|
12
|
+
with priority-based resolution
|
|
13
|
+
- **macOS SSID redaction workaround** -- optional Swift scanner (`extras/ssid_scanner/`)
|
|
14
|
+
uses CoreWLAN + CoreLocation to return real SSIDs on macOS 15+
|
|
15
|
+
- **Zero dependencies** -- pure Python, stdlib only
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install wifi-controller
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or with Poetry:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
poetry add wifi-controller
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from wifi_controller import WiFiController
|
|
33
|
+
|
|
34
|
+
wifi = WiFiController()
|
|
35
|
+
|
|
36
|
+
# Get current network
|
|
37
|
+
ssid = wifi.get_current_ssid()
|
|
38
|
+
print(f"Connected to: {ssid}")
|
|
39
|
+
|
|
40
|
+
# Scan nearby networks
|
|
41
|
+
networks = wifi.scan()
|
|
42
|
+
for net in networks:
|
|
43
|
+
print(f" {net.ssid} (RSSI={net.rssi}, CH={net.channel})")
|
|
44
|
+
|
|
45
|
+
# Connect to a network
|
|
46
|
+
wifi.connect("MyNetwork", "hunter2")
|
|
47
|
+
|
|
48
|
+
# Poll for a specific SSID
|
|
49
|
+
found = wifi.scan_for_ssid("MyNetwork", timeout_sec=30)
|
|
50
|
+
|
|
51
|
+
# Disconnect
|
|
52
|
+
wifi.disconnect()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## macOS 15+ SSID Redaction
|
|
56
|
+
|
|
57
|
+
Starting with macOS 15 (Sequoia), Apple redacts SSID information from
|
|
58
|
+
`system_profiler`, `CoreWLAN`, and other system APIs unless the calling process
|
|
59
|
+
has Location Services authorization via a signed app bundle.
|
|
60
|
+
|
|
61
|
+
The built-in Python providers **cannot** work around this limitation. To get
|
|
62
|
+
real SSIDs on macOS 15+, build the Swift scanner from `extras/ssid_scanner/`:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Prerequisites: Xcode Command Line Tools + Apple Development certificate
|
|
66
|
+
make -C extras/ssid_scanner check # verify prerequisites
|
|
67
|
+
make -C extras/ssid_scanner all # build and sign
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then register the Swift providers:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from wifi_controller import WiFiController
|
|
74
|
+
from wifi_controller._swift import (
|
|
75
|
+
SwiftSsidScannerCurrentSSID,
|
|
76
|
+
SwiftSsidScannerScan,
|
|
77
|
+
SwiftSsidScannerConnect,
|
|
78
|
+
SwiftSsidScannerDisconnect,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
wifi = WiFiController()
|
|
82
|
+
binary = "extras/ssid_scanner/ssid_scanner" # path to built binary
|
|
83
|
+
|
|
84
|
+
wifi.register_scan_provider(SwiftSsidScannerScan(binary), priority=10)
|
|
85
|
+
wifi.register_current_ssid_provider(SwiftSsidScannerCurrentSSID(binary), priority=10)
|
|
86
|
+
wifi.register_connect_provider(SwiftSsidScannerConnect(binary), priority=10)
|
|
87
|
+
wifi.register_disconnect_provider(SwiftSsidScannerDisconnect(binary), priority=10)
|
|
88
|
+
|
|
89
|
+
# Now scan() returns real SSIDs on macOS 15+
|
|
90
|
+
networks = wifi.scan()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Custom Providers
|
|
94
|
+
|
|
95
|
+
Implement any of the four provider ABCs to add support for additional tools:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from wifi_controller import WiFiController, SSIDScanProvider, SSIDInfo
|
|
99
|
+
|
|
100
|
+
class MyCustomScanner(SSIDScanProvider):
|
|
101
|
+
@property
|
|
102
|
+
def name(self) -> str:
|
|
103
|
+
return "my_scanner"
|
|
104
|
+
|
|
105
|
+
def is_available(self) -> bool:
|
|
106
|
+
return True # check if your tool is installed
|
|
107
|
+
|
|
108
|
+
def scan_ssids(self, interface: str, timeout: int = 15) -> list[SSIDInfo]:
|
|
109
|
+
# ... your implementation ...
|
|
110
|
+
return [SSIDInfo(ssid="Example", bssid="00:11:22:33:44:55", rssi=-42, channel=6)]
|
|
111
|
+
|
|
112
|
+
wifi = WiFiController()
|
|
113
|
+
wifi.register_scan_provider(MyCustomScanner(), priority=20)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Provider ABCs:
|
|
117
|
+
|
|
118
|
+
| ABC | Operation |
|
|
119
|
+
|-----|-----------|
|
|
120
|
+
| `CurrentSSIDProvider` | Get the currently-connected SSID |
|
|
121
|
+
| `SSIDScanProvider` | Scan for nearby networks |
|
|
122
|
+
| `SSIDConnectProvider` | Connect to a network (SSID + password) |
|
|
123
|
+
| `SSIDDisconnectProvider` | Disconnect from the current network |
|
|
124
|
+
|
|
125
|
+
Higher priority providers are tried first. The first provider whose
|
|
126
|
+
`is_available()` returns `True` is used and cached for subsequent calls.
|
|
127
|
+
|
|
128
|
+
## Project Layout
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
wifi_controller/
|
|
132
|
+
├── src/wifi_controller/ # Python package (ships on PyPI)
|
|
133
|
+
│ ├── __init__.py # WiFiController orchestrator
|
|
134
|
+
│ ├── _types.py # SSIDInfo, WiFiConnectionError
|
|
135
|
+
│ ├── _abc.py # Four provider ABCs
|
|
136
|
+
│ ├── _macos.py # Built-in macOS providers
|
|
137
|
+
│ ├── _linux.py # Built-in Linux providers
|
|
138
|
+
│ └── _swift.py # Python wrappers for Swift binary
|
|
139
|
+
├── extras/ssid_scanner/ # Swift source (not on PyPI, clone to use)
|
|
140
|
+
│ ├── scan.swift # CoreWLAN + CoreLocation scanner
|
|
141
|
+
│ ├── Makefile # Build, sign, test
|
|
142
|
+
│ └── *.plist # App bundle configuration
|
|
143
|
+
├── docs/ # Architecture diagrams (PlantUML)
|
|
144
|
+
└── tests/ # Unit tests
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Architecture
|
|
148
|
+
|
|
149
|
+
See [docs/](docs/) for PlantUML diagrams covering:
|
|
150
|
+
|
|
151
|
+
- **Class diagram** -- provider ABCs, WiFiController, built-in implementations
|
|
152
|
+
- **Sequence diagram** -- provider resolution and operation flow
|
|
153
|
+
- **Component diagram** -- package structure and platform boundaries
|
|
154
|
+
|
|
155
|
+
## Development
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Install dev dependencies
|
|
159
|
+
poetry install
|
|
160
|
+
|
|
161
|
+
# Run tests
|
|
162
|
+
poetry run pytest
|
|
163
|
+
|
|
164
|
+
# Lint
|
|
165
|
+
poetry run ruff check src/ tests/
|
|
166
|
+
|
|
167
|
+
# Format
|
|
168
|
+
poetry run ruff format src/ tests/
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
MIT -- see [LICENSE](LICENSE).
|
|
174
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["poetry-core>=1.0.0"]
|
|
3
|
+
build-backend = "poetry.core.masonry.api"
|
|
4
|
+
|
|
5
|
+
[tool.poetry]
|
|
6
|
+
name = "wifi-controller"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Cross-platform Wi-Fi controller with pluggable providers for macOS, Linux, and Windows."
|
|
9
|
+
authors = ["jugglingbear"]
|
|
10
|
+
license = "MIT"
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
homepage = "https://github.com/jugglingbear/wifi_controller"
|
|
13
|
+
repository = "https://github.com/jugglingbear/wifi_controller"
|
|
14
|
+
keywords = ["wifi", "wireless", "macos", "linux", "network"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: MacOS",
|
|
20
|
+
"Operating System :: POSIX :: Linux",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: System :: Networking",
|
|
27
|
+
]
|
|
28
|
+
packages = [{ include = "wifi_controller", from = "src" }]
|
|
29
|
+
|
|
30
|
+
[tool.poetry.dependencies]
|
|
31
|
+
python = ">=3.10,<4.0"
|
|
32
|
+
bear-tools = "^0.1.37"
|
|
33
|
+
|
|
34
|
+
[tool.poetry.group.dev.dependencies]
|
|
35
|
+
pytest = ">=7.0"
|
|
36
|
+
pytest-cov = ">=4.0"
|
|
37
|
+
ruff = ">=0.4"
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
testpaths = ["tests"]
|
|
41
|
+
|
|
42
|
+
[tool.ruff]
|
|
43
|
+
target-version = "py310"
|
|
44
|
+
line-length = 120
|
|
45
|
+
src = ["src"]
|
|
46
|
+
|
|
47
|
+
[tool.ruff.lint]
|
|
48
|
+
select = ["E", "F", "W", "I", "UP", "B", "SIM"]
|