Skip to content

Return typed Pydantic models from external API calls and centralize request logging by status class#129

Merged
fabieu merged 16 commits intomainfrom
copilot/update-api-response-to-pydantic
Mar 19, 2026
Merged

Return typed Pydantic models from external API calls and centralize request logging by status class#129
fabieu merged 16 commits intomainfrom
copilot/update-api-response-to-pydantic

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 13, 2026

This pull request refactors the SureHub API service layer to improve response handling and data validation. The main change is replacing the legacy http_utils module with a new response_handler, which centralizes response parsing, error handling, and model validation using Pydantic. Additionally, dependency version specifications are updated for better compatibility and maintainability.

Service Layer Refactoring:

  • Replaced all uses of http_utils.extract_response_data and http_utils.raise_for_status with response_handler.parse and response_handler.raise_for_status in service files (auth.py, dashboard.py, devices.py, households.py, pets.py, reports.py, timeline.py). This ensures consistent response parsing and error handling across the codebase. [1] [2] [3] [4] [5] [6] [7]
  • Updated function signatures to use explicit Pydantic models for return types, improving type safety and clarity (e.g., returning List[official.Device] instead of list). [1] [2] [3]

Response Handler Improvements:

  • Introduced the new response_handler.py (renamed from http_utils.py), which adds logging, robust error extraction, and Pydantic model validation to HTTP response parsing. [1] [2]
  • Enhanced response parsing logic to support extracting nested keys and validating against provided models, improving reliability and maintainability.

Dependency Management:

  • Updated dependency version specifications in pyproject.toml to use explicit version ranges (>=,<) instead of ~= for both runtime and development dependencies, reducing the risk of breaking changes from future releases. [1] [2]

Code Quality and Consistency:

  • Fixed inconsistent naming and usage for device/tag/profile enums and endpoint URLs, ensuring uniformity throughout service modules. [1] [2]
  • Removed unnecessary imports and simplified code in several service files for clarity and maintainability. [1] [2]

API Behavior Adjustments:

  • Improved error handling in timeline and pet services to raise HTTP exceptions for invalid or missing data, ensuring API consumers receive clear feedback. [1] [2]

These changes collectively make the codebase more robust, maintainable, and type-safe, while standardizing response handling and error management across all API services.External API responses were being propagated as untyped dicts, requiring repeated ad-hoc parsing in services. This change introduces centralized response-model validation and consistent per-request logging with status-based severity (2xx→INFO, 4xx/5xx→ERROR).

  • Centralized response parsing and validation

    • Extended http_utils.extract_response_data(...) with an optional model parameter.
    • When provided, response payloads are validated/converted via pydantic.TypeAdapter, enabling direct return of typed models (including collections like List[official.Pet]).
    • Validation errors now surface as structured 500s with schema mismatch detail.
  • Centralized external request logging

    • Added request logging in http_utils.raise_for_status(...) using response metadata (method, url, status_code).
    • Enforced log levels:
      • INFO for 2xx
      • ERROR for 4xx/5xx
  • Service-layer adoption of typed models

    • Updated external API service methods to pass explicit model types into extract_response_data(...) across:
      • dashboard, reports, households, devices, pets
    • Removed now-redundant local re-validation paths where responses are already typed.
    • Routed auth and timeline error handling through shared HTTP utilities to ensure logging and status handling are consistent.
  • Related consistency cleanup

    • Normalized endpoint usage in devices service to settings.endpoint for all device/tag calls.
# Before
data = http_utils.extract_response_data(response)          # dict/list payload

# After
pet = http_utils.extract_response_data(response, model=official.Pet)
pets = http_utils.extract_response_data(response, model=List[official.Pet])

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Update external API to return Pydantic models Return typed Pydantic models from external API calls and centralize request logging by status class Feb 13, 2026
Copilot AI requested a review from fabieu February 13, 2026 17:06
Copilot AI and others added 12 commits February 26, 2026 23:28
Co-authored-by: fabieu <43068791+fabieu@users.noreply.github.com>

# Conflicts:
#	surehub_api/services/pets.py
Co-authored-by: fabieu <43068791+fabieu@users.noreply.github.com>
Co-authored-by: fabieu <43068791+fabieu@users.noreply.github.com>
Co-authored-by: fabieu <43068791+fabieu@users.noreply.github.com>
- Update dependencies
- Rename http_utils to response_handler
…131)

This updates the OpenAPI entity modules so class definitions are
consistently ordered alphabetically by class name, as requested.
Reordering introduced forward-reference ordering changes, so annotation
evaluation was adjusted to keep imports and type references stable.

- **Class layout normalization**
  - Reordered all class blocks alphabetically in:
    - `surehub_api/entities/official.py`
    - `surehub_api/entities/official_v2.py`
  - Preserved class contents/signatures; only declaration order changed.

- **Forward-reference safety after reorder**
  - Added postponed annotation evaluation in both files:
    - `from __future__ import annotations`
- Prevents import-time `NameError` when a class annotation references a
type declared later in the file after alphabetical sorting.

- **Ordering guardrail**
- Extended `tests/test_official_openapi_models.py` with a file-level
check that class declarations in both entity files remain alphabetically
sorted.

```python
# added at top of both files
from __future__ import annotations
```

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: fabieu <43068791+fabieu@users.noreply.github.com>
Co-authored-by: Fabian Eulitz <dev@sustineo.de>
@fabieu fabieu force-pushed the copilot/update-api-response-to-pydantic branch from 50ef431 to 0663e65 Compare February 26, 2026 22:32
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
8.5% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@fabieu fabieu marked this pull request as ready for review March 19, 2026 17:08
@fabieu fabieu merged commit b8fe6fd into main Mar 19, 2026
1 check failed
@fabieu fabieu deleted the copilot/update-api-response-to-pydantic branch March 19, 2026 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants