pytvt 0.5.1__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 (60) hide show
  1. pytvt-0.5.1/.gitignore +64 -0
  2. pytvt-0.5.1/CHANGELOG.md +131 -0
  3. pytvt-0.5.1/CONTRIBUTING.md +113 -0
  4. pytvt-0.5.1/LICENSE +21 -0
  5. pytvt-0.5.1/MANIFEST.in +41 -0
  6. pytvt-0.5.1/PKG-INFO +662 -0
  7. pytvt-0.5.1/README.md +628 -0
  8. pytvt-0.5.1/RELEASE_NOTES.md +90 -0
  9. pytvt-0.5.1/pyproject.toml +127 -0
  10. pytvt-0.5.1/src/pytvt/__init__.py +112 -0
  11. pytvt-0.5.1/src/pytvt/__main__.py +6 -0
  12. pytvt-0.5.1/src/pytvt/cli.py +366 -0
  13. pytvt-0.5.1/src/pytvt/config.py +111 -0
  14. pytvt-0.5.1/src/pytvt/constants.py +153 -0
  15. pytvt-0.5.1/src/pytvt/device_manager.py +436 -0
  16. pytvt-0.5.1/src/pytvt/diff.py +444 -0
  17. pytvt-0.5.1/src/pytvt/discovery.py +636 -0
  18. pytvt-0.5.1/src/pytvt/exceptions.py +23 -0
  19. pytvt-0.5.1/src/pytvt/models.py +237 -0
  20. pytvt-0.5.1/src/pytvt/netsdk/__init__.py +54 -0
  21. pytvt-0.5.1/src/pytvt/netsdk/bindings.py +291 -0
  22. pytvt-0.5.1/src/pytvt/netsdk/client.py +991 -0
  23. pytvt-0.5.1/src/pytvt/netsdk/constants.py +416 -0
  24. pytvt-0.5.1/src/pytvt/netsdk/loader.py +161 -0
  25. pytvt-0.5.1/src/pytvt/netsdk/types.py +523 -0
  26. pytvt-0.5.1/src/pytvt/nvr_api.py +824 -0
  27. pytvt-0.5.1/src/pytvt/output.py +333 -0
  28. pytvt-0.5.1/src/pytvt/protocol.py +685 -0
  29. pytvt-0.5.1/src/pytvt/registry.py +202 -0
  30. pytvt-0.5.1/src/pytvt/scanner.py +111 -0
  31. pytvt-0.5.1/src/pytvt/sdk_http.py +67 -0
  32. pytvt-0.5.1/src/pytvt/sdk_http_client.py +390 -0
  33. pytvt-0.5.1/src/pytvt/sdk_local.py +103 -0
  34. pytvt-0.5.1/src/pytvt/snapshot.py +880 -0
  35. pytvt-0.5.1/src/pytvt/webapi/__init__.py +22 -0
  36. pytvt-0.5.1/src/pytvt/webapi/client.py +894 -0
  37. pytvt-0.5.1/src/pytvt/webapi/errors.py +107 -0
  38. pytvt-0.5.1/src/pytvt/webapi/models.py +160 -0
  39. pytvt-0.5.1/src/pytvt/webapi/xml.py +137 -0
  40. pytvt-0.5.1/tests/__init__.py +0 -0
  41. pytvt-0.5.1/tests/conftest.py +131 -0
  42. pytvt-0.5.1/tests/test_architecture.py +409 -0
  43. pytvt-0.5.1/tests/test_cli.py +112 -0
  44. pytvt-0.5.1/tests/test_config.py +141 -0
  45. pytvt-0.5.1/tests/test_device_manager.py +439 -0
  46. pytvt-0.5.1/tests/test_diff.py +635 -0
  47. pytvt-0.5.1/tests/test_discovery.py +152 -0
  48. pytvt-0.5.1/tests/test_models.py +169 -0
  49. pytvt-0.5.1/tests/test_netsdk_client.py +494 -0
  50. pytvt-0.5.1/tests/test_netsdk_constants.py +235 -0
  51. pytvt-0.5.1/tests/test_netsdk_types.py +346 -0
  52. pytvt-0.5.1/tests/test_output.py +173 -0
  53. pytvt-0.5.1/tests/test_protocol.py +342 -0
  54. pytvt-0.5.1/tests/test_scanner.py +223 -0
  55. pytvt-0.5.1/tests/test_sdk_http.py +68 -0
  56. pytvt-0.5.1/tests/test_sdk_http_client.py +363 -0
  57. pytvt-0.5.1/tests/test_sdk_local.py +62 -0
  58. pytvt-0.5.1/tests/test_webapi_client.py +424 -0
  59. pytvt-0.5.1/tests/test_webapi_errors.py +108 -0
  60. pytvt-0.5.1/tests/test_webapi_xml.py +206 -0
pytvt-0.5.1/.gitignore ADDED
@@ -0,0 +1,64 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+
9
+ # pypi
10
+ .pypirc
11
+
12
+ # Build / publish artefacts
13
+ *.whl
14
+ *.tar.gz
15
+
16
+ # Proprietary/native SDK artefacts
17
+ *.so
18
+ *.so.*
19
+ *.dll
20
+ *.dylib
21
+ *.lib
22
+ *.a
23
+ *.h
24
+
25
+ # Local vendor SDK checkouts/extractions
26
+ bridges/sdk_local/tvt/
27
+ tvt-api/tvt/
28
+
29
+ # Node (bridges/sdk_local)
30
+ bridges/sdk_local/node_modules/
31
+
32
+ # Environment / secrets
33
+ .env
34
+
35
+ # OS
36
+ .DS_Store
37
+
38
+ # Device inventory (contains site-specific data)
39
+ files/
40
+
41
+ # Debug/development scripts (not in tools/)
42
+ debug_*.py
43
+ parse_init.py
44
+
45
+ # Logs and dumps
46
+ *.log
47
+ *.dump
48
+ *.pcap
49
+ *.cap
50
+
51
+ # Scan output artifacts
52
+ output/
53
+ *.csv
54
+ *.json.bak
55
+ *.xlsx
56
+ failed_devices.json
57
+
58
+ # Docker (Dockerfile lives in tvt-api repo now)
59
+ Dockerfile
60
+ .dockerignore
61
+
62
+ # Legacy
63
+ Pipfile.lock
64
+
@@ -0,0 +1,131 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.5.1] — 2026-04-14
9
+
10
+ ### Changed
11
+
12
+ - **Release hardening for PyPI** — native TVT SDK components are now loaded only
13
+ at runtime from explicit user-provided paths or environment variables.
14
+ - **SDK path configuration** — added `TVT_SDK_PATH` and `TVT_SCAN_SCRIPT`
15
+ support across config loading, `DeviceManager`, `NetSdkClient`, and the
16
+ local Node.js bridge, while preserving legacy env vars for local workflows.
17
+ - **Packaging safety** — expanded build exclusions, MANIFEST rules, and
18
+ `.gitignore` patterns to prevent native SDK binaries, headers, and local SDK
19
+ workspaces from being published or accidentally committed.
20
+ - **Documentation** — clarified that the proprietary TVT SDK is never
21
+ redistributed, documented runtime SDK setup, and separated SDK-backed
22
+ features from SDK-free features.
23
+
24
+ ## [0.5.0] — 2026-04-09
25
+
26
+ ### Added
27
+
28
+ - **`DeviceManager` unified facade** — single API for TVT device operations with
29
+ automatic backend selection. Probes native SDK availability first, then falls
30
+ back to an SDK bridge service. Supports forced backend selection.
31
+ - `device_info()`, `device_time()`, `snapshot()`, `rtsp_url()`, `ptz()`,
32
+ `ptz_preset()`, `reboot()` — all return the same result types regardless
33
+ of backend.
34
+ - `available_backends()` — probe what's available on the current platform.
35
+ - `Backend` enum, `NoBackendAvailable` exception.
36
+ - **`is_netsdk_available()` probe** — check if the native SDK is loadable without
37
+ actually loading it (platform + architecture + file existence check).
38
+ - **Expanded netsdk loader** — searches explicit path/env var → SDK root →
39
+ system. Added `_arch_dir()` for platform-specific directory selection,
40
+ pre-loading of companion `.so` dependencies.
41
+ - **aarch64 support** — loader recognizes `linux-arm64` bin directory for ARM64 Linux.
42
+
43
+ ### Changed
44
+
45
+ - `netsdk/__init__.py` now exports `is_netsdk_available` and `NetSdkUnavailable`.
46
+ - Public `__init__.py` exports `DeviceManager`, `Backend`, `NoBackendAvailable`,
47
+ `available_backends`.
48
+
49
+ ## [0.4.0] — 2026-04-08
50
+
51
+ ### Added
52
+
53
+ - **`pytvt.netsdk` package** — ctypes bindings for the TVT NetSDK C++ library
54
+ (`libdvrnetsdk.so`). `NetSdkClient` + `DeviceSession` with 25+ methods covering
55
+ device info, PTZ, snapshots, RTSP URLs, alarms, recording, firmware, disks,
56
+ users, time sync, and more.
57
+ - **`SdkHttpClient`** — typed Python client for an SDK bridge service with
58
+ 10 methods: `health()`, `scan()`, `device_info()`, `device_time()`, `snapshot()`,
59
+ `rtsp_url()`, `ptz()`, `ptz_preset()`, `reboot()`.
60
+ - **Result dataclasses** — `DeviceInfoResult`, `DeviceTimeResult`, `RtspUrlResult`,
61
+ `CommandResult` for SDK HTTP responses.
62
+ - **135 netsdk tests** + **26 SdkHttpClient tests** (161 new tests).
63
+
64
+ ## [0.3.0] — 2026-04-07
65
+
66
+ ### Added
67
+
68
+ - **`WebApiClient`** — TVT HTTP API (LAPI protocol) client with HTTP Basic auth.
69
+ Per-device management: capability detection, device info, channels, disks,
70
+ date/time, password management, image/stream/audio/OSD configuration, snapshots
71
+ with RTSP fallback, recording status and search.
72
+ - **66 new tests** for the Web API client.
73
+
74
+ ## [0.2.0] — 2026-04-06
75
+
76
+ First packaged release. Restructured from flat scripts into an installable Python
77
+ package with formalized architecture, new operator-facing features, and
78
+ comprehensive test coverage.
79
+
80
+ ### Added
81
+
82
+ - **Scan diffing / change detection** — compare two JSON scan result files to detect
83
+ device and camera changes between runs. New `pytvt-diff` CLI command with
84
+ human-readable, JSON, and summary output modes. New library API:
85
+ `diff_scans()`, `load_scan_file()`, `ScanDiff`, `DeviceDiff`.
86
+ - **Backend family / integration mode architecture** — formalized `BackendFamily`
87
+ (protocol, sdk) and `IntegrationMode` (compat_bridge, direct_sdk) enums with
88
+ `CompositeStrategy` for multi-backend fallback.
89
+ - **Execution plan layer** — `ExecutionPlan` dataclass and `resolve_execution_plan()`
90
+ resolver that makes "what will be executed" explicit and inspectable before a
91
+ scan runs.
92
+ - **Backend registry** — `register()` / `get()` / `dispatch()` dispatch table
93
+ mapping (family, mode) tuples to scan callables, with default wiring at import time.
94
+ - **Research / reference isolation** — protocol reverse-engineering scripts moved to
95
+ `research/` with clear warning headers. Import boundary enforced by test.
96
+ - **Typed exception hierarchy** — `PytvtError`, `BackendError`, `RegistryError`.
97
+ - **Comprehensive test suite** — 237 tests across 13 files covering protocol
98
+ encryption, config precedence, models, scanner dispatch, CLI parsing, output
99
+ formatting, discovery, SDK backends, architecture invariants, and scan diffing.
100
+ - **CI pipeline** — GitHub Actions running pytest + ruff on Python 3.10–3.13.
101
+ - **Contributor docs** — CONTRIBUTING.md with code tier guidance, PR template,
102
+ issue templates.
103
+ - **`pytvt-diff` console script** — registered in pyproject.toml alongside the
104
+ existing four CLI entry points.
105
+
106
+ ### Changed
107
+
108
+ - **Package layout** — migrated from flat scripts to `src/pytvt/` installable
109
+ package with hatchling build backend.
110
+ - **CLI decomposition** — split monolithic main.py into focused modules: cli.py,
111
+ config.py, models.py, scanner.py, protocol.py, discovery.py, output.py,
112
+ sdk_http.py, sdk_local.py, nvr_api.py, snapshot.py.
113
+ - **Data models** — replaced raw dicts with typed dataclasses (`ScannerConfig`,
114
+ `DeviceEntry`, `CameraInfo`, `ScanResult`) with factory methods and serialization.
115
+ - **Backend normalization** — CLI backend strings (`protocol`, `sdk`, `sdk-local`,
116
+ `both`) are normalized via `resolve_backend()` with backward-compatible aliases
117
+ (`sdk_local` → `sdk-local`, `compat_bridge` → `sdk`, `direct_sdk` → `sdk-local`).
118
+ - **Node.js bridge** — moved `scan_nvr.mjs` to `bridges/sdk_local/` with its own
119
+ `package.json`, isolated from the Python package.
120
+ - **README** — complete rewrite with architecture diagram, backend comparison table,
121
+ integration mode explanations, full CLI reference, and project structure tree.
122
+
123
+ ### Licensing
124
+
125
+ - Licensed under MIT starting from 1.0.0. Previous versions were AGPLv3.
126
+
127
+ [0.5.1]: https://github.com/dannielperez/pytvt/compare/v0.5.0...v0.5.1
128
+ [0.5.0]: https://github.com/dannielperez/pytvt/compare/v0.4.0...v0.5.0
129
+ [0.4.0]: https://github.com/dannielperez/pytvt/compare/v0.3.0...v0.4.0
130
+ [0.3.0]: https://github.com/dannielperez/pytvt/compare/v0.2.0...v0.3.0
131
+ [0.2.0]: https://github.com/dannielperez/pytvt/releases/tag/v0.2.0
@@ -0,0 +1,113 @@
1
+ # Contributing to pytvt
2
+
3
+ Thanks for your interest in contributing. This is a solo-maintained project, but bug reports, fixes, and well-scoped improvements are welcome.
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ git clone https://github.com/dannielperez/pytvt.git
9
+ cd pytvt
10
+ pip install -e ".[dev]"
11
+ ```
12
+
13
+ ## Development
14
+
15
+ ### Running tests
16
+
17
+ ```bash
18
+ pytest
19
+ ```
20
+
21
+ ### Linting + formatting
22
+
23
+ ```bash
24
+ ruff check src/ tests/
25
+ ruff format src/ tests/
26
+ ```
27
+
28
+ ### Type checking (optional)
29
+
30
+ ```bash
31
+ mypy src/pytvt/
32
+ ```
33
+
34
+ ## Releases
35
+
36
+ Releases should use GitHub Actions OIDC trusted publishing, not manual `twine upload` tokens.
37
+
38
+ Configure trusted publishers on both TestPyPI and PyPI with these values:
39
+
40
+ - Owner: `dannielperez`
41
+ - Repository: `pytvt`
42
+ - Workflow: `publish.yml`
43
+ - Environment: `testpypi` for TestPyPI, `pypi` for production PyPI
44
+
45
+ The publish workflow is designed to:
46
+
47
+ - run CI and build validation
48
+ - publish to TestPyPI via OIDC
49
+ - install and smoke-test the TestPyPI package
50
+ - publish to PyPI via OIDC only after TestPyPI validation succeeds
51
+
52
+ ## Code Style
53
+
54
+ - Python 3.10+ — use modern syntax (`X | Y` unions, etc.)
55
+ - Formatting and linting handled by [Ruff](https://docs.astral.sh/ruff/)
56
+ - Prefer stdlib `dataclasses` for data models
57
+ - Keep functions small and testable — avoid side effects in library code
58
+ - Include type annotations on public APIs
59
+
60
+ ## Pull Requests
61
+
62
+ 1. Fork the repo and create a feature branch
63
+ 2. Keep changes focused — one concern per PR
64
+ 3. Add or update tests for changed behavior
65
+ 4. Run `ruff check` and `pytest` before submitting
66
+ 5. Fill out the PR template
67
+
68
+ ## Code Tiers
69
+
70
+ pytvt separates code into three tiers. Understand which tier you are working in:
71
+
72
+ | Tier | Location | CI-gated | Imported at runtime |
73
+ |---|---|---|---|
74
+ | **Published package** | `src/pytvt/` | Yes | Yes |
75
+ | **Local helper runtimes** | `bridges/`, `tvt-api/` | No | Optional, developer-managed |
76
+ | **Research / reference** | `research/` | No | **No** — never import |
77
+ | **Operational tools** | `tools/` | No | Imports *from* pytvt |
78
+
79
+ **Key rule:** code in `src/pytvt/` must never import from `research/` or `tools/`. This boundary is enforced by `tests/test_architecture.py::TestImportBoundary`.
80
+
81
+ If you are adding protocol research scripts, put them in `research/` with the standard header:
82
+
83
+ ```python
84
+ #!/usr/bin/env python3
85
+ """
86
+ RESEARCH / REFERENCE ONLY — not part of the pytvt runtime.
87
+
88
+ <description>
89
+
90
+ See research/README.md for context.
91
+ """
92
+ ```
93
+
94
+ ## Bug Reports
95
+
96
+ Use the GitHub issue templates. Include:
97
+
98
+ - Python version and OS
99
+ - Steps to reproduce
100
+ - Expected vs actual behavior
101
+ - Full error output / traceback
102
+
103
+ ## Scope
104
+
105
+ This project focuses on TVT NVR device management. Out-of-scope:
106
+
107
+ - Support for non-TVT vendors (see related repos)
108
+ - Features requiring always-on infrastructure
109
+ - GUI / web interface
110
+
111
+ ## License
112
+
113
+ By contributing, you agree that your contributions will be licensed under the [MIT License](LICENSE).
pytvt-0.5.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Danniel Perez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,41 @@
1
+ # MANIFEST.in — controls source distribution (sdist) contents.
2
+ #
3
+ # Hatchling does not use MANIFEST.in directly, but this file serves as an
4
+ # explicit record of what is intentionally excluded from the published package
5
+ # and acts as a safety net for other build tools.
6
+ #
7
+ # The published pytvt sdist ships only:
8
+ # - src/pytvt/** (pure-Python package)
9
+ # - tests/** (test suite)
10
+ # - pyproject.toml
11
+ # - README.md
12
+ # - CHANGELOG.md
13
+ # - LICENSE
14
+ #
15
+ # Explicitly excluded (not redistributed):
16
+ # - bridges/ Local Node.js bridge scripts
17
+ # - tvt-api/ Local SDK helper workspace
18
+ # - research/ Reverse-engineering research scripts
19
+ # - tools/ Maintenance utilities
20
+ # - files/ Sample and local scan outputs
21
+ # - config.json Local device inventory example (site-specific)
22
+ # - .env.example Local secrets template
23
+
24
+ include pyproject.toml
25
+ include README.md
26
+ include CHANGELOG.md
27
+ include LICENSE
28
+
29
+ recursive-include src/pytvt *.py
30
+ recursive-include tests *.py
31
+ global-exclude *.so *.so.* *.dll *.dylib *.lib *.a *.h
32
+
33
+ prune bridges
34
+ prune files
35
+ prune tvt-api
36
+ prune research
37
+ prune tools
38
+ exclude config.json
39
+ exclude .env.example
40
+ exclude .editorconfig
41
+ exclude .gitmodules