Feature: Implement missing PyAleph API endpoints#276
Feature: Implement missing PyAleph API endpoints#276
Conversation
get_address_stats
foxpatch-aleph
left a comment
There was a problem hiding this comment.
The PR cleanly adds three new endpoints (address stats, account files, chain balances) with corresponding filters and response models, following the existing code style well. There are no security issues or critical bugs, but there are several quality issues: a dead-code condition in a fixture that obscures intent, test assertions that don't actually validate filter behavior, a misplaced enum that creates a backwards import dependency between responses and filters, and minor inconsistencies in null-checking and model strictness.
tests/unit/conftest.py (line 192): if int(1) == 1: is always True — this is dead code. The intent was probably to conditionally build data_dict based on page, but page isn't in scope here (it's the lambda parameter below). The block should simply be removed and the dict built unconditionally, since the lambda already handles the page guard on line 206. As written, the condition is misleading and makes the fixture look like it supports multi-page behaviour when it doesn't.
tests/unit/test_asynchronous_get.py (line 148): test_get_address_stats passes address_contains="0xa1" as a filter but then asserts len(address_stats) == 2. Only one of the two fixture addresses (0xa1B3...) matches that prefix; the other (0x51A5...) does not. Because the mock bypasses server-side filtering, both addresses are returned, so the assertion passes — but it gives a false impression that filter behavior is being verified. The test should either (a) assert len == 1 with the filtered mock, or (b) drop the filter and clarify this is only testing the HTTP plumbing.
src/aleph/sdk/query/filters.py (line 36): FileType is a domain model concept (a classification of stored objects), not a query parameter concept. Defining it in filters.py creates a backwards import dependency: responses.py imports from filters.py, which is unusual and harder to follow. It would be cleaner in responses.py itself (since that's the only consumer) or in a shared types.py / models.py.
src/aleph/sdk/client/http.py (line 755): if not filter: should be if filter is None: (same pattern applies at lines 784 and 818). While custom class instances are truthy by default, using is None is the idiomatic and safer check, consistent with how get_balances already uses filter.as_http_params() if filter else None. It also avoids a future bug if a filter subclass ever defines __bool__.
src/aleph/sdk/query/responses.py (line 134): AddressStats uses extra="forbid", but it's unclear whether the real API response includes a total field alongside the individual type counts. The SortByMessageType enum has a TOTAL variant (implying the server tracks a total separately), and the fixture maps item["total"] → "messages". If the live API returns both messages and total fields, pydantic will raise a validation error here. Consider using extra="ignore" until the exact API shape is confirmed, or add total: int to the model.
src/aleph/sdk/query/filters.py (line 339): min_balance is documented as "must be >= 1" but there is no validation. If the API returns a 4xx for values < 1, callers will get an unhelpful HTTP error rather than a clear ValueError. Consider adding a validator or at minimum removing the constraint from the doc if it isn't actually enforced.
This pull request adds support for querying address statistics from the Aleph node API, including filtering and sorting capabilities. It introduces new models and filters for handling address stats, updates the HTTP client to support these queries, and adds comprehensive unit tests for the new functionality.
Address stats query feature:
AddressesFilterclass tosrc/aleph/sdk/query/filters.pyfor filtering and sorting address stats queries, including options for substring filtering and sorting by message type and order.SortByMessageTypeenum to specify supported sort fields in address stats queries.AddressStatsandAddressStatsResponsemodels insrc/aleph/sdk/query/responses.pyto represent address statistics and the paginated response structure.src/aleph/sdk/client/http.pyto add theget_address_statsmethod, allowing asynchronous retrieval of address statistics with filtering and pagination support. [1] [2]Testing and validation:
tests/unit/test_asynchronous_get.pyto verify the new address stats query functionality, including tests for filtered and unfiltered queries, and introduced fixtures intests/unit/conftest.pyto provide mock address stats data and responses. [1] [2] [3]