feat(python): expand bindings to cover all major read domains, document parity scope (closes #66) - #113
Merged
Merged
Conversation
…nt parity scope (closes #66)
joshrotenberg
marked this pull request as ready for review
June 2, 2026 04:31
This was referenced Jun 2, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Task: Python bindings parity — define scope and implement high-value domains (issue #66)
Setup (sequential — verify each step before proceeding)
/Users/josh.rotenberg/Code/active/redis-cloud-rsfeat/66-python-parity:git branch --show-currentgit statuscargo check --workspace 2>&1 | tail -5cd python && maturin develop --uv 2>&1 | tail -10cd python && python -m pytest tests/ -v 2>&1 | tail -20cd /Users/josh.rotenberg/Code/active/redis-cloud-rsContext
This repo is a Rust client library (
redis-cloud) for the Redis Cloud REST API, with PyO3-basedPython bindings in the
python/subdirectory. The Python extension is built withmaturin.The Rust library was harmonized in issue #65 (PR #112, merged): every domain handler now has
both verbose legacy names (
get_all_subscriptions,get_subscription_by_id, etc.) AND simplifiedalias methods (
list,get,create,update,delete). The Python bindings should align withthe simplified alias names where possible.
Current Python surface (
python/src/client.rs)Read
/Users/josh.rotenberg/Code/active/redis-cloud-rs/python/src/client.rscompletely.Currently exposed:
account/account_sync— viaAccountHandler::get_current_account()subscriptions/subscriptions_sync— viaSubscriptionHandler::get_all_subscriptions()subscription/subscription_sync— viaSubscriptionHandler::get_subscription_by_id()databases/databases_sync— viaDatabaseHandler::get_subscription_databases()database/database_sync— viaDatabaseHandler::get_subscription_database_by_id()all_databases/all_databases_sync— viaDatabaseHandler::get_all_databases()get,get_sync,post,post_sync,delete,delete_sync— raw HTTPtimeoutpropertyRust handler inventory (after #65)
Read these files to understand available handlers and method signatures:
/Users/josh.rotenberg/Code/active/redis-cloud-rs/src/lib.rs— re-exports and handler overview/Users/josh.rotenberg/Code/active/redis-cloud-rs/src/tasks.rs—TasksHandler:list(),get(task_id: String)/Users/josh.rotenberg/Code/active/redis-cloud-rs/src/users.rs—UsersHandler:list(),get(user_id: i32),delete(user_id: i32)/Users/josh.rotenberg/Code/active/redis-cloud-rs/src/acl.rs—AclHandler:list_redis_rules(),list_roles(),list_acl_users(),get_acl_user(id)/Users/josh.rotenberg/Code/active/redis-cloud-rs/src/cloud_accounts.rs—CloudAccountsHandler:list(),get(id),delete(id)/Users/josh.rotenberg/Code/active/redis-cloud-rs/src/fixed/subscriptions.rs—FixedSubscriptionHandler:list(),get_by_id(id),delete_by_id(id)/Users/josh.rotenberg/Code/active/redis-cloud-rs/src/fixed/databases.rs—FixedDatabaseHandler:list(sub_id),get_by_id(sub_id, db_id),backup(sub_id, db_id)/Users/josh.rotenberg/Code/active/redis-cloud-rs/src/account.rs—AccountHandler:get(),system_logs(...),payment_methods()Decision: Python parity scope
This task implements option 1 from the issue: Python is a deliberately smaller convenience
layer. The rationale:
field engineering tooling.
the raw HTTP helpers (
post,put,patch) that are already exposed.domains with at minimum a
listand/orgetmethod.The scope decision must be documented in two places:
python/README.md(create this file — it does not currently exist)README.md(update the "Python Bindings" section to reference the scope decision)Task: what exactly to implement
Phase 1: Update
python/src/client.rs— add new domain methodsAdd the following methods to
PyCloudClient. Each method needs an async variant and a_syncvariant, following the exact same pattern as the existing methods.The pattern (study before coding):
Async variant:
Sync variant:
Methods to add, grouped by domain:
Tasks domain
tasks()/tasks_sync()— callsTasksHandler::list(), returns all taskstask(task_id: String)/task_sync(task_id: String)— callsTasksHandler::get(task_id)Users domain
users()/users_sync()— callsUsersHandler::list()user(user_id: i64)/user_sync(user_id: i64)— callsUsersHandler::get(user_id as i32)ACL domain
acl_redis_rules()/acl_redis_rules_sync()— callsAclHandler::list_redis_rules()acl_roles()/acl_roles_sync()— callsAclHandler::list_roles()acl_users()/acl_users_sync()— callsAclHandler::list_acl_users()Cloud accounts domain
cloud_accounts()/cloud_accounts_sync()— callsCloudAccountsHandler::list()cloud_account(cloud_account_id: i64)/cloud_account_sync(cloud_account_id: i64)— callsCloudAccountsHandler::get(id as i32)Fixed (Essentials) subscriptions domain
fixed_subscriptions()/fixed_subscriptions_sync()— callsFixedSubscriptionHandler::list()fixed_subscription(subscription_id: i64)/fixed_subscription_sync(subscription_id: i64)— callsFixedSubscriptionHandler::get_by_id(id as i32)Fixed (Essentials) databases domain
fixed_databases(subscription_id: i64)/fixed_databases_sync(subscription_id: i64)— callsFixedDatabaseHandler::list(sub_id as i32)fixed_database(subscription_id: i64, database_id: i64)/fixed_database_sync(...)— callsFixedDatabaseHandler::get_by_id(sub_id as i32, db_id as i32)Import additions needed in
python/src/client.rs:Check the actual re-export names in
src/lib.rscarefully before writing the imports:TasksHandleris re-exported asTaskHandlerUsersHandleris re-exported asUserHandlerCloudAccountsHandleris re-exported asCloudAccountHandlerPhase 2: Update
python/src/lib.rs— no changes needed unless new types are exportedReview
python/src/lib.rs. No changes are expected unless new types need to be registeredas Python classes (they don't for this task — we continue using the JSON-to-Python pattern).
Phase 3: Update Python tests (
python/tests/test_client.py)Add a new test class
TestNewDomainMethodswithhasattrexistence checks for each newmethod pair. Follow the existing
TestClientMethodspattern exactly:Add tests for: tasks, task, users, user, acl_redis_rules, acl_roles, acl_users,
cloud_accounts, cloud_account, fixed_subscriptions, fixed_subscription,
fixed_databases, fixed_database.
Phase 4: Create
python/README.mdCreate
/Users/josh.rotenberg/Code/active/redis-cloud-rs/python/README.mdwith:smaller convenience layer. It covers read-oriented operations across all major API
domains. Write operations (create, update, delete) are available via the raw HTTP
helpers (
post,put,patch,delete) or the Rust client."account,account_syncsubscriptions,subscriptions_sync,subscription,subscription_syncdatabases,databases_sync,database,database_sync,all_databases,all_databases_synctasks,tasks_sync,task,task_syncusers,users_sync,user,user_syncacl_redis_rules,acl_redis_rules_sync,acl_roles,acl_roles_sync,acl_users,acl_users_synccloud_accounts,cloud_accounts_sync,cloud_account,cloud_account_syncfixed_subscriptions,fixed_subscriptions_sync,fixed_subscription,fixed_subscription_syncfixed_databases,fixed_databases_sync,fixed_database,fixed_database_syncget,get_sync,post,post_sync,delete,delete_syncOut-of-scope section: List what's intentionally deferred and why (connectivity
handlers, cost_report, write operations, pagination beyond
all_databases).Quick start example in Python showing how to use the client.
Installation instructions (maturin / PyPI).
Phase 5: Update
README.mdPython Bindings sectionFind the "Python Bindings" section in the root
README.md(around line 132-142). Update it to:python/README.mdfor the full supported API."a convenience layer covering read operations across all major API domains."
Verification gates
After each phase:
After Phase 1 (Rust changes):
cargo check --workspace 2>&1 | tail -10— must be cleancargo clippy --workspace --all-targets -- -D warnings 2>&1 | tail -20— must be cleancargo fmt --allAfter Phase 2 (build Python extension):
4.
cd /Users/josh.rotenberg/Code/active/redis-cloud-rs/python && maturin develop --uv 2>&1 | tail -15Must complete without error. If it fails, read the full error and fix.
After Phase 3 (Python tests):
5.
cd /Users/josh.rotenberg/Code/active/redis-cloud-rs/python && python -m pytest tests/ -v 2>&1All tests must pass. The new
TestNewDomainMethodstests must all be present and green.Final:
6.
cargo test --workspace 2>&1 | tail -20— Rust tests must pass7.
cd /Users/josh.rotenberg/Code/active/redis-cloud-rs && cargo test --test openapi_route_coverage 2>&1— must stay greenTool-call discipline
client.rs, read the whole file before adding any new methods.src/lib.rsre-exports to confirm the exact Rust type names to import.Cargo.tomlentries).json_to_pyandpy_to_jsonhelpers are already inpython/src/client.rs— use them.Constraints
gh pr create(the runner created the draft PR).git push.python/src/client.rs.python/Cargo.tomldependencies.src/(Rust library) except as needed to satisfy compilation.Actually: do NOT modify the Rust library files at all — they were settled in api(consistency): finish harmonized handler surface across remaining domains #65.
to the Python bindings — these are explicitly out of scope for this parity round.
Commit (at the end, after all checks pass)
git add python/src/client.rs python/tests/test_client.py python/README.md README.md git commit -m "feat(python): expand bindings to cover all major read domains, document parity scope (closes #66)"