Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Feature: Implement missing PyAleph API endpoints#276

Open
1yam wants to merge 3 commits intomainaleph-im/aleph-sdk-python:mainfrom
1yam-address-statsaleph-im/aleph-sdk-python:1yam-address-statsCopy head branch name to clipboard
Open

Feature: Implement missing PyAleph API endpoints#276
1yam wants to merge 3 commits intomainaleph-im/aleph-sdk-python:mainfrom
1yam-address-statsaleph-im/aleph-sdk-python:1yam-address-statsCopy head branch name to clipboard

Conversation

@1yam
Copy link
Member

@1yam 1yam commented Jan 21, 2026

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:

  • Added a new AddressesFilter class to src/aleph/sdk/query/filters.py for filtering and sorting address stats queries, including options for substring filtering and sorting by message type and order.
  • Introduced the SortByMessageType enum to specify supported sort fields in address stats queries.
  • Implemented the AddressStats and AddressStatsResponse models in src/aleph/sdk/query/responses.py to represent address statistics and the paginated response structure.
  • Updated the HTTP client in src/aleph/sdk/client/http.py to add the get_address_stats method, allowing asynchronous retrieval of address statistics with filtering and pagination support. [1] [2]

Testing and validation:

  • Added unit tests in tests/unit/test_asynchronous_get.py to verify the new address stats query functionality, including tests for filtered and unfiltered queries, and introduced fixtures in tests/unit/conftest.py to provide mock address stats data and responses. [1] [2] [3]

@1yam 1yam requested review from aliel, nesitor and odesenfans January 21, 2026 10:35
@aleph-im aleph-im deleted a comment from github-actions bot Jan 21, 2026
@1yam 1yam changed the title Feature: new method in AlephHttpClient get_address_stats Feature: Implement missing PyAleph API endpoints Jan 21, 2026
Copy link

@foxpatch-aleph foxpatch-aleph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

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

Morty Proxy This is a proxified and sanitized view of the page, visit original site.