unifi-network-maps 1.2.4__tar.gz → 1.3.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.
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/CHANGELOG.md +15 -0
- unifi_network_maps-1.3.0/LICENSES.md +10 -0
- unifi_network_maps-1.3.0/MANIFEST.in +10 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/PKG-INFO +63 -8
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/README.md +60 -6
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/pyproject.toml +11 -5
- unifi_network_maps-1.3.0/src/unifi_network_maps/__init__.py +1 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps/adapters/__init__.py +1 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps/adapters}/config.py +7 -1
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps/adapters}/unifi.py +1 -1
- unifi_network_maps-1.3.0/src/unifi_network_maps/assets/themes/dark.yaml +47 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps/assets/themes/default.yaml +47 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps/cli/__init__.py +41 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps/cli/__main__.py +8 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps/cli/main.py +281 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps/io/__init__.py +1 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps/io}/debug.py +1 -1
- unifi_network_maps-1.3.0/src/unifi_network_maps/model/__init__.py +1 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps/model/labels.py +35 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps/model}/lldp.py +19 -33
- unifi_network_maps-1.3.0/src/unifi_network_maps/model/ports.py +23 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps/model}/topology.py +216 -89
- unifi_network_maps-1.3.0/src/unifi_network_maps/render/__init__.py +1 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps/render}/mermaid.py +21 -16
- unifi_network_maps-1.3.0/src/unifi_network_maps/render/mermaid_theme.py +46 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps/render}/svg.py +208 -175
- unifi_network_maps-1.3.0/src/unifi_network_maps/render/svg_theme.py +64 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps/render/theme.py +90 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/src/unifi_network_maps.egg-info/PKG-INFO +63 -8
- unifi_network_maps-1.3.0/src/unifi_network_maps.egg-info/SOURCES.txt +97 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps.egg-info/entry_points.txt +2 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/src/unifi_network_maps.egg-info/requires.txt +1 -0
- unifi_network_maps-1.3.0/src/unifi_network_maps.egg-info/top_level.txt +1 -0
- unifi_network_maps-1.3.0/tests/test_cli.py +219 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_clients.py +1 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_config.py +16 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_debug.py +2 -2
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_export.py +1 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_groups.py +2 -2
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_labels.py +16 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_lldp.py +1 -1
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_mermaid.py +2 -2
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_svg.py +13 -3
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_svg_iso.py +2 -2
- unifi_network_maps-1.3.0/tests/test_theme.py +39 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_topology.py +52 -3
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/tests/test_unifi.py +2 -2
- unifi_network_maps-1.2.4/LICENSES.md +0 -10
- unifi_network_maps-1.2.4/MANIFEST.in +0 -9
- unifi_network_maps-1.2.4/src/unifi_mermaid/__init__.py +0 -1
- unifi_network_maps-1.2.4/src/unifi_mermaid/cli.py +0 -197
- unifi_network_maps-1.2.4/src/unifi_mermaid/labels.py +0 -15
- unifi_network_maps-1.2.4/src/unifi_network_maps.egg-info/SOURCES.txt +0 -84
- unifi_network_maps-1.2.4/src/unifi_network_maps.egg-info/entry_points.txt +0 -2
- unifi_network_maps-1.2.4/src/unifi_network_maps.egg-info/top_level.txt +0 -1
- unifi_network_maps-1.2.4/tests/test_cli.py +0 -193
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/CONTRIBUTING.md +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/LICENSE +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/RELEASING.md +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/SECURITY.md +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/setup.cfg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/__init__.py +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/__init__.py +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/access-point.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/ISOPACKS_LICENSE +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/block.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/cache.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/cardterminal.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/cloud.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/cronjob.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/cube.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/desktop.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/diamond.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/dns.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/document.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/firewall.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/function-module.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/image.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/laptop.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/loadbalancer.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/lock.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/mail.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/mailmultiple.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/mobiledevice.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/office.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/package-module.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/paymentcard.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/plane.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/printer.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/pyramid.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/queue.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/router.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/server.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/speech.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/sphere.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/storage.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/switch-module.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/tower.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/truck-2.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/truck.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/user.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/isometric/vm.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/laptop.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/router-network.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/server-network.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps}/assets/icons/server.svg +0 -0
- {unifi_network_maps-1.2.4/src/unifi_mermaid → unifi_network_maps-1.3.0/src/unifi_network_maps/io}/export.py +0 -0
- {unifi_network_maps-1.2.4 → unifi_network_maps-1.3.0}/src/unifi_network_maps.egg-info/dependency_links.txt +0 -0
|
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
- TBD.
|
|
7
7
|
|
|
8
|
+
## v1.3.0
|
|
9
|
+
- Reorganized package into submodules (`adapters/`, `model/`, `render/`, `io/`, `cli/`).
|
|
10
|
+
- YAML-based theming with default + dark themes and `--theme-file`.
|
|
11
|
+
- CLI help now grouped by category; CLI logic split into focused helpers.
|
|
12
|
+
- Isometric SVG layout constants centralized; extra viewBox padding to avoid clipping.
|
|
13
|
+
- LLDP port index fallback matches `port_table` `ifname`/`name`.
|
|
14
|
+
- Added PoE/edge/device count logging and improved label ordering helpers.
|
|
15
|
+
- Coverage excludes asset packages; docs updated (options/groups + AI disclosure).
|
|
16
|
+
|
|
17
|
+
## v1.2.4
|
|
18
|
+
- Added typed `UplinkInfo`/`PortInfo` and uplink fallback for LLDP gaps.
|
|
19
|
+
- Deterministic edge ordering for repeatable output.
|
|
20
|
+
- CI publish workflow (trusted publishing) and release docs.
|
|
21
|
+
- Project metadata and packaging updated for OSS readiness.
|
|
22
|
+
|
|
8
23
|
## v1.1.0
|
|
9
24
|
- Added isometric SVG output with grid-aligned links and isometric icon set.
|
|
10
25
|
- Improved port label placement and client labeling in SVG outputs.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Third-Party Licenses
|
|
2
|
+
|
|
3
|
+
## markmanx/isopacks (MIT)
|
|
4
|
+
|
|
5
|
+
Isometric SVG icons are vendored under `src/unifi_network_maps/assets/icons/isometric/`.
|
|
6
|
+
The upstream MIT license is included at:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
src/unifi_network_maps/assets/icons/isometric/ISOPACKS_LICENSE
|
|
10
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include CHANGELOG.md
|
|
4
|
+
include SECURITY.md
|
|
5
|
+
include CONTRIBUTING.md
|
|
6
|
+
include LICENSES.md
|
|
7
|
+
include RELEASING.md
|
|
8
|
+
recursive-include src/unifi_network_maps/assets/icons *.svg
|
|
9
|
+
recursive-include src/unifi_network_maps/assets/icons/isometric ISOPACKS_LICENSE
|
|
10
|
+
recursive-include src/unifi_network_maps/assets/themes *.yaml
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unifi-network-maps
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary: Dynamic UniFi ->
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: Dynamic UniFi -> network maps in mermaid or svg
|
|
5
5
|
Author: Merlijn
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/merlijntishauser/unifi-network-maps
|
|
@@ -26,6 +26,7 @@ License-File: LICENSE
|
|
|
26
26
|
License-File: LICENSES.md
|
|
27
27
|
Requires-Dist: unifi-controller-api
|
|
28
28
|
Requires-Dist: python-dotenv
|
|
29
|
+
Requires-Dist: PyYAML
|
|
29
30
|
Provides-Extra: dev
|
|
30
31
|
Requires-Dist: pre-commit; extra == "dev"
|
|
31
32
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -66,6 +67,12 @@ export UNIFI_PASS=********
|
|
|
66
67
|
export UNIFI_VERIFY_SSL=false
|
|
67
68
|
```
|
|
68
69
|
|
|
70
|
+
Use a custom env file:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
unifi-network-maps --env-file ./site.env --stdout
|
|
74
|
+
```
|
|
75
|
+
|
|
69
76
|
## Usage
|
|
70
77
|
|
|
71
78
|
Basic map (tree layout by LLDP hops):
|
|
@@ -137,24 +144,72 @@ See `LICENSES.md` for third-party license info.
|
|
|
137
144
|
|
|
138
145
|
## Options
|
|
139
146
|
|
|
140
|
-
|
|
147
|
+
The CLI groups options by category (`Source`, `Functional`, `Mermaid`, `SVG`, `Output`, `Debug`).
|
|
148
|
+
|
|
149
|
+
Source:
|
|
150
|
+
- `--site`: override `UNIFI_SITE`.
|
|
151
|
+
- `--env-file`: load environment variables from a specific `.env` file.
|
|
152
|
+
|
|
153
|
+
Functional:
|
|
141
154
|
- `--include-ports`: show port labels (Mermaid shows both ends; SVG shows compact labels).
|
|
155
|
+
- `--include-clients`: add active wired clients as leaf nodes.
|
|
142
156
|
- `--only-unifi`: only include neighbors that are UniFi devices.
|
|
157
|
+
|
|
158
|
+
Mermaid:
|
|
143
159
|
- `--direction LR|TB`: diagram direction for Mermaid (default TB).
|
|
144
|
-
- `--stdout`: write output to stdout.
|
|
145
|
-
- `--markdown`: wrap Mermaid output in a code fence.
|
|
146
160
|
- `--group-by-type`: group nodes by gateway/switch/AP in Mermaid subgraphs.
|
|
147
|
-
- `--include-clients`: add active wired clients as leaf nodes.
|
|
148
161
|
- `--legend-only`: render just the legend as a separate Mermaid graph (Mermaid only).
|
|
162
|
+
|
|
163
|
+
SVG:
|
|
164
|
+
- `--svg-width/--svg-height`: override SVG output dimensions.
|
|
165
|
+
- `--theme-file`: load a YAML theme for Mermaid + SVG colors (see `examples/theme.yaml` and `examples/theme-dark.yaml`).
|
|
166
|
+
|
|
167
|
+
Output:
|
|
168
|
+
- `--format mermaid|svg|svg-iso`: output format (default mermaid).
|
|
169
|
+
- `--stdout`: write output to stdout.
|
|
170
|
+
- `--markdown`: wrap Mermaid output in a code fence.
|
|
171
|
+
|
|
172
|
+
Debug:
|
|
149
173
|
- `--debug-dump`: dump gateway + sample devices to stderr for debugging.
|
|
150
174
|
- `--debug-sample N`: number of non-gateway devices in debug dump (default 2).
|
|
151
|
-
- `--svg-width/--svg-height`: override SVG output dimensions.
|
|
152
175
|
|
|
153
176
|
## Notes
|
|
154
177
|
|
|
155
178
|
- Default output is top-to-bottom (TB) and rendered as a hop-based tree from the gateway(s).
|
|
156
179
|
- Nodes are color-coded by type (gateway/switch/AP/client) with a sensible default palette.
|
|
157
180
|
- PoE links are highlighted in blue and annotated with a power icon when detected from `port_table`.
|
|
158
|
-
- SVG output uses vendored device glyphs from `src/
|
|
181
|
+
- SVG output uses vendored device glyphs from `src/unifi_network_maps/assets/icons`.
|
|
159
182
|
- Isometric SVG output uses MIT-licensed icons from `markmanx/isopacks`.
|
|
160
183
|
- SVG port labels render inside child nodes for readability.
|
|
184
|
+
|
|
185
|
+
## AI Disclosure
|
|
186
|
+
|
|
187
|
+
This project used OpenAI Codex as a coding assistant for portions of the implementation and documentation.
|
|
188
|
+
|
|
189
|
+
## Theme file
|
|
190
|
+
|
|
191
|
+
Example theme YAML (override only the values you want):
|
|
192
|
+
|
|
193
|
+
```yaml
|
|
194
|
+
mermaid:
|
|
195
|
+
nodes:
|
|
196
|
+
gateway:
|
|
197
|
+
fill: "#ffe3b3"
|
|
198
|
+
stroke: "#d98300"
|
|
199
|
+
poe_link: "#1e88e5"
|
|
200
|
+
svg:
|
|
201
|
+
links:
|
|
202
|
+
standard:
|
|
203
|
+
from: "#2ecc71"
|
|
204
|
+
to: "#1b8f4a"
|
|
205
|
+
poe:
|
|
206
|
+
from: "#1e88e5"
|
|
207
|
+
to: "#0d47a1"
|
|
208
|
+
nodes:
|
|
209
|
+
switch:
|
|
210
|
+
from: "#d6ecff"
|
|
211
|
+
to: "#b6dcff"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The built-in themes live at `src/unifi_network_maps/assets/themes/default.yaml` and
|
|
215
|
+
`src/unifi_network_maps/assets/themes/dark.yaml`.
|
|
@@ -31,6 +31,12 @@ export UNIFI_PASS=********
|
|
|
31
31
|
export UNIFI_VERIFY_SSL=false
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
Use a custom env file:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
unifi-network-maps --env-file ./site.env --stdout
|
|
38
|
+
```
|
|
39
|
+
|
|
34
40
|
## Usage
|
|
35
41
|
|
|
36
42
|
Basic map (tree layout by LLDP hops):
|
|
@@ -102,24 +108,72 @@ See `LICENSES.md` for third-party license info.
|
|
|
102
108
|
|
|
103
109
|
## Options
|
|
104
110
|
|
|
105
|
-
|
|
111
|
+
The CLI groups options by category (`Source`, `Functional`, `Mermaid`, `SVG`, `Output`, `Debug`).
|
|
112
|
+
|
|
113
|
+
Source:
|
|
114
|
+
- `--site`: override `UNIFI_SITE`.
|
|
115
|
+
- `--env-file`: load environment variables from a specific `.env` file.
|
|
116
|
+
|
|
117
|
+
Functional:
|
|
106
118
|
- `--include-ports`: show port labels (Mermaid shows both ends; SVG shows compact labels).
|
|
119
|
+
- `--include-clients`: add active wired clients as leaf nodes.
|
|
107
120
|
- `--only-unifi`: only include neighbors that are UniFi devices.
|
|
121
|
+
|
|
122
|
+
Mermaid:
|
|
108
123
|
- `--direction LR|TB`: diagram direction for Mermaid (default TB).
|
|
109
|
-
- `--stdout`: write output to stdout.
|
|
110
|
-
- `--markdown`: wrap Mermaid output in a code fence.
|
|
111
124
|
- `--group-by-type`: group nodes by gateway/switch/AP in Mermaid subgraphs.
|
|
112
|
-
- `--include-clients`: add active wired clients as leaf nodes.
|
|
113
125
|
- `--legend-only`: render just the legend as a separate Mermaid graph (Mermaid only).
|
|
126
|
+
|
|
127
|
+
SVG:
|
|
128
|
+
- `--svg-width/--svg-height`: override SVG output dimensions.
|
|
129
|
+
- `--theme-file`: load a YAML theme for Mermaid + SVG colors (see `examples/theme.yaml` and `examples/theme-dark.yaml`).
|
|
130
|
+
|
|
131
|
+
Output:
|
|
132
|
+
- `--format mermaid|svg|svg-iso`: output format (default mermaid).
|
|
133
|
+
- `--stdout`: write output to stdout.
|
|
134
|
+
- `--markdown`: wrap Mermaid output in a code fence.
|
|
135
|
+
|
|
136
|
+
Debug:
|
|
114
137
|
- `--debug-dump`: dump gateway + sample devices to stderr for debugging.
|
|
115
138
|
- `--debug-sample N`: number of non-gateway devices in debug dump (default 2).
|
|
116
|
-
- `--svg-width/--svg-height`: override SVG output dimensions.
|
|
117
139
|
|
|
118
140
|
## Notes
|
|
119
141
|
|
|
120
142
|
- Default output is top-to-bottom (TB) and rendered as a hop-based tree from the gateway(s).
|
|
121
143
|
- Nodes are color-coded by type (gateway/switch/AP/client) with a sensible default palette.
|
|
122
144
|
- PoE links are highlighted in blue and annotated with a power icon when detected from `port_table`.
|
|
123
|
-
- SVG output uses vendored device glyphs from `src/
|
|
145
|
+
- SVG output uses vendored device glyphs from `src/unifi_network_maps/assets/icons`.
|
|
124
146
|
- Isometric SVG output uses MIT-licensed icons from `markmanx/isopacks`.
|
|
125
147
|
- SVG port labels render inside child nodes for readability.
|
|
148
|
+
|
|
149
|
+
## AI Disclosure
|
|
150
|
+
|
|
151
|
+
This project used OpenAI Codex as a coding assistant for portions of the implementation and documentation.
|
|
152
|
+
|
|
153
|
+
## Theme file
|
|
154
|
+
|
|
155
|
+
Example theme YAML (override only the values you want):
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
mermaid:
|
|
159
|
+
nodes:
|
|
160
|
+
gateway:
|
|
161
|
+
fill: "#ffe3b3"
|
|
162
|
+
stroke: "#d98300"
|
|
163
|
+
poe_link: "#1e88e5"
|
|
164
|
+
svg:
|
|
165
|
+
links:
|
|
166
|
+
standard:
|
|
167
|
+
from: "#2ecc71"
|
|
168
|
+
to: "#1b8f4a"
|
|
169
|
+
poe:
|
|
170
|
+
from: "#1e88e5"
|
|
171
|
+
to: "#0d47a1"
|
|
172
|
+
nodes:
|
|
173
|
+
switch:
|
|
174
|
+
from: "#d6ecff"
|
|
175
|
+
to: "#b6dcff"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The built-in themes live at `src/unifi_network_maps/assets/themes/default.yaml` and
|
|
179
|
+
`src/unifi_network_maps/assets/themes/dark.yaml`.
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "unifi-network-maps"
|
|
7
|
-
version = "1.
|
|
8
|
-
description = "Dynamic UniFi ->
|
|
7
|
+
version = "1.3.0"
|
|
8
|
+
description = "Dynamic UniFi -> network maps in mermaid or svg"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = { text = "MIT" }
|
|
@@ -27,6 +27,7 @@ classifiers = [
|
|
|
27
27
|
dependencies = [
|
|
28
28
|
"unifi-controller-api",
|
|
29
29
|
"python-dotenv",
|
|
30
|
+
"PyYAML",
|
|
30
31
|
]
|
|
31
32
|
|
|
32
33
|
[project.urls]
|
|
@@ -44,7 +45,7 @@ dev = [
|
|
|
44
45
|
]
|
|
45
46
|
|
|
46
47
|
[project.scripts]
|
|
47
|
-
unifi-network-maps = "
|
|
48
|
+
unifi-network-maps = "unifi_network_maps.cli:main"
|
|
48
49
|
|
|
49
50
|
[tool.ruff]
|
|
50
51
|
line-length = 100
|
|
@@ -59,10 +60,15 @@ line-ending = "lf"
|
|
|
59
60
|
|
|
60
61
|
[tool.pytest.ini_options]
|
|
61
62
|
testpaths = ["tests"]
|
|
63
|
+
norecursedirs = ["src/unifi_network_maps/assets"]
|
|
62
64
|
|
|
63
65
|
[tool.coverage.run]
|
|
64
66
|
branch = true
|
|
65
|
-
source = ["
|
|
67
|
+
source = ["unifi_network_maps"]
|
|
68
|
+
omit = [
|
|
69
|
+
"src/unifi_network_maps/assets/*",
|
|
70
|
+
"src/unifi_network_maps/assets/**",
|
|
71
|
+
]
|
|
66
72
|
|
|
67
73
|
[tool.coverage.report]
|
|
68
74
|
show_missing = true
|
|
@@ -71,7 +77,7 @@ show_missing = true
|
|
|
71
77
|
package-dir = {"" = "src"}
|
|
72
78
|
|
|
73
79
|
[tool.setuptools.package-data]
|
|
74
|
-
"
|
|
80
|
+
"unifi_network_maps" = [
|
|
75
81
|
"assets/icons/*.svg",
|
|
76
82
|
"assets/icons/isometric/*.svg",
|
|
77
83
|
"assets/icons/isometric/ISOPACKS_LICENSE",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.3.0"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Package module."""
|
|
@@ -26,7 +26,13 @@ class Config:
|
|
|
26
26
|
verify_ssl: bool
|
|
27
27
|
|
|
28
28
|
@classmethod
|
|
29
|
-
def from_env(cls) -> Config:
|
|
29
|
+
def from_env(cls, *, env_file: str | None = None) -> Config:
|
|
30
|
+
if env_file:
|
|
31
|
+
try:
|
|
32
|
+
from dotenv import load_dotenv
|
|
33
|
+
except ImportError:
|
|
34
|
+
raise ValueError("python-dotenv required for --env-file") from None
|
|
35
|
+
load_dotenv(dotenv_path=env_file)
|
|
30
36
|
url = os.environ.get("UNIFI_URL", "").strip()
|
|
31
37
|
site = os.environ.get("UNIFI_SITE", "default").strip()
|
|
32
38
|
user = os.environ.get("UNIFI_USER", "").strip()
|
|
@@ -20,7 +20,7 @@ logger = logging.getLogger(__name__)
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def _cache_dir() -> Path:
|
|
23
|
-
return Path(os.environ.get("UNIFI_CACHE_DIR", ".cache/
|
|
23
|
+
return Path(os.environ.get("UNIFI_CACHE_DIR", ".cache/unifi_network_maps"))
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def _cache_ttl_seconds() -> int:
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
mermaid:
|
|
2
|
+
nodes:
|
|
3
|
+
gateway:
|
|
4
|
+
fill: "#5c3b00"
|
|
5
|
+
stroke: "#ffb347"
|
|
6
|
+
switch:
|
|
7
|
+
fill: "#0f2b3d"
|
|
8
|
+
stroke: "#5dade2"
|
|
9
|
+
ap:
|
|
10
|
+
fill: "#0f3b2d"
|
|
11
|
+
stroke: "#2ecc71"
|
|
12
|
+
client:
|
|
13
|
+
fill: "#2b1f3b"
|
|
14
|
+
stroke: "#b084ff"
|
|
15
|
+
other:
|
|
16
|
+
fill: "#2a2a2a"
|
|
17
|
+
stroke: "#9e9e9e"
|
|
18
|
+
poe_link: "#64b5f6"
|
|
19
|
+
poe_link_width: 2
|
|
20
|
+
poe_link_arrow: "none"
|
|
21
|
+
standard_link: "#66bb6a"
|
|
22
|
+
standard_link_width: 2
|
|
23
|
+
standard_link_arrow: "none"
|
|
24
|
+
svg:
|
|
25
|
+
links:
|
|
26
|
+
standard:
|
|
27
|
+
from: "#66bb6a"
|
|
28
|
+
to: "#2e7d32"
|
|
29
|
+
poe:
|
|
30
|
+
from: "#64b5f6"
|
|
31
|
+
to: "#1e88e5"
|
|
32
|
+
nodes:
|
|
33
|
+
gateway:
|
|
34
|
+
from: "#5c3b00"
|
|
35
|
+
to: "#3e2a00"
|
|
36
|
+
switch:
|
|
37
|
+
from: "#0f2b3d"
|
|
38
|
+
to: "#0a1f2c"
|
|
39
|
+
ap:
|
|
40
|
+
from: "#0f3b2d"
|
|
41
|
+
to: "#0b2a20"
|
|
42
|
+
client:
|
|
43
|
+
from: "#2b1f3b"
|
|
44
|
+
to: "#20162b"
|
|
45
|
+
other:
|
|
46
|
+
from: "#2a2a2a"
|
|
47
|
+
to: "#1f1f1f"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
mermaid:
|
|
2
|
+
nodes:
|
|
3
|
+
gateway:
|
|
4
|
+
fill: "#ffe3b3"
|
|
5
|
+
stroke: "#d98300"
|
|
6
|
+
switch:
|
|
7
|
+
fill: "#d6ecff"
|
|
8
|
+
stroke: "#3a7bd5"
|
|
9
|
+
ap:
|
|
10
|
+
fill: "#d7f5e7"
|
|
11
|
+
stroke: "#27ae60"
|
|
12
|
+
client:
|
|
13
|
+
fill: "#f2e5ff"
|
|
14
|
+
stroke: "#7f3fbf"
|
|
15
|
+
other:
|
|
16
|
+
fill: "#eeeeee"
|
|
17
|
+
stroke: "#8f8f8f"
|
|
18
|
+
poe_link: "#1e88e5"
|
|
19
|
+
poe_link_width: 2
|
|
20
|
+
poe_link_arrow: "none"
|
|
21
|
+
standard_link: "#2ecc71"
|
|
22
|
+
standard_link_width: 2
|
|
23
|
+
standard_link_arrow: "none"
|
|
24
|
+
svg:
|
|
25
|
+
links:
|
|
26
|
+
standard:
|
|
27
|
+
from: "#2ecc71"
|
|
28
|
+
to: "#1b8f4a"
|
|
29
|
+
poe:
|
|
30
|
+
from: "#1e88e5"
|
|
31
|
+
to: "#0d47a1"
|
|
32
|
+
nodes:
|
|
33
|
+
gateway:
|
|
34
|
+
from: "#ffe3b3"
|
|
35
|
+
to: "#f7c77b"
|
|
36
|
+
switch:
|
|
37
|
+
from: "#d6ecff"
|
|
38
|
+
to: "#b6dcff"
|
|
39
|
+
ap:
|
|
40
|
+
from: "#d7f5e7"
|
|
41
|
+
to: "#b8f0d2"
|
|
42
|
+
client:
|
|
43
|
+
from: "#f2e5ff"
|
|
44
|
+
to: "#e0c9ff"
|
|
45
|
+
other:
|
|
46
|
+
from: "#eeeeee"
|
|
47
|
+
to: "#d7d7d7"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""CLI package facade."""
|
|
2
|
+
|
|
3
|
+
from .main import (
|
|
4
|
+
Config,
|
|
5
|
+
SvgOptions,
|
|
6
|
+
build_client_edges,
|
|
7
|
+
build_device_index,
|
|
8
|
+
build_node_type_map,
|
|
9
|
+
build_topology,
|
|
10
|
+
debug_dump_devices,
|
|
11
|
+
fetch_clients,
|
|
12
|
+
fetch_devices,
|
|
13
|
+
group_devices_by_type,
|
|
14
|
+
main,
|
|
15
|
+
normalize_devices,
|
|
16
|
+
render_legend,
|
|
17
|
+
render_mermaid,
|
|
18
|
+
render_svg,
|
|
19
|
+
resolve_themes,
|
|
20
|
+
write_output,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"Config",
|
|
25
|
+
"SvgOptions",
|
|
26
|
+
"build_client_edges",
|
|
27
|
+
"build_device_index",
|
|
28
|
+
"build_node_type_map",
|
|
29
|
+
"build_topology",
|
|
30
|
+
"debug_dump_devices",
|
|
31
|
+
"fetch_clients",
|
|
32
|
+
"fetch_devices",
|
|
33
|
+
"group_devices_by_type",
|
|
34
|
+
"main",
|
|
35
|
+
"normalize_devices",
|
|
36
|
+
"render_legend",
|
|
37
|
+
"render_mermaid",
|
|
38
|
+
"render_svg",
|
|
39
|
+
"resolve_themes",
|
|
40
|
+
"write_output",
|
|
41
|
+
]
|