ipmg 4.0.0b1__tar.gz → 4.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 (116) hide show
  1. ipmg-4.2.0/PKG-INFO +275 -0
  2. ipmg-4.2.0/README.md +220 -0
  3. {ipmg-4.0.0b1 → ipmg-4.2.0}/pyproject.toml +21 -7
  4. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/__init__.py +1 -1
  5. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/cli/commands.py +21 -14
  6. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/cli/completion.py +10 -10
  7. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/cli/config.py +62 -23
  8. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/cli/parser.py +92 -3
  9. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/cron.py +8 -11
  10. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/diff.py +199 -42
  11. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/discovery.py +14 -15
  12. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/engine.py +19 -18
  13. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/health.py +3 -3
  14. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/httpcheck.py +15 -15
  15. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/neighbours.py +21 -21
  16. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/ping.py +5 -9
  17. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/portscan.py +11 -11
  18. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/security.py +1 -1
  19. ipmg-4.2.0/src/ipmg/core/snmp/__init__.py +57 -0
  20. ipmg-4.2.0/src/ipmg/core/snmp/ber.py +265 -0
  21. ipmg-4.2.0/src/ipmg/core/snmp/client.py +543 -0
  22. ipmg-4.2.0/src/ipmg/core/snmp/poller.py +331 -0
  23. ipmg-4.2.0/src/ipmg/core/snmp/usm.py +152 -0
  24. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/infrastructure/database.py +200 -42
  25. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/infrastructure/file_io.py +165 -2
  26. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/infrastructure/incremental.py +28 -27
  27. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/infrastructure/notify.py +27 -25
  28. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/infrastructure/retention.py +19 -17
  29. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/reporting/diff_report.py +8 -8
  30. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/reporting/frames.py +11 -10
  31. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/reporting/live.py +6 -5
  32. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/reporting/machine.py +4 -4
  33. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/reporting/metrics.py +7 -7
  34. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/reporting/summary.py +72 -3
  35. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/reporting/ui.py +19 -11
  36. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/services/history_service.py +17 -12
  37. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/services/scan_service.py +119 -33
  38. ipmg-4.2.0/src/ipmg/services/snmp_settings.py +147 -0
  39. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/utils/helpers.py +7 -8
  40. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/app.py +74 -54
  41. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/manager.py +10 -10
  42. ipmg-4.2.0/src/ipmg/web/network.py +242 -0
  43. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/scheduler.py +10 -9
  44. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/schemas.py +88 -51
  45. ipmg-4.2.0/src/ipmg/web/server.py +163 -0
  46. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/static/css/app.css +2 -0
  47. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/static/index.html +2 -2
  48. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/static/js/api.js +2 -1
  49. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/static/js/app.js +2 -2
  50. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/static/js/demo.js +16 -1
  51. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/static/js/views.js +148 -9
  52. ipmg-4.2.0/src/ipmg.egg-info/PKG-INFO +275 -0
  53. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg.egg-info/SOURCES.txt +11 -0
  54. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg.egg-info/requires.txt +6 -2
  55. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_api_contract.py +7 -7
  56. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_commands.py +1 -0
  57. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_httpcheck.py +1 -0
  58. ipmg-4.2.0/tests/test_snmp.py +546 -0
  59. ipmg-4.2.0/tests/test_snmp_agents.py +291 -0
  60. ipmg-4.2.0/tests/test_snmp_scan.py +516 -0
  61. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_web_api.py +37 -10
  62. ipmg-4.2.0/tests/test_web_network.py +263 -0
  63. ipmg-4.0.0b1/PKG-INFO +0 -1100
  64. ipmg-4.0.0b1/README.md +0 -1048
  65. ipmg-4.0.0b1/src/ipmg/web/server.py +0 -117
  66. ipmg-4.0.0b1/src/ipmg.egg-info/PKG-INFO +0 -1100
  67. {ipmg-4.0.0b1 → ipmg-4.2.0}/LICENSE +0 -0
  68. {ipmg-4.0.0b1 → ipmg-4.2.0}/setup.cfg +0 -0
  69. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/__main__.py +0 -0
  70. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/cli/__init__.py +0 -0
  71. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/__init__.py +0 -0
  72. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/core/wake.py +0 -0
  73. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/data/oui.tsv.gz +0 -0
  74. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/exceptions.py +0 -0
  75. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/infrastructure/__init__.py +0 -0
  76. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/reporting/__init__.py +0 -0
  77. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/services/__init__.py +0 -0
  78. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/utils/__init__.py +0 -0
  79. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/__init__.py +0 -0
  80. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/db.py +0 -0
  81. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg/web/static/js/charts.js +0 -0
  82. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg.egg-info/dependency_links.txt +0 -0
  83. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg.egg-info/entry_points.txt +0 -0
  84. {ipmg-4.0.0b1 → ipmg-4.2.0}/src/ipmg.egg-info/top_level.txt +0 -0
  85. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_completion.py +0 -0
  86. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_config.py +0 -0
  87. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_contrib.py +0 -0
  88. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_database_history.py +0 -0
  89. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_diff.py +0 -0
  90. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_diff_report.py +0 -0
  91. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_discover.py +0 -0
  92. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_engine.py +0 -0
  93. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_file_io.py +0 -0
  94. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_health.py +0 -0
  95. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_history_service.py +0 -0
  96. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_incremental.py +0 -0
  97. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_ipv6.py +0 -0
  98. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_live.py +0 -0
  99. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_machine_output.py +0 -0
  100. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_metrics.py +0 -0
  101. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_neighbours.py +0 -0
  102. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_notify.py +0 -0
  103. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_parser.py +0 -0
  104. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_ping.py +0 -0
  105. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_ping_command.py +0 -0
  106. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_portscan.py +0 -0
  107. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_retention.py +0 -0
  108. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_scan_service.py +0 -0
  109. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_schedules.py +0 -0
  110. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_tcp_probe.py +0 -0
  111. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_ui.py +0 -0
  112. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_utils.py +0 -0
  113. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_wake.py +0 -0
  114. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_web_db.py +0 -0
  115. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_web_manager.py +0 -0
  116. {ipmg-4.0.0b1 → ipmg-4.2.0}/tests/test_web_server.py +0 -0
ipmg-4.2.0/PKG-INFO ADDED
@@ -0,0 +1,275 @@
1
+ Metadata-Version: 2.4
2
+ Name: ipmg
3
+ Version: 4.2.0
4
+ Summary: Network discovery and change detection: ping sweeps, scan history, and reports for what changed on your network
5
+ Author: Sameer Alam
6
+ Maintainer-email: Sameer Alam <sameeralam3127@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://sameeralam3127.github.io/ipmg/
9
+ Project-URL: Documentation, https://github.com/sameeralam3127/ipmg#readme
10
+ Project-URL: Repository, https://github.com/sameeralam3127/ipmg
11
+ Project-URL: Issues, https://github.com/sameeralam3127/ipmg/issues
12
+ Project-URL: Changelog, https://github.com/sameeralam3127/ipmg/releases
13
+ Keywords: ip,network,ping,monitoring,cli,port-scan,network-scanner,ping-sweep,subnet-scanner,homelab,sysadmin
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Internet
22
+ Classifier: Topic :: System :: Networking
23
+ Classifier: Topic :: System :: Monitoring
24
+ Classifier: Intended Audience :: System Administrators
25
+ Classifier: Intended Audience :: Information Technology
26
+ Classifier: Operating System :: OS Independent
27
+ Classifier: Environment :: Console
28
+ Requires-Python: >=3.10
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: openpyxl>=3.1
32
+ Requires-Dist: rich>=13.0
33
+ Requires-Dist: tomli>=2.0.1; python_version < "3.11"
34
+ Provides-Extra: web
35
+ Requires-Dist: fastapi>=0.110; extra == "web"
36
+ Requires-Dist: pydantic>=2.7; extra == "web"
37
+ Requires-Dist: uvicorn>=0.27; extra == "web"
38
+ Requires-Dist: websockets>=12; extra == "web"
39
+ Requires-Dist: python-multipart>=0.0.9; extra == "web"
40
+ Provides-Extra: snmp
41
+ Requires-Dist: cryptography>=42; extra == "snmp"
42
+ Provides-Extra: all
43
+ Requires-Dist: ipmg[snmp,web]; extra == "all"
44
+ Provides-Extra: dev
45
+ Requires-Dist: ipmg[snmp,web]; extra == "dev"
46
+ Requires-Dist: pytest>=7.4; extra == "dev"
47
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
48
+ Requires-Dist: ruff>=0.4; extra == "dev"
49
+ Requires-Dist: mypy>=1.10; extra == "dev"
50
+ Requires-Dist: pre-commit>=3.5.0; extra == "dev"
51
+ Requires-Dist: python-semantic-release>=10.5.3; extra == "dev"
52
+ Requires-Dist: httpx>=0.27; extra == "dev"
53
+ Requires-Dist: httpx2>=2.0; extra == "dev"
54
+ Dynamic: license-file
55
+
56
+ <p align="center">
57
+ <img src="https://raw.githubusercontent.com/sameeralam3127/ipmg/main/docs/assets/ipmg-logo.svg" alt="" width="88">
58
+ </p>
59
+
60
+ <h1 align="center">IPMG</h1>
61
+
62
+ <p align="center">
63
+ <b>IP Management &amp; Ping Monitoring Tool</b><br>
64
+ Know what changed on your network since the last scan.
65
+ </p>
66
+
67
+ <p align="center">
68
+ <a href="https://pypi.org/project/ipmg/"><img src="https://img.shields.io/github/v/release/sameeralam3127/ipmg?label=pypi" alt="PyPI"></a>
69
+ <a href="https://pypi.org/project/ipmg/"><img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python Version"></a>
70
+ <a href="https://github.com/sameeralam3127/ipmg/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License"></a>
71
+ <a href="https://github.com/sameeralam3127/ipmg/actions/workflows/publish.yml"><img src="https://github.com/sameeralam3127/ipmg/actions/workflows/publish.yml/badge.svg" alt="Publish"></a>
72
+ </p>
73
+
74
+ <p align="center">
75
+ <a href="https://sameeralam3127.github.io/ipmg/"><b>Website</b></a>
76
+ &nbsp;·&nbsp;
77
+ <a href="https://sameeralam3127.github.io/ipmg/demo/"><b>Live demo</b></a>
78
+ &nbsp;·&nbsp;
79
+ <a href="https://sameeralam3127.github.io/ipmg/#builder"><b>Command builder</b></a>
80
+ &nbsp;·&nbsp;
81
+ <a href="https://github.com/sameeralam3127/ipmg#documentation"><b>Docs</b></a>
82
+ </p>
83
+
84
+ <p align="center">
85
+ <img src="https://raw.githubusercontent.com/sameeralam3127/ipmg/main/docs/assets/ipmg-compare.gif" alt="ipmg scans 13 hosts with --stream, printing each one as it answers; a new address is added to the target file; a second scan with --compare reports it as a new host (warning) against the first" width="820">
86
+ </p>
87
+
88
+ IPMG sweeps IPs, CIDR blocks, and ranges in parallel, remembers every scan, and
89
+ tells you what changed since the last one: hosts that went down or appeared, a
90
+ new MAC address or hostname behind an address, slower replies, a web service
91
+ that started failing. Only the changes that matter reach Slack, Teams, a
92
+ webhook, or email, or fail your cron job or CI step.
93
+
94
+ ## Features
95
+
96
+ - **Fast, without root.** IPv4 and IPv6, CIDR blocks, ranges, and target
97
+ files (text, CSV, Excel, JSON), many hosts at a time, using your system's own
98
+ `ping`.
99
+ - **Finds hosts that block ping** with TCP probes (`--probe icmp,tcp`), and
100
+ checks web services (`--http-check`: status, response time, TLS, certificate
101
+ expiry).
102
+ - **Names every device** by reverse DNS and, on your LAN, by MAC address
103
+ and vendor (`--mac`). Wakes them with Wake-on-LAN (`ipmg wake`).
104
+ - **Tells you what changed** since the last scan, with a severity for each
105
+ change, and alerts Slack, Teams, webhooks, or email.
106
+ - **Made for automation:** exit codes for cron and CI, a GitHub Action,
107
+ `--json` for scripts, systemd and launchd templates, Prometheus metrics.
108
+ - **IPMG Web**, a local dashboard: live scans, history, changes, inventory,
109
+ and scheduled scans.
110
+ - **Reports** in Excel, CSV, JSON, JSON Lines, and Markdown, written as the
111
+ scan runs, so an interrupted scan keeps its results.
112
+
113
+ [How IPMG compares](https://github.com/sameeralam3127/ipmg/blob/main/docs/COMPARISON.md)
114
+ with nmap, fping, and Uptime Kuma.
115
+
116
+ ## Install
117
+
118
+ ```bash
119
+ # Linux and macOS, no Python needed
120
+ curl -sSL https://raw.githubusercontent.com/sameeralam3127/ipmg/main/install.sh | bash
121
+ ```
122
+
123
+ ```powershell
124
+ # Windows, no administrator rights
125
+ irm https://raw.githubusercontent.com/sameeralam3127/ipmg/main/install.ps1 | iex
126
+ ```
127
+
128
+ Or from PyPI, with Python 3.10 or newer:
129
+
130
+ ```bash
131
+ # With pip, in a virtual environment
132
+ pip install ipmg # the command line
133
+ pip install "ipmg[web]" # the command line and IPMG Web, the browser dashboard
134
+ ```
135
+
136
+ ```bash
137
+ # With pipx
138
+ pipx install "ipmg[web]"
139
+ ```
140
+
141
+ ```bash
142
+ # With uv, which fetches Python 3.10+ if you need it
143
+ uv tool install --python ">=3.10" "ipmg[web]"
144
+ ```
145
+
146
+ Also on:
147
+
148
+ - **Homebrew:** `brew install sameeralam3127/tap/ipmg`
149
+ - **Docker:** `docker run --rm sameeralam3127/ipmg --input 10.0.0.0/24`, or from GHCR: `ghcr.io/sameeralam3127/ipmg`
150
+
151
+ > **Tip:** `[web]` adds IPMG Web; `pip install ipmg` alone is the command line.
152
+ > Where the system Python is older than 3.10 (RHEL 9, Ubuntu 20.04, SLES 15),
153
+ > pip and pipx quietly install an older IPMG: use the installer or uv there. The
154
+ > [install guide](https://github.com/sameeralam3127/ipmg/blob/main/docs/INSTALL.md)
155
+ > covers version pinning, upgrading from 3.x, and tab completion.
156
+
157
+ ## Quick start
158
+
159
+ ```bash
160
+ ipmg --discover # scan the network you are on, right now
161
+ ipmg --discover --compare # later: scan again and see what changed
162
+ ipmg web --lan # open the dashboard from any machine on your network
163
+ ```
164
+
165
+ Every scan is saved to a local history (`~/.ipmg/dashboard.db`), so
166
+ `--compare` always has the previous scan to compare with.
167
+
168
+ <details>
169
+ <summary>What a scan prints</summary>
170
+
171
+ ```text
172
+ ipmg X.Y.Z · scan
173
+ ICMP probes only — scan only networks you are authorized to scan.
174
+
175
+ Source 192.168.1.0/24
176
+ Targets 254 hosts
177
+ Config 50 threads · 2s timeout · 1 ping
178
+
179
+ Results
180
+ ● Active 12 ━─────────────────────── 4.7%
181
+ ● Timeout 242 ━━━━━━━━━━━━━━━━━━━━━━━━ 95.3%
182
+
183
+ 254 hosts · 4.7% active · 3.1 ms avg · 5.21s · 2026-10-18 09:15:02
184
+
185
+ Saved results_20261018_091502.xlsx
186
+ ```
187
+
188
+ </details>
189
+
190
+ > **Note:** only scan networks you are authorized to scan. Unauthorized scanning
191
+ > may violate your organization's policies or the law.
192
+
193
+ ## Common tasks
194
+
195
+ | I want to… | Command |
196
+ | --- | --- |
197
+ | Scan the network I am on | `ipmg --discover` |
198
+ | Scan hosts listed in a file, plus a few more | `ipmg --input targets.txt 10.0.0.5` |
199
+ | See what changed since last time | `ipmg --input targets.txt --compare` |
200
+ | Get alerted when something changes | `ipmg --input targets.txt --interval 15 --notify-slack` |
201
+ | Find hosts that block ping | `ipmg --input 10.0.0.0/24 --probe icmp,tcp` |
202
+ | Know which device each address is | `ipmg --discover --resolve --mac` |
203
+ | Check that a web service works | `ipmg --http-check https://intranet.example.com/` |
204
+ | Watch switches and routers: reboots, interfaces going down | `ipmg --input switches.txt --snmp --compare` |
205
+ | See which services are listening | `ipmg --input targets.txt --scan-ports` |
206
+ | Get a report I can send to someone | `ipmg --input targets.txt --formats md csv` |
207
+ | Pipe the results into a script | `ipmg --input targets.txt --json \| jq .` |
208
+ | Fail a cron job or CI step when hosts are down | `ipmg --input servers.txt --fail-on-down` |
209
+ | Wake a machine | `ipmg wake AA:BB:CC:DD:EE:FF` |
210
+ | Use the dashboard from another machine | `ipmg web --lan` |
211
+ | Keep it running after logout and reboots | [systemd and launchd templates](https://github.com/sameeralam3127/ipmg/blob/main/docs/SERVICES.md) |
212
+ | See every option | `ipmg --help`, or the [command reference](https://github.com/sameeralam3127/ipmg/blob/main/docs/COMMANDS.md) |
213
+
214
+ ## IPMG Web
215
+
216
+ ```bash
217
+ ipmg web # this machine: opens http://127.0.0.1:8080 in your browser
218
+ ipmg web --lan # any machine on your network: prints the link to open
219
+ ```
220
+
221
+ With `--lan`, IPMG Web prints the link with this machine's address and access
222
+ token, checks the firewall, and tells you the exact command that opens the
223
+ port if it is blocked (`sudo ipmg web --open-firewall` opens it only while
224
+ IPMG Web runs). Every request needs the token in that link.
225
+
226
+ <p align="center">
227
+ <img src="https://raw.githubusercontent.com/sameeralam3127/ipmg/main/docs/assets/ipmg-web.png" alt="IPMG Web dashboard: scan totals, a status donut of 16 active, 1 timeout and 1 inactive host, a latency trend chart, and a list of recent scans" width="820">
228
+ </p>
229
+
230
+ Dashboard, live monitor, history, changes, inventory with Wake-on-LAN, and
231
+ scheduled scans; see the
232
+ [IPMG Web guide](https://github.com/sameeralam3127/ipmg/blob/main/docs/WEB.md),
233
+ or try it first in the [live demo](https://sameeralam3127.github.io/ipmg/demo/).
234
+
235
+ ## Documentation
236
+
237
+ | Guide | What is in it |
238
+ | --- | --- |
239
+ | [Install](https://github.com/sameeralam3127/ipmg/blob/main/docs/INSTALL.md) | Installers, Docker, pip, Python versions, upgrading from 3.x, tab completion, verified systems |
240
+ | [Command reference](https://github.com/sameeralam3127/ipmg/blob/main/docs/COMMANDS.md) | Every command and flag with examples: targets, probes, HTTP checks, reports, history, change detection, notifications, `ipmg.toml`, exit codes |
241
+ | [IPMG Web](https://github.com/sameeralam3127/ipmg/blob/main/docs/WEB.md) | The dashboard, opening it from other machines, the firewall, scheduled scans, Prometheus metrics |
242
+ | [Web API](https://github.com/sameeralam3127/ipmg/blob/main/docs/API.md) | Scripting IPMG Web over HTTP and WebSocket |
243
+ | [Running as a service](https://github.com/sameeralam3127/ipmg/blob/main/docs/SERVICES.md) | systemd and launchd templates for scheduled scans and IPMG Web |
244
+ | [GitHub Action](https://github.com/sameeralam3127/ipmg/blob/main/docs/GITHUB-ACTION.md) | Reachability checks in CI, before a deploy or on a schedule |
245
+ | [SNMP polling](https://github.com/sameeralam3127/ipmg/blob/main/docs/SNMP.md) | Switches and routers over SNMP v2c and v3: credentials, interfaces, reboots, reports |
246
+ | [How it compares](https://github.com/sameeralam3127/ipmg/blob/main/docs/COMPARISON.md) | IPMG next to nmap, fping, and Uptime Kuma |
247
+ | [Troubleshooting](https://github.com/sameeralam3127/ipmg/blob/main/docs/TROUBLESHOOTING.md) and [FAQ](https://github.com/sameeralam3127/ipmg/blob/main/docs/FAQ.md) | Install errors, timeouts, slow scans, empty MAC addresses, common questions |
248
+ | [Architecture](https://github.com/sameeralam3127/ipmg/blob/main/docs/ARCHITECTURE.md) | How the code fits together, for contributors |
249
+
250
+ ## Security
251
+
252
+ IPMG runs `ping` as a direct process call with no shell, validates every
253
+ target first, and needs no root. IPMG Web listens on `127.0.0.1` unless you
254
+ pass `--lan`, serves everything locally, and requires its access token on
255
+ every request, behind a strict Content-Security-Policy. The only outbound
256
+ requests IPMG makes are the notifications and HTTP checks you ask for. Found a
257
+ vulnerability? See
258
+ [SECURITY.md](https://github.com/sameeralam3127/ipmg/blob/main/.github/SECURITY.md).
259
+
260
+ ## Contributing
261
+
262
+ Contributions are welcome.
263
+ [CONTRIBUTING.md](https://github.com/sameeralam3127/ipmg/blob/main/.github/CONTRIBUTING.md)
264
+ covers the development setup, the tests, and the commit format that drives
265
+ releases, and
266
+ [ARCHITECTURE.md](https://github.com/sameeralam3127/ipmg/blob/main/docs/ARCHITECTURE.md)
267
+ explains the code. Everyone taking part is expected to follow the
268
+ [Code of Conduct](https://github.com/sameeralam3127/ipmg/blob/main/.github/CODE_OF_CONDUCT.md).
269
+
270
+ If IPMG saves you time, a star on
271
+ [GitHub](https://github.com/sameeralam3127/ipmg) helps other people find it.
272
+
273
+ ## License
274
+
275
+ MIT — free for commercial and personal use.
ipmg-4.2.0/README.md ADDED
@@ -0,0 +1,220 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/sameeralam3127/ipmg/main/docs/assets/ipmg-logo.svg" alt="" width="88">
3
+ </p>
4
+
5
+ <h1 align="center">IPMG</h1>
6
+
7
+ <p align="center">
8
+ <b>IP Management &amp; Ping Monitoring Tool</b><br>
9
+ Know what changed on your network since the last scan.
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="https://pypi.org/project/ipmg/"><img src="https://img.shields.io/github/v/release/sameeralam3127/ipmg?label=pypi" alt="PyPI"></a>
14
+ <a href="https://pypi.org/project/ipmg/"><img src="https://img.shields.io/badge/python-3.10%2B-blue" alt="Python Version"></a>
15
+ <a href="https://github.com/sameeralam3127/ipmg/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License"></a>
16
+ <a href="https://github.com/sameeralam3127/ipmg/actions/workflows/publish.yml"><img src="https://github.com/sameeralam3127/ipmg/actions/workflows/publish.yml/badge.svg" alt="Publish"></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="https://sameeralam3127.github.io/ipmg/"><b>Website</b></a>
21
+ &nbsp;·&nbsp;
22
+ <a href="https://sameeralam3127.github.io/ipmg/demo/"><b>Live demo</b></a>
23
+ &nbsp;·&nbsp;
24
+ <a href="https://sameeralam3127.github.io/ipmg/#builder"><b>Command builder</b></a>
25
+ &nbsp;·&nbsp;
26
+ <a href="https://github.com/sameeralam3127/ipmg#documentation"><b>Docs</b></a>
27
+ </p>
28
+
29
+ <p align="center">
30
+ <img src="https://raw.githubusercontent.com/sameeralam3127/ipmg/main/docs/assets/ipmg-compare.gif" alt="ipmg scans 13 hosts with --stream, printing each one as it answers; a new address is added to the target file; a second scan with --compare reports it as a new host (warning) against the first" width="820">
31
+ </p>
32
+
33
+ IPMG sweeps IPs, CIDR blocks, and ranges in parallel, remembers every scan, and
34
+ tells you what changed since the last one: hosts that went down or appeared, a
35
+ new MAC address or hostname behind an address, slower replies, a web service
36
+ that started failing. Only the changes that matter reach Slack, Teams, a
37
+ webhook, or email, or fail your cron job or CI step.
38
+
39
+ ## Features
40
+
41
+ - **Fast, without root.** IPv4 and IPv6, CIDR blocks, ranges, and target
42
+ files (text, CSV, Excel, JSON), many hosts at a time, using your system's own
43
+ `ping`.
44
+ - **Finds hosts that block ping** with TCP probes (`--probe icmp,tcp`), and
45
+ checks web services (`--http-check`: status, response time, TLS, certificate
46
+ expiry).
47
+ - **Names every device** by reverse DNS and, on your LAN, by MAC address
48
+ and vendor (`--mac`). Wakes them with Wake-on-LAN (`ipmg wake`).
49
+ - **Tells you what changed** since the last scan, with a severity for each
50
+ change, and alerts Slack, Teams, webhooks, or email.
51
+ - **Made for automation:** exit codes for cron and CI, a GitHub Action,
52
+ `--json` for scripts, systemd and launchd templates, Prometheus metrics.
53
+ - **IPMG Web**, a local dashboard: live scans, history, changes, inventory,
54
+ and scheduled scans.
55
+ - **Reports** in Excel, CSV, JSON, JSON Lines, and Markdown, written as the
56
+ scan runs, so an interrupted scan keeps its results.
57
+
58
+ [How IPMG compares](https://github.com/sameeralam3127/ipmg/blob/main/docs/COMPARISON.md)
59
+ with nmap, fping, and Uptime Kuma.
60
+
61
+ ## Install
62
+
63
+ ```bash
64
+ # Linux and macOS, no Python needed
65
+ curl -sSL https://raw.githubusercontent.com/sameeralam3127/ipmg/main/install.sh | bash
66
+ ```
67
+
68
+ ```powershell
69
+ # Windows, no administrator rights
70
+ irm https://raw.githubusercontent.com/sameeralam3127/ipmg/main/install.ps1 | iex
71
+ ```
72
+
73
+ Or from PyPI, with Python 3.10 or newer:
74
+
75
+ ```bash
76
+ # With pip, in a virtual environment
77
+ pip install ipmg # the command line
78
+ pip install "ipmg[web]" # the command line and IPMG Web, the browser dashboard
79
+ ```
80
+
81
+ ```bash
82
+ # With pipx
83
+ pipx install "ipmg[web]"
84
+ ```
85
+
86
+ ```bash
87
+ # With uv, which fetches Python 3.10+ if you need it
88
+ uv tool install --python ">=3.10" "ipmg[web]"
89
+ ```
90
+
91
+ Also on:
92
+
93
+ - **Homebrew:** `brew install sameeralam3127/tap/ipmg`
94
+ - **Docker:** `docker run --rm sameeralam3127/ipmg --input 10.0.0.0/24`, or from GHCR: `ghcr.io/sameeralam3127/ipmg`
95
+
96
+ > **Tip:** `[web]` adds IPMG Web; `pip install ipmg` alone is the command line.
97
+ > Where the system Python is older than 3.10 (RHEL 9, Ubuntu 20.04, SLES 15),
98
+ > pip and pipx quietly install an older IPMG: use the installer or uv there. The
99
+ > [install guide](https://github.com/sameeralam3127/ipmg/blob/main/docs/INSTALL.md)
100
+ > covers version pinning, upgrading from 3.x, and tab completion.
101
+
102
+ ## Quick start
103
+
104
+ ```bash
105
+ ipmg --discover # scan the network you are on, right now
106
+ ipmg --discover --compare # later: scan again and see what changed
107
+ ipmg web --lan # open the dashboard from any machine on your network
108
+ ```
109
+
110
+ Every scan is saved to a local history (`~/.ipmg/dashboard.db`), so
111
+ `--compare` always has the previous scan to compare with.
112
+
113
+ <details>
114
+ <summary>What a scan prints</summary>
115
+
116
+ ```text
117
+ ipmg X.Y.Z · scan
118
+ ICMP probes only — scan only networks you are authorized to scan.
119
+
120
+ Source 192.168.1.0/24
121
+ Targets 254 hosts
122
+ Config 50 threads · 2s timeout · 1 ping
123
+
124
+ Results
125
+ ● Active 12 ━─────────────────────── 4.7%
126
+ ● Timeout 242 ━━━━━━━━━━━━━━━━━━━━━━━━ 95.3%
127
+
128
+ 254 hosts · 4.7% active · 3.1 ms avg · 5.21s · 2026-10-18 09:15:02
129
+
130
+ Saved results_20261018_091502.xlsx
131
+ ```
132
+
133
+ </details>
134
+
135
+ > **Note:** only scan networks you are authorized to scan. Unauthorized scanning
136
+ > may violate your organization's policies or the law.
137
+
138
+ ## Common tasks
139
+
140
+ | I want to… | Command |
141
+ | --- | --- |
142
+ | Scan the network I am on | `ipmg --discover` |
143
+ | Scan hosts listed in a file, plus a few more | `ipmg --input targets.txt 10.0.0.5` |
144
+ | See what changed since last time | `ipmg --input targets.txt --compare` |
145
+ | Get alerted when something changes | `ipmg --input targets.txt --interval 15 --notify-slack` |
146
+ | Find hosts that block ping | `ipmg --input 10.0.0.0/24 --probe icmp,tcp` |
147
+ | Know which device each address is | `ipmg --discover --resolve --mac` |
148
+ | Check that a web service works | `ipmg --http-check https://intranet.example.com/` |
149
+ | Watch switches and routers: reboots, interfaces going down | `ipmg --input switches.txt --snmp --compare` |
150
+ | See which services are listening | `ipmg --input targets.txt --scan-ports` |
151
+ | Get a report I can send to someone | `ipmg --input targets.txt --formats md csv` |
152
+ | Pipe the results into a script | `ipmg --input targets.txt --json \| jq .` |
153
+ | Fail a cron job or CI step when hosts are down | `ipmg --input servers.txt --fail-on-down` |
154
+ | Wake a machine | `ipmg wake AA:BB:CC:DD:EE:FF` |
155
+ | Use the dashboard from another machine | `ipmg web --lan` |
156
+ | Keep it running after logout and reboots | [systemd and launchd templates](https://github.com/sameeralam3127/ipmg/blob/main/docs/SERVICES.md) |
157
+ | See every option | `ipmg --help`, or the [command reference](https://github.com/sameeralam3127/ipmg/blob/main/docs/COMMANDS.md) |
158
+
159
+ ## IPMG Web
160
+
161
+ ```bash
162
+ ipmg web # this machine: opens http://127.0.0.1:8080 in your browser
163
+ ipmg web --lan # any machine on your network: prints the link to open
164
+ ```
165
+
166
+ With `--lan`, IPMG Web prints the link with this machine's address and access
167
+ token, checks the firewall, and tells you the exact command that opens the
168
+ port if it is blocked (`sudo ipmg web --open-firewall` opens it only while
169
+ IPMG Web runs). Every request needs the token in that link.
170
+
171
+ <p align="center">
172
+ <img src="https://raw.githubusercontent.com/sameeralam3127/ipmg/main/docs/assets/ipmg-web.png" alt="IPMG Web dashboard: scan totals, a status donut of 16 active, 1 timeout and 1 inactive host, a latency trend chart, and a list of recent scans" width="820">
173
+ </p>
174
+
175
+ Dashboard, live monitor, history, changes, inventory with Wake-on-LAN, and
176
+ scheduled scans; see the
177
+ [IPMG Web guide](https://github.com/sameeralam3127/ipmg/blob/main/docs/WEB.md),
178
+ or try it first in the [live demo](https://sameeralam3127.github.io/ipmg/demo/).
179
+
180
+ ## Documentation
181
+
182
+ | Guide | What is in it |
183
+ | --- | --- |
184
+ | [Install](https://github.com/sameeralam3127/ipmg/blob/main/docs/INSTALL.md) | Installers, Docker, pip, Python versions, upgrading from 3.x, tab completion, verified systems |
185
+ | [Command reference](https://github.com/sameeralam3127/ipmg/blob/main/docs/COMMANDS.md) | Every command and flag with examples: targets, probes, HTTP checks, reports, history, change detection, notifications, `ipmg.toml`, exit codes |
186
+ | [IPMG Web](https://github.com/sameeralam3127/ipmg/blob/main/docs/WEB.md) | The dashboard, opening it from other machines, the firewall, scheduled scans, Prometheus metrics |
187
+ | [Web API](https://github.com/sameeralam3127/ipmg/blob/main/docs/API.md) | Scripting IPMG Web over HTTP and WebSocket |
188
+ | [Running as a service](https://github.com/sameeralam3127/ipmg/blob/main/docs/SERVICES.md) | systemd and launchd templates for scheduled scans and IPMG Web |
189
+ | [GitHub Action](https://github.com/sameeralam3127/ipmg/blob/main/docs/GITHUB-ACTION.md) | Reachability checks in CI, before a deploy or on a schedule |
190
+ | [SNMP polling](https://github.com/sameeralam3127/ipmg/blob/main/docs/SNMP.md) | Switches and routers over SNMP v2c and v3: credentials, interfaces, reboots, reports |
191
+ | [How it compares](https://github.com/sameeralam3127/ipmg/blob/main/docs/COMPARISON.md) | IPMG next to nmap, fping, and Uptime Kuma |
192
+ | [Troubleshooting](https://github.com/sameeralam3127/ipmg/blob/main/docs/TROUBLESHOOTING.md) and [FAQ](https://github.com/sameeralam3127/ipmg/blob/main/docs/FAQ.md) | Install errors, timeouts, slow scans, empty MAC addresses, common questions |
193
+ | [Architecture](https://github.com/sameeralam3127/ipmg/blob/main/docs/ARCHITECTURE.md) | How the code fits together, for contributors |
194
+
195
+ ## Security
196
+
197
+ IPMG runs `ping` as a direct process call with no shell, validates every
198
+ target first, and needs no root. IPMG Web listens on `127.0.0.1` unless you
199
+ pass `--lan`, serves everything locally, and requires its access token on
200
+ every request, behind a strict Content-Security-Policy. The only outbound
201
+ requests IPMG makes are the notifications and HTTP checks you ask for. Found a
202
+ vulnerability? See
203
+ [SECURITY.md](https://github.com/sameeralam3127/ipmg/blob/main/.github/SECURITY.md).
204
+
205
+ ## Contributing
206
+
207
+ Contributions are welcome.
208
+ [CONTRIBUTING.md](https://github.com/sameeralam3127/ipmg/blob/main/.github/CONTRIBUTING.md)
209
+ covers the development setup, the tests, and the commit format that drives
210
+ releases, and
211
+ [ARCHITECTURE.md](https://github.com/sameeralam3127/ipmg/blob/main/docs/ARCHITECTURE.md)
212
+ explains the code. Everyone taking part is expected to follow the
213
+ [Code of Conduct](https://github.com/sameeralam3127/ipmg/blob/main/.github/CODE_OF_CONDUCT.md).
214
+
215
+ If IPMG saves you time, a star on
216
+ [GitHub](https://github.com/sameeralam3127/ipmg) helps other people find it.
217
+
218
+ ## License
219
+
220
+ MIT — free for commercial and personal use.
@@ -13,7 +13,7 @@ build-backend = "setuptools.build_meta"
13
13
 
14
14
  [project]
15
15
  name = "ipmg"
16
- version = "4.0.0-beta.1" # Managed automatically by semantic-release
16
+ version = "4.2.0" # Managed automatically by semantic-release
17
17
  description = "Network discovery and change detection: ping sweeps, scan history, and reports for what changed on your network"
18
18
  readme = "README.md"
19
19
  requires-python = ">=3.10"
@@ -73,13 +73,17 @@ web = [
73
73
  "websockets>=12",
74
74
  "python-multipart>=0.0.9",
75
75
  ]
76
- # Everything; what the one-line installers and the Docker image install.
77
- all = ["ipmg[web]"]
76
+ # SNMPv3 encryption (`--snmp` with a privacy key). SNMP v2c and v3 without
77
+ # encryption need nothing extra.
78
+ snmp = ["cryptography>=42"]
79
+ # Everything.
80
+ all = ["ipmg[web,snmp]"]
78
81
  dev = [
79
- "ipmg[web]",
82
+ "ipmg[web,snmp]",
80
83
  "pytest>=7.4",
81
84
  "pytest-cov>=5.0",
82
85
  "ruff>=0.4",
86
+ "mypy>=1.10",
83
87
  "pre-commit>=3.5.0",
84
88
  "python-semantic-release>=10.5.3",
85
89
  # The TestClient's HTTP client. Starlette 1.x wants httpx2 and warns
@@ -99,10 +103,11 @@ ipmg = "ipmg.cli.commands:run"
99
103
 
100
104
  [dependency-groups]
101
105
  dev = [
102
- "ipmg[web]",
106
+ "ipmg[web,snmp]",
103
107
  "pytest>=7.4",
104
108
  "pytest-cov>=5.0",
105
109
  "ruff>=0.4",
110
+ "mypy>=1.10",
106
111
  "pre-commit>=3.5.0",
107
112
  "python-semantic-release>=10.5.3",
108
113
  # The TestClient's HTTP client. Starlette 1.x wants httpx2 and warns
@@ -160,6 +165,14 @@ where = ["src"]
160
165
  # Testing
161
166
  # ==========================================================
162
167
 
168
+ [tool.mypy]
169
+ python_version = "3.10"
170
+ # Optional extras (openpyxl stubs, pysnmp) are not all typed.
171
+ ignore_missing_imports = true
172
+ warn_unused_ignores = true
173
+ files = ["src"]
174
+
175
+
163
176
  [tool.pytest.ini_options]
164
177
  testpaths = ["tests"]
165
178
  pythonpath = ["src"]
@@ -189,8 +202,9 @@ line-length = 100
189
202
  target-version = "py310"
190
203
 
191
204
  [tool.ruff.lint]
192
- select = ["E", "F", "W", "I", "C90"]
193
- ignore = ["E501"]
205
+ select = ["E", "F", "W", "I", "C90", "UP"]
206
+ # UP038 (isinstance(x, A | B)) is slower than a tuple and deprecated in ruff.
207
+ ignore = ["E501", "UP038"]
194
208
 
195
209
  [tool.ruff.lint.isort]
196
210
  combine-as-imports = true
@@ -2,4 +2,4 @@
2
2
  ipmg - IP Management & Ping Monitoring Tool
3
3
  """
4
4
 
5
- __version__ = "4.0.0-beta.1"
5
+ __version__ = "4.2.0"