feat: Enhance APIClient to support legacy and modern API detection#7
Conversation
- Added automatic detection of API generation (modern vs legacy) in APIClient. - Implemented endpoint mapping for legacy Communication and Print Board. - Updated raw GET and POST methods to handle different API structures. - Introduced properties for API version and board type. - Enhanced error handling for connection issues and 404 responses. - Updated models to normalize node fields between API versions. - Added tests for both modern and legacy API interactions, including node actions and configurations.
|
waiting on #8 |
…s and allow None values
… for HTTP connections
…ard and simplify command usage
There was a problem hiding this comment.
Pull request overview
This PR enhances the DucoPy library to support both modern Connectivity Board and legacy Communication and Print Board APIs. The changes enable automatic detection of board types and handle API differences transparently through endpoint mapping and response transformation.
Key changes:
- Added automatic API generation detection in
APIClientthat distinguishes between modern and legacy boards - Implemented endpoint mapping to translate Connectivity Board endpoints to Communication and Print Board equivalents
- Enhanced models with field normalization and optional fields to support both API versions
- Updated tests to cover both modern and legacy API interactions
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ducopy/rest/client.py | Added detect_generation() method, endpoint mapping, legacy API transformations, and properties for board type/version detection |
| src/ducopy/rest/utils.py | Updated DucoUrlSession to accept endpoint_mapper callback, added timeout parameter, and enhanced API key generation to handle both board types |
| src/ducopy/rest/models.py | Improved Pydantic version detection, added field normalization validators, and made fields optional for legacy compatibility |
| tests/test_client.py | Added test fixtures and test cases for both modern and legacy API interactions, including detection mocking |
| tests/test_restapi.py | Updated assertions to handle optional Code field and multiple success result formats |
| src/ducopy/cli.py | Enhanced commands to include generation info in outputs and updated help text for multi-board support |
| README.md | Updated documentation to reflect support for both board types and corrected CLI command examples |
| pyproject.toml | Added pytest filter to suppress InsecureRequestWarning during tests |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…xible base URL handling in tests
… for Connectivity Board compatibility
…at for Communication and Print Board
…Connectivity board formats
…on and serial number extraction
…or Connectivity and Communication/Print Boards
…e for Communication/Print Boards
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 12 comments.
Comments suppressed due to low confidence (1)
src/ducopy/rest/client.py:579
- raw_post() does not apply endpoint mapping for legacy boards (unlike raw_get()), so callers using raw_post with modern-style endpoints will fail on Communication/Print boards. Consider mapping the endpoint via _map_endpoint() here as well for consistency, or explicitly document that raw_post is "no mapping".
def raw_post(self, endpoint: str, data: str | None = None) -> dict:
"""
Perform a raw POST request to the specified endpoint with retry logic.
Args:
endpoint (str): The endpoint to send the POST request to (e.g., "/api").
data (dict, optional): The data to include in the request body.
params (dict, optional): Query parameters to include in the request.
Returns:
dict: JSON response from the server.
"""
logger.info(f"Performing raw POST request to endpoint: {endpoint} with data: {data}")
response = self.session.post(endpoint, json=data)
response.raise_for_status()
logger.debug("Received response for raw POST request to endpoint: {}", endpoint)
return response.json()
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…s and improve logging
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…clarity and type safety
…rl in DucoPy and APIClient
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…improved flexibility
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…UrlSession for improved error handling


This PR allows the inclusion of older "Communication and Print" systems within the library. Due to the nature of difference between "newer" generation Communication boards and the older communication and print, we have used the library to abstract some of the commands away so systems utilizing the library dont need to be overly complex to deal with different type of connectivity systems. This means the library will handle all of the nuances between generational communication boards (At the moment this is Communication and print and connectivity board V1). It does not, however, do everything. For example if you request https on a older board, this will not work.
Due to the fact DUCO communication and print never exposes the API version on any of the API endpoints, the only "way" you can actually programmatically see this would be the zeroconf broadcast where it actually mentions the API version. Being that this library never has done auto discovery, I think it would be pointless to add it for one type of connectivity board. Annoyingly, on the more modern versions, you can see this within the REST endpoints. With this in mind, we have used certain endpoints to actually see if we are talking to a communication and print board or a connectivity board and save that for further use.
Noteworthy changes