diff options
| author | Roberto Bertó <463349+robertoberto@users.noreply.github.com> | 2025-11-02 19:55:55 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-02 19:55:55 -0300 |
| commit | 6ca1269b138696b69c33d2db4bcf7dd03ea4caeb (patch) | |
| tree | 4c0a634730df2123ff506252cbec050de006dac8 /docs/development/quality-and-utils.md | |
| parent | 1ada32975f0bb559ec7526e0dd545700dde1cb94 (diff) | |
| parent | 6b4e9015744ab8c9f17a6b8e23387cd676b1d827 (diff) | |
| download | pyvyos-6ca1269b138696b69c33d2db4bcf7dd03ea4caeb.tar.gz pyvyos-6ca1269b138696b69c33d2db4bcf7dd03ea4caeb.zip | |
Merge pull request #27 from vyos-contrib/feat/architecture-and-quality-improvements
feat: v0.4.0 - Architecture refactor, bug fixes, and quality improvem…
Diffstat (limited to 'docs/development/quality-and-utils.md')
| -rw-r--r-- | docs/development/quality-and-utils.md | 72 |
1 files changed, 72 insertions, 0 deletions
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_<do>_when_<condition>` +- 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 |
