Skip to content

feat(python-sdk): list_namespaces() so an agent can discover namespaces [WALM-651] - #930

Merged
nikola0x0 merged 1 commit into
devfrom
nikolale/walm-651-python-sdk-list-namespaces
Sep 18, 2026
Merged

nikola0x0 merged 1 commit into
devfrom
nikolale/walm-651-python-sdk-list-namespaces

Conversation

@nikola0x0

Copy link
Copy Markdown
Collaborator

Closes WALM-651. Python counterpart of the TS listNamespaces() from #830 (WALM-395).

What

MemWal.list_namespaces(cursor=None, limit=None) -> NamespacesResult. It lists the namespaces that hold memories, so a Python agent can find them instead of guessing or falling back to "default". Metadata only: no blob fetch, no decryption, no SEAL session.

Same design as the TS SDK:

  • Owner lookup. The route needs the owner address in the path, but the client only has a delegate key and account id. It learns the owner from POST /api/stats once per client. Concurrent first calls share one lookup, and a failed lookup is retried on the next call.
  • Signed query string. The relayer verifies against path_and_query, so updated_after / limit are part of the signed path.
  • Pagination. On has_more, not page length (the relayer clamps limit).
  • Parity. MemWalSync, MemWalMock and MemWalMockSync get the same method. The mock follows the relayer's cursor format and snapshot walk, same as the TS mock.

Bumps memwal to 0.1.11 (0.1.10 is already on PyPI), so merging triggers the Python release job.

Checks

  • 16 new unit tests (11 client, 5 mock), each seen failing before the code existed
  • Full unit suite passes on Python 3.9 and 3.12 (168 passed); ruff clean
  • Live: new read-only integration test walks every page at limit=1 against relayer.dev.memwal.ai. It found 3 namespaces, with the cursor in the signed query string on each page, and the relayer accepted every request
  • check-docs-code-sync, check-docs-freshness, verify-manual-sdk-release pass
  • README, docs/python-sdk/api-reference.md and both changelogs updated

Not in this PR

…es [WALM-651]

Python counterpart of the TS listNamespaces() from #830 (WALM-395).

- MemWal.list_namespaces(cursor=None, limit=None) -> NamespacesResult:
  signed GET /v1/owners/{owner}/namespaces, metadata only, no SEAL
  session. The query string is signed, since the relayer verifies
  path_and_query.
- Owner resolved once per client via POST /api/stats; concurrent first
  calls share one lookup, and a failed lookup is retried on the next call.
- MemWalSync, MemWalMock and MemWalMockSync get the same method. The mock
  follows the relayer's cursor format and snapshot walk.
- Bump memwal to 0.1.11; README, API reference and changelogs updated.

@ducnmm ducnmm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Summary

This is a careful Python port of TS listNamespaces(): signed GET /v1/owners/{owner}/namespaces with updated_after/limit in the signed query string, owner discovery via memoized POST /api/stats, no SEAL session, and MemWalSync / mock / sync-mock parity. Mapping to NamespacesResult matches the relayer wire shape (has_more, opaque next_cursor, snapshot_version), and the mock’s keyset + snapshot walk matches query_owner_namespaces (including terminal snapshot_at: null so the next poll is a fresh walk). Tests pin the contract (single-flight owner lookup, failed lookup retry, signature covers path_and_query, mock pagination); version is bumped consistently to 0.1.11. No correctness issues found.

Issue counts by severity

  • bugs: 0
  • suggestions: 0
  • nits: 0

@nikola0x0
nikola0x0 merged commit c8e072a into dev Sep 18, 2026
24 of 25 checks passed
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