python-netgear-switch-library 0.1.post2__tar.gz → 0.1.post4__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 (427) hide show
  1. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/PKG-INFO +1 -1
  2. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/debian/control +8 -3
  3. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/mcp.rst +28 -3
  4. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/_version.py +2 -2
  5. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/mcp/server.py +85 -6
  6. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_mcp_server.py +83 -0
  7. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/.github/workflows/ci.yml +0 -0
  8. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/.github/workflows/deb.yml +0 -0
  9. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/.github/workflows/publish-pypi.yml +0 -0
  10. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/.gitignore +0 -0
  11. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/.readthedocs.yaml +0 -0
  12. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/CLAUDE.md +0 -0
  13. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/LICENSE +0 -0
  14. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/README.md +0 -0
  15. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/RELEASING.md +0 -0
  16. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/debian/changelog +0 -0
  17. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/debian/copyright +0 -0
  18. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/debian/rules +0 -0
  19. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/debian/source/format +0 -0
  20. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/Makefile +0 -0
  21. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_ext/filelinks.py +0 -0
  22. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_ext/support_tables.py +0 -0
  23. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gs105pe.png +0 -0
  24. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gs110emx.png +0 -0
  25. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gs305ep.png +0 -0
  26. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gs728tpp.png +0 -0
  27. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gsm7228ps.jpg +0 -0
  28. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gsm7252ps.jpg +0 -0
  29. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/models/m4300-16x.png +0 -0
  30. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/models/m4300-24x.png +0 -0
  31. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/_static/ngsw.css +0 -0
  32. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/cli.rst +0 -0
  33. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/core.rst +0 -0
  34. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/facades.rst +0 -0
  35. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/index.rst +0 -0
  36. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/mcp.rst +0 -0
  37. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/operations.rst +0 -0
  38. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/protocols.rst +0 -0
  39. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/transport.rst +0 -0
  40. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/api/virtual.rst +0 -0
  41. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/cli.rst +0 -0
  42. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/conf.py +0 -0
  43. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/development.rst +0 -0
  44. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/fake/index.rst +0 -0
  45. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/fake/internals.rst +0 -0
  46. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/fake/serving.rst +0 -0
  47. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/fake/testing.rst +0 -0
  48. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/guide/concepts.rst +0 -0
  49. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/guide/configuration.rst +0 -0
  50. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/guide/installation.rst +0 -0
  51. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/guide/principles.rst +0 -0
  52. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/guide/quickstart.rst +0 -0
  53. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/guide/reading.rst +0 -0
  54. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/guide/writing.rst +0 -0
  55. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/index.rst +0 -0
  56. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/gs105pe.rst +0 -0
  57. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/gs110emx.rst +0 -0
  58. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/gs305ep.rst +0 -0
  59. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/gs728tpp.rst +0 -0
  60. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/gsm7228ps.rst +0 -0
  61. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/gsm7252ps.rst +0 -0
  62. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/index.rst +0 -0
  63. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/m4300-16x.rst +0 -0
  64. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/m4300-24x.rst +0 -0
  65. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/models/support.rst +0 -0
  66. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/cli.rst +0 -0
  67. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/cheetah-form.rst +0 -0
  68. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/cheetah-v1.rst +0 -0
  69. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/gambit.rst +0 -0
  70. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/merge-hash-cgi.rst +0 -0
  71. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/xml-api.rst +0 -0
  72. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/http.rst +0 -0
  73. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/index.rst +0 -0
  74. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/nsdp.rst +0 -0
  75. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/protocols/snmp.rst +0 -0
  76. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-15-foundation.md +0 -0
  77. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-17-slice-02-snmp-read-core.md +0 -0
  78. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-17-slice-03-read-apis.md +0 -0
  79. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-04-snmp-write.md +0 -0
  80. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-05-nsdp.md +0 -0
  81. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-06-http.md +0 -0
  82. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-07-cli.md +0 -0
  83. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-08-packaging-ci.md +0 -0
  84. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-23-gsm7252ps-http-xe-dialect.md +0 -0
  85. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-07-15-netgear-control-library-design.md +0 -0
  86. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-07-23-gsm7252ps-http-xe-dialect-design.md +0 -0
  87. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-08-02-gs728tpp-poe-vlan-live.md +0 -0
  88. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-08-02-snmp-surface-findings.md +0 -0
  89. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-08-03-snmp-vendor-oid-sweep.md +0 -0
  90. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/packaging/apt-index.html +0 -0
  91. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/packaging/ci-build.sh +0 -0
  92. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/packaging/deb-version.py +0 -0
  93. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/pyproject.toml +0 -0
  94. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/__init__.py +0 -0
  95. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/_dispatch.py +0 -0
  96. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/aio_api.py +0 -0
  97. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/capabilities.py +0 -0
  98. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/__init__.py +0 -0
  99. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/capture.py +0 -0
  100. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/context.py +0 -0
  101. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/format.py +0 -0
  102. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/main.py +0 -0
  103. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/resolve.py +0 -0
  104. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/safety.py +0 -0
  105. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli_read.py +0 -0
  106. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli_write.py +0 -0
  107. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/config.py +0 -0
  108. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/errors.py +0 -0
  109. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/http_read.py +0 -0
  110. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/http_write.py +0 -0
  111. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/mcp/__init__.py +0 -0
  112. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/models.py +0 -0
  113. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/nsdp_read.py +0 -0
  114. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/nsdp_write.py +0 -0
  115. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/__init__.py +0 -0
  116. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/cli/__init__.py +0 -0
  117. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/cli/commands.py +0 -0
  118. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/cli/parse.py +0 -0
  119. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/__init__.py +0 -0
  120. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/crypt.py +0 -0
  121. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/endpoints.py +0 -0
  122. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/forms.py +0 -0
  123. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/goahead.py +0 -0
  124. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/parse.py +0 -0
  125. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/session.py +0 -0
  126. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/types.py +0 -0
  127. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/__init__.py +0 -0
  128. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/auth.py +0 -0
  129. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/client.py +0 -0
  130. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/parsers.py +0 -0
  131. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/protocol.py +0 -0
  132. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/types.py +0 -0
  133. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/write.py +0 -0
  134. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/__init__.py +0 -0
  135. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/client.py +0 -0
  136. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/oids.py +0 -0
  137. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/parse.py +0 -0
  138. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/write.py +0 -0
  139. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/py.typed +0 -0
  140. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/registry.py +0 -0
  141. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/snmp_read.py +0 -0
  142. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/snmp_write.py +0 -0
  143. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/sync_api.py +0 -0
  144. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/__init__.py +0 -0
  145. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/aio/__init__.py +0 -0
  146. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/aio/nsdp_udp.py +0 -0
  147. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/aio/snmp_pysnmp.py +0 -0
  148. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/__init__.py +0 -0
  149. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/console.py +0 -0
  150. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/session.py +0 -0
  151. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/ssh.py +0 -0
  152. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/telnet.py +0 -0
  153. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/http/__init__.py +0 -0
  154. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/http/client.py +0 -0
  155. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/sync/__init__.py +0 -0
  156. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/sync/nsdp_udp.py +0 -0
  157. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/sync/snmp_netsnmp_cli.py +0 -0
  158. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/__init__.py +0 -0
  159. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/cli_fastpath.py +0 -0
  160. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/__init__.py +0 -0
  161. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/cli.py +0 -0
  162. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/http.py +0 -0
  163. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/mibview.py +0 -0
  164. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/nsdp.py +0 -0
  165. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/snmp.py +0 -0
  166. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/seed.py +0 -0
  167. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/server.py +0 -0
  168. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/state.py +0 -0
  169. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web.py +0 -0
  170. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_fastpath_vlan.py +0 -0
  171. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_fastpath_xui.py +0 -0
  172. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gs105pe.py +0 -0
  173. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gs110emx.py +0 -0
  174. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gs110emx_templates.py +0 -0
  175. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gs728tpp.py +0 -0
  176. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gsm7228ps.py +0 -0
  177. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gsm7252ps.py +0 -0
  178. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_m4300.py +0 -0
  179. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/capture_parity.py +0 -0
  180. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_capture.py +0 -0
  181. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_cli_integration.py +0 -0
  182. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_control_poe_port.py +0 -0
  183. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_control_vlan_ip.py +0 -0
  184. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_format.py +0 -0
  185. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_main_framework.py +0 -0
  186. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_new_commands.py +0 -0
  187. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_op_coverage.py +0 -0
  188. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_prompt_wiring.py +0 -0
  189. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_read_commands.py +0 -0
  190. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_resolve.py +0 -0
  191. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_safety.py +0 -0
  192. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/cli/test_serve.py +0 -0
  193. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/conftest.py +0 -0
  194. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/equivalence.py +0 -0
  195. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/captures/gsm7228ps.json +0 -0
  196. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/captures/gsm7252ps.json +0 -0
  197. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/captures/m4300-16x.json +0 -0
  198. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/captures/m4300-24x.json +0 -0
  199. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_environment.txt +0 -0
  200. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_lldp.txt +0 -0
  201. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_mac_table.txt +0 -0
  202. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_network.txt +0 -0
  203. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_poe.txt +0 -0
  204. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_port_all.txt +0 -0
  205. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_show_version.txt +0 -0
  206. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_vlan.txt +0 -0
  207. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_vlan_brief.txt +0 -0
  208. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_vlan_port_all.txt +0 -0
  209. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_environment.txt +0 -0
  210. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_interface_ethernet_1_0_1.txt +0 -0
  211. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_lldp_remote_device_all.txt +0 -0
  212. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_mac_addr_table.txt +0 -0
  213. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_network.txt +0 -0
  214. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_poe_port_info_all.txt +0 -0
  215. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_port_all.txt +0 -0
  216. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_version.txt +0 -0
  217. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_vlan_90.txt +0 -0
  218. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_vlan_brief.txt +0 -0
  219. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_vlan_port_all.txt +0 -0
  220. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_environment.txt +0 -0
  221. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_interface_ethernet_1_0_1.txt +0 -0
  222. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_ip_management.txt +0 -0
  223. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_lldp_remote_device_all.txt +0 -0
  224. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_mac_addr_table.txt +0 -0
  225. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_poe_port_info_all.txt +0 -0
  226. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_port_all.txt +0 -0
  227. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_version.txt +0 -0
  228. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan.txt +0 -0
  229. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan_1.txt +0 -0
  230. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan_4.txt +0 -0
  231. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan_5.txt +0 -0
  232. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan_port_all.txt +0 -0
  233. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_environment.txt +0 -0
  234. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_interface_ethernet_1_0_1.txt +0 -0
  235. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_ip_management.txt +0 -0
  236. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_lldp_remote_device_all.txt +0 -0
  237. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_mac_addr_table.txt +0 -0
  238. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_port_all.txt +0 -0
  239. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_version.txt +0 -0
  240. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_vlan.txt +0 -0
  241. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_vlan_5.txt +0 -0
  242. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_vlan_90.txt +0 -0
  243. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_vlan_port_all.txt +0 -0
  244. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_membership.html +0 -0
  245. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_portstats.html +0 -0
  246. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_pvid.html +0 -0
  247. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_status.html +0 -0
  248. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_switch_info.html +0 -0
  249. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_vlancfg.html +0 -0
  250. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_cf8021q.html +0 -0
  251. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_interface_stats.html +0 -0
  252. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_login.html +0 -0
  253. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_port_settings.html +0 -0
  254. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_pvid.html +0 -0
  255. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_redirect.html +0 -0
  256. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_sysinfo.html +0 -0
  257. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_vlanmembership.html +0 -0
  258. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_dashboard.html +0 -0
  259. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_login.html +0 -0
  260. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_membership.html +0 -0
  261. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_poestatus.html +0 -0
  262. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_portstats.html +0 -0
  263. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_pvid.html +0 -0
  264. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_vlancfg.html +0 -0
  265. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_device_info_and_sensors.xml +0 -0
  266. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_lldp.xml +0 -0
  267. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_macs.xml +0 -0
  268. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_mgmt_ip.xml +0 -0
  269. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_poe.xml +0 -0
  270. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_ports.xml +0 -0
  271. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_pvids_membership.xml +0 -0
  272. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_vlan_membership_per_vlan.xml +0 -0
  273. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_vlans.xml +0 -0
  274. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_basicAddressTable.html +0 -0
  275. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_http_configuration.html +0 -0
  276. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_ipConfiguration.html +0 -0
  277. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_lldpRemoteInventory.html +0 -0
  278. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_poeInterfaceConfiguration.html +0 -0
  279. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_portPvidConfiguration.html +0 -0
  280. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_portStatistics.html +0 -0
  281. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_portsConfiguration.html +0 -0
  282. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_sysInfo.html +0 -0
  283. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_syslog_configuration.html +0 -0
  284. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_vlanPortCfg_vlan5.html +0 -0
  285. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_vlanStatus.html +0 -0
  286. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_basicAddressTable.html +0 -0
  287. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_http_configuration.html +0 -0
  288. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_https_configuration.html +0 -0
  289. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_ipConfiguration.html +0 -0
  290. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_lldpRemoteInventory.html +0 -0
  291. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_login.html +0 -0
  292. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_poeInterfaceConfiguration.html +0 -0
  293. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_portPvidConfiguration.html +0 -0
  294. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_portStatistics.html +0 -0
  295. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_portsConfiguration.html +0 -0
  296. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_ssh_configuration.html +0 -0
  297. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_sysInfo.html +0 -0
  298. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_syslog_configuration.html +0 -0
  299. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_telnet.html +0 -0
  300. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_user_configuration.html +0 -0
  301. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_user_management.html +0 -0
  302. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlanPortCfg_vlan1.html +0 -0
  303. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlanPortCfg_vlan141.html +0 -0
  304. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlanStatus.html +0 -0
  305. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlan_add_form.html +0 -0
  306. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlan_configuration.js +0 -0
  307. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlan_configuration_live.html +0 -0
  308. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlan_status_live.html +0 -0
  309. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_lldpRemoteInventory.html +0 -0
  310. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_mgmtVlanIpv4Configuration.html +0 -0
  311. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_poeInterfaceConfiguration.html +0 -0
  312. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_portsConfiguration.html +0 -0
  313. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_syslog_configuration.html +0 -0
  314. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_vlanportcfg_vlan4.html +0 -0
  315. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_http_configuration.html +0 -0
  316. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_https_configuration.html +0 -0
  317. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_poeInterfaceConfiguration.html +0 -0
  318. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_ssh_configuration.html +0 -0
  319. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_syslog_configuration.html +0 -0
  320. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_telnet.html +0 -0
  321. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_user_management.html +0 -0
  322. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_addresstable.html +0 -0
  323. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_lldpRemoteInventory.html +0 -0
  324. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_mgmtVlanIpv4Configuration.html +0 -0
  325. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_ports.html +0 -0
  326. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_portstats.html +0 -0
  327. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_pvid.html +0 -0
  328. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_sysinfo.html +0 -0
  329. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_vlanportcfg_vlan1.html +0 -0
  330. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_vlanstatus.html +0 -0
  331. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/snmp/gsm7252ps_fans.txt +0 -0
  332. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/snmp/gsm7252ps_ifhighspeed.txt +0 -0
  333. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/snmp/gsm7252ps_ifoperstatus.txt +0 -0
  334. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/fixtures/snmp/gsm7252ps_psu.txt +0 -0
  335. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/http_specs.py +0 -0
  336. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/cli/test_cli_parse.py +0 -0
  337. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_crypt.py +0 -0
  338. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_endpoints.py +0 -0
  339. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_forms.py +0 -0
  340. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_goahead_write.py +0 -0
  341. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_parse.py +0 -0
  342. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/nsdp/test_auth.py +0 -0
  343. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/nsdp/test_parsers.py +0 -0
  344. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/nsdp/test_protocol.py +0 -0
  345. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/nsdp/test_write_frame.py +0 -0
  346. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_client.py +0 -0
  347. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_oids.py +0 -0
  348. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_lldp_macs.py +0 -0
  349. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_mgmt_ip.py +0 -0
  350. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_poe_sensors.py +0 -0
  351. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_ports.py +0 -0
  352. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_system_info.py +0 -0
  353. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_vlans.py +0 -0
  354. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_write_encode.py +0 -0
  355. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/snmp_fakes.py +0 -0
  356. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_aio_api.py +0 -0
  357. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_capabilities.py +0 -0
  358. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_cli_read.py +0 -0
  359. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_cli_vlan_write.py +0 -0
  360. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_cli_write.py +0 -0
  361. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_config.py +0 -0
  362. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_cross_backend_equivalence.py +0 -0
  363. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_deb_version.py +0 -0
  364. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_dispatch.py +0 -0
  365. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_docs_coverage.py +0 -0
  366. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_errors.py +0 -0
  367. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_facade_equivalence.py +0 -0
  368. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_flow_control.py +0 -0
  369. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_dispatch.py +0 -0
  370. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_equivalence.py +0 -0
  371. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_hostname_emx.py +0 -0
  372. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_read.py +0 -0
  373. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_services.py +0 -0
  374. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_syslog.py +0 -0
  375. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_users.py +0 -0
  376. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_vlan_membership.py +0 -0
  377. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_write.py +0 -0
  378. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_http_xui_writes.py +0 -0
  379. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_import.py +0 -0
  380. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_models.py +0 -0
  381. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_models_snmp_read.py +0 -0
  382. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_nsdp_integration.py +0 -0
  383. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_nsdp_read.py +0 -0
  384. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_nsdp_write.py +0 -0
  385. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_port_speed.py +0 -0
  386. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_port_speed_http.py +0 -0
  387. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_public_api.py +0 -0
  388. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_quality_gates.py +0 -0
  389. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_registry.py +0 -0
  390. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_snmp_integration.py +0 -0
  391. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_snmp_read.py +0 -0
  392. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_snmp_write.py +0 -0
  393. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_sync_api.py +0 -0
  394. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_syslog_collectors.py +0 -0
  395. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_version.py +0 -0
  396. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/test_write_equivalence.py +0 -0
  397. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/_fastpath_fake.py +0 -0
  398. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_cli_console.py +0 -0
  399. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_cli_scp_cert.py +0 -0
  400. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_cli_telnet.py +0 -0
  401. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_http_client.py +0 -0
  402. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_nsdp_udp_sync.py +0 -0
  403. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_set_transport.py +0 -0
  404. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_snmp_netsnmp_cli.py +0 -0
  405. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_snmp_pysnmp.py +0 -0
  406. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/transport/test_value_parity.py +0 -0
  407. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_cli_cross_backend.py +0 -0
  408. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_cli_gsm7228ps_parity.py +0 -0
  409. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_gs728tpp_vlan_fidelity.py +0 -0
  410. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_gsm7228ps_seed.py +0 -0
  411. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_hostname.py +0 -0
  412. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_m4300_seeds.py +0 -0
  413. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_mibview.py +0 -0
  414. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_mutable_state.py +0 -0
  415. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_nsdp_state.py +0 -0
  416. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_port_description_outcomes.py +0 -0
  417. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_serve_daemon.py +0 -0
  418. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_snmp_write_face.py +0 -0
  419. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_state_seed.py +0 -0
  420. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_switchport_vlan_write.py +0 -0
  421. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_syslog_fidelity.py +0 -0
  422. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_virtual_http_face.py +0 -0
  423. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_virtual_nsdp_face.py +0 -0
  424. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_virtual_snmp_face.py +0 -0
  425. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_web_projection.py +0 -0
  426. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_write_outcomes.py +0 -0
  427. {python_netgear_switch_library-0.1.post2 → python_netgear_switch_library-0.1.post4}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: python-netgear-switch-library
3
- Version: 0.1.post2
3
+ Version: 0.1.post4
4
4
  Summary: Python library and CLI to query and control Netgear switches over SNMP, NSDP and HTTP.
5
5
  Author-email: Tim Ansell <me@mith.ro>
6
6
  License-Expression: Apache-2.0
@@ -20,8 +20,11 @@ Architecture: all
20
20
  Depends: ${python3:Depends},
21
21
  ${misc:Depends},
22
22
  snmp
23
- Recommends: python3-httpx
24
- Suggests: python3-pysnmp
23
+ Recommends: python3-httpx,
24
+ python3-mcp
25
+ Suggests: python3-pysnmp,
26
+ python3-paramiko,
27
+ python3-serial
25
28
  Description: query and control Netgear switches over SNMP, NSDP and HTTP
26
29
  Python library (import name netgear_switch) and CLI (ngsw) to query and control
27
30
  Netgear managed and Plus switches behind one model-driven API. Managed switches
@@ -30,4 +33,6 @@ Description: query and control Netgear switches over SNMP, NSDP and HTTP
30
33
  The synchronous SNMP transport shells out to the net-snmp command-line tools
31
34
  (snmpget/snmpbulkwalk/snmpset) from the "snmp" package, which is why it is a
32
35
  hard runtime dependency. The optional asynchronous transport uses python3-pysnmp
33
- and the HTTP transport uses python3-httpx.
36
+ and the HTTP transport uses python3-httpx. The ngsw-mcp MCP server (installed
37
+ unconditionally) needs python3-mcp; the FASTPATH SSH/serial CLI backends need
38
+ python3-paramiko / python3-serial.
@@ -2,17 +2,32 @@ MCP server
2
2
  ==========
3
3
 
4
4
  ``ngsw-mcp`` exposes the library as `Model Context Protocol
5
- <https://modelcontextprotocol.io>`_ tools over stdio, so an LLM-driven client
6
- can inspect — and, if you let it, reconfigure — your switches.
5
+ <https://modelcontextprotocol.io>`_ tools, so an LLM-driven client can inspect
6
+ — and, if you let it, reconfigure — your switches.
7
7
 
8
8
  .. code-block:: sh
9
9
 
10
10
  pip install 'python-netgear-switch-library[mcp]'
11
- ngsw-mcp
11
+ ngsw-mcp # stdio: one client, on stdin/stdout
12
+ ngsw-mcp --transport streamable-http --host 127.0.0.1 --port 8766 # shared
13
+
14
+ Transports
15
+ ----------
16
+
17
+ ``--transport stdio`` (the default) serves the one client that spawned the
18
+ process. ``--transport streamable-http`` listens on ``--host``/``--port`` so any
19
+ number of clients share one long-lived server — for example a systemd
20
+ socket-activated service that several agents on the same host connect to.
21
+ Each option also has an environment form, ``NGSW_MCP_TRANSPORT``,
22
+ ``NGSW_MCP_HOST`` and ``NGSW_MCP_PORT`` (a flag beats the environment), so a
23
+ service unit can set them once and keep ``ExecStart=ngsw-mcp``. An invalid
24
+ transport or port — from either tier — is rejected at start-up.
12
25
 
13
26
  Configuring a client
14
27
  --------------------
15
28
 
29
+ A client that spawns its own server (stdio):
30
+
16
31
  .. code-block:: json
17
32
 
18
33
  {
@@ -32,6 +47,16 @@ Every tool resolves its target switch through the **same resolver the CLI uses**
32
47
  with credentials layered from arguments, environment and inventory. See
33
48
  :doc:`guide/configuration`.
34
49
 
50
+ A client connecting to a shared streamable-http server instead names its URL:
51
+
52
+ .. code-block:: json
53
+
54
+ {
55
+ "mcpServers": {
56
+ "netgear": {"type": "http", "url": "http://127.0.0.1:8765/mcp"}
57
+ }
58
+ }
59
+
35
60
  .. note::
36
61
 
37
62
  ``$NGSW_INVENTORY`` is an MCP-server convenience — an MCP client has no
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.1.post2'
22
- __version_tuple__ = version_tuple = (0, 1, 'post2')
21
+ __version__ = version = '0.1.post4'
22
+ __version_tuple__ = version_tuple = (0, 1, 'post4')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -37,6 +37,8 @@ from ..models import PortSpeed, VlanMode
37
37
  from ..registry import Backend
38
38
 
39
39
  if TYPE_CHECKING:
40
+ from collections.abc import Mapping, Sequence
41
+
40
42
  from ..sync_api import SyncSwitch
41
43
 
42
44
  _WRITE_ENV = "NGSW_MCP_ALLOW_WRITES"
@@ -168,13 +170,28 @@ def list_inventory_switches(
168
170
  ]
169
171
 
170
172
 
171
- def build_server(env: dict[str, str] | None = None): # type: ignore[no-untyped-def]
173
+ def build_server( # type: ignore[no-untyped-def]
174
+ env: dict[str, str] | None = None,
175
+ *,
176
+ host: str | None = None,
177
+ port: int | None = None,
178
+ ):
172
179
  """Construct the FastMCP server. Write tools are registered only when
173
- ``$NGSW_MCP_ALLOW_WRITES`` is set (see module docstring)."""
180
+ ``$NGSW_MCP_ALLOW_WRITES`` is set (see module docstring).
181
+
182
+ ``host``/``port`` are the bind address for the HTTP transport (see
183
+ :func:`main`); they are passed to FastMCP only when given, so the stdio
184
+ default is untouched.
185
+ """
174
186
  from mcp.server.fastmcp import FastMCP
175
187
 
176
188
  env = env if env is not None else dict(os.environ)
177
- mcp = FastMCP("netgear-switch")
189
+ bind: dict[str, Any] = {}
190
+ if host is not None:
191
+ bind["host"] = host
192
+ if port is not None:
193
+ bind["port"] = port
194
+ mcp = FastMCP("netgear-switch", **bind)
178
195
 
179
196
  def resolver(
180
197
  switch: str | None,
@@ -811,9 +828,71 @@ def _register_write_tools(mcp, resolver) -> None: # type: ignore[no-untyped-def
811
828
  )
812
829
 
813
830
 
814
- def main() -> None:
815
- """Entry point (``ngsw-mcp``): run the server over stdio."""
816
- build_server().run()
831
+ _TRANSPORTS = ("stdio", "streamable-http")
832
+ _TRANSPORT_ENV = "NGSW_MCP_TRANSPORT"
833
+ _HOST_ENV = "NGSW_MCP_HOST"
834
+ _PORT_ENV = "NGSW_MCP_PORT"
835
+
836
+
837
+ def _parse_args(
838
+ argv: Sequence[str] | None, env: Mapping[str, str]
839
+ ) -> argparse.Namespace:
840
+ """``ngsw-mcp`` options. Flag > ``$NGSW_MCP_*`` environment > default.
841
+
842
+ The environment tier exists for service managers: a systemd unit sets
843
+ ``Environment=NGSW_MCP_TRANSPORT=streamable-http`` once and the ExecStart
844
+ stays a bare ``ngsw-mcp``. Defaults are strings so argparse applies the
845
+ same ``choices``/``type`` validation to an env value as to a flag -- a
846
+ bad ``$NGSW_MCP_PORT`` is rejected up front, not at bind time.
847
+ """
848
+ ap = argparse.ArgumentParser(
849
+ prog="ngsw-mcp",
850
+ description=(
851
+ "MCP server over the python-netgear-switch-library read/write API. "
852
+ "stdio (default) serves one client on stdin/stdout; streamable-http "
853
+ "listens on --host:--port for any number of clients."
854
+ ),
855
+ )
856
+ ap.add_argument(
857
+ "--transport",
858
+ choices=_TRANSPORTS,
859
+ default=env.get(_TRANSPORT_ENV, "stdio"),
860
+ help=f"MCP transport (default: ${_TRANSPORT_ENV} or stdio)",
861
+ )
862
+ ap.add_argument(
863
+ "--host",
864
+ default=env.get(_HOST_ENV),
865
+ help=f"bind address for streamable-http (default: ${_HOST_ENV}, "
866
+ "else FastMCP's 127.0.0.1)",
867
+ )
868
+ ap.add_argument(
869
+ "--port",
870
+ type=int,
871
+ default=env.get(_PORT_ENV),
872
+ help=f"TCP port for streamable-http (default: ${_PORT_ENV}, "
873
+ "else FastMCP's 8000)",
874
+ )
875
+ args = ap.parse_args(argv)
876
+ # argparse validates `choices` only for values given on the command line,
877
+ # not for a default -- so an env-supplied transport is checked by hand.
878
+ if args.transport not in _TRANSPORTS:
879
+ ap.error(
880
+ f"argument --transport (from ${_TRANSPORT_ENV}): invalid choice: "
881
+ f"{args.transport!r} (choose from {', '.join(_TRANSPORTS)})"
882
+ )
883
+ return args
884
+
885
+
886
+ def main(
887
+ argv: Sequence[str] | None = None, env: Mapping[str, str] | None = None
888
+ ) -> None:
889
+ """Entry point (``ngsw-mcp``): build the server and run it over the chosen
890
+ transport -- stdio by default, or streamable-http on ``--host``/``--port``
891
+ for a shared, long-lived server (e.g. systemd socket activation)."""
892
+ env = env if env is not None else dict(os.environ)
893
+ args = _parse_args(argv, env)
894
+ server = build_server(dict(env), host=args.host, port=args.port)
895
+ server.run(transport=args.transport)
817
896
 
818
897
 
819
898
  if __name__ == "__main__":
@@ -443,3 +443,86 @@ def test_set_vlan_membership_rejects_bad_mode(monkeypatch) -> None:
443
443
  {"host": "h", "model": "gs110emx", "vlan": 90, "port": 1, "mode": "bogus"},
444
444
  )[0]
445
445
  assert "invalid mode" in res["error"]
446
+
447
+
448
+ # ---------------------------------------------------------------------------
449
+ # Entry point: transport selection (ngsw-mcp --transport / $NGSW_MCP_TRANSPORT)
450
+ # ---------------------------------------------------------------------------
451
+ # A shared, socket-activated ngsw-mcp (systemd --user on ten64, 2026-08-22) needs
452
+ # the server on a local TCP port; a per-client stdio server stays the default.
453
+
454
+
455
+ class _FakeServer:
456
+ def __init__(self, calls: dict[str, object]) -> None:
457
+ self._calls = calls
458
+
459
+ def run(self, transport: str = "stdio") -> None:
460
+ self._calls["transport"] = transport
461
+
462
+
463
+ def _fake_build(calls: dict[str, object]): # type: ignore[no-untyped-def]
464
+ def build(env=None, *, host=None, port=None): # type: ignore[no-untyped-def]
465
+ calls["host"] = host
466
+ calls["port"] = port
467
+ return _FakeServer(calls)
468
+
469
+ return build
470
+
471
+
472
+ def test_main_defaults_to_stdio(monkeypatch) -> None:
473
+ calls: dict[str, object] = {}
474
+ monkeypatch.setattr(mod, "build_server", _fake_build(calls))
475
+ mod.main([], env={})
476
+ assert calls == {"host": None, "port": None, "transport": "stdio"}
477
+
478
+
479
+ def test_main_streamable_http_flags_reach_the_server(monkeypatch) -> None:
480
+ calls: dict[str, object] = {}
481
+ monkeypatch.setattr(mod, "build_server", _fake_build(calls))
482
+ mod.main(
483
+ ["--transport", "streamable-http", "--host", "127.0.0.1", "--port", "8766"],
484
+ env={},
485
+ )
486
+ assert calls == {
487
+ "host": "127.0.0.1",
488
+ "port": 8766,
489
+ "transport": "streamable-http",
490
+ }
491
+
492
+
493
+ def test_main_env_supplies_defaults_and_flags_win(monkeypatch) -> None:
494
+ env = {
495
+ "NGSW_MCP_TRANSPORT": "streamable-http",
496
+ "NGSW_MCP_HOST": "127.0.0.1",
497
+ "NGSW_MCP_PORT": "9000",
498
+ }
499
+ calls: dict[str, object] = {}
500
+ monkeypatch.setattr(mod, "build_server", _fake_build(calls))
501
+ mod.main([], env=env)
502
+ assert calls == {"host": "127.0.0.1", "port": 9000, "transport": "streamable-http"}
503
+
504
+ calls.clear()
505
+ mod.main(["--port", "9001"], env=env)
506
+ assert calls["port"] == 9001
507
+ assert calls["transport"] == "streamable-http"
508
+
509
+
510
+ @pytest.mark.parametrize(
511
+ ("argv", "env"),
512
+ [
513
+ (["--transport", "sse"], {}),
514
+ ([], {"NGSW_MCP_TRANSPORT": "carrier-pigeon"}),
515
+ (["--port", "not-a-port"], {}),
516
+ ([], {"NGSW_MCP_PORT": "8765x"}),
517
+ ],
518
+ )
519
+ def test_main_rejects_bad_transport_or_port(monkeypatch, argv, env) -> None:
520
+ monkeypatch.setattr(mod, "build_server", _fake_build({}))
521
+ with pytest.raises(SystemExit) as exc:
522
+ mod.main(argv, env=env)
523
+ assert exc.value.code != 0
524
+
525
+
526
+ def test_build_server_applies_host_and_port() -> None:
527
+ srv = mod.build_server(env={}, host="127.0.0.1", port=8766)
528
+ assert (srv.settings.host, srv.settings.port) == ("127.0.0.1", 8766)