Release v2: Async client, TLS enforcement, retries/backoff, and CI upgrades#3
Release v2: Async client, TLS enforcement, retries/backoff, and CI upgrades#3devinslick merged 28 commits intomainfrom
Conversation
Critical fixes for Home Assistant integration: - Add configurable HTTP request timeouts (default 30s) to all requests - Fix version format inconsistency (_version.py now uses PEP 440 dot notation) - Add py.typed marker file for PEP 561 compliance - Reimplement export_data_zip for client-side packaging (no server endpoint) - Extract pictures as actual image files with format detection - Remove redundant encrypted blobs from exports Changes: - FmdClient: Add timeout parameter to __init__, create(), and _make_api_request() - Export: Fetch locations/pictures via existing APIs, decrypt and package into ZIP - Export: Include info.json, locations.json, pictures/*.jpg with manifest - Tests: Add test_timeout_configuration() and update export tests - Documentation: Update HOME_ASSISTANT_REVIEW.md with fix details
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment Thanks for integrating Codecov - We've got you covered ☂️ |
There was a problem hiding this comment.
Pull Request Overview
This PR introduces fmd_api v2.0.1, a major refactoring from a monolithic module to a device-oriented async client architecture with comprehensive test coverage and CI/CD pipeline.
Purpose: Complete rewrite of the FMD API client with async/await support, device-oriented design, improved error handling, retry logic, and production-ready features for Home Assistant integration.
Key Changes:
- Migrated from synchronous
fmd_api.pymodule to asyncFmdClientandDeviceclasses - Added 1,782 lines of unit tests with 82.6% coverage
- Implemented HTTP retry logic with exponential backoff and rate limit handling
- Added functional test suite with credential management utilities
- Set up CI/CD with GitHub Actions (test, lint, type check, codecov integration)
Reviewed Changes
Copilot reviewed 52 out of 55 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
fmd_api/client.py |
New 718-line async client with authentication, retry logic, timeout handling |
fmd_api/device.py |
New 149-line Device class wrapping per-device operations |
fmd_api/models.py |
Data models for Location and PhotoResult |
fmd_api/exceptions.py |
Typed exception hierarchy |
tests/unit/test_client.py |
1,029 lines of comprehensive unit tests for FmdClient |
tests/unit/test_device.py |
753 lines of unit tests for Device class |
tests/functional/ |
6 functional test scripts with credential utilities |
pyproject.toml |
Updated to v2.0.1 with proper package configuration |
.github/workflows/test.yml |
CI pipeline for lint, type check, and tests |
setup.py |
Removed (replaced by pyproject.toml) |
fmd_api.py |
Removed (replaced by package structure) |
fmd_client.py |
Removed (functionality migrated to new structure) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| {name = "Devin Slick", email = "fmd_client_github@devinslick.com"}, | ||
| ] | ||
| description = "A Python client for the FMD server API" | ||
| version = "2.0.1" |
There was a problem hiding this comment.
Version 2.0.1 suggests this is a patch release, but the PR description and changes indicate this is a major breaking rewrite (v1 to v2). Consider whether this should be 2.0.0 instead, as .1 typically indicates a bugfix on top of a stable 2.0.0 release. If 2.0.0 was already released, this is fine; otherwise, use 2.0.0 for the initial v2 release.
Summary
This major release delivers a production-ready async client with robust TLS handling, resilient request logic (timeouts, retries, rate limits), and a fully wired CI pipeline (lint, type-check, tests, coverage). It replaces the legacy synchronous v1 client and prepares the project for Home Assistant and broader integration.
Highlights
FmdClientwith an async factory (await FmdClient.create(...)) and async context manager (async with ...).base_urlenforcement (rejects plain HTTP).ssl=False(dev only) or pass a customssl.SSLContext.py.typed) and mypy-clean.Breaking changes
client = FmdApi(...); client.authenticate(...); client.get_all_locations()client = await FmdClient.create(base_url, fmd_id, password, ...)await client.get_locations(...),await client.get_pictures(...),await client.send_command(...)async with FmdClient.create(...) as client: ...base_urlmust be HTTPS; plain HTTP raisesValueError.Migration guide
FmdApiusage with the asyncFmdClient:await FmdClient.create(...)andasync withfor safe resource management.ssl=False.ssl.SSLContext.conn_limit,conn_limit_per_host,keepalive_timeouton the TCPConnector via client init.Error handling and semantics
FmdApiExceptionwhere appropriate; messages mask sensitive data.Documentation and examples
pin_cert_example.pydemonstrates secure pinning and avoids CLI secrets.CI/CD and release automation
test.yml: runs on push/PR for all branches (lint, mypy, unit tests matrix, coverage, optional functional tests).publish.yml: builds on push/releases; publishes to TestPyPI for non-main pushes, PyPI on main or release.Checklist
Notes
ssl=Falsesparingly and never in production.CHANGELOG.mdentry for 2.0.0 is recommended if not already included.