From 6b4e9015744ab8c9f17a6b8e23387cd676b1d827 Mon Sep 17 00:00:00 2001 From: roberto berto Date: Sun, 2 Nov 2025 22:54:44 +0000 Subject: feat: v0.4.0 - Architecture refactor, bug fixes, and quality improvements - Fixed #25: config_file_save/load now include path: [] in payload - Added exception hierarchy (SDKError, HttpError, ApiError, ValidationError) - Added utility functions (json, ids, paths) - Added structured logging with request ID tracking - Added optional Pydantic validation models - Refactored to pyvyos.core.* structure with backward compatibility shims - Moved JSON specs to docs/development/vyos_api/ - Added comprehensive test suite (19 shim tests, 16 utils tests, 6 exception tests) - Updated pyproject.toml for uv sync editable installation - Added development documentation (architecture, roadmap, quality guidelines) Maintains 100% backward compatibility with 0.3.0 --- docs/development/quality-and-utils.md | 72 +++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/development/quality-and-utils.md (limited to 'docs/development/quality-and-utils.md') diff --git a/docs/development/quality-and-utils.md b/docs/development/quality-and-utils.md new file mode 100644 index 0000000..ff78ec2 --- /dev/null +++ b/docs/development/quality-and-utils.md @@ -0,0 +1,72 @@ +# Quality, Utils, and Pitfalls + +## Goals +- Reduce regressions and supportability burden +- Consistent error handling and logging +- Clear utilities to avoid duplication + +## Exceptions (typed) +- `SDKError` (base) +- `HttpError(status, message)` +- `ApiError(message, details=None)` # when success=False +- `ValidationError(message)` # client-side validation + +## Logging +- Use `logging.getLogger("pyvyos")` +- Include: op, command, status, elapsed_ms, request_id +- Redact secrets (api key) – via `utils.json.redact_key(data, keys=["key"])` +- Default INFO; DEBUG guarded by env `PYVYOS_DEBUG=1` + +## Timeouts & Retries +- Default timeout: 10s (configurable) +- No implicit retries by default +- Future: retry idempotent ops only (exponential backoff) + +## Security +- `verify=True` by default +- Document `urllib3.disable_warnings()` only for dev +- Never log secrets or full payloads by default + +## Utilities (proposal) +- `utils.paths.build(*segments) -> list[str]` +- `utils.ids.request_id() -> str` +- `utils.json.safe_dumps(obj) -> str` (with redaction) +- `utils.http.timeout(seconds) -> int` (normalize) + +## Validation (optional) +- `specs.commands.*` Pydantic models validate request structures +- Enforce path rules (e.g., config-file requires `path=[]`) +- Gate behind feature flag or optional dependency group + +## Testing +- Unit: small, isolated, no real I/O +- Contract: success/error fixtures per command +- Naming: `test_should__when_` +- Use monkeypatch on `_execute_request` + +## Documentation +- Keep developer docs scoped and short (≤100 lines) +- Update api-reference and path rules on changes + +## Style & Types +- Type hints on public APIs, avoid `Any` +- Early returns, no deep nesting, no bare `except` +- Constants for command/operation strings + +## Release Hygiene +- Conventional commits; CHANGELOG generated +- Tag every release; ensure `git push --tags` +- Patch bumps for fixes, minor for features + +## Potential Pitfalls & Fixes +- Path handling inconsistencies → centralize in RestClient +- Logging secrets → redact before logging +- Tight coupling device↔transport → maintain clean core boundaries +- Hidden breaking changes → keep shims until 1.0.0 +- Non-deterministic tests → remove sleeps, use fixed seeds + +## Next Steps (ordered) +1. Introduce `exceptions.py` and wire into RestClient +2. Add `utils/` with `json.py`, `paths.py`, `ids.py` +3. Add optional `specs/` models for high-value commands +4. CI: lint+type-check, codecov, test matrix -- cgit v1.2.3