python-netgear-switch-library 0.0.post405__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.
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/.github/workflows/ci.yml +4 -1
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/.github/workflows/deb.yml +23 -8
- python_netgear_switch_library-0.1.post4/.github/workflows/publish-pypi.yml +71 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/PKG-INFO +4 -4
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/README.md +3 -3
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/RELEASING.md +29 -9
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/debian/control +8 -3
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/guide/installation.rst +8 -7
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/mcp.rst +28 -3
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/packaging/apt-index.html +4 -4
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/pyproject.toml +10 -5
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/_version.py +2 -2
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/mcp/server.py +85 -6
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_deb_version.py +40 -11
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_mcp_server.py +83 -0
- python_netgear_switch_library-0.0.post405/.github/workflows/publish-pypi.yml +0 -52
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/.gitignore +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/.readthedocs.yaml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/CLAUDE.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/LICENSE +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/debian/changelog +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/debian/copyright +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/debian/rules +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/debian/source/format +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/Makefile +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_ext/filelinks.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_ext/support_tables.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gs105pe.png +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gs110emx.png +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gs305ep.png +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gs728tpp.png +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gsm7228ps.jpg +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/models/gsm7252ps.jpg +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/models/m4300-16x.png +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/models/m4300-24x.png +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/_static/ngsw.css +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/cli.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/core.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/facades.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/index.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/mcp.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/operations.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/protocols.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/transport.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/api/virtual.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/cli.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/conf.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/development.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/fake/index.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/fake/internals.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/fake/serving.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/fake/testing.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/guide/concepts.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/guide/configuration.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/guide/principles.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/guide/quickstart.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/guide/reading.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/guide/writing.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/index.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/gs105pe.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/gs110emx.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/gs305ep.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/gs728tpp.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/gsm7228ps.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/gsm7252ps.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/index.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/m4300-16x.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/m4300-24x.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/models/support.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/cli.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/cheetah-form.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/cheetah-v1.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/gambit.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/merge-hash-cgi.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/http/xml-api.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/http.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/index.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/nsdp.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/protocols/snmp.rst +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-15-foundation.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-17-slice-02-snmp-read-core.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-17-slice-03-read-apis.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-04-snmp-write.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-05-nsdp.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-06-http.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-07-cli.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-18-slice-08-packaging-ci.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/plans/2026-07-23-gsm7252ps-http-xe-dialect.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-07-15-netgear-control-library-design.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-07-23-gsm7252ps-http-xe-dialect-design.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-08-02-gs728tpp-poe-vlan-live.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-08-02-snmp-surface-findings.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/superpowers/specs/2026-08-03-snmp-vendor-oid-sweep.md +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/packaging/ci-build.sh +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/packaging/deb-version.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/aio_api.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/capabilities.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/capture.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/context.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/format.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/main.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/resolve.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli/safety.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/cli_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/config.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/errors.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/http_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/http_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/mcp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/models.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/nsdp_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/nsdp_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/cli/commands.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/cli/parse.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/crypt.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/endpoints.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/forms.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/goahead.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/parse.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/session.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/http/types.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/auth.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/client.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/parsers.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/protocol.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/types.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/nsdp/write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/client.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/oids.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/parse.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/protocols/snmp/write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/py.typed +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/registry.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/snmp_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/sync_api.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/aio/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/aio/nsdp_udp.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/aio/snmp_pysnmp.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/console.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/session.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/ssh.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/cli/telnet.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/http/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/http/client.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/sync/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/sync/nsdp_udp.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/transport/sync/snmp_netsnmp_cli.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/cli_fastpath.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/cli.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/http.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/mibview.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/nsdp.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/faces/snmp.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/seed.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/server.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/state.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_fastpath_vlan.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_fastpath_xui.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gs105pe.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gs110emx.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gs110emx_templates.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gs728tpp.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gsm7228ps.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_gsm7252ps.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/src/netgear_switch/virtual/web_m4300.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/capture_parity.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_capture.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_cli_integration.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_control_poe_port.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_control_vlan_ip.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_format.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_main_framework.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_new_commands.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_op_coverage.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_prompt_wiring.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_read_commands.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_resolve.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_safety.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/cli/test_serve.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/conftest.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/captures/gsm7228ps.json +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/captures/gsm7252ps.json +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/captures/m4300-16x.json +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/captures/m4300-24x.json +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_lldp.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_mac_table.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_network.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_poe.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_vlan_brief.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7228ps_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_network.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_poe_port_info_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_vlan_90.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_vlan_brief.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/gsm7252ps_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_ip_management.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_poe_port_info_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan_1.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan_4.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan_5.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_16x_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_ip_management.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_vlan_5.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_vlan_90.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/cli/m4300_24x_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_membership.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_status.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_switch_info.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs105pe_vlancfg.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_cf8021q.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_interface_stats.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_login.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_port_settings.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_redirect.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_sysinfo.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs110emx_vlanmembership.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_dashboard.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_login.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_membership.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_poestatus.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs305ep_vlancfg.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_device_info_and_sensors.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_lldp.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_macs.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_mgmt_ip.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_poe.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_ports.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_pvids_membership.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_vlan_membership_per_vlan.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gs728tpp_vlans.xml +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_basicAddressTable.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_http_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_ipConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_portPvidConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_portStatistics.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_sysInfo.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_syslog_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_vlanPortCfg_vlan5.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7228ps_vlanStatus.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_basicAddressTable.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_http_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_https_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_ipConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_login.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_portPvidConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_portStatistics.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_ssh_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_sysInfo.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_syslog_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_telnet.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_user_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_user_management.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlanPortCfg_vlan1.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlanPortCfg_vlan141.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlanStatus.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlan_add_form.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlan_configuration.js +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlan_configuration_live.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/gsm7252ps_vlan_status_live.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_mgmtVlanIpv4Configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_syslog_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_16x_vlanportcfg_vlan4.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_http_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_https_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_ssh_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_syslog_configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_telnet.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_24x_user_management.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_addresstable.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_mgmtVlanIpv4Configuration.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_ports.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_sysinfo.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_vlanportcfg_vlan1.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/http/m4300_vlanstatus.html +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/snmp/gsm7252ps_fans.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/snmp/gsm7252ps_ifhighspeed.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/snmp/gsm7252ps_ifoperstatus.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/fixtures/snmp/gsm7252ps_psu.txt +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/http_specs.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/cli/test_cli_parse.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_crypt.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_endpoints.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_forms.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_goahead_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/http/test_parse.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/nsdp/test_auth.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/nsdp/test_parsers.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/nsdp/test_protocol.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/nsdp/test_write_frame.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_client.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_oids.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_lldp_macs.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_mgmt_ip.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_poe_sensors.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_ports.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_system_info.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_parse_vlans.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/protocols/snmp/test_write_encode.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/snmp_fakes.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_aio_api.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_capabilities.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_cli_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_cli_vlan_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_cli_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_config.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_cross_backend_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_docs_coverage.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_errors.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_facade_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_flow_control.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_hostname_emx.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_services.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_syslog.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_users.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_vlan_membership.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_http_xui_writes.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_import.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_models.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_models_snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_nsdp_integration.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_nsdp_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_nsdp_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_port_speed.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_port_speed_http.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_public_api.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_quality_gates.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_registry.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_snmp_integration.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_snmp_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_sync_api.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_syslog_collectors.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_version.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/test_write_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/_fastpath_fake.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_cli_console.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_cli_scp_cert.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_cli_telnet.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_http_client.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_nsdp_udp_sync.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_set_transport.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_snmp_netsnmp_cli.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_snmp_pysnmp.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/transport/test_value_parity.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_cli_cross_backend.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_cli_gsm7228ps_parity.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_gs728tpp_vlan_fidelity.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_gsm7228ps_seed.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_hostname.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_m4300_seeds.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_mibview.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_mutable_state.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_nsdp_state.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_port_description_outcomes.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_serve_daemon.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_snmp_write_face.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_state_seed.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_switchport_vlan_write.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_syslog_fidelity.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_virtual_http_face.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_virtual_nsdp_face.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_virtual_snmp_face.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_web_projection.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/tests/virtual/test_write_outcomes.py +0 -0
- {python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/uv.lock +0 -0
|
@@ -2,7 +2,10 @@ name: CI
|
|
|
2
2
|
|
|
3
3
|
# Runs the SAME gates as local development (ruff, mypy --strict, pytest with
|
|
4
4
|
# coverage >= 90) on every push to main and every pull request. A green run here
|
|
5
|
-
# is what "mergeable" means
|
|
5
|
+
# is what "mergeable" means -- and what "releasable" means: publish-pypi.yml and
|
|
6
|
+
# deb.yml are triggered by this workflow COMPLETING on main and proceed only
|
|
7
|
+
# when it succeeded (workflow_run + conclusion check), so a red push to main
|
|
8
|
+
# is never published. Renaming this workflow breaks that trigger.
|
|
6
9
|
on:
|
|
7
10
|
push:
|
|
8
11
|
branches: [main]
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
name: Debian Packages + apt repo
|
|
2
2
|
|
|
3
|
-
# Rolling release: every push to main builds python3-netgear-switch-library
|
|
4
|
-
# Debian trixie AND sid and republishes a signed flat apt repository on
|
|
5
|
-
# Pages (https://
|
|
6
|
-
# used by other mithro apt-repo projects (sensors2mqtt, ten64-controller).
|
|
7
|
-
# package is Architecture: all (pure Python), so it builds on the default x86
|
|
8
|
-
# runner and installs on any Debian arch.
|
|
3
|
+
# Rolling release: every GREEN push to main builds python3-netgear-switch-library
|
|
4
|
+
# for Debian trixie AND sid and republishes a signed flat apt repository on
|
|
5
|
+
# GitHub Pages (https://mith.ro/python-netgear-switch-library/). Mirrors the
|
|
6
|
+
# pattern used by other mithro apt-repo projects (sensors2mqtt, ten64-controller).
|
|
7
|
+
# The package is Architecture: all (pure Python), so it builds on the default x86
|
|
8
|
+
# runner and installs on any Debian arch. The version is git-derived (vX.Y at a
|
|
9
|
+
# tag, vX.Y.postN after it -- identical to the wheel's).
|
|
10
|
+
#
|
|
11
|
+
# Gated on CI exactly like publish-pypi.yml: triggered when the "CI" workflow
|
|
12
|
+
# completes for main, and build-deb only proceeds when that run succeeded, so a
|
|
13
|
+
# red commit never reaches the apt repo. workflow_dispatch stays for re-runs.
|
|
9
14
|
on:
|
|
10
|
-
|
|
15
|
+
workflow_run:
|
|
16
|
+
workflows: [CI]
|
|
17
|
+
types: [completed]
|
|
11
18
|
branches: [main]
|
|
12
19
|
workflow_dispatch:
|
|
13
20
|
|
|
14
21
|
jobs:
|
|
15
22
|
build-deb:
|
|
23
|
+
# workflow_run fires on every completion (failure/cancelled too); only a
|
|
24
|
+
# successful CI run is a release. publish-apt inherits the skip via needs.
|
|
25
|
+
if: >-
|
|
26
|
+
github.event_name == 'workflow_dispatch' ||
|
|
27
|
+
github.event.workflow_run.conclusion == 'success'
|
|
16
28
|
runs-on: ubuntu-latest
|
|
17
29
|
strategy:
|
|
18
30
|
fail-fast: false
|
|
@@ -21,7 +33,10 @@ jobs:
|
|
|
21
33
|
steps:
|
|
22
34
|
- uses: actions/checkout@v5
|
|
23
35
|
with:
|
|
24
|
-
|
|
36
|
+
# Pin to the SHA CI validated, not the default-branch HEAD (which a
|
|
37
|
+
# workflow_run checkout would otherwise use and may already be past).
|
|
38
|
+
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
|
39
|
+
fetch-depth: 0 # full history + tags so deb-version.py can describe
|
|
25
40
|
|
|
26
41
|
- name: Build package in debian:${{ matrix.suite }}
|
|
27
42
|
run: |
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Every GREEN push to main is a release. The version is derived from git by
|
|
4
|
+
# hatch-vcs (see pyproject.toml): vX.Y at a tag, vX.Y.postN N commits later, so
|
|
5
|
+
# each commit produces a new, unique version -- no manual bump.
|
|
6
|
+
#
|
|
7
|
+
# This workflow is gated on CI: it runs when the "CI" workflow (ruff, mypy,
|
|
8
|
+
# pytest + coverage, docs) COMPLETES for a push to main, and the build job only
|
|
9
|
+
# proceeds when that run SUCCEEDED. Before this gate, a red CI run and a PyPI
|
|
10
|
+
# upload raced each other and broken commits were published (13ef042 shipped
|
|
11
|
+
# with the docs job failing, a60bae6 with every test job failing). The
|
|
12
|
+
# workflow_dispatch path stays for manual re-runs.
|
|
13
|
+
#
|
|
14
|
+
# Publishing uses PyPI Trusted Publishing (OIDC): there is no API token in the
|
|
15
|
+
# repo; the `pypi` environment + trusted publisher are registered (see
|
|
16
|
+
# RELEASING.md).
|
|
17
|
+
on:
|
|
18
|
+
workflow_run:
|
|
19
|
+
workflows: [CI]
|
|
20
|
+
types: [completed]
|
|
21
|
+
branches: [main]
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
build:
|
|
26
|
+
# workflow_run fires on EVERY completion (failure and cancelled included);
|
|
27
|
+
# only a successful CI run is a release. Dependent jobs inherit the skip.
|
|
28
|
+
if: >-
|
|
29
|
+
github.event_name == 'workflow_dispatch' ||
|
|
30
|
+
github.event.workflow_run.conclusion == 'success'
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v5
|
|
34
|
+
with:
|
|
35
|
+
# A workflow_run checkout defaults to the default branch HEAD, which
|
|
36
|
+
# may already be PAST the commit CI just validated. Pin to the SHA
|
|
37
|
+
# CI actually ran on, so the published version is exactly the one
|
|
38
|
+
# that went green.
|
|
39
|
+
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
|
40
|
+
fetch-depth: 0 # full history + tags for hatch-vcs version derivation
|
|
41
|
+
|
|
42
|
+
- uses: astral-sh/setup-uv@v7
|
|
43
|
+
|
|
44
|
+
- name: Build sdist + wheel
|
|
45
|
+
run: uv build
|
|
46
|
+
|
|
47
|
+
- name: Show derived version
|
|
48
|
+
run: ls -1 dist/
|
|
49
|
+
|
|
50
|
+
- uses: actions/upload-artifact@v7
|
|
51
|
+
with:
|
|
52
|
+
name: dist
|
|
53
|
+
path: dist/
|
|
54
|
+
|
|
55
|
+
publish:
|
|
56
|
+
needs: build
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
# Trusted Publishing requires an OIDC token and a named environment.
|
|
59
|
+
environment: pypi
|
|
60
|
+
permissions:
|
|
61
|
+
id-token: write
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/download-artifact@v8
|
|
64
|
+
with:
|
|
65
|
+
name: dist
|
|
66
|
+
path: dist/
|
|
67
|
+
|
|
68
|
+
- name: Publish to PyPI (OIDC trusted publishing)
|
|
69
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
70
|
+
with:
|
|
71
|
+
skip-existing: true
|
{python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: python-netgear-switch-library
|
|
3
|
-
Version: 0.
|
|
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
|
|
@@ -83,14 +83,14 @@ GitHub Pages apt repository. Pick the line matching your suite:
|
|
|
83
83
|
|
|
84
84
|
```sh
|
|
85
85
|
sudo install -d -m0755 /etc/apt/keyrings
|
|
86
|
-
curl -fsSL https://
|
|
86
|
+
curl -fsSL https://mith.ro/python-netgear-switch-library/netgear-switch.gpg \
|
|
87
87
|
| sudo tee /etc/apt/keyrings/netgear-switch.gpg > /dev/null
|
|
88
88
|
|
|
89
89
|
# trixie:
|
|
90
|
-
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://
|
|
90
|
+
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://mith.ro/python-netgear-switch-library/trixie/ ./" \
|
|
91
91
|
| sudo tee /etc/apt/sources.list.d/netgear-switch.list
|
|
92
92
|
# sid:
|
|
93
|
-
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://
|
|
93
|
+
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://mith.ro/python-netgear-switch-library/sid/ ./" \
|
|
94
94
|
| sudo tee /etc/apt/sources.list.d/netgear-switch.list
|
|
95
95
|
|
|
96
96
|
sudo apt update
|
{python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/README.md
RENAMED
|
@@ -48,14 +48,14 @@ GitHub Pages apt repository. Pick the line matching your suite:
|
|
|
48
48
|
|
|
49
49
|
```sh
|
|
50
50
|
sudo install -d -m0755 /etc/apt/keyrings
|
|
51
|
-
curl -fsSL https://
|
|
51
|
+
curl -fsSL https://mith.ro/python-netgear-switch-library/netgear-switch.gpg \
|
|
52
52
|
| sudo tee /etc/apt/keyrings/netgear-switch.gpg > /dev/null
|
|
53
53
|
|
|
54
54
|
# trixie:
|
|
55
|
-
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://
|
|
55
|
+
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://mith.ro/python-netgear-switch-library/trixie/ ./" \
|
|
56
56
|
| sudo tee /etc/apt/sources.list.d/netgear-switch.list
|
|
57
57
|
# sid:
|
|
58
|
-
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://
|
|
58
|
+
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://mith.ro/python-netgear-switch-library/sid/ ./" \
|
|
59
59
|
| sudo tee /etc/apt/sources.list.d/netgear-switch.list
|
|
60
60
|
|
|
61
61
|
sudo apt update
|
{python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/RELEASING.md
RENAMED
|
@@ -1,19 +1,38 @@
|
|
|
1
1
|
# Releasing
|
|
2
2
|
|
|
3
|
-
This project is a **rolling release**. There are no
|
|
4
|
-
|
|
5
|
-
`packaging/deb-version.py` for the `.deb`)
|
|
6
|
-
|
|
3
|
+
This project is a **rolling release**. There are no manual version bumps: the
|
|
4
|
+
version is derived from `git describe` (`hatch-vcs` for the wheel,
|
|
5
|
+
`packaging/deb-version.py` for the `.deb`) — `X.Y` at a `vX.Y` tag,
|
|
6
|
+
`X.Y.postN` N commits after it — and **every green merge to `main` publishes
|
|
7
|
+
new packages** automatically:
|
|
7
8
|
|
|
8
9
|
- `.github/workflows/ci.yml` — runs the gates (ruff, mypy --strict, pytest with
|
|
9
|
-
coverage >= 90) on every push and PR. A green run is what
|
|
10
|
+
coverage >= 90, docs build) on every push and PR. A green run is what
|
|
11
|
+
"mergeable" means, and it is what triggers the two release workflows.
|
|
10
12
|
- `.github/workflows/publish-pypi.yml` — builds and uploads the wheel + sdist to
|
|
11
|
-
PyPI
|
|
13
|
+
PyPI when CI **succeeds** on `main` (`workflow_run`; a failed or cancelled CI
|
|
14
|
+
run publishes nothing, and the checkout is pinned to the SHA CI validated).
|
|
12
15
|
- `.github/workflows/deb.yml` — builds `.deb`s for trixie + sid and republishes
|
|
13
|
-
the signed apt repo on GitHub Pages
|
|
16
|
+
the signed apt repo on GitHub Pages, gated the same way.
|
|
14
17
|
|
|
15
18
|
Merges to `main` MUST use `--no-ff` merge commits so history stays linear per PR.
|
|
16
19
|
|
|
20
|
+
## Tags
|
|
21
|
+
|
|
22
|
+
Tags are the only human input to the version. `v0.0` sits on the root commit
|
|
23
|
+
(so `git describe` works from the start of history, per the repo-setup
|
|
24
|
+
guidance) and `v0.1` marks where the CI-gated pipeline landed (2026-08-22). The
|
|
25
|
+
fallback before any tag existed was `0.0.post<commit count>`, which reached
|
|
26
|
+
`0.0.post405` on PyPI; `v0.1` was chosen because it sorts above that in both
|
|
27
|
+
PEP 440 and Debian ordering, whereas counting from a root tag alone would have
|
|
28
|
+
re-issued `0.0.post404`/`405` (and `skip-existing` would have silently dropped
|
|
29
|
+
the upload).
|
|
30
|
+
|
|
31
|
+
To cut a new series, push an annotated `vX.Y` tag on `main` (a GitHub tag
|
|
32
|
+
ruleset only admits `vXX.ZZZ`-shaped tags) — the next green CI run publishes
|
|
33
|
+
`X.Y`, and every commit after it `X.Y.postN`. Never move or delete a tag that
|
|
34
|
+
has been published from.
|
|
35
|
+
|
|
17
36
|
## One-time human setup
|
|
18
37
|
|
|
19
38
|
These steps are done ONCE by a maintainer. **No secret or key is ever committed
|
|
@@ -83,7 +102,7 @@ re-runs idempotent.
|
|
|
83
102
|
|
|
84
103
|
1. Settings → Pages → Source: **GitHub Actions**.
|
|
85
104
|
2. The `deb.yml` `publish-apt` job deploys the apt repo to
|
|
86
|
-
`https://
|
|
105
|
+
`https://mith.ro/python-netgear-switch-library/`. It targets the
|
|
87
106
|
`github-pages` deployment environment, which GitHub creates automatically
|
|
88
107
|
once Pages is enabled — no separate environment setup is needed for this
|
|
89
108
|
one (unlike the `pypi` environment above, which must be created by hand).
|
|
@@ -91,7 +110,8 @@ re-runs idempotent.
|
|
|
91
110
|
## Verifying a release
|
|
92
111
|
|
|
93
112
|
- PyPI: check https://pypi.org/project/python-netgear-switch-library/ for the new
|
|
94
|
-
`
|
|
113
|
+
`X.Y.postN` version (matches `git describe --tags` on `main`, e.g. `v0.1-3-g…`
|
|
114
|
+
→ `0.1.post3`).
|
|
95
115
|
- apt: `sudo apt update && apt-cache policy python3-netgear-switch-library` on a
|
|
96
116
|
Debian trixie/sid box configured per the README. Before the GPG key is set
|
|
97
117
|
(see step 2 above), expect `apt update` to fail with a signature error for
|
{python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/debian/control
RENAMED
|
@@ -20,8 +20,11 @@ Architecture: all
|
|
|
20
20
|
Depends: ${python3:Depends},
|
|
21
21
|
${misc:Depends},
|
|
22
22
|
snmp
|
|
23
|
-
Recommends: python3-httpx
|
|
24
|
-
|
|
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.
|
|
@@ -82,14 +82,14 @@ GitHub Pages apt repository:
|
|
|
82
82
|
.. code-block:: sh
|
|
83
83
|
|
|
84
84
|
sudo install -d -m0755 /etc/apt/keyrings
|
|
85
|
-
curl -fsSL https://
|
|
85
|
+
curl -fsSL https://mith.ro/python-netgear-switch-library/netgear-switch.gpg \
|
|
86
86
|
| sudo tee /etc/apt/keyrings/netgear-switch.gpg > /dev/null
|
|
87
87
|
|
|
88
88
|
# trixie:
|
|
89
|
-
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://
|
|
89
|
+
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://mith.ro/python-netgear-switch-library/trixie/ ./" \
|
|
90
90
|
| sudo tee /etc/apt/sources.list.d/netgear-switch.list
|
|
91
91
|
# sid:
|
|
92
|
-
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://
|
|
92
|
+
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://mith.ro/python-netgear-switch-library/sid/ ./" \
|
|
93
93
|
| sudo tee /etc/apt/sources.list.d/netgear-switch.list
|
|
94
94
|
|
|
95
95
|
sudo apt update
|
|
@@ -102,10 +102,11 @@ the net-snmp tools automatically. The packaging lives in ``debian/`` and
|
|
|
102
102
|
Versioning
|
|
103
103
|
----------
|
|
104
104
|
|
|
105
|
-
A **rolling release**. The version is derived from git by
|
|
106
|
-
|
|
107
|
-
``
|
|
108
|
-
|
|
105
|
+
A **rolling release**. The version is derived from ``git describe`` by
|
|
106
|
+
``hatch-vcs``: ``X.Y`` at a ``vX.Y`` tag, ``X.Y.postN`` N commits after it
|
|
107
|
+
(``0.1``, ``0.1.post1``, …). Every merge to ``main`` whose CI run is green
|
|
108
|
+
publishes to PyPI and to the apt repository — a red run publishes nothing. No
|
|
109
|
+
manual version bumps — see ``RELEASING.md``.
|
|
109
110
|
|
|
110
111
|
.. note::
|
|
111
112
|
|
{python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/docs/mcp.rst
RENAMED
|
@@ -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
|
|
6
|
-
|
|
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
|
|
@@ -14,10 +14,10 @@ Rolling release — every push to <code>main</code> publishes a new version
|
|
|
14
14
|
<h2>Setup (Debian trixie)</h2>
|
|
15
15
|
<pre>
|
|
16
16
|
sudo install -d -m0755 /etc/apt/keyrings
|
|
17
|
-
curl -fsSL https://
|
|
17
|
+
curl -fsSL https://mith.ro/python-netgear-switch-library/netgear-switch.gpg \
|
|
18
18
|
| sudo tee /etc/apt/keyrings/netgear-switch.gpg > /dev/null
|
|
19
19
|
|
|
20
|
-
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://
|
|
20
|
+
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://mith.ro/python-netgear-switch-library/trixie/ ./" \
|
|
21
21
|
| sudo tee /etc/apt/sources.list.d/netgear-switch.list
|
|
22
22
|
|
|
23
23
|
sudo apt update
|
|
@@ -27,10 +27,10 @@ sudo apt install python3-netgear-switch-library
|
|
|
27
27
|
<h2>Setup (Debian sid)</h2>
|
|
28
28
|
<pre>
|
|
29
29
|
sudo install -d -m0755 /etc/apt/keyrings
|
|
30
|
-
curl -fsSL https://
|
|
30
|
+
curl -fsSL https://mith.ro/python-netgear-switch-library/netgear-switch.gpg \
|
|
31
31
|
| sudo tee /etc/apt/keyrings/netgear-switch.gpg > /dev/null
|
|
32
32
|
|
|
33
|
-
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://
|
|
33
|
+
echo "deb [signed-by=/etc/apt/keyrings/netgear-switch.gpg] https://mith.ro/python-netgear-switch-library/sid/ ./" \
|
|
34
34
|
| sudo tee /etc/apt/sources.list.d/netgear-switch.list
|
|
35
35
|
|
|
36
36
|
sudo apt update
|
{python_netgear_switch_library-0.0.post405 → python_netgear_switch_library-0.1.post4}/pyproject.toml
RENAMED
|
@@ -63,11 +63,16 @@ ngsw-mcp = "netgear_switch.mcp.server:main"
|
|
|
63
63
|
[dependency-groups]
|
|
64
64
|
dev = ["pytest>=8.0", "ruff>=0.6", "mypy>=1.11", "pytest-cov>=5.0"]
|
|
65
65
|
|
|
66
|
-
# Rolling release: the version is derived from git
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
66
|
+
# Rolling release: the version is derived from git (`git describe`), never
|
|
67
|
+
# hand-edited. vX.Y tags (v0.0 on the root commit per the repo-setup guidance,
|
|
68
|
+
# v0.1 when the CI-gated release pipeline landed on 2026-08-22) are the only
|
|
69
|
+
# human input; every commit after a tag increments the distance, so post-release
|
|
70
|
+
# versioning yields a real, monotonic version: X.Y at the tag, X.Y.postN N
|
|
71
|
+
# commits later. (Before any tag existed the fallback was 0.0.post<commit
|
|
72
|
+
# count>, which reached 0.0.post405 on PyPI -- v0.1 was chosen to sort ABOVE
|
|
73
|
+
# that, since re-counting from a root tag would have re-issued 0.0.post404/405.)
|
|
74
|
+
# "no-local-version" keeps the version PyPI-upload safe. These forms are also
|
|
75
|
+
# valid Debian versions verbatim; packaging/deb-version.py applies the same rule.
|
|
71
76
|
[tool.hatch.version]
|
|
72
77
|
source = "vcs"
|
|
73
78
|
|
|
@@ -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.
|
|
22
|
-
__version_tuple__ = version_tuple = (0,
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
815
|
-
|
|
816
|
-
|
|
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__":
|
|
@@ -6,11 +6,14 @@ container with no third-party packages installed), so these tests drive it
|
|
|
6
6
|
via ``subprocess`` under plain ``python3`` rather than importing it -- that
|
|
7
7
|
also proves it truly needs nothing beyond the standard library.
|
|
8
8
|
|
|
9
|
-
The
|
|
10
|
-
here hard-codes today's
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
HEAD
|
|
9
|
+
The version changes every time this repo gets a commit or a tag, so nothing
|
|
10
|
+
here hard-codes today's value; each assertion recomputes the expected value
|
|
11
|
+
from ``git`` at test time. The live-repo check deliberately uses DIFFERENT git
|
|
12
|
+
commands from the script (``describe --abbrev=0`` + ``rev-list --count
|
|
13
|
+
TAG..HEAD`` versus the script's ``describe --long`` regex) so the two can
|
|
14
|
+
disagree if either is wrong. The tagless fallback (``0.0.post<count>``) is
|
|
15
|
+
exercised in a throwaway repo: the live repo has been tagged since v0.0/v0.1
|
|
16
|
+
on 2026-08-22, so it no longer takes that path.
|
|
14
17
|
"""
|
|
15
18
|
|
|
16
19
|
from __future__ import annotations
|
|
@@ -116,12 +119,37 @@ def test_only_stdlib_imports():
|
|
|
116
119
|
assert seen <= stdlib_allow, f"non-stdlib imports found: {seen - stdlib_allow}"
|
|
117
120
|
|
|
118
121
|
|
|
119
|
-
def
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
+
def test_live_repo_version_matches_git_describe():
|
|
123
|
+
"""The real checkout: X.Y at the nearest vX.Y tag, X.Y.postN N commits on.
|
|
124
|
+
|
|
125
|
+
Expected value is derived independently of the script: the nearest tag via
|
|
126
|
+
``describe --abbrev=0`` and the distance via ``rev-list --count TAG..HEAD``
|
|
127
|
+
(the script parses ``describe --long`` instead). This broke on 2026-08-22
|
|
128
|
+
when v0.1 was pushed and the old assertion still expected the tagless
|
|
129
|
+
``0.0.post<count>`` fallback -- CI went red and, correctly, nothing was
|
|
130
|
+
published for that commit.
|
|
131
|
+
"""
|
|
132
|
+
tag = _git("describe", "--tags", "--abbrev=0", "--match", "v[0-9]*")
|
|
133
|
+
assert tag.startswith("v"), tag
|
|
134
|
+
base = tag[1:]
|
|
135
|
+
distance = int(_git("rev-list", "--count", f"{tag}..HEAD"))
|
|
136
|
+
expected = base if distance == 0 else f"{base}.post{distance}"
|
|
122
137
|
assert _run() == expected
|
|
123
138
|
|
|
124
139
|
|
|
140
|
+
def test_commit_count_fallback_in_tagless_repo(tmp_path):
|
|
141
|
+
"""With no vX.Y tag at all the version is 0.0.post<commit count>.
|
|
142
|
+
|
|
143
|
+
The live repo left this path when it was tagged, so exercise it in a
|
|
144
|
+
throwaway repo: three commits, no tags -> 0.0.post3.
|
|
145
|
+
"""
|
|
146
|
+
repo = tmp_path / "tagless-repo"
|
|
147
|
+
_init_repo(repo)
|
|
148
|
+
for i in range(3):
|
|
149
|
+
_commit(repo, f"commit {i}")
|
|
150
|
+
assert _run_in_repo(repo).stdout.strip() == "0.0.post3"
|
|
151
|
+
|
|
152
|
+
|
|
125
153
|
def test_version_is_a_valid_debian_version_string():
|
|
126
154
|
printed = _run()
|
|
127
155
|
assert _DEBIAN_VERSION_RE.match(printed), printed
|
|
@@ -159,9 +187,10 @@ def test_write_changelog_produces_parseable_debian_changelog(tmp_path):
|
|
|
159
187
|
def test_version_tag_based_path(tmp_path):
|
|
160
188
|
"""vX.Y -> X.Y at the tag; X.Y.postN with N commits after it.
|
|
161
189
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
190
|
+
This is the path the live upstream repo takes since v0.0 (root commit) and
|
|
191
|
+
v0.1 (2026-08-22) were tagged; the live-repo test above checks it against
|
|
192
|
+
the real checkout, this one pins the exact arithmetic on a throwaway
|
|
193
|
+
repo whose tag and distance are fully controlled.
|
|
165
194
|
"""
|
|
166
195
|
repo = tmp_path / "tag-repo"
|
|
167
196
|
_init_repo(repo)
|