Skip to content

feat: refinements in api generator; initial polytest integration for algod #222

Merged
aorumbayev merged 49 commits intodecouplingfrom
decoupling-algod-tweaks
Dec 8, 2025
Merged

feat: refinements in api generator; initial polytest integration for algod #222
aorumbayev merged 49 commits intodecouplingfrom
decoupling-algod-tweaks

Conversation

@aorumbayev
Copy link
Contributor

@aorumbayev aorumbayev commented Nov 28, 2025

WIP draft, remaining polytest tests are still being implemented

Notes

- Only set format=msgpack when msgpack is explicitly selected
- Remove unnecessary format=json assignments for JSON-only endpoints
- Align with TypeScript client behavior
Generated output from updated client.py.j2 template:
- Remove format=json for endpoints that only support JSON
- Simplify msgpack format selection logic
- Reduce unnecessary query parameters
When dataclasses use slots=True and have fields named 'bytes' or 'type',
the class namespace contains member descriptors that interfere with
get_type_hints() evaluation.

Fix by passing explicit globalns with builtins and empty localns to
get_type_hints() to avoid the class namespace pollution.

Fixes TypeError: unsupported operand type(s) for |: 'member_descriptor' and 'NoneType'
The local_state_schema and global_state_schema fields may not always
be present in wire data from the ledger state delta endpoint.
Make them optional with default=None to handle missing fields gracefully.
Add Docker container-based mock server fixtures using testcontainers:
- MockServerContainer class to manage PollyJS mock server lifecycle
- Session-scoped fixtures for algod, indexer, and kmd mock servers
- Mock server replays pre-recorded HAR files for deterministic testing
- Fixtures automatically start/stop containers per test session
- Configure via POLYTEST_MOCK_SERVER_IMAGE and POLYTEST_RECORDINGS_PATH env vars
- Add test configuration constants matching TS mock server config
- Add testcontainers>=4.0.0 to dev dependencies for mock server containers
- Add polytest generate/validate tasks for algod, indexer, kmd clients
- Update transact polytest config to use algorandfoundation repo
- Add polytest-generate-all and polytest-validate-all aggregate tasks
- Add group_common_tests pytest marker for polytest test groups
- Install Rust toolchain and polytest CLI
- Run polytest-validate-algod to ensure test structure matches polytest config
- Validates that generated test files follow the expected naming conventions
Move manually written tests to tests/modules/algod_client/manual/ to
distinguish them from polytest-generated test stubs:
- test_block.py
- test_ledger_state_delta.py
- test_pending_transaction_information.py
- test_raw_transaction.py
- test_simulate_transactions.py
- test_suggested_params.py

Also fix localnet tests to use AlgorandClient.default_localnet().client.algod
consistently instead of mixing mock server with localnet transactions.
Add NOT IMPLEMENTED test stubs for algod client API endpoints:
- DELETE endpoints (catchup, ledger_sync)
- GET endpoints (boxes, state proofs, deltas, devmode, experimental, etc.)
- POST endpoints (catchup, ledger_sync, shutdown, teal, transactions)

All stubs are marked with @pytest.mark.skip(reason='Test not implemented')
and follow the polytest naming convention matching TypeScript tests.

These stubs serve as placeholders for future test implementation and
ensure structural parity with algokit-utils-ts polytest suite.
- Implement test_get_genesis.py, test_get_health.py, test_get_versions.py
- Implement test_get_v2_status.py, test_get_v2_ledger_supply.py
- Implement test_get_v2_transactions_params.py
- Implement test_get_v2_accounts_address.py with localnet
- Implement test_get_v2_blocks_round.py with mainnet/testnet endpoints
- Implement test_get_v2_deltas_round.py with mainnet endpoint
- Skip msgpack-related tests matching TypeScript approach
- All tests verify client methods return correct model types
- Move indexer and kmd integration tests to manual/ folders
- These tests require localnet with indexer/kmd, not mock server
- Update tests to use localnet clients directly
- Add E501, W292, I001 lint ignores for tests/modules/**/* in pyproject.toml
- Fix trailing newlines in polytest stub files (pre-commit format)
@aorumbayev aorumbayev force-pushed the decoupling-algod-tweaks branch from e7c4710 to 59851d2 Compare December 2, 2025 22:33
@aorumbayev aorumbayev requested a review from Copilot December 2, 2025 23:52
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces polytest integration for the algod client and includes refinements to the API generator. The changes establish a mock server testing infrastructure and add initial test coverage for algod API endpoints using recorded HAR files.

Key changes:

  • Adds mock server infrastructure for deterministic API testing
  • Implements polytest-based tests for ~30 algod endpoints
  • Refactors model field defaults to be more explicit
  • Renames/consolidates API client methods for consistency

Reviewed changes

Copilot reviewed 293 out of 310 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/modules/_mock_server.py Docker-based mock server infrastructure with retry logic
tests/modules/conftest.py Shared test utilities including dataclass serializer
tests/modules/algod_client/conftest.py Algod-specific mock server fixture
tests/modules/algod_client/test_*.py Polytest suite for algod endpoints
src/algokit_kmd_client/client.py Adds retry mechanism with exponential backoff
src/algokit_kmd_client/models/*.py Updates field defaults and model naming
src/algokit_transact/models/*.py Adds Unknown transaction type fallback
Comments suppressed due to low confidence (1)

tests/modules/_mock_server.py:1

  • The jitter calculation produces values between 0.5 and 1.5, which means backoff is always reduced by at least 50% (when jitter is 0.5). This differs from typical jitter implementations that add randomness around the base value. Consider using a more standard jitter approach like random.uniform(0.5, 1.5) (which is already implemented) or documenting this specific backoff reduction strategy.
"""Mock server infrastructure for algod/indexer/kmd client testing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@aorumbayev
Copy link
Contributor Author

aorumbayev commented Dec 2, 2025

@daniel-makerx a few bits around consumption of mock client are to be decided and still missing a set of kmd algod and indexer tests to be covered (missing har files on mock server side) - otherwise ready for preliminary review. The main aim here was aligning with Neil's progress on the various algod/indexer/kmd generator and spec related refinements. The following 2 were split into separate branches and mainly cover the addition of polytest generated stubs while majority of all tweaks and refinements are within this branch. #224 -> to be merged into -> #225 -> to be merged into -> this branch

aorumbayev and others added 4 commits December 3, 2025 01:03
* test: add indexer client polytest tests

- Add 21 indexer client endpoint tests aligned with TypeScript implementation
- Add test constants for indexer test data (address, app_id, asset_id, txid, round)
- Add JSON snapshots for all indexer endpoints
- Tests use mock server recordings for deterministic testing

* test: add KMD client polytest tests (#224)

- Add 23 KMD client endpoint tests aligned with TypeScript implementation
- Fix init_wallet_handle method name in kmd_account_manager.py
- Fix manual test_key_management.py (remove non-existent display_mnemonic param)
- Add JSON snapshots for KMD endpoints with recordings
- Most tests skipped due to missing mock server recordings (require localnet)
@aorumbayev
Copy link
Contributor Author

aorumbayev commented Dec 3, 2025

@daniel-makerx @lempira - ready for review - before merging would require one extra commit to:

  1. change mock server image tag to ghcr on algorandfoundation org once ci: adds shared reusable setup polytest and mock server actions algokit-polytest#18 is merged
  2. change setup-polytest action path to point to algorandfoundation's algokit-polytest repo once ci: adds shared reusable setup polytest and mock server actions algokit-polytest#18 is merged
  3. Updating branch to point to main (source urls for specs which are now pulled from remote paths) once fix: more oas refinement algokit-oas-generator#3 is merged
  4. If we are ok with this change fix: fixes casing of version strings joe-p/polytest#57 then no changes needed in polytest stubs, however if we do decide on further alternative naming for the file names for stubs generated with polytest - both ts and py would need to be regenerated via uv run poe tasks (which now include dedicated polytest tasks for generation and validation)

Post merge remaining polytest stubs are to be implemented on kmd/algod/indexer site as remaining har recordings become available in mock server for testing.

@aorumbayev aorumbayev marked this pull request as ready for review December 3, 2025 19:55
aorumbayev and others added 2 commits December 8, 2025 21:49
…er (#231)

* refactor: change test setup to use external mock servers

Updates the test suite to utilize externally managed mock servers for algod, indexer, and kmd clients.

This change decouples the test environment from Docker-based mock servers, promoting greater flexibility and simplifying setup, especially in CI/CD environments. It leverages the algokit-polytest repository for managing the mock server lifecycles.

The tests now connect to mock servers via environment variables.

* chore: tweaks

* chore: enable polytest validate in ci for algod, indexer, kmd
@aorumbayev aorumbayev force-pushed the decoupling-algod-tweaks branch from ea4f023 to a8ddedb Compare December 8, 2025 21:07
Renames `get_arc56_method` to `get_abi_method` for clarity and consistency across the codebase, reflecting the shift towards using ABI method specifications.

Also, replace calls to transaction.tx_id with transaction.tx_id() to align with ts
@aorumbayev aorumbayev force-pushed the decoupling-algod-tweaks branch from a8ddedb to b147c37 Compare December 8, 2025 21:27
@aorumbayev aorumbayev merged commit 6347860 into decoupling Dec 8, 2025
5 checks passed
@aorumbayev aorumbayev deleted the decoupling-algod-tweaks branch December 8, 2025 21:34
mrcointreau pushed a commit that referenced this pull request Mar 2, 2026
…algod (#222)

* refactor: algod and api generator refinements aligning with ts

* chore: txnleases

* feat: default value handling of required fields; omitting txn leases field

* fix(api): refine format parameter handling in client generator template

- Only set format=msgpack when msgpack is explicitly selected
- Remove unnecessary format=json assignments for JSON-only endpoints
- Align with TypeScript client behavior

* fix(api): regenerate algod client with refined format handling

Generated output from updated client.py.j2 template:
- Remove format=json for endpoints that only support JSON
- Simplify msgpack format selection logic
- Reduce unnecessary query parameters

* fix(serde): handle dataclass fields that shadow builtin names

When dataclasses use slots=True and have fields named 'bytes' or 'type',
the class namespace contains member descriptors that interfere with
get_type_hints() evaluation.

Fix by passing explicit globalns with builtins and empty localns to
get_type_hints() to avoid the class namespace pollution.

Fixes TypeError: unsupported operand type(s) for |: 'member_descriptor' and 'NoneType'

* fix(algod): make LedgerAppParams schema fields optional

The local_state_schema and global_state_schema fields may not always
be present in wire data from the ledger state delta endpoint.
Make them optional with default=None to handle missing fields gracefully.

* feat(test): integrate polytest mock server for API client testing

Add Docker container-based mock server fixtures using testcontainers:
- MockServerContainer class to manage PollyJS mock server lifecycle
- Session-scoped fixtures for algod, indexer, and kmd mock servers
- Mock server replays pre-recorded HAR files for deterministic testing
- Fixtures automatically start/stop containers per test session
- Configure via POLYTEST_MOCK_SERVER_IMAGE and POLYTEST_RECORDINGS_PATH env vars
- Add test configuration constants matching TS mock server config

* build: add testcontainers dependency and polytest poe tasks

- Add testcontainers>=4.0.0 to dev dependencies for mock server containers
- Add polytest generate/validate tasks for algod, indexer, kmd clients
- Update transact polytest config to use algorandfoundation repo
- Add polytest-generate-all and polytest-validate-all aggregate tasks
- Add group_common_tests pytest marker for polytest test groups

* ci: add polytest validation to check-python workflow

- Install Rust toolchain and polytest CLI
- Run polytest-validate-algod to ensure test structure matches polytest config
- Validates that generated test files follow the expected naming conventions

* refactor(test): move manual algod tests to dedicated folder

Move manually written tests to tests/modules/algod_client/manual/ to
distinguish them from polytest-generated test stubs:
- test_block.py
- test_ledger_state_delta.py
- test_pending_transaction_information.py
- test_raw_transaction.py
- test_simulate_transactions.py
- test_suggested_params.py

Also fix localnet tests to use AlgorandClient.default_localnet().client.algod
consistently instead of mixing mock server with localnet transactions.

* test(algod): generate polytest stubs for all algod client endpoints

Add NOT IMPLEMENTED test stubs for algod client API endpoints:
- DELETE endpoints (catchup, ledger_sync)
- GET endpoints (boxes, state proofs, deltas, devmode, experimental, etc.)
- POST endpoints (catchup, ledger_sync, shutdown, teal, transactions)

All stubs are marked with @pytest.mark.skip(reason='Test not implemented')
and follow the polytest naming convention matching TypeScript tests.

These stubs serve as placeholders for future test implementation and
ensure structural parity with algokit-utils-ts polytest suite.

* test(algod): implement polytest stubs aligning with TypeScript tests

- Implement test_get_genesis.py, test_get_health.py, test_get_versions.py
- Implement test_get_v2_status.py, test_get_v2_ledger_supply.py
- Implement test_get_v2_transactions_params.py
- Implement test_get_v2_accounts_address.py with localnet
- Implement test_get_v2_blocks_round.py with mainnet/testnet endpoints
- Implement test_get_v2_deltas_round.py with mainnet endpoint
- Skip msgpack-related tests matching TypeScript approach
- All tests verify client methods return correct model types

* fix(test): move integration tests to manual folders and fix lint ignores

- Move indexer and kmd integration tests to manual/ folders
- These tests require localnet with indexer/kmd, not mock server
- Update tests to use localnet clients directly
- Add E501, W292, I001 lint ignores for tests/modules/**/* in pyproject.toml
- Fix trailing newlines in polytest stub files (pre-commit format)

* style: fix indentation in oas-generator template renderer

* chore: update api client to support latest refined specs with inline duplicate schemas removed

* chore: refine fixtures for cross worker access to mock server with filelock dependency

* feat: add graceful handling of unknown transaction types

* refactor: ensure models that are not used anywhere and/or are referenced by filtered oas tags are not generated

* chore: extra fixes for unknown txn support

* chore: adding snapshot testing; migration notes

* chore: remove refs

* chore: linter tweaks

* chore: sqlite as default value from spec; retry mechanism for generated clients; minor alignment with latest on ts

* feat: support fetching oas specs directly from oas-generator repo

* chore: integrate docker image from fork; shared action

* chore: temporarily comment out polytest validate in ci

* docs: regen docs

* chore: regen clients

* chore: regen kmd clients; simplify remote oas fetching

* chore: refine mock server fixtures

* chore: refine pre commit; fix mypy warnings

* chore: add jitter and polling health check to the mock server fixture

* docs: remove mentions of oas shorthand

* test: add indexer client polytest tests (#225)

* test: add indexer client polytest tests

- Add 21 indexer client endpoint tests aligned with TypeScript implementation
- Add test constants for indexer test data (address, app_id, asset_id, txid, round)
- Add JSON snapshots for all indexer endpoints
- Tests use mock server recordings for deterministic testing

* test: add KMD client polytest tests (#224)

- Add 23 KMD client endpoint tests aligned with TypeScript implementation
- Fix init_wallet_handle method name in kmd_account_manager.py
- Fix manual test_key_management.py (remove non-existent display_mnemonic param)
- Add JSON snapshots for KMD endpoints with recordings
- Most tests skipped due to missing mock server recordings (require localnet)

* chore: add support for overriding mock server urls for local dev

* docs: update migration guide

* chore: refresh kmd client

* chore: refresh docs

* feat: add support for skip tag in oas generator; dropping dryrun

* chore: update branch for oas generator remote source to main

* chore: further simplify mock server

* docs: add documentation to prevent base type docs appearing

* chore: refresh docs

* refactor: change test setup to use external mock servers without docker (#231)

* refactor: change test setup to use external mock servers

Updates the test suite to utilize externally managed mock servers for algod, indexer, and kmd clients.

This change decouples the test environment from Docker-based mock servers, promoting greater flexibility and simplifying setup, especially in CI/CD environments. It leverages the algokit-polytest repository for managing the mock server lifecycles.

The tests now connect to mock servers via environment variables.

* chore: tweaks

* chore: enable polytest validate in ci for algod, indexer, kmd

* chore: remove slow stages from pre commit

* refactor: change arc56 method to abi method

Renames `get_arc56_method` to `get_abi_method` for clarity and consistency across the codebase, reflecting the shift towards using ABI method specifications.

Also, replace calls to transaction.tx_id with transaction.tx_id() to align with ts

---------

Co-authored-by: Daniel McGregor <daniel.mcgregor@makerx.com.au>
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.

3 participants