Enhance API role assignment and user functionality with documentation updates#3
Conversation
* Change parameter name from `params` to `body` for consistency. * Update API requests to use `json=body` instead of `params=params`. * Enhance `PaginatedResponse` to handle plain lists from API. * Modify resource actions serialization to match backend expectations. * Add integration tests for comprehensive coverage of SDK functionality.
* Revise changelog to reflect new features and APIs * Enhance README with usage examples and context management * Clarify installation and configuration instructions
There was a problem hiding this comment.
Pull request overview
This PR updates the SDK’s docs and adds a live-backend integration test suite, alongside a few API/model compatibility tweaks (resource action serialization, role assignment parsing, list-response handling, and role-unassign request shape).
Changes:
- Add
tests/test_integration.pyexercising end-to-end CRUD + permission checks against a localhost backend. - Update README examples (installation, init/scope auto-detection, async/sync usage, expanded API sections).
- Adjust SDK internals for backend compatibility: resource actions request shape, list responses that may return plain lists, user sync URL, and role-unassign DELETE payloads.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_integration.py | New live-backend integration tests and cleanup logic |
| README.md | Substantial documentation/example updates for usage patterns and APIs |
| permissio/models/role_assignment.py | Add fallback parsing for key fields in assignment reads |
| permissio/models/resource.py | Serialize resource actions as a backend-expected map |
| permissio/models/common.py | Support endpoints returning a plain list in paginated wrapper |
| permissio/api/users.py | Change sync() to PUT users/{key} and send unassign payload as JSON |
| permissio/api/role_assignments.py | Send unassign payload as JSON in DELETE requests |
| CHANGELOG.md | Rewrite changelog with an alpha release entry and expanded feature list |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| API_KEY = os.environ.get( | ||
| "PERMIS_API_KEY", | ||
| "permis_key_d39064912cd9d1f0052a98430e3eb7d689a350d84f2d0a018843541b5da3e5ef", | ||
| ) |
| """ | ||
| Integration tests for the Permissio Python SDK. | ||
|
|
||
| These tests run against a live backend at http://localhost:3001. | ||
| All test data uses timestamped keys and is cleaned up after each run. | ||
|
|
|
|
||
| assert read_allowed is True, "read should be allowed" | ||
| assert write_allowed is False, "write should be denied (not in role perms)" | ||
| assert delete_allowed is False, "delete should be denied" | ||
|
|
||
| # 10. getPermissions() – roles + permissions via users.get_roles() ------- | ||
|
|
||
| def test_19_get_permissions(self, client): | ||
| """ |
| user_data = dict(user) | ||
|
|
||
| url = self._build_facts_url("users") | ||
| user_key = user_data.get("key", "") | ||
| url = self._build_facts_url(f"users/{user_key}") | ||
| response = self.put(url, json=user_data) |
| user_data = dict(user) | ||
|
|
||
| url = self._build_facts_url("users") | ||
| user_key = user_data.get("key", "") | ||
| url = self._build_facts_url(f"users/{user_key}") | ||
| response = await self.put_async(url, json=user_data) |
| # Sync role (upsert) | ||
| permissio.api.roles.sync("editor", name="Editor", permissions=["document:read"]) | ||
|
|
||
| # Unassign a role | ||
| permissio.unassign_role("user@example.com", "editor", tenant="acme-corp") | ||
| # Permission management | ||
| permissio.api.roles.add_permission("editor", "document:delete") | ||
| permissio.api.roles.remove_permission("editor", "document:delete") | ||
| permissions = permissio.api.roles.get_permissions("editor") |
| # Role inheritance (extends) | ||
| permissio.api.roles.add_extends("editor", "viewer") | ||
| permissio.api.roles.remove_extends("editor", "viewer") | ||
| extends = permissio.api.roles.get_extends("editor") |
| # Sync resource type (upsert) | ||
| permissio.api.resources.sync("document", name="Document") | ||
|
|
|
|
||
| --- | ||
|
|
||
| ## [0.1.0-alpha.1] - 2025-03-15 |
| - **Tenants API** (`api.tenants`): Full sync and async CRUD — `list`, `get`, `create`, `update`, `delete`, plus `sync` | ||
| - **Roles API** (`api.roles`): Full sync and async CRUD plus `add_permissions()`, `add_permissions_async()`, `remove_permissions()`, `remove_permissions_async()` | ||
| - **Resources API** (`api.resources`): Full sync and async CRUD plus action management (`list_actions`, `create_action`, `delete_action`) and attribute management (`list_attributes`, `create_attribute`, `delete_attribute`) |
* Modify pytest command to run only non-integration tests * Add marker for integration tests in pyproject.toml
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment Thanks for integrating Codecov - We've got you covered ☂️ |
No description provided.