-
Notifications
You must be signed in to change notification settings - Fork 24
Pr 128 #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Pr 128 #143
Conversation
- Update response types for various endpoints - Add new endpoints for user identities management
Fix the singularization bug that was generating incorrect method names: - create_user_identitie → create_user_identity - get_identitie → get_identity - update_identitie → update_identity - delete_identitie → delete_identity Changes: - Add _singularize_resource() helper method to centralize singularization logic - Handle special cases: user_identities → user_identity, identities → identity - Update both _generate_methods() and _create_api_method() to use the helper - Maintains existing behavior for other resources (users, organizations, etc.) This fixes a pre-existing bug that was exposed by PR kinde-oss#128's addition of user_identities and identities endpoints.
WalkthroughUpdated ManagementClient endpoints to use pluralized resource paths, added identity/user_identity endpoints, introduced Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as ManagementClient
participant Gen as _generate_methods()
participant Sing as _singularize_resource()
participant APIMethod as generated API method
participant Server as Kinde API
Dev->>Gen: initialize -> generate dynamic methods
Gen->>Sing: singularize(resource_name)
Sing-->>Gen: singular form (handles special cases)
Gen->>APIMethod: emit API caller (path, verb, response mapping)
Dev->>APIMethod: call create_feature_flag(key,type,value)
APIMethod->>Server: POST /feature_flags with body {key,type,value}
Server-->>APIMethod: 200 + payload
APIMethod-->>Dev: return mapped response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Update test assertions to reflect removed endpoints: - Remove get_permission assertion (permissions no longer has get endpoint) - Remove get_feature_flags and get_feature_flag assertions (removed in PR kinde-oss#128) - Remove update_api_application assertion (removed in PR kinde-oss#128) - Update test_feature_flags_api_calls to test create_feature_flag instead These changes align tests with the updated Management API endpoints introduced in PR kinde-oss#128.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
kinde_sdk/management/management_client.py (2)
387-408: Incomplete handling of-iesplural forms.The method correctly handles
user_identitiesandidentities, but other resources ending in-ieswould produce incorrect singular forms:
industries→industrie(should beindustry)properties→propertie(should beproperty)Currently these resources only have
listactions so no singular methods are generated, but this could break if singular actions are added later.Consider a more robust approach:
def _singularize_resource(self, resource: str) -> str: # Handle special cases if resource == 'business': return 'business' # Don't remove 's' from 'business' elif resource == 'user_identities': return 'user_identity' # Replace 'identities' with 'identity' elif resource == 'identities': return 'identity' # Replace 'identities' with 'identity' + # Handle words ending in 'ies' -> 'y' (e.g., properties -> property) + elif resource.endswith('ies'): + return resource[:-3] + 'y' # Default: remove trailing 's' if present elif resource.endswith('s'): return resource[:-1] else: return resource
474-480: Dead code: manual query string construction is unused.The
final_pathvariable constructed here is never used. The actual query parameter handling is done byparam_serializeat line 489, which receivesquery_paramsdirectly.Consider removing this unused code block:
- # FIXED: Use param_serialize to properly construct the full URL with host - # Handle query parameters by appending them to the path - final_path = formatted_path - if query_params and http_method in ('GET', 'DELETE'): - query_string = '&'.join([f"{k}={v}" for k, v in query_params.items() if v is not None]) - if query_string: - separator = '&' if '?' in final_path else '?' - final_path = f"{final_path}{separator}{query_string}" - # Use param_serialize to get the proper URL with host
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
kinde_sdk/management/management_client.py(11 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
kinde_sdk/management/management_client.py
[error] 1-1: Dynamic method generation missing 'get_permission' method. The ManagementClient should expose a 'get_permission' method for permissions API.
[error] 1-1: ManagementClient does not implement get_feature_flags; only has create_feature_flag as per tests.
🔇 Additional comments (3)
kinde_sdk/management/management_client.py (3)
207-215: LGTM! New identity endpoints correctly added.The new
user_identitiesandidentitiesresources are properly structured with appropriate paths and HTTP methods. This addresses the PR objective of fixing the singularization bug for these endpoints.
348-356: LGTM!Response type mappings for the new identity endpoints are correctly structured with appropriate status codes (201 for create, 200 for others).
410-434: LGTM!The method generation logic correctly uses the centralized
_singularize_resourcehelper, ensuring consistent singular form derivation for all dynamically generated method names.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
testv2/testv2_management/test_management_client.py (1)
491-533: Feature flag test now matches create‑via‑POST behaviorThe
test_feature_flags_api_callsupdate correctly models the newcreate_feature_flagflow: POST to/feature_flagswith a{"key", "type", "value"}body and a single-flag response object, and the test wiring (token, deserialize, assertion) is consistent with other tests in this file.If you want this test to guard more strongly against regressions, consider also asserting on
mock_api_client_instance.param_serialize.call_args(HTTP method, URL, and body) rather than justassert_called_once(), but that’s optional given the existing patterns.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
testv2/testv2_management/test_management_client.py(4 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-07-04T07:09:21.430Z
Learnt from: brettchaldecott
Repo: kinde-oss/kinde-python-sdk PR: 83
File: kinde_sdk/auth/feature_flags.py:85-102
Timestamp: 2025-07-04T07:09:21.430Z
Learning: In the Kinde Python SDK v2, the maintainer (brettchaldecott) prefers to keep async keywords on methods in the feature flags module even when they don't currently perform await operations, as this approach has been tested and is preferred for the SDK's design.
Applied to files:
testv2/testv2_management/test_management_client.py
📚 Learning: 2025-08-21T04:46:50.368Z
Learnt from: KomanRudden
Repo: kinde-oss/kinde-python-sdk PR: 101
File: kinde_sdk/auth/permissions.py:6-7
Timestamp: 2025-08-21T04:46:50.368Z
Learning: The kinde_sdk has both frontend and management API modules. The frontend permissions_api.py exists at kinde_sdk/frontend/api/permissions_api.py and contains PermissionsApi class. Using the management API instead of the frontend API for user permissions would be incorrect.
Applied to files:
testv2/testv2_management/test_management_client.py
🔇 Additional comments (1)
testv2/testv2_management/test_management_client.py (1)
98-120: Comment updates correctly capture removed management methodsThe new notes about
get_permission,get_feature_flags/get_feature_flag, andupdate_api_applicationbeing removed align with the updated ManagementClient surface and help future readers understand why those methods aren’t asserted here. No functional changes introduced in this block; looks good as-is.
Add the missing 'list' endpoint to feature_flags resource to enable
get_feature_flags() method generation.
Changes:
- Add 'list': ('GET', '/api/v1/feature_flags') to feature_flags API_ENDPOINTS
- Add corresponding response type mapping: 'list': {'200': 'GetFeatureFlagsResponse', ...}
- Update test to assert get_feature_flags method exists
This addresses the CodeRabbit review comment on PR kinde-oss#143 and enables
the SDK to generate the get_feature_flags() method as documented in
the Kinde Management API.
…nse types - Corrected endpoint paths for organizations and API applications to use plural forms. - Updated response types for create endpoints to reflect correct HTTP status codes (201). - Adjusted test assertions to ensure alignment with the updated API structure. These changes enhance consistency with the Kinde Management API specifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
kinde_sdk/management/management_client.py (1)
77-83:permissionsstill lacks agetaction /get_permissionmappingThe
permissionsresource only defines list/create/update/delete and has no'get'entry in eitherAPI_ENDPOINTSorRESPONSE_TYPES. A prior review noted this was causing a missingget_permissionmethod and pipeline failures; that appears unchanged here. If your API and consumers expect aget_permissionmethod, you’ll still need to add:
"'get': ('GET', '/api/v1/permissions/{permission_id}'),"underAPI_ENDPOINTS['permissions']- A corresponding
'get'mapping underRESPONSE_TYPES['permissions']using the appropriate single‑permission response model.Also applies to: 258-263
🧹 Nitpick comments (1)
kinde_sdk/management/management_client.py (1)
174-178: Minor:update_businessdocstring suggests an ID param that the endpoint does not useFor the
businessresource,updateis defined asPATCH /api/v1/businesswith no path parameter. The generic docstring generator foraction == 'update'will still describe an ID argument (business_id), but the generated method accepts only*args, **kwargsand ignores any positional ID because the path has no{}placeholder. If you want the docs to match behavior, consider special‑casing this resource/action in the docstring generation or adjusting the wording to omit the ID parameter.Also applies to: 327-330
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
kinde_sdk/management/management_client.py(12 hunks)testv2/testv2_management/test_management_client.py(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- testv2/testv2_management/test_management_client.py
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-21T04:46:50.368Z
Learnt from: KomanRudden
Repo: kinde-oss/kinde-python-sdk PR: 101
File: kinde_sdk/auth/permissions.py:6-7
Timestamp: 2025-08-21T04:46:50.368Z
Learning: The kinde_sdk has both frontend and management API modules. The frontend permissions_api.py exists at kinde_sdk/frontend/api/permissions_api.py and contains PermissionsApi class. Using the management API instead of the frontend API for user permissions would be incorrect.
Applied to files:
kinde_sdk/management/management_client.py
📚 Learning: 2025-07-04T07:09:21.430Z
Learnt from: brettchaldecott
Repo: kinde-oss/kinde-python-sdk PR: 83
File: kinde_sdk/auth/feature_flags.py:85-102
Timestamp: 2025-07-04T07:09:21.430Z
Learning: In the Kinde Python SDK v2, the maintainer (brettchaldecott) prefers to keep async keywords on methods in the feature flags module even when they don't currently perform await operations, as this approach has been tested and is preferred for the SDK's design.
Applied to files:
kinde_sdk/management/management_client.py
🔇 Additional comments (2)
kinde_sdk/management/management_client.py (2)
41-41: Pluralized create endpoints and new identity routes look coherent—please confirm against the Management API specThe shifts to plural resource paths (organizations, roles, permissions, feature_flags, applications, apis, subscribers, properties) and the new user_identities / identities routes are consistent with the rest of the mapping and should generate the expected method names (e.g.,
create_user_identity,get_identity,update_identity,delete_identity). Please double‑check these paths and verbs (especially the PATCH→PUT changes) against the live Management API docs so the generated client stays in sync with the server.Also applies to: 72-72, 80-80, 88-89, 97-97, 106-106, 114-114, 131-131, 177-178, 208-216
389-411: New_singularize_resourcehelper cleanly fixes theidentitiemethod-name bugUsing
_singularize_resourcewith explicit cases forbusiness,user_identities, andidentitiesensures that dynamic methods are now correctly named (create_user_identity,get_identity,update_identity,delete_identity) while leaving existing resources’ method names stable. Reusing the same helper in_generate_methodsand_create_api_methodkeeps docstrings and method names aligned. This directly addresses the prior singularization issue without introducing obvious regressions.Also applies to: 415-415, 451-451, 208-216, 354-357
| 'list': {'200': 'UsersResponse', '400': 'ErrorResponse', '403': 'ErrorResponse', '429': 'ErrorResponse'}, | ||
| 'get': {'200': 'User', '400': 'ErrorResponse', '403': 'ErrorResponse', '404': 'ErrorResponse', '429': 'ErrorResponse'}, | ||
| 'create': {'201': 'CreateUserResponse', '400': 'ErrorResponse', '403': 'ErrorResponse', '429': 'ErrorResponse'}, | ||
| 'create': {'200': 'CreateUserResponse', '400': 'ErrorResponse', '403': 'ErrorResponse', '429': 'ErrorResponse'}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if management_client.py exists and get file size
find . -name "management_client.py" -type fRepository: kinde-oss/kinde-python-sdk
Length of output: 113
🏁 Script executed:
#!/bin/bash
# Get line count and read the relevant sections
wc -l ./kinde_sdk/management/management_client.pyRepository: kinde-oss/kinde-python-sdk
Length of output: 117
🏁 Script executed:
#!/bin/bash
# Read the relevant sections of the file to see the status code mappings
sed -n '220,360p' ./kinde_sdk/management/management_client.py | cat -nRepository: kinde-oss/kinde-python-sdk
Length of output: 13362
🏁 Script executed:
#!/bin/bash
# Search for test files related to management client
find . -name "*test*.py" -o -name "*spec*.py" | grep -i management | head -20Repository: kinde-oss/kinde-python-sdk
Length of output: 426
🏁 Script executed:
#!/bin/bash
# Check the size of test files and look for relevant tests
wc -l ./test_management_client.py ./testv2/testv2_management/test_management_client.pyRepository: kinde-oss/kinde-python-sdk
Length of output: 174
🏁 Script executed:
#!/bin/bash
# Search for tests related to status codes and the operations mentioned in the review
echo "=== Searching for create/update/webhooks/subscribers/api_applications tests ==="
rg -n "users.*create|roles.*update|webhooks|subscribers.*create|api_applications|connected_apps" ./test_management_client.py ./testv2/testv2_management/test_management_client.py -A 3 -B 1 | head -100Repository: kinde-oss/kinde-python-sdk
Length of output: 2696
🏁 Script executed:
#!/bin/bash
# Search for OpenAPI/Swagger specs or API documentation
find . -name "*.yaml" -o -name "*.yml" -o -name "*.json" | grep -i "spec\|openapi\|swagger\|api" | head -20Repository: kinde-oss/kinde-python-sdk
Length of output: 52
🏁 Script executed:
#!/bin/bash
# Look for models or response definitions
find . -name "*model*.py" -o -name "*response*.py" | head -20Repository: kinde-oss/kinde-python-sdk
Length of output: 1319
🏁 Script executed:
#!/bin/bash
# Check the api_response.py file and search for response_deserialize logic
wc -l ./kinde_sdk/management/api_response.py
cat -n ./kinde_sdk/management/api_response.pyRepository: kinde-oss/kinde-python-sdk
Length of output: 910
🏁 Script executed:
#!/bin/bash
# Search for response_deserialize in the management client
rg -n "response_deserialize" ./kinde_sdk/management/management_client.py -A 20 -B 5Repository: kinde-oss/kinde-python-sdk
Length of output: 1517
🏁 Script executed:
#!/bin/bash
# Find where api_client is initialized and its type
rg -n "self.api_client" ./kinde_sdk/management/management_client.py | head -10Repository: kinde-oss/kinde-python-sdk
Length of output: 432
🏁 Script executed:
#!/bin/bash
# Search for ApiClient class and response_deserialize method
find . -name "*.py" -type f | xargs grep -l "class ApiClient" | head -5Repository: kinde-oss/kinde-python-sdk
Length of output: 106
🏁 Script executed:
#!/bin/bash
# Read api_client.py and search for response_deserialize
wc -l ./kinde_sdk/management/api_client.py
rg -n "def response_deserialize" ./kinde_sdk/management/api_client.py -A 30Repository: kinde-oss/kinde-python-sdk
Length of output: 1631
🏁 Script executed:
#!/bin/bash
# Read more of response_deserialize to understand full error handling
sed -n '286,350p' ./kinde_sdk/management/api_client.py | cat -nRepository: kinde-oss/kinde-python-sdk
Length of output: 3366
🌐 Web query:
Kinde Management API documentation roles update status code response
💡 Result:
Short answer
- Successful update: HTTP 200 OK (JSON body with success info). [1][2]
- Validation/client errors: HTTP 4xx with JSON error object (example: {"code":"PERMISSIONS_REQUIRED","message":"Permissions parameter is required"}). [3]
- Other common responses: 401/403 for auth/scopes, 429 for rate limiting, 5xx for server errors. See rate-limit handling headers. [1][4]
Sources
- Kinde Management API reference / APIs overview. [docs.kinde.com]. [1]
- Kinde "Manage user roles" (describes updating roles via Management API). [2]
- Community example showing a PATCH error response with PERMISSIONS_REQUIRED. [3]
- Kinde API rate-limits and 429 handling. [4]
🌐 Web query:
Kinde Management API users create POST response status code 200 201
💡 Result:
Short answer: Kinde’s Management API docs don’t explicitly state a single required success status for the create-user endpoint; community examples and the official SDK show the POST /v1/user (or /api/v1/user) returns the created user object on success, but implementations in the wild may return either 200 OK or 201 Created. Check the actual response status on your tenant (inspect the HTTP response) and rely on the presence of the created-user JSON (and Location header if present) rather than assuming only 200 or only 201. Sources: Kinde API docs and community threads. [1][2]
Sources
- Kinde Management API docs (API reference / management). [1]
- Community reports / Q&A about POST /v1/user behavior. [2]
Fix incorrect status code mapping for roles.update and verify other operations match actual API responses
The Kinde Management API documentation confirms that successful update operations return HTTP 200 OK, not 201. However, roles.update is currently mapped to '201': 'SuccessResponse', which will cause response_deserialize to fail matching the response status code. When the API returns 200 but the mapping expects 201, the deserialization skips silently (response_type remains None), resulting in callers receiving data=None instead of the actual response.
Additionally, the mappings for several other operations require verification against actual Kinde API responses:
users.create(currently200) — confirm whether the API actually returns 200 or 201webhooks.create(currently200) — verify if create endpoints consistently return 200subscribers.create(currently201) — confirm this is correctapi_applications.create(currently201) — confirm this is correctconnected_apps.update(currently200) — verify update operations- Identity models (
GetIdentitiesResponse,CreateIdentityResponse,Identity) — confirm these exist and match API responses
Mismatches between mapped status codes and actual API responses will cause silent deserialization failures.
🤖 Prompt for AI Agents
In kinde_sdk/management/management_client.py around line 224, the response
status mapping for roles.update is incorrectly set to '201' which causes
response_deserialize to miss a 200 OK response; change the mapping to use '200'
for roles.update and then audit the surrounding operation mappings to ensure
they match the API (verify users.create, webhooks.create, subscribers.create,
api_applications.create, connected_apps.update) and update their expected status
codes to the actual API responses (200 vs 201) as needed; also confirm the
referenced identity models (GetIdentitiesResponse, CreateIdentityResponse,
Identity) exist and match API shapes, update model names or imports if
necessary, and run integration/unit tests or a quick live call to each endpoint
to validate deserialization returns data instead of None.
Explain your changes
fix: correct singularization for user_identities and identities
Fix singularization bug that generated incorrect method names for
user_identities and identities endpoints. Add _singularize_resource()
helper to handle special cases and maintain backward compatibility.
Fixes: create_user_identitie → create_user_identity
get_identitie → get_identity
update_identitie → update_identity
delete_identitie → delete_identity
Checklist
🛟 If you need help, consider asking for advice over in the Kinde community.