unifi-network-maps 1.3.0__tar.gz → 1.4.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 (110) hide show
  1. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/CHANGELOG.md +19 -2
  2. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/CONTRIBUTING.md +2 -1
  3. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/PKG-INFO +109 -18
  4. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/README.md +97 -3
  5. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/RELEASING.md +2 -1
  6. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/pyproject.toml +22 -19
  7. unifi_network_maps-1.4.0/src/unifi_network_maps/__init__.py +1 -0
  8. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/adapters/unifi.py +90 -9
  9. unifi_network_maps-1.4.0/src/unifi_network_maps/cli/main.py +614 -0
  10. unifi_network_maps-1.4.0/src/unifi_network_maps/io/mock_data.py +23 -0
  11. unifi_network_maps-1.4.0/src/unifi_network_maps/io/mock_generate.py +299 -0
  12. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/model/lldp.py +26 -12
  13. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/model/topology.py +141 -7
  14. unifi_network_maps-1.4.0/src/unifi_network_maps/render/device_ports_md.py +462 -0
  15. unifi_network_maps-1.4.0/src/unifi_network_maps/render/lldp_md.py +275 -0
  16. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/render/mermaid.py +67 -3
  17. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/render/svg.py +18 -6
  18. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps.egg-info/PKG-INFO +109 -18
  19. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps.egg-info/SOURCES.txt +7 -0
  20. unifi_network_maps-1.4.0/src/unifi_network_maps.egg-info/requires.txt +10 -0
  21. unifi_network_maps-1.4.0/tests/test_cli.py +442 -0
  22. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_clients.py +10 -1
  23. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_debug.py +2 -2
  24. unifi_network_maps-1.4.0/tests/test_device_ports_md.py +526 -0
  25. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_groups.py +6 -2
  26. unifi_network_maps-1.4.0/tests/test_lldp_md.py +296 -0
  27. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_mermaid.py +14 -2
  28. unifi_network_maps-1.4.0/tests/test_mock_generate.py +28 -0
  29. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_svg.py +8 -0
  30. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_svg_iso.py +8 -0
  31. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_topology.py +36 -0
  32. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_unifi.py +72 -0
  33. unifi_network_maps-1.3.0/src/unifi_network_maps/__init__.py +0 -1
  34. unifi_network_maps-1.3.0/src/unifi_network_maps/cli/main.py +0 -281
  35. unifi_network_maps-1.3.0/src/unifi_network_maps.egg-info/requires.txt +0 -9
  36. unifi_network_maps-1.3.0/tests/test_cli.py +0 -219
  37. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/LICENSE +0 -0
  38. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/LICENSES.md +0 -0
  39. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/MANIFEST.in +0 -0
  40. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/SECURITY.md +0 -0
  41. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/setup.cfg +0 -0
  42. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/adapters/__init__.py +0 -0
  43. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/adapters/config.py +0 -0
  44. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/__init__.py +0 -0
  45. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/__init__.py +0 -0
  46. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/access-point.svg +0 -0
  47. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/ISOPACKS_LICENSE +0 -0
  48. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/block.svg +0 -0
  49. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/cache.svg +0 -0
  50. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/cardterminal.svg +0 -0
  51. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/cloud.svg +0 -0
  52. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/cronjob.svg +0 -0
  53. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/cube.svg +0 -0
  54. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/desktop.svg +0 -0
  55. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/diamond.svg +0 -0
  56. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/dns.svg +0 -0
  57. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/document.svg +0 -0
  58. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/firewall.svg +0 -0
  59. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/function-module.svg +0 -0
  60. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/image.svg +0 -0
  61. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/laptop.svg +0 -0
  62. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/loadbalancer.svg +0 -0
  63. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/lock.svg +0 -0
  64. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/mail.svg +0 -0
  65. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/mailmultiple.svg +0 -0
  66. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/mobiledevice.svg +0 -0
  67. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/office.svg +0 -0
  68. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/package-module.svg +0 -0
  69. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/paymentcard.svg +0 -0
  70. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/plane.svg +0 -0
  71. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/printer.svg +0 -0
  72. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/pyramid.svg +0 -0
  73. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/queue.svg +0 -0
  74. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/router.svg +0 -0
  75. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/server.svg +0 -0
  76. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/speech.svg +0 -0
  77. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/sphere.svg +0 -0
  78. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/storage.svg +0 -0
  79. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/switch-module.svg +0 -0
  80. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/tower.svg +0 -0
  81. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/truck-2.svg +0 -0
  82. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/truck.svg +0 -0
  83. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/user.svg +0 -0
  84. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/isometric/vm.svg +0 -0
  85. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/laptop.svg +0 -0
  86. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/router-network.svg +0 -0
  87. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/server-network.svg +0 -0
  88. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/icons/server.svg +0 -0
  89. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/themes/dark.yaml +0 -0
  90. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/assets/themes/default.yaml +0 -0
  91. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/cli/__init__.py +0 -0
  92. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/cli/__main__.py +0 -0
  93. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/io/__init__.py +0 -0
  94. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/io/debug.py +0 -0
  95. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/io/export.py +0 -0
  96. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/model/__init__.py +0 -0
  97. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/model/labels.py +0 -0
  98. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/model/ports.py +0 -0
  99. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/render/__init__.py +0 -0
  100. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/render/mermaid_theme.py +0 -0
  101. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/render/svg_theme.py +0 -0
  102. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps/render/theme.py +0 -0
  103. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps.egg-info/dependency_links.txt +0 -0
  104. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps.egg-info/entry_points.txt +0 -0
  105. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/src/unifi_network_maps.egg-info/top_level.txt +0 -0
  106. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_config.py +0 -0
  107. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_export.py +0 -0
  108. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_labels.py +0 -0
  109. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_lldp.py +0 -0
  110. {unifi_network_maps-1.3.0 → unifi_network_maps-1.4.0}/tests/test_theme.py +0 -0
@@ -2,8 +2,25 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## Unreleased
6
- - TBD.
5
+ ## v1.4.0
6
+ - Added MkDocs output, which includes gateway/switch details and per-port tables.
7
+ - Port tables show speed, PoE status, power, and wired clients per port.
8
+ - Added compact legend with sidebar injection (`--mkdocs-sidebar-legend`).
9
+ - LLDP markdown includes the same device details and port tables when enabled.
10
+ - Improved uplink labeling (gateway shows Internet for WAN/unknown).
11
+ - Aggregated ports are combined into single LAG rows.
12
+ - Bumped minimum Python to 3.13 and aligned CI to 3.13.
13
+ - Pinned runtime/dev/build dependencies and added `requirements*.txt` + `constraints.txt`.
14
+ - Added `--mock-data` for safe, offline rendering from fixtures.
15
+ - Added Faker-powered `--generate-mock` for deterministic mock fixtures (dev-only).
16
+ - Added mock fixtures + SVG/Mermaid examples, with mock smoketest/CI steps.
17
+
18
+ ## v1.3.1
19
+ - Added `lldp-md` output with per-device details tables and optional client sections.
20
+ - Added `--client-scope wired|wireless|all` and dashed wireless client links in Mermaid/SVG.
21
+ - Expanded smoketest outputs for wireless/all client scopes and LLDP markdown.
22
+ - Fixed SVG icon loading paths after package reorg.
23
+ - Tuned isometric port label placement on front tiles.
7
24
 
8
25
  ## v1.3.0
9
26
  - Reorganized package into submodules (`adapters/`, `model/`, `render/`, `io/`, `cli/`).
@@ -7,7 +7,8 @@ Thanks for considering a contribution!
7
7
  ```bash
8
8
  python -m venv .venv
9
9
  source .venv/bin/activate
10
- pip install -e ".[dev]"
10
+ pip install -r requirements-build.txt
11
+ pip install -r requirements-dev.txt -c constraints.txt
11
12
  pre-commit install
12
13
  ```
13
14
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unifi-network-maps
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Dynamic UniFi -> network maps in mermaid or svg
5
5
  Author: Merlijn
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/merlijntishauser/unifi-network-maps
8
8
  Project-URL: Repository, https://github.com/merlijntishauser/unifi-network-maps
9
9
  Project-URL: Issues, https://github.com/merlijntishauser/unifi-network-maps/issues
@@ -11,27 +11,24 @@ Project-URL: Changelog, https://github.com/merlijntishauser/unifi-network-maps/b
11
11
  Keywords: unifi,mermaid,network,topology,diagram,svg
12
12
  Classifier: Development Status :: 3 - Alpha
13
13
  Classifier: Intended Audience :: System Administrators
14
- Classifier: License :: OSI Approved :: MIT License
15
14
  Classifier: Operating System :: OS Independent
16
15
  Classifier: Programming Language :: Python :: 3
17
16
  Classifier: Programming Language :: Python :: 3 :: Only
18
- Classifier: Programming Language :: Python :: 3.10
19
- Classifier: Programming Language :: Python :: 3.11
20
- Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
21
18
  Classifier: Topic :: Documentation
22
19
  Classifier: Topic :: System :: Networking
23
- Requires-Python: >=3.10
20
+ Requires-Python: >=3.13
24
21
  Description-Content-Type: text/markdown
25
22
  License-File: LICENSE
26
- License-File: LICENSES.md
27
- Requires-Dist: unifi-controller-api
28
- Requires-Dist: python-dotenv
29
- Requires-Dist: PyYAML
23
+ Requires-Dist: unifi-controller-api==0.3.2
24
+ Requires-Dist: python-dotenv==1.2.1
25
+ Requires-Dist: PyYAML==6.0.3
30
26
  Provides-Extra: dev
31
- Requires-Dist: pre-commit; extra == "dev"
32
- Requires-Dist: pytest; extra == "dev"
33
- Requires-Dist: pytest-cov; extra == "dev"
34
- Requires-Dist: ruff; extra == "dev"
27
+ Requires-Dist: Faker==40.1.0; extra == "dev"
28
+ Requires-Dist: pre-commit==4.5.1; extra == "dev"
29
+ Requires-Dist: pytest==9.0.2; extra == "dev"
30
+ Requires-Dist: pytest-cov==7.0.0; extra == "dev"
31
+ Requires-Dist: ruff==0.14.10; extra == "dev"
35
32
  Dynamic: license-file
36
33
 
37
34
  # unifi-network-maps
@@ -40,13 +37,14 @@ Dynamic UniFi -> Mermaid network maps generated from LLDP topology.
40
37
 
41
38
  ## Setup
42
39
 
43
- - Python >= 3.10
40
+ - Python >= 3.13
44
41
  - Virtualenv required
45
42
 
46
43
  ```bash
47
44
  python -m venv .venv
48
45
  source .venv/bin/activate
49
- pip install -e .
46
+ pip install -r requirements-build.txt
47
+ pip install -e . -c constraints.txt
50
48
  ```
51
49
 
52
50
  Local install (non-editable):
@@ -103,12 +101,24 @@ Isometric SVG output:
103
101
 
104
102
  ```bash
105
103
  unifi-network-maps --format svg-iso --output ./network.svg
104
+
105
+ # Single-page MkDocs output (ports included, no clients)
106
+ unifi-network-maps --format mkdocs --output ./docs/unifi-network.md
107
+
108
+ # MkDocs output (map + legend + gateway/switch port tables)
109
+ unifi-network-maps --format mkdocs --output ./docs/unifi-network.md
110
+
111
+ # Include wired clients in the port tables
112
+ unifi-network-maps --format mkdocs --include-clients --output ./docs/unifi-network.md
106
113
  ```
107
114
 
108
115
  SVG size overrides:
109
116
 
110
117
  ```bash
111
118
  unifi-network-maps --format svg --svg-width 1400 --svg-height 900 --output ./network.svg
119
+
120
+ # LLDP tables for troubleshooting
121
+ unifi-network-maps --format lldp-md --output ./lldp.md
112
122
  ```
113
123
 
114
124
  Legend only:
@@ -117,12 +127,61 @@ Legend only:
117
127
  unifi-network-maps --legend-only --stdout
118
128
  ```
119
129
 
130
+ ## Examples (mock data)
131
+
132
+ These examples are generated from `examples/mock_data.json` (safe, anonymized fixture).
133
+ Mock generation requires dev dependencies (`pip install -r requirements-dev.txt -c constraints.txt`).
134
+ Regenerate the fixture + SVG with `make mock-data`.
135
+
136
+ Generate mock data (dev-only, uses Faker):
137
+
138
+ ```bash
139
+ unifi-network-maps --generate-mock examples/mock_data.json --mock-seed 1337
140
+ ```
141
+
142
+ Generate the isometric SVG:
143
+
144
+ ```bash
145
+ unifi-network-maps --mock-data examples/mock_data.json \
146
+ --include-ports --include-clients --format svg-iso \
147
+ --output examples/output/network_ports_clients_iso.svg
148
+ ```
149
+
150
+ ![Isometric network example](examples/output/network_ports_clients_iso.svg)
151
+
152
+ Mermaid example with ports:
153
+
154
+ ```mermaid
155
+ graph TB
156
+ core_switch["Core Switch"] ---|"Core Switch: Port 7 (AP Attic) <-> AP Attic: Port 1 (Core Switch)"| ap_attic["AP Attic"];
157
+ core_switch["Core Switch"] ---|"Core Switch: Port 3 (AP Living Room) <-> AP Living Room: Port 1 (Core Switch)"| ap_living_room["AP Living Room"];
158
+ cloud_gateway["Cloud Gateway"] ---|"Cloud Gateway: Port 9 (Core Switch) <-> Core Switch: Port 1 (Cloud Gateway)"| core_switch["Core Switch"];
159
+ class cloud_gateway node_gateway;
160
+ class core_switch node_switch;
161
+ class ap_living_room node_ap;
162
+ class ap_attic node_ap;
163
+ classDef node_gateway fill:#ffe3b3,stroke:#d98300,stroke-width:1px;
164
+ classDef node_switch fill:#d6ecff,stroke:#3a7bd5,stroke-width:1px;
165
+ classDef node_ap fill:#d7f5e7,stroke:#27ae60,stroke-width:1px;
166
+ classDef node_client fill:#f2e5ff,stroke:#7f3fbf,stroke-width:1px;
167
+ classDef node_other fill:#eeeeee,stroke:#8f8f8f,stroke-width:1px;
168
+ classDef node_legend font-size:10px;
169
+ linkStyle 0 stroke:#1e88e5,stroke-width:2px,arrowhead:none;
170
+ linkStyle 1 stroke:#1e88e5,stroke-width:2px,arrowhead:none;
171
+ ```
172
+
120
173
  ## Local install check
121
174
 
122
175
  ```bash
123
176
  pip install .
124
177
  ```
125
178
 
179
+ ## Dev
180
+
181
+ ```bash
182
+ pip install -r requirements-dev.txt -c constraints.txt
183
+ ```
184
+
126
185
  ## Release
127
186
 
128
187
  Build and upload to PyPI:
@@ -142,6 +201,20 @@ git push origin vX.Y.Z
142
201
 
143
202
  See `LICENSES.md` for third-party license info.
144
203
 
204
+ ## Installation
205
+
206
+ PyPI: https://pypi.org/project/unifi-network-maps/
207
+
208
+ ```bash
209
+ pip install unifi-network-maps
210
+ ```
211
+
212
+ Then run:
213
+
214
+ ```bash
215
+ unifi-network-maps --help
216
+ ```
217
+
145
218
  ## Options
146
219
 
147
220
  The CLI groups options by category (`Source`, `Functional`, `Mermaid`, `SVG`, `Output`, `Debug`).
@@ -149,15 +222,26 @@ The CLI groups options by category (`Source`, `Functional`, `Mermaid`, `SVG`, `O
149
222
  Source:
150
223
  - `--site`: override `UNIFI_SITE`.
151
224
  - `--env-file`: load environment variables from a specific `.env` file.
225
+ - `--mock-data`: use mock data JSON instead of the UniFi API.
226
+ Mock:
227
+ - `--generate-mock`: write mock data JSON and exit.
228
+ - `--mock-seed`: seed for deterministic mock generation.
229
+ - `--mock-switches`: number of switches to generate.
230
+ - `--mock-aps`: number of access points to generate.
231
+ - `--mock-wired-clients`: number of wired clients to generate.
232
+ - `--mock-wireless-clients`: number of wireless clients to generate.
152
233
 
153
234
  Functional:
154
235
  - `--include-ports`: show port labels (Mermaid shows both ends; SVG shows compact labels).
155
236
  - `--include-clients`: add active wired clients as leaf nodes.
237
+ - `--client-scope wired|wireless|all`: which client types to include (default wired).
156
238
  - `--only-unifi`: only include neighbors that are UniFi devices.
157
239
 
158
240
  Mermaid:
159
241
  - `--direction LR|TB`: diagram direction for Mermaid (default TB).
160
242
  - `--group-by-type`: group nodes by gateway/switch/AP in Mermaid subgraphs.
243
+ - `--legend-scale`: scale legend font/link sizes for Mermaid outputs (default 1.0).
244
+ - `--legend-style auto|compact|diagram`: legend rendering mode (auto uses compact for mkdocs).
161
245
  - `--legend-only`: render just the legend as a separate Mermaid graph (Mermaid only).
162
246
 
163
247
  SVG:
@@ -165,9 +249,10 @@ SVG:
165
249
  - `--theme-file`: load a YAML theme for Mermaid + SVG colors (see `examples/theme.yaml` and `examples/theme-dark.yaml`).
166
250
 
167
251
  Output:
168
- - `--format mermaid|svg|svg-iso`: output format (default mermaid).
252
+ - `--format mermaid|svg|svg-iso|lldp-md|mkdocs`: output format (default mermaid).
169
253
  - `--stdout`: write output to stdout.
170
254
  - `--markdown`: wrap Mermaid output in a code fence.
255
+ - `--mkdocs-sidebar-legend`: write assets to place the compact legend in the MkDocs right sidebar.
171
256
 
172
257
  Debug:
173
258
  - `--debug-dump`: dump gateway + sample devices to stderr for debugging.
@@ -178,6 +263,7 @@ Debug:
178
263
  - Default output is top-to-bottom (TB) and rendered as a hop-based tree from the gateway(s).
179
264
  - Nodes are color-coded by type (gateway/switch/AP/client) with a sensible default palette.
180
265
  - PoE links are highlighted in blue and annotated with a power icon when detected from `port_table`.
266
+ - Wireless client links render as dashed lines to indicate the last-known upstream.
181
267
  - SVG output uses vendored device glyphs from `src/unifi_network_maps/assets/icons`.
182
268
  - Isometric SVG output uses MIT-licensed icons from `markmanx/isopacks`.
183
269
  - SVG port labels render inside child nodes for readability.
@@ -211,5 +297,10 @@ svg:
211
297
  to: "#b6dcff"
212
298
  ```
213
299
 
300
+ ## MkDocs Material example
301
+
302
+ See `examples/mkdocs/` for a ready-to-use setup that renders Mermaid diagrams
303
+ with Material for MkDocs, including a sample `unifi-network` page and legend.
304
+
214
305
  The built-in themes live at `src/unifi_network_maps/assets/themes/default.yaml` and
215
306
  `src/unifi_network_maps/assets/themes/dark.yaml`.
@@ -4,13 +4,14 @@ Dynamic UniFi -> Mermaid network maps generated from LLDP topology.
4
4
 
5
5
  ## Setup
6
6
 
7
- - Python >= 3.10
7
+ - Python >= 3.13
8
8
  - Virtualenv required
9
9
 
10
10
  ```bash
11
11
  python -m venv .venv
12
12
  source .venv/bin/activate
13
- pip install -e .
13
+ pip install -r requirements-build.txt
14
+ pip install -e . -c constraints.txt
14
15
  ```
15
16
 
16
17
  Local install (non-editable):
@@ -67,12 +68,24 @@ Isometric SVG output:
67
68
 
68
69
  ```bash
69
70
  unifi-network-maps --format svg-iso --output ./network.svg
71
+
72
+ # Single-page MkDocs output (ports included, no clients)
73
+ unifi-network-maps --format mkdocs --output ./docs/unifi-network.md
74
+
75
+ # MkDocs output (map + legend + gateway/switch port tables)
76
+ unifi-network-maps --format mkdocs --output ./docs/unifi-network.md
77
+
78
+ # Include wired clients in the port tables
79
+ unifi-network-maps --format mkdocs --include-clients --output ./docs/unifi-network.md
70
80
  ```
71
81
 
72
82
  SVG size overrides:
73
83
 
74
84
  ```bash
75
85
  unifi-network-maps --format svg --svg-width 1400 --svg-height 900 --output ./network.svg
86
+
87
+ # LLDP tables for troubleshooting
88
+ unifi-network-maps --format lldp-md --output ./lldp.md
76
89
  ```
77
90
 
78
91
  Legend only:
@@ -81,12 +94,61 @@ Legend only:
81
94
  unifi-network-maps --legend-only --stdout
82
95
  ```
83
96
 
97
+ ## Examples (mock data)
98
+
99
+ These examples are generated from `examples/mock_data.json` (safe, anonymized fixture).
100
+ Mock generation requires dev dependencies (`pip install -r requirements-dev.txt -c constraints.txt`).
101
+ Regenerate the fixture + SVG with `make mock-data`.
102
+
103
+ Generate mock data (dev-only, uses Faker):
104
+
105
+ ```bash
106
+ unifi-network-maps --generate-mock examples/mock_data.json --mock-seed 1337
107
+ ```
108
+
109
+ Generate the isometric SVG:
110
+
111
+ ```bash
112
+ unifi-network-maps --mock-data examples/mock_data.json \
113
+ --include-ports --include-clients --format svg-iso \
114
+ --output examples/output/network_ports_clients_iso.svg
115
+ ```
116
+
117
+ ![Isometric network example](examples/output/network_ports_clients_iso.svg)
118
+
119
+ Mermaid example with ports:
120
+
121
+ ```mermaid
122
+ graph TB
123
+ core_switch["Core Switch"] ---|"Core Switch: Port 7 (AP Attic) <-> AP Attic: Port 1 (Core Switch)"| ap_attic["AP Attic"];
124
+ core_switch["Core Switch"] ---|"Core Switch: Port 3 (AP Living Room) <-> AP Living Room: Port 1 (Core Switch)"| ap_living_room["AP Living Room"];
125
+ cloud_gateway["Cloud Gateway"] ---|"Cloud Gateway: Port 9 (Core Switch) <-> Core Switch: Port 1 (Cloud Gateway)"| core_switch["Core Switch"];
126
+ class cloud_gateway node_gateway;
127
+ class core_switch node_switch;
128
+ class ap_living_room node_ap;
129
+ class ap_attic node_ap;
130
+ classDef node_gateway fill:#ffe3b3,stroke:#d98300,stroke-width:1px;
131
+ classDef node_switch fill:#d6ecff,stroke:#3a7bd5,stroke-width:1px;
132
+ classDef node_ap fill:#d7f5e7,stroke:#27ae60,stroke-width:1px;
133
+ classDef node_client fill:#f2e5ff,stroke:#7f3fbf,stroke-width:1px;
134
+ classDef node_other fill:#eeeeee,stroke:#8f8f8f,stroke-width:1px;
135
+ classDef node_legend font-size:10px;
136
+ linkStyle 0 stroke:#1e88e5,stroke-width:2px,arrowhead:none;
137
+ linkStyle 1 stroke:#1e88e5,stroke-width:2px,arrowhead:none;
138
+ ```
139
+
84
140
  ## Local install check
85
141
 
86
142
  ```bash
87
143
  pip install .
88
144
  ```
89
145
 
146
+ ## Dev
147
+
148
+ ```bash
149
+ pip install -r requirements-dev.txt -c constraints.txt
150
+ ```
151
+
90
152
  ## Release
91
153
 
92
154
  Build and upload to PyPI:
@@ -106,6 +168,20 @@ git push origin vX.Y.Z
106
168
 
107
169
  See `LICENSES.md` for third-party license info.
108
170
 
171
+ ## Installation
172
+
173
+ PyPI: https://pypi.org/project/unifi-network-maps/
174
+
175
+ ```bash
176
+ pip install unifi-network-maps
177
+ ```
178
+
179
+ Then run:
180
+
181
+ ```bash
182
+ unifi-network-maps --help
183
+ ```
184
+
109
185
  ## Options
110
186
 
111
187
  The CLI groups options by category (`Source`, `Functional`, `Mermaid`, `SVG`, `Output`, `Debug`).
@@ -113,15 +189,26 @@ The CLI groups options by category (`Source`, `Functional`, `Mermaid`, `SVG`, `O
113
189
  Source:
114
190
  - `--site`: override `UNIFI_SITE`.
115
191
  - `--env-file`: load environment variables from a specific `.env` file.
192
+ - `--mock-data`: use mock data JSON instead of the UniFi API.
193
+ Mock:
194
+ - `--generate-mock`: write mock data JSON and exit.
195
+ - `--mock-seed`: seed for deterministic mock generation.
196
+ - `--mock-switches`: number of switches to generate.
197
+ - `--mock-aps`: number of access points to generate.
198
+ - `--mock-wired-clients`: number of wired clients to generate.
199
+ - `--mock-wireless-clients`: number of wireless clients to generate.
116
200
 
117
201
  Functional:
118
202
  - `--include-ports`: show port labels (Mermaid shows both ends; SVG shows compact labels).
119
203
  - `--include-clients`: add active wired clients as leaf nodes.
204
+ - `--client-scope wired|wireless|all`: which client types to include (default wired).
120
205
  - `--only-unifi`: only include neighbors that are UniFi devices.
121
206
 
122
207
  Mermaid:
123
208
  - `--direction LR|TB`: diagram direction for Mermaid (default TB).
124
209
  - `--group-by-type`: group nodes by gateway/switch/AP in Mermaid subgraphs.
210
+ - `--legend-scale`: scale legend font/link sizes for Mermaid outputs (default 1.0).
211
+ - `--legend-style auto|compact|diagram`: legend rendering mode (auto uses compact for mkdocs).
125
212
  - `--legend-only`: render just the legend as a separate Mermaid graph (Mermaid only).
126
213
 
127
214
  SVG:
@@ -129,9 +216,10 @@ SVG:
129
216
  - `--theme-file`: load a YAML theme for Mermaid + SVG colors (see `examples/theme.yaml` and `examples/theme-dark.yaml`).
130
217
 
131
218
  Output:
132
- - `--format mermaid|svg|svg-iso`: output format (default mermaid).
219
+ - `--format mermaid|svg|svg-iso|lldp-md|mkdocs`: output format (default mermaid).
133
220
  - `--stdout`: write output to stdout.
134
221
  - `--markdown`: wrap Mermaid output in a code fence.
222
+ - `--mkdocs-sidebar-legend`: write assets to place the compact legend in the MkDocs right sidebar.
135
223
 
136
224
  Debug:
137
225
  - `--debug-dump`: dump gateway + sample devices to stderr for debugging.
@@ -142,6 +230,7 @@ Debug:
142
230
  - Default output is top-to-bottom (TB) and rendered as a hop-based tree from the gateway(s).
143
231
  - Nodes are color-coded by type (gateway/switch/AP/client) with a sensible default palette.
144
232
  - PoE links are highlighted in blue and annotated with a power icon when detected from `port_table`.
233
+ - Wireless client links render as dashed lines to indicate the last-known upstream.
145
234
  - SVG output uses vendored device glyphs from `src/unifi_network_maps/assets/icons`.
146
235
  - Isometric SVG output uses MIT-licensed icons from `markmanx/isopacks`.
147
236
  - SVG port labels render inside child nodes for readability.
@@ -175,5 +264,10 @@ svg:
175
264
  to: "#b6dcff"
176
265
  ```
177
266
 
267
+ ## MkDocs Material example
268
+
269
+ See `examples/mkdocs/` for a ready-to-use setup that renders Mermaid diagrams
270
+ with Material for MkDocs, including a sample `unifi-network` page and legend.
271
+
178
272
  The built-in themes live at `src/unifi_network_maps/assets/themes/default.yaml` and
179
273
  `src/unifi_network_maps/assets/themes/dark.yaml`.
@@ -10,7 +10,8 @@
10
10
  ```
11
11
  3) Build the package:
12
12
  ```bash
13
- python -m pip install build twine
13
+ python -m pip install -r requirements-build.txt
14
+ python -m pip install build twine -c constraints.txt
14
15
  python -m build
15
16
  ```
16
17
  4) Inspect the artifacts:
@@ -1,33 +1,31 @@
1
1
  [build-system]
2
- requires = ["setuptools>=68", "wheel"]
2
+ requires = ["setuptools==80.9.0", "wheel==0.45.1"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "unifi-network-maps"
7
- version = "1.3.0"
7
+ version = "1.4.0"
8
8
  description = "Dynamic UniFi -> network maps in mermaid or svg"
9
9
  readme = "README.md"
10
- requires-python = ">=3.10"
11
- license = { text = "MIT" }
10
+ requires-python = ">=3.13"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
12
13
  authors = [{ name = "Merlijn" }]
13
14
  keywords = ["unifi", "mermaid", "network", "topology", "diagram", "svg"]
14
15
  classifiers = [
15
16
  "Development Status :: 3 - Alpha",
16
17
  "Intended Audience :: System Administrators",
17
- "License :: OSI Approved :: MIT License",
18
18
  "Operating System :: OS Independent",
19
19
  "Programming Language :: Python :: 3",
20
20
  "Programming Language :: Python :: 3 :: Only",
21
- "Programming Language :: Python :: 3.10",
22
- "Programming Language :: Python :: 3.11",
23
- "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
24
22
  "Topic :: Documentation",
25
23
  "Topic :: System :: Networking",
26
24
  ]
27
25
  dependencies = [
28
- "unifi-controller-api",
29
- "python-dotenv",
30
- "PyYAML",
26
+ "unifi-controller-api==0.3.2",
27
+ "python-dotenv==1.2.1",
28
+ "PyYAML==6.0.3",
31
29
  ]
32
30
 
33
31
  [project.urls]
@@ -38,10 +36,11 @@ Changelog = "https://github.com/merlijntishauser/unifi-network-maps/blob/main/CH
38
36
 
39
37
  [project.optional-dependencies]
40
38
  dev = [
41
- "pre-commit",
42
- "pytest",
43
- "pytest-cov",
44
- "ruff",
39
+ "Faker==40.1.0",
40
+ "pre-commit==4.5.1",
41
+ "pytest==9.0.2",
42
+ "pytest-cov==7.0.0",
43
+ "ruff==0.14.10",
45
44
  ]
46
45
 
47
46
  [project.scripts]
@@ -49,7 +48,7 @@ unifi-network-maps = "unifi_network_maps.cli:main"
49
48
 
50
49
  [tool.ruff]
51
50
  line-length = 100
52
- target-version = "py310"
51
+ target-version = "py313"
53
52
 
54
53
  [tool.ruff.lint]
55
54
  select = ["E", "F", "I", "B", "UP"]
@@ -61,13 +60,17 @@ line-ending = "lf"
61
60
  [tool.pytest.ini_options]
62
61
  testpaths = ["tests"]
63
62
  norecursedirs = ["src/unifi_network_maps/assets"]
63
+ # Remove --cov from here so it doesn't conflict with PyCharm's runner
64
+ addopts = "-ra"
64
65
 
65
66
  [tool.coverage.run]
66
67
  branch = true
67
68
  source = ["unifi_network_maps"]
68
- omit = [
69
- "src/unifi_network_maps/assets/*",
70
- "src/unifi_network_maps/assets/**",
69
+
70
+ [tool.coverage.paths]
71
+ source = [
72
+ "src/unifi_network_maps",
73
+ "*/site-packages/unifi_network_maps",
71
74
  ]
72
75
 
73
76
  [tool.coverage.report]
@@ -0,0 +1 @@
1
+ __version__ = "1.4.0"