chore: Fix incorrect Management API docs in Python SDK#675
chore: Fix incorrect Management API docs in Python SDK#675Koosha-Owji wants to merge 3 commits intokinde-oss:mainfrom
Conversation
WalkthroughDocumentation reworked to center the Python Management API around a standalone ManagementClient (client-credentials flow). Examples, authentication patterns, dynamic endpoint discovery (snake_case API properties), error handling, and dotenv-based credential loading were updated and reorganized. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/content/docs/developer-tools/sdks/backend/python-sdk.mdx`:
- Around line 1408-1412: The snippet imports load_dotenv and will raise
ModuleNotFoundError unless python-dotenv is installed; update the docs near the
example to explicitly state the prerequisite and installation command (e.g.,
"pip install python-dotenv") and mention that load_dotenv() must be called
before initializing ManagementClient to load environment variables; reference
the import load_dotenv and the ManagementClient usage so the reader knows where
the note applies.
- Around line 1573-1580: The get_user endpoint currently catches broad Exception
and returns the raw error in HTTPException; change get_user to catch the
SDK-specific error type (e.g., ApiException or the SDK's typed error from
management.users_api.get_user_data) and handle it explicitly: map known SDK
status codes to appropriate FastAPI responses and return sanitized error
messages (no raw exception text) in HTTPException(detail=...), while logging the
full error server-side (using your logger) for diagnostics; leave a generic 500
catch-all that logs the error but returns a non-sensitive generic message.
|
Kindly resolve the coderabbit issues and it should be good. |
tamalchowdhury
left a comment
There was a problem hiding this comment.
Resolve the coderabbit issues and it should be ready to go.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)
1566-1593: The defensive check forApiException.statusis not necessary in this context.
ApiExceptionis OpenAPI-generated and always includes an HTTP status code when raised from a response. Thee.statusattribute will be populated as an integer in all normal exception flows. Adding a defensive fallback like502introduces unnecessary complexity for documentation code that should demonstrate the standard pattern.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/content/docs/developer-tools/sdks/backend/python-sdk.mdx` around lines 1566 - 1593, The docs example should rely on the OpenAPI-generated ApiException having a populated status, so in the get_user handler remove any defensive fallback for ApiException.status and raise HTTPException using e.status directly; update the exception block that references ApiException, keeping logger.error("Kinde API error: %s %s", e.status, e.body) and replacing any code like "status_code=e.status or 502" with "status_code=e.status" so the example shows the standard pattern for ApiException handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/content/docs/developer-tools/sdks/backend/python-sdk.mdx`:
- Around line 1597-1604: Update the documentation text describing
ManagementClient's refresh behavior: remove the hardcoded "60 seconds before
expiration" claim and instead state that the client requests new tokens via the
client credentials grant when existing tokens expire, and that token lifetime is
configurable in the Kinde portal per application; adjust the sentence
referencing "Automatic re-acquisition" to reflect this and keep the rest of the
token acquisition/caching/shared-token wording unchanged (refer to the
ManagementClient description block).
---
Nitpick comments:
In `@src/content/docs/developer-tools/sdks/backend/python-sdk.mdx`:
- Around line 1566-1593: The docs example should rely on the OpenAPI-generated
ApiException having a populated status, so in the get_user handler remove any
defensive fallback for ApiException.status and raise HTTPException using
e.status directly; update the exception block that references ApiException,
keeping logger.error("Kinde API error: %s %s", e.status, e.body) and replacing
any code like "status_code=e.status or 502" with "status_code=e.status" so the
example shows the standard pattern for ApiException handling.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 6d6f0327-68c6-4c56-b385-bf0e0357ca3e
📒 Files selected for processing (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
| The `ManagementClient` has its own token management system that is separate from the OAuth authentication clients. It uses the OAuth2 client credentials flow and automatically handles: | ||
|
|
||
| - **accessing Kinde Management API endpoints**: Obtains tokens for accessing Kinde's management endpoints | ||
| - **Token refresh**: Automatically refreshes management API tokens when they expire | ||
| - **Token storage**: Securely stores management API tokens | ||
| - **Thread safety**: Ensures thread-safe token handling for concurrent requests | ||
| - **Token acquisition**: Obtains tokens using a client credentials grant on the first API call | ||
| - **Token caching**: Tokens are cached and reused to avoid unnecessary requests | ||
| - **Automatic re-acquisition**: Requests new tokens via a client credentials grant when existing ones near expiry (60 seconds before expiration) | ||
| - **Shared tokens**: Multiple `ManagementClient` instances with the same domain and client ID share the same token | ||
|
|
||
| You don't need to manually manage Management API tokens - the client handles this for you. This is different from the core SDK's user session token management, which handles user authentication tokens automatically. | ||
| You don't need to manually manage tokens -- the client handles this for you. Note that credentials are validated on the first API call, not during client initialization. If your credentials are incorrect, the error will surface when you make your first request. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's find if there's a kinde-python-sdk directory or reference in the repository
find . -type d -name "*python*" -o -type d -name "*kinde*" 2>/dev/null | head -20Repository: kinde-oss/documentation
Length of output: 280
🏁 Script executed:
# Search for any references to ManagementClient and token refresh in the current repo
rg -i "managementclient" --type=md -A 3 -B 3 | head -50Repository: kinde-oss/documentation
Length of output: 49
🏁 Script executed:
# Look for the specific documentation file mentioned
find . -path "*python-sdk.mdx" 2>/dev/nullRepository: kinde-oss/documentation
Length of output: 129
🏁 Script executed:
# Read the specific lines mentioned in the review
sed -n '1590,1610p' ./src/content/docs/developer-tools/sdks/backend/python-sdk.mdxRepository: kinde-oss/documentation
Length of output: 1565
🌐 Web query:
kinde-python-sdk ManagementClient token refresh 60 seconds
💡 Result:
In kinde-python-sdk, the ManagementClient / Management API client uses the OAuth2 client credentials flow, so it doesn’t use a refresh token; instead it caches the management access token and automatically fetches a new one when it expires. Multiple client instances with the same domain + client id can share the cached token. [1]
If you configure your Kinde application’s access token lifetime to 60 seconds, then the management access token will naturally expire every ~60 seconds and the SDK will renew it that often. Token lifetimes are configured in the Kinde portal per application (Settings → Environment → Applications → View details → Tokens → set expiry in seconds). [2]
Kinde’s Python SDK docs also note the Management API client’s token handling is separate from user-session token management and that it auto-refreshes management API tokens on expiry. [3]
Sources:
[1] Kinde Python SDK repo (Token Management section) (github.com)
[2] Kinde docs: Configure token and session expiry (docs.kinde.com)
[3] Kinde docs: Python SDK → Management API → Token management (docs.kinde.com)
Citations:
- 1: https://github.com/kinde-oss/kinde-python-sdk
- 2: https://docs.kinde.com/build/tokens/configure-tokens/
- 3: https://docs.kinde.com/developer-tools/sdks/backend/python-sdk/
🌐 Web query:
kinde-python-sdk github repository
💡 Result:
The kinde-python-sdk GitHub repository is: https://github.com/kinde-oss/kinde-python-sdk [1].
(Starter kit repo: https://github.com/kinde-starter-kits/python-starter-kit [2].)
🏁 Script executed:
# Let's look at the kinde-python-sdk repository to verify the actual token refresh logic
# Search for token refresh/renewal code references
curl -s "https://api.github.com/repos/kinde-oss/kinde-python-sdk/contents/" | jq -r '.[].name' | head -20Repository: kinde-oss/documentation
Length of output: 131
🏁 Script executed:
# Search within the documentation repo for any other token-related discussions
rg -i "60 seconds|token.*expir" ./src/content/docs/developer-tools/sdks/ -A 2 -B 2 --type=md | head -60Repository: kinde-oss/documentation
Length of output: 49
Clarify ManagementClient token refresh behavior — it's not a hardcoded 60-second buffer.
The statement "Requests new tokens via a client credentials grant when existing ones near expiry (60 seconds before expiration)" is misleading. The SDK doesn't have a hardcoded 60-second pre-expiry refresh. Instead, token lifetime is configurable in the Kinde portal per application, and the SDK automatically refreshes when tokens expire. The "60 seconds" only applies if the application's token lifetime is configured to 60 seconds.
Rephrase to: "Requests new tokens via a client credentials grant when existing tokens expire" and remove the specific timeout reference. The token caching and shared-token-across-instances claims are accurate.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/developer-tools/sdks/backend/python-sdk.mdx` around lines
1597 - 1604, Update the documentation text describing ManagementClient's refresh
behavior: remove the hardcoded "60 seconds before expiration" claim and instead
state that the client requests new tokens via the client credentials grant when
existing tokens expire, and that token lifetime is configurable in the Kinde
portal per application; adjust the sentence referencing "Automatic
re-acquisition" to reflect this and keep the rest of the token
acquisition/caching/shared-token wording unchanged (refer to the
ManagementClient description block).
|
I'll resolve CAai comment tonight. |
Description (required)
The Management API section of the Python SDK docs showed
oauth.get_management()— a method that doesn't exist on any of the SDK's OAuth classes. Rewrote the section to use the correctManagementClientclass with non-deprecated API class methods, accurate method signatures, proper FastAPI handler definitions, and correct token lifecycle documentation.Summary by CodeRabbit