woninet 2.0.3__tar.gz → 2.2.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.
Files changed (95) hide show
  1. woninet-2.2.0/PKG-INFO +321 -0
  2. woninet-2.2.0/README.md +292 -0
  3. {woninet-2.0.3 → woninet-2.2.0}/pyproject.toml +7 -2
  4. {woninet-2.0.3 → woninet-2.2.0}/tests/test_alert_events.py +74 -0
  5. woninet-2.2.0/tests/test_api.py +151 -0
  6. woninet-2.2.0/tests/test_arp_lookup.py +36 -0
  7. woninet-2.2.0/tests/test_availability.py +46 -0
  8. woninet-2.2.0/tests/test_system_ping.py +121 -0
  9. {woninet-2.0.3 → woninet-2.2.0}/woninet/__init__.py +1 -1
  10. {woninet-2.0.3 → woninet-2.2.0}/woninet/core/alerts.py +103 -18
  11. {woninet-2.0.3 → woninet-2.2.0}/woninet/core/collectors.py +56 -33
  12. {woninet-2.0.3 → woninet-2.2.0}/woninet/core/engine.py +259 -14
  13. {woninet-2.0.3 → woninet-2.2.0}/woninet/core/manual_ip_enumerator.py +3 -3
  14. {woninet-2.0.3 → woninet-2.2.0}/woninet/core/models.py +25 -11
  15. {woninet-2.0.3 → woninet-2.2.0}/woninet/core/storage.py +103 -2
  16. {woninet-2.0.3 → woninet-2.2.0}/woninet/core/subnet_enumerator.py +1 -1
  17. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/engine.py +1 -1
  18. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/alert_event_repository.py +12 -2
  19. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/alert_state_repository.py +29 -3
  20. woninet-2.2.0/woninet/database/repositories/availability_repository.py +113 -0
  21. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/device_repository.py +31 -4
  22. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/metric_repository.py +1 -1
  23. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/tables.py +25 -4
  24. woninet-2.2.0/woninet/exc.py +2 -0
  25. {woninet-2.0.3 → woninet-2.2.0}/woninet/main.py +5 -1
  26. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/app.py +19 -18
  27. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/dependencies.py +1 -1
  28. woninet-2.2.0/woninet/server/routes/api/alerts.py +29 -0
  29. woninet-2.2.0/woninet/server/routes/api/devices.py +46 -0
  30. woninet-2.2.0/woninet/server/routes/api/settings.py +47 -0
  31. woninet-2.2.0/woninet/server/routes/page/about.py +23 -0
  32. woninet-2.2.0/woninet/server/routes/page/alerts.py +14 -0
  33. woninet-2.2.0/woninet/server/routes/page/settings.py +14 -0
  34. woninet-2.2.0/woninet/server/static/css/about.css +141 -0
  35. woninet-2.2.0/woninet/server/static/css/alerts.css +143 -0
  36. woninet-2.2.0/woninet/server/static/css/device_info.css +274 -0
  37. woninet-2.2.0/woninet/server/static/css/settings.css +142 -0
  38. woninet-2.2.0/woninet/server/static/css/style.css +532 -0
  39. woninet-2.2.0/woninet/server/static/js/alerts.js +118 -0
  40. woninet-2.2.0/woninet/server/static/js/app.js +113 -0
  41. woninet-2.2.0/woninet/server/static/js/device_info.js +289 -0
  42. woninet-2.2.0/woninet/server/static/js/settings.js +248 -0
  43. woninet-2.2.0/woninet/server/templates/about.html +114 -0
  44. woninet-2.2.0/woninet/server/templates/alerts.html +95 -0
  45. woninet-2.2.0/woninet/server/templates/dashboard.html +153 -0
  46. woninet-2.2.0/woninet/server/templates/device_info.html +159 -0
  47. woninet-2.2.0/woninet/server/templates/settings.html +126 -0
  48. {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/arguments.py +2 -2
  49. {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/create_configuration.py +8 -1
  50. woninet-2.2.0/woninet/utilities/detect_gateway.py +66 -0
  51. {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/detect_ip_range.py +1 -1
  52. {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/ip_validator.py +1 -1
  53. woninet-2.2.0/woninet/utilities/ping.py +103 -0
  54. woninet-2.2.0/woninet/utilities/update_configuration.py +33 -0
  55. woninet-2.2.0/woninet.egg-info/PKG-INFO +321 -0
  56. {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/SOURCES.txt +23 -5
  57. {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/requires.txt +3 -1
  58. woninet-2.0.3/PKG-INFO +0 -272
  59. woninet-2.0.3/README.md +0 -245
  60. woninet-2.0.3/tests/test_api.py +0 -10
  61. woninet-2.0.3/woninet/core/graph.py +0 -66
  62. woninet-2.0.3/woninet/server/routes/api/devices.py +0 -43
  63. woninet-2.0.3/woninet/server/static/css/style.css +0 -368
  64. woninet-2.0.3/woninet/server/static/js/app.js +0 -242
  65. woninet-2.0.3/woninet/server/static/js/device_info.js +0 -95
  66. woninet-2.0.3/woninet/server/static/swagger-ui/favicon-32x32.png +0 -0
  67. woninet-2.0.3/woninet/server/static/swagger-ui/swagger-ui-bundle.js +0 -2
  68. woninet-2.0.3/woninet/server/static/swagger-ui/swagger-ui.css +0 -3
  69. woninet-2.0.3/woninet/server/templates/dashboard.html +0 -118
  70. woninet-2.0.3/woninet/server/templates/device_info.html +0 -93
  71. woninet-2.0.3/woninet.egg-info/PKG-INFO +0 -272
  72. {woninet-2.0.3 → woninet-2.2.0}/LICENSE +0 -0
  73. {woninet-2.0.3 → woninet-2.2.0}/setup.cfg +0 -0
  74. {woninet-2.0.3 → woninet-2.2.0}/tests/test_ip_validation.py +0 -0
  75. {woninet-2.0.3 → woninet-2.2.0}/tests/test_storage.py +0 -0
  76. {woninet-2.0.3 → woninet-2.2.0}/woninet/__main__.py +0 -0
  77. {woninet-2.0.3 → woninet-2.2.0}/woninet/core/__init__.py +0 -0
  78. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/__init__.py +0 -0
  79. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/base.py +0 -0
  80. {woninet-2.0.3 → woninet-2.2.0}/woninet/database/repositories/__init__.py +0 -0
  81. {woninet-2.0.3 → woninet-2.2.0}/woninet/logging.yaml +0 -0
  82. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/__init__.py +0 -0
  83. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/__init__.py +0 -0
  84. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/api/__init__.py +0 -0
  85. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/api/stats.py +0 -0
  86. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/page/__init__.py +0 -0
  87. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/routes/page/devices.py +0 -0
  88. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/static/css/404.css +0 -0
  89. {woninet-2.0.3 → woninet-2.2.0}/woninet/server/templates/404.html +0 -0
  90. {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/__init__.py +0 -0
  91. {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/cli_parser.py +0 -0
  92. {woninet-2.0.3 → woninet-2.2.0}/woninet/utilities/logger.py +0 -0
  93. {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/dependency_links.txt +0 -0
  94. {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/entry_points.txt +0 -0
  95. {woninet-2.0.3 → woninet-2.2.0}/woninet.egg-info/top_level.txt +0 -0
woninet-2.2.0/PKG-INFO ADDED
@@ -0,0 +1,321 @@
1
+ Metadata-Version: 2.4
2
+ Name: woninet
3
+ Version: 2.2.0
4
+ Summary: A Python-based ARP+ICMP network monitoring tool
5
+ Author-email: Alireza Teymuri <teymuri.alireza98@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/teymuri-alireza/woninet
8
+ Project-URL: Documentation, https://github.com/teymuri-alireza/woninet/tree/main/docs
9
+ Project-URL: Repository, https://github.com/teymuri-alireza/woninet
10
+ Project-URL: Issues, https://github.com/teymuri-alireza/woninet/issues
11
+ Project-URL: Changelog, https://github.com/teymuri-alireza/woninet/blob/main/CHANGELOG.md
12
+ Keywords: network,network-monitoring,icmp,arp
13
+ Requires-Python: >=3.12
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: icmplib<3.1,>=3.0.4
17
+ Requires-Dist: fastapi<0.137,>=0.136.0
18
+ Requires-Dist: Jinja2<3.2,>=3.1.6
19
+ Requires-Dist: uvicorn<0.45,>=0.44.0
20
+ Requires-Dist: PyYAML<6.1,>=6.0.3
21
+ Requires-Dist: SQLAlchemy<2.1,>=2.0.46
22
+ Requires-Dist: python-multipart==0.0.32
23
+ Requires-Dist: fastapi-swagger<0.5,>=0.4.64
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest<9.2,>=9.1.1; extra == "test"
26
+ Requires-Dist: httpx<0.29,>=0.28.1; extra == "test"
27
+ Requires-Dist: ruff<0.16,>=0.15.11; extra == "test"
28
+ Dynamic: license-file
29
+
30
+ # Woninet
31
+
32
+ [![PyPI version](https://img.shields.io/pypi/v/woninet)](https://pypi.org/project/woninet/)
33
+ [![Python](https://img.shields.io/badge/python-3.12-blue)](https://www.python.org/)
34
+ [![License](https://img.shields.io/pypi/l/woninet)](https://github.com/teymuri-alireza/woninet/blob/main/LICENSE)
35
+ [![Downloads](https://img.shields.io/pypi/dm/woninet)](https://pypi.org/project/woninet/)
36
+
37
+ A local network monitoring system.
38
+
39
+ **Woninet** continuously monitors devices on a local network using ARP and ICMP probes. It enumerates candidate IP addresses in a /24 subnet, determines device availability, measures latency, packet loss, and jitter, stores metrics in database, and evaluates configurable alert rules in real time.
40
+
41
+ ![Woninet dashboard](https://github.com/teymuri-alireza/woninet/blob/dev/public/img/woninet-dasboard.png)
42
+
43
+ ## Table of Contents
44
+
45
+ - [Features](#features)
46
+ - [Requirements](#requirements)
47
+ - [Quick Start](#quick-start)
48
+ - [Installation](#installation)
49
+ - [Configuration](#configuration)
50
+ - [Usage](#usage)
51
+ - [Platform Notes](#platform-notes)
52
+ - [Testing](#testing)
53
+ - [Known Issues](#known-issues)
54
+ - [Documentation](#documentation)
55
+ - [Contributing](#contributing)
56
+ - [License](#license)
57
+
58
+ ## Features
59
+
60
+ - **ARP + ICMP host detection.** Distinguishes real devices from nonexistent IP addresses and filters out Wi-Fi ARP-delay noise.
61
+ - **Alert engine.** Evaluates real-time alert rules, such as latency thresholds, against collected metrics.
62
+ - **Threaded collectors.** Sends ICMP probes concurrently using a configurable number of worker threads.
63
+ - **SQLite storage.** Persists devices, recorded metrics, alert states, and alert events.
64
+ - **Database access from the CLI.** Accepts a positional argument for easier access to the database.
65
+ - **Detailed logging.**
66
+
67
+ ## Requirements
68
+
69
+ - Python 3.12 or later.
70
+ - Elevated network privileges, because ARP and ICMP probing use raw sockets. On Linux, either of the following satisfies this requirement:
71
+ - the `cap_net_raw` capability granted to the Python interpreter (recommended, see [Installation](#installation)), or
72
+ - root privileges (discouraged for security reasons).
73
+
74
+ ## Quick Start
75
+
76
+ On Linux, the minimal path is:
77
+
78
+ ```shell
79
+ python3 -m venv --copies venv
80
+ source venv/bin/activate
81
+ pip install woninet
82
+ sudo setcap cap_net_raw=eip venv/bin/python3
83
+ woninet --help
84
+ ```
85
+
86
+ For Docker, macOS, Windows, and source installs, see [Installation](#installation).
87
+
88
+ ## Installation
89
+
90
+ ### Option 1: Install from PyPI
91
+
92
+ #### Linux (recommended: `icmplib` with `cap_net_raw`)
93
+
94
+ Create and activate a virtual environment. The `--copies` flag forces Python to copy the interpreter instead of symlinking it, which is required because the capability is applied directly to the interpreter binary:
95
+
96
+ ```shell
97
+ python3 -m venv --copies venv
98
+ source venv/bin/activate
99
+ ```
100
+
101
+ Install Woninet:
102
+
103
+ ```shell
104
+ pip install woninet
105
+ ```
106
+
107
+ Grant the required capability to the Python interpreter:
108
+
109
+ ```shell
110
+ sudo setcap cap_net_raw=eip venv/bin/python3
111
+ ```
112
+
113
+ Run Woninet:
114
+
115
+ ```shell
116
+ woninet --help
117
+ ```
118
+
119
+ #### Linux (fallback: system `ping`)
120
+
121
+ If you do not grant the capability, Woninet falls back to the system `ping` command. Create the environment without `--copies`:
122
+
123
+ ```shell
124
+ python3 -m venv venv
125
+ source venv/bin/activate
126
+ pip install woninet
127
+ woninet --help
128
+ ```
129
+
130
+ #### macOS and Windows
131
+
132
+ ```shell
133
+ pip install woninet
134
+ woninet --help
135
+ ```
136
+
137
+ See [Platform Notes](#platform-notes) for privilege considerations on these systems.
138
+
139
+ ### Option 2: Docker (Linux only)
140
+
141
+ Clone the repository and run:
142
+
143
+ ```shell
144
+ chmod +x build_docker.sh
145
+ sudo ./build_docker.sh
146
+ ```
147
+
148
+ The script runs `docker compose up -d --build` and prints the device's private IP address to standard output so you can open the web interface in a browser.
149
+
150
+ To open Woninet manually, type device's private IP address with the default `8080` port in the browser.
151
+
152
+ ### Option 3: Install from source
153
+
154
+ 1. Clone the repository:
155
+
156
+ ```shell
157
+ git clone https://github.com/teymuri-alireza/woninet
158
+ cd woninet
159
+ ```
160
+
161
+ 2. Create and activate a virtual environment **outside** the project directory to avoid `Multiple top-level packages discovered in a flat-layout` errors.
162
+
163
+ Linux
164
+
165
+ ```shell
166
+ python3 -m venv --copies ../venv
167
+ source ../venv/bin/activate
168
+ ```
169
+
170
+ Windows (PowerShell):
171
+
172
+ ```powershell
173
+ py -m venv ..\venv
174
+ ..\venv\Scripts\Activate.ps1
175
+ ```
176
+
177
+ 3. Install Woninet locally:
178
+
179
+ ```shell
180
+ pip3 install .
181
+ ```
182
+
183
+ 4. Grant raw-socket access and run.
184
+
185
+ **Linux:** grant the capability to the virtual environment's interpreter, then run Woninet:
186
+
187
+ ```shell
188
+ sudo setcap cap_net_raw=eip ../venv/bin/python3
189
+ woninet --version
190
+ ```
191
+
192
+ Running with `sudo` instead is possible but discouraged for security reasons:
193
+
194
+ ```shell
195
+ sudo ../venv/bin/python3 -m woninet
196
+ ```
197
+
198
+ **macOS and Windows:** run `woninet --version` after installation.
199
+
200
+ ## Configuration
201
+
202
+ Alert rules and monitoring settings are defined in a JSON file. Rename `config.example.json` to `config.json`; Woninet loads it at startup.
203
+
204
+ When installing from PyPI, `config.example.json` is not included, so Woninet creates a `config.json` file with default values.
205
+
206
+ To use a different configuration file, pass its path with the `--config` CLI flag.
207
+
208
+ ### Example
209
+
210
+ ```json
211
+ {
212
+ "monitoring": {
213
+ "arp_noise_limit": 300.0,
214
+ "max_workers": 4
215
+ },
216
+ "database": "woninet.db",
217
+ "target_ip_list": [
218
+ "192.168.1.1", "192.168.1.10", "192.168.1.20-30"
219
+ ],
220
+ "alert_rules": [
221
+ {
222
+ "metric": "latency",
223
+ "threshold": 100,
224
+ "consecutive_checks": 3
225
+ },
226
+ {
227
+ "metric": "packet_loss",
228
+ "threshold": 0.0,
229
+ "consecutive_checks": 1
230
+ },
231
+ {
232
+ "metric": "jitter",
233
+ "threshold": 40.0,
234
+ "consecutive_checks": 3
235
+ }
236
+ ]
237
+ }
238
+ ```
239
+
240
+ ### Settings reference
241
+
242
+ #### Monitoring
243
+
244
+ | Key | Description |
245
+ |---|---|
246
+ | `arp_noise_limit` | Latency threshold in milliseconds used to filter ARP resolution noise. Set to `0` to disable filtering. Helps eliminate Wi-Fi latency spikes. |
247
+ | `max_workers` | Maximum number of worker threads used to send ICMP pings. Higher values may increase system load and latency. |
248
+
249
+ #### Database
250
+
251
+ | Key | Description |
252
+ |---|---|
253
+ | `database` | Path to the SQLite database file where metrics and alerts are stored. |
254
+
255
+ #### Target IP list
256
+
257
+ | Key | Description |
258
+ |---|---|
259
+ | `target_ip_list` | A single address, a list of addresses, or a range (for example `192.168.1.1-100`) to scan. Monitoring is currently limited to a /24 subnet (see [Known Issues](#known-issues)). |
260
+
261
+ #### Alert rules
262
+
263
+ | Key | Description |
264
+ |---|---|
265
+ | `metric` | The metric to evaluate: `latency`, `packet_loss`, or `jitter`. |
266
+ | `threshold` | The value that triggers the alert. |
267
+ | `consecutive_checks` | Number of consecutive evaluations required before the alert state changes. Higher values reduce false positives. |
268
+
269
+ #### Units and ranges
270
+
271
+ - **Latency:** thresholds are evaluated in milliseconds.
272
+ - **Jitter:** thresholds are evaluated in milliseconds.
273
+ - **Packet loss:** values are percentages in the range 0.0 to 100.0. A value of 100.0 indicates 100% packet loss, and a threshold of 0.0 triggers on any packet loss.
274
+
275
+ ## Usage
276
+
277
+ See the [usage guide](https://github.com/teymuri-alireza/woninet/blob/main/docs/usage.md) for common ways to run Woninet and how to resolve common issues.
278
+
279
+ ## Platform Notes
280
+
281
+ | Platform | Probing method | Privileges |
282
+ |---|---|---|
283
+ | Linux | `icmplib` (recommended) or system `ping` (fallback) | `cap_net_raw` on the interpreter, or root |
284
+ | macOS | Untested | Untested |
285
+ | Windows | Untested | Untested |
286
+
287
+ Woninet has been developed and tested on Linux. macOS and Windows have not been tested, so installation and behavior on those platforms are not guaranteed. Feedback and bug reports from users on these systems are welcome.
288
+
289
+ Docker deployment is available on Linux only.
290
+
291
+ ## Testing
292
+
293
+ Install the optional test dependencies:
294
+
295
+ ```shell
296
+ pip install -e ".[test]"
297
+ ```
298
+
299
+ Then run:
300
+
301
+ ```shell
302
+ pytest
303
+ ```
304
+
305
+ The test suite currently focuses on API behavior and core logic and uses pytest for automated verification.
306
+
307
+ ## Known Issues
308
+
309
+ - Monitoring is currently limited to a single /24 subnet.
310
+
311
+ ## Documentation
312
+
313
+ For questions or clarification, see the [documentation](https://github.com/teymuri-alireza/woninet/blob/main/docs/documentation.md).
314
+
315
+ ## Contributing
316
+
317
+ Thank you for considering a contribution to Woninet. To help maintain code quality, stability, and a predictable release process, please review the [Contributing Guide](https://github.com/teymuri-alireza/woninet/blob/main/CONTRIBUTING.md) before submitting changes.
318
+
319
+ ## License
320
+
321
+ This project is licensed under the terms of the MIT license.
@@ -0,0 +1,292 @@
1
+ # Woninet
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/woninet)](https://pypi.org/project/woninet/)
4
+ [![Python](https://img.shields.io/badge/python-3.12-blue)](https://www.python.org/)
5
+ [![License](https://img.shields.io/pypi/l/woninet)](https://github.com/teymuri-alireza/woninet/blob/main/LICENSE)
6
+ [![Downloads](https://img.shields.io/pypi/dm/woninet)](https://pypi.org/project/woninet/)
7
+
8
+ A local network monitoring system.
9
+
10
+ **Woninet** continuously monitors devices on a local network using ARP and ICMP probes. It enumerates candidate IP addresses in a /24 subnet, determines device availability, measures latency, packet loss, and jitter, stores metrics in database, and evaluates configurable alert rules in real time.
11
+
12
+ ![Woninet dashboard](https://github.com/teymuri-alireza/woninet/blob/dev/public/img/woninet-dasboard.png)
13
+
14
+ ## Table of Contents
15
+
16
+ - [Features](#features)
17
+ - [Requirements](#requirements)
18
+ - [Quick Start](#quick-start)
19
+ - [Installation](#installation)
20
+ - [Configuration](#configuration)
21
+ - [Usage](#usage)
22
+ - [Platform Notes](#platform-notes)
23
+ - [Testing](#testing)
24
+ - [Known Issues](#known-issues)
25
+ - [Documentation](#documentation)
26
+ - [Contributing](#contributing)
27
+ - [License](#license)
28
+
29
+ ## Features
30
+
31
+ - **ARP + ICMP host detection.** Distinguishes real devices from nonexistent IP addresses and filters out Wi-Fi ARP-delay noise.
32
+ - **Alert engine.** Evaluates real-time alert rules, such as latency thresholds, against collected metrics.
33
+ - **Threaded collectors.** Sends ICMP probes concurrently using a configurable number of worker threads.
34
+ - **SQLite storage.** Persists devices, recorded metrics, alert states, and alert events.
35
+ - **Database access from the CLI.** Accepts a positional argument for easier access to the database.
36
+ - **Detailed logging.**
37
+
38
+ ## Requirements
39
+
40
+ - Python 3.12 or later.
41
+ - Elevated network privileges, because ARP and ICMP probing use raw sockets. On Linux, either of the following satisfies this requirement:
42
+ - the `cap_net_raw` capability granted to the Python interpreter (recommended, see [Installation](#installation)), or
43
+ - root privileges (discouraged for security reasons).
44
+
45
+ ## Quick Start
46
+
47
+ On Linux, the minimal path is:
48
+
49
+ ```shell
50
+ python3 -m venv --copies venv
51
+ source venv/bin/activate
52
+ pip install woninet
53
+ sudo setcap cap_net_raw=eip venv/bin/python3
54
+ woninet --help
55
+ ```
56
+
57
+ For Docker, macOS, Windows, and source installs, see [Installation](#installation).
58
+
59
+ ## Installation
60
+
61
+ ### Option 1: Install from PyPI
62
+
63
+ #### Linux (recommended: `icmplib` with `cap_net_raw`)
64
+
65
+ Create and activate a virtual environment. The `--copies` flag forces Python to copy the interpreter instead of symlinking it, which is required because the capability is applied directly to the interpreter binary:
66
+
67
+ ```shell
68
+ python3 -m venv --copies venv
69
+ source venv/bin/activate
70
+ ```
71
+
72
+ Install Woninet:
73
+
74
+ ```shell
75
+ pip install woninet
76
+ ```
77
+
78
+ Grant the required capability to the Python interpreter:
79
+
80
+ ```shell
81
+ sudo setcap cap_net_raw=eip venv/bin/python3
82
+ ```
83
+
84
+ Run Woninet:
85
+
86
+ ```shell
87
+ woninet --help
88
+ ```
89
+
90
+ #### Linux (fallback: system `ping`)
91
+
92
+ If you do not grant the capability, Woninet falls back to the system `ping` command. Create the environment without `--copies`:
93
+
94
+ ```shell
95
+ python3 -m venv venv
96
+ source venv/bin/activate
97
+ pip install woninet
98
+ woninet --help
99
+ ```
100
+
101
+ #### macOS and Windows
102
+
103
+ ```shell
104
+ pip install woninet
105
+ woninet --help
106
+ ```
107
+
108
+ See [Platform Notes](#platform-notes) for privilege considerations on these systems.
109
+
110
+ ### Option 2: Docker (Linux only)
111
+
112
+ Clone the repository and run:
113
+
114
+ ```shell
115
+ chmod +x build_docker.sh
116
+ sudo ./build_docker.sh
117
+ ```
118
+
119
+ The script runs `docker compose up -d --build` and prints the device's private IP address to standard output so you can open the web interface in a browser.
120
+
121
+ To open Woninet manually, type device's private IP address with the default `8080` port in the browser.
122
+
123
+ ### Option 3: Install from source
124
+
125
+ 1. Clone the repository:
126
+
127
+ ```shell
128
+ git clone https://github.com/teymuri-alireza/woninet
129
+ cd woninet
130
+ ```
131
+
132
+ 2. Create and activate a virtual environment **outside** the project directory to avoid `Multiple top-level packages discovered in a flat-layout` errors.
133
+
134
+ Linux
135
+
136
+ ```shell
137
+ python3 -m venv --copies ../venv
138
+ source ../venv/bin/activate
139
+ ```
140
+
141
+ Windows (PowerShell):
142
+
143
+ ```powershell
144
+ py -m venv ..\venv
145
+ ..\venv\Scripts\Activate.ps1
146
+ ```
147
+
148
+ 3. Install Woninet locally:
149
+
150
+ ```shell
151
+ pip3 install .
152
+ ```
153
+
154
+ 4. Grant raw-socket access and run.
155
+
156
+ **Linux:** grant the capability to the virtual environment's interpreter, then run Woninet:
157
+
158
+ ```shell
159
+ sudo setcap cap_net_raw=eip ../venv/bin/python3
160
+ woninet --version
161
+ ```
162
+
163
+ Running with `sudo` instead is possible but discouraged for security reasons:
164
+
165
+ ```shell
166
+ sudo ../venv/bin/python3 -m woninet
167
+ ```
168
+
169
+ **macOS and Windows:** run `woninet --version` after installation.
170
+
171
+ ## Configuration
172
+
173
+ Alert rules and monitoring settings are defined in a JSON file. Rename `config.example.json` to `config.json`; Woninet loads it at startup.
174
+
175
+ When installing from PyPI, `config.example.json` is not included, so Woninet creates a `config.json` file with default values.
176
+
177
+ To use a different configuration file, pass its path with the `--config` CLI flag.
178
+
179
+ ### Example
180
+
181
+ ```json
182
+ {
183
+ "monitoring": {
184
+ "arp_noise_limit": 300.0,
185
+ "max_workers": 4
186
+ },
187
+ "database": "woninet.db",
188
+ "target_ip_list": [
189
+ "192.168.1.1", "192.168.1.10", "192.168.1.20-30"
190
+ ],
191
+ "alert_rules": [
192
+ {
193
+ "metric": "latency",
194
+ "threshold": 100,
195
+ "consecutive_checks": 3
196
+ },
197
+ {
198
+ "metric": "packet_loss",
199
+ "threshold": 0.0,
200
+ "consecutive_checks": 1
201
+ },
202
+ {
203
+ "metric": "jitter",
204
+ "threshold": 40.0,
205
+ "consecutive_checks": 3
206
+ }
207
+ ]
208
+ }
209
+ ```
210
+
211
+ ### Settings reference
212
+
213
+ #### Monitoring
214
+
215
+ | Key | Description |
216
+ |---|---|
217
+ | `arp_noise_limit` | Latency threshold in milliseconds used to filter ARP resolution noise. Set to `0` to disable filtering. Helps eliminate Wi-Fi latency spikes. |
218
+ | `max_workers` | Maximum number of worker threads used to send ICMP pings. Higher values may increase system load and latency. |
219
+
220
+ #### Database
221
+
222
+ | Key | Description |
223
+ |---|---|
224
+ | `database` | Path to the SQLite database file where metrics and alerts are stored. |
225
+
226
+ #### Target IP list
227
+
228
+ | Key | Description |
229
+ |---|---|
230
+ | `target_ip_list` | A single address, a list of addresses, or a range (for example `192.168.1.1-100`) to scan. Monitoring is currently limited to a /24 subnet (see [Known Issues](#known-issues)). |
231
+
232
+ #### Alert rules
233
+
234
+ | Key | Description |
235
+ |---|---|
236
+ | `metric` | The metric to evaluate: `latency`, `packet_loss`, or `jitter`. |
237
+ | `threshold` | The value that triggers the alert. |
238
+ | `consecutive_checks` | Number of consecutive evaluations required before the alert state changes. Higher values reduce false positives. |
239
+
240
+ #### Units and ranges
241
+
242
+ - **Latency:** thresholds are evaluated in milliseconds.
243
+ - **Jitter:** thresholds are evaluated in milliseconds.
244
+ - **Packet loss:** values are percentages in the range 0.0 to 100.0. A value of 100.0 indicates 100% packet loss, and a threshold of 0.0 triggers on any packet loss.
245
+
246
+ ## Usage
247
+
248
+ See the [usage guide](https://github.com/teymuri-alireza/woninet/blob/main/docs/usage.md) for common ways to run Woninet and how to resolve common issues.
249
+
250
+ ## Platform Notes
251
+
252
+ | Platform | Probing method | Privileges |
253
+ |---|---|---|
254
+ | Linux | `icmplib` (recommended) or system `ping` (fallback) | `cap_net_raw` on the interpreter, or root |
255
+ | macOS | Untested | Untested |
256
+ | Windows | Untested | Untested |
257
+
258
+ Woninet has been developed and tested on Linux. macOS and Windows have not been tested, so installation and behavior on those platforms are not guaranteed. Feedback and bug reports from users on these systems are welcome.
259
+
260
+ Docker deployment is available on Linux only.
261
+
262
+ ## Testing
263
+
264
+ Install the optional test dependencies:
265
+
266
+ ```shell
267
+ pip install -e ".[test]"
268
+ ```
269
+
270
+ Then run:
271
+
272
+ ```shell
273
+ pytest
274
+ ```
275
+
276
+ The test suite currently focuses on API behavior and core logic and uses pytest for automated verification.
277
+
278
+ ## Known Issues
279
+
280
+ - Monitoring is currently limited to a single /24 subnet.
281
+
282
+ ## Documentation
283
+
284
+ For questions or clarification, see the [documentation](https://github.com/teymuri-alireza/woninet/blob/main/docs/documentation.md).
285
+
286
+ ## Contributing
287
+
288
+ Thank you for considering a contribution to Woninet. To help maintain code quality, stability, and a predictable release process, please review the [Contributing Guide](https://github.com/teymuri-alireza/woninet/blob/main/CONTRIBUTING.md) before submitting changes.
289
+
290
+ ## License
291
+
292
+ This project is licensed under the terms of the MIT license.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "woninet"
7
- version = "2.0.3"
7
+ version = "2.2.0"
8
8
  description = "A Python-based ARP+ICMP network monitoring tool"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -28,9 +28,13 @@ dependencies = [
28
28
  "uvicorn>=0.44.0,<0.45",
29
29
  "PyYAML>=6.0.3,<6.1",
30
30
  "SQLAlchemy>=2.0.46,<2.1",
31
- "matplotlib>=3.11.0,<3.12",
31
+ "python-multipart==0.0.32",
32
+ "fastapi-swagger>=0.4.64,<0.5",
32
33
  ]
33
34
 
35
+ [tool.setuptools.packages.find]
36
+ include = ["woninet*"]
37
+
34
38
  [tool.setuptools.package-data]
35
39
  woninet = [
36
40
  "server/static/**/*",
@@ -52,4 +56,5 @@ woninet = "woninet.main:main"
52
56
  test = [
53
57
  "pytest>=9.1.1,<9.2",
54
58
  "httpx>=0.28.1,<0.29",
59
+ "ruff>=0.15.11,<0.16",
55
60
  ]