-
Notifications
You must be signed in to change notification settings - Fork 35
docs: update Python SDK documentation #489
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?
docs: update Python SDK documentation #489
Conversation
""" WalkthroughThe documentation updates remove deprecated environment variables, rename Management API client credentials, reorganize OAuth client and route registration examples into tabbed sections, and add a new detailed section on Machine-to-Machine (M2M) applications for server-to-server communication with step-by-step setup instructions. Changes
Possibly related PRs
Suggested reviewers
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 4
♻️ Duplicate comments (2)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (2)
1150-1167
: Sync call toget_users
againSame async inconsistency as in FastAPI example. Adjust to real SDK signature and, if async, run inside an event-loop (
asyncio.run
orasync_to_sync
).
1214-1221
: Django: same token logging leakageSame concern as FastAPI — remove the slice logging.
🧹 Nitpick comments (3)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (3)
933-957
: Rate-limit store is process-local and not thread-safeUsing a module-level dict for rate limiting will:
- Reset on every process restart.
- Break under multi-worker deployments (Gunicorn, Uvicorn workers).
- Cause race conditions in async contexts.
Document that this is illustrative only and recommend Redis / memcached for production.
Also prefer anasyncio.Lock
oranyio
semaphore around dict mutation.
1085-1093
:get_management_token_flask
replicates FastAPI logic – factor outThe logic is 100 % duplicated. Consider extracting a shared helper (pure-python) used by both frameworks to avoid drift.
1254-1263
: Userequest.META["token_manager"]
orrequest.state
, not attribute injectionAttaching arbitrary attributes can collide with future Django fields. Prefer
request._token_manager
(underscore) or wrapping insiderequest.META
.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
(1 hunks)
🔇 Additional comments (3)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (3)
1333-1340
: URL patterns omit trailing slash consistencyConventionally Django API endpoints end without a trailing slash when
APPEND_SLASH=False
. Decide on one style and stick to it; earlier examples use/management/users
(no slash).
902-909
: Confirm whetherget_token_scopes
is asynchronous and update the docs accordinglyIt looks like the example in
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
callstoken_manager.get_token_scopes()
withoutawait
, which could silently fail if that method is defined asasync
. Since we don’t have the SDK source here, please verify its signature and:
- If it’s
async def get_token_scopes(...)
, change the snippet to:token_scopes = await token_manager.get_token_scopes()- Otherwise, no change is needed.
• File: src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
• Lines: ~902–909
796-805
: Verifyvalidate_and_set_via_introspection
SignatureI wasn’t able to import the SDK in this environment to confirm whether
validate_and_set_via_introspection
is defined as anasync def
or a regular method. Please check the actual SDK source (e.g.kinde_sdk/auth/management.py
) or your installed package:
- If it’s declared as
async def validate_and_set_via_introspection(…)
, update the example to:and change the wrapper to- introspection_result = token_manager.validate_and_set_via_introspection(bearer_token) + introspection_result = await token_manager.validate_and_set_via_introspection(bearer_token)async def get_management_token(...)
.- If it’s a synchronous method, no changes are needed.
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 (5)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (5)
801-804
: Stop logging bearer tokens altogether
Even trimming to 20 chars is still sensitive. Remove the log or replace with a constant message.- logger.debug(f"Received bearer token (first 20 chars): {bearer_token[:20]}...") + # logger.debug("Bearer token received")
829-833
: Second token leakage via logging
The full bearer token is interpolated into the log line. Remove it.- logger.debug(f"ManagementTokenManager instantiated {bearer_token}") + # logger.debug("ManagementTokenManager instantiated")
1011-1019
: Fragile string matching for errors – catch concrete exceptions instead
Matching"unauthorized"
/"forbidden"
in error strings is brittle and localisation-dependent. Raise/handle specific SDK exceptions (KindeUnauthorizedError
, etc.).
1116-1120
: Token leaked in Flask log
Same leakage issue as in FastAPI example. Drop the log.
1158-1160
: Don’t mutateflask.request
; useflask.g
Attaching arbitrary attributes to the request proxy can clash with Werkzeug internals. Store thetoken_manager
onflask.g
instead.- request.token_manager = token_manager + from flask import g + g.token_manager = token_manager
🧹 Nitpick comments (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)
960-983
: In-memory rate limiter is not multi-process safe
A global dict won’t work behind gunicorn/uvicorn workers. Use Redis or another external store, or document this limitation explicitly.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
(1 hunks)
🔇 Additional comments (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)
881-886
: Cannot verify async signature ofget_users
; manual check required
I didn’t find any Python SDK source files in this repo to confirm whetherget_users
is defined asasync def
or a regular sync method. Please verify in the Python SDK package itself (e.g., inspect the installedmanagement_client
module or its documentation) whetherget_users
is asynchronous.If it is async, update the snippet in
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
to:- users_response = management_client.get_users() + users_response = await management_client.get_users()Otherwise, no change is needed.
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
♻️ Duplicate comments (4)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (4)
803-804
: Token-prefix logging still leaks credentials
Earlier feedback (lines 799-804) already covered this. Please remove the[:20]
preview entirely.
824-832
: Blocking network I/O inside a synchronous dependency – reiterating previous warning
validate_and_set_via_introspection()
performs remote introspection yet is called in a plaindef
dependency.
This stalls the event-loop and defeats FastAPI’s async benefits. The prior review suggested converting
get_management_token
toasync def
and running the blocking call in a thread executor.
881-884
:management_client.get_users()
is awaited nowherePrevious reviews established that
get_users
is an async SDK call. Calling it withoutawait
returns a coroutine and the example will confuse readers.- users_response = management_client.get_users() + users_response = await management_client.get_users()
829-830
: Remove full bearer token from logs – severe credential leakage
logger.debug(f"ManagementTokenManager instantiated {bearer_token}")
dumps the entire bearer token into logs.
This is a direct secret disclosure risk (PII / credentials) that violates OWASP logging guidance.
Replace it with a constant string or a request correlation id.- logger.debug(f"ManagementTokenManager instantiated {bearer_token}") + logger.debug("ManagementTokenManager instantiated")
🧹 Nitpick comments (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)
960-980
: In-memory rate limiter is not process-safe
request_counts
is a module-level dict.
Under multi-process servers (Gunicorn/Uvicorn workers) or after restart it loses state, and it is not thread-safe.
Consider pointing readers to Redis / Memcached orasyncio.Lock
-guarded stores instead.
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 (2)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (2)
803-805
: Stop logging bearer-token materialEven partial token output (
bearer_token[:20]
) is sensitive ‑ it aids token-padding & timing attacks and violates zero-secrets-in-logs guidelines.
Remove these debug statements entirely.- logger.debug(f"Received bearer token (first 20 chars): {bearer_token[:20]}...") ... - logger.debug(f"ManagementTokenManager instantiated {bearer_token}") + # logger.debug("Bearer token received") # avoid leaking PII / secretsAlso applies to: 829-830, 1169-1170, 1298-1299
881-886
: Await the asynchronousManagementClient.get_*
methods
ManagementClient.get_users()
/get_organizations()
areasync def
in the SDK.
Calling them withoutawait
returns a coroutine and the examples will fail at runtime.- users_response = management_client.get_users() + users_response = await management_client.get_users()Apply the same change for every occurrence in the FastAPI, Flask and Django snippets.
Also applies to: 909-914, 1026-1033, 1370-1377, 1237-1244
🧹 Nitpick comments (2)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (2)
806-810
: Domain stripping can break multi-tenant sub-domains
ManagementTokenManager
expects a full host, including protocol (https://
).
By stripping the scheme you risk mis-constructing discovery URLs (/.well-known/openid-configuration
) for custom domains. Consider passing the value as-is.- if domain.startswith(('http://', 'https://')): - domain = domain.split('://', 1)[1] + # Keep scheme; the SDK handles full URLs.
1207-1210
: Avoid mutating framework request objectsStoring
token_manager
ong
(Flask) was good, but Django snippet mutatesrequest.token_manager
.
Consider usingrequest.state
(ASGI) or a customSimpleLazyObject
instead to avoid namespace clashes.- request.token_manager = token_manager + request._kinde_token_manager = token_manager # at least prefix to avoid collisionsAlso applies to: 1336-1339
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
(1 hunks)
🔇 Additional comments (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)
930-941
:token_manager.get_token_scopes()
may not existThe public API of
ManagementTokenManager
(v2.0) exposesget_scopes()
;get_token_scopes()
will raiseAttributeError
, breaking the decorator example.- token_scopes = token_manager.get_token_scopes() + token_scopes = token_manager.get_scopes()Please verify against the current SDK.
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.
Copy okay - code not tested by me
…ironment variables - Updated environment variable names (MGMT_API_* -> KINDE_MANAGEMENT_*) - Removed deprecated SITE_HOST, SITE_PORT, SITE_URL variables - Added comprehensive .env file examples with real values - Reorganized code examples with tabbed interface for Flask/FastAPI - Moved M2M application setup section to Management API section - Removed extensive M2M framework implementation examples - Improved overall documentation structure and readability
- Complete merge of remote changes with local documentation updates - Replace actual credentials with placeholder values for security - Maintain documentation improvements while ensuring no sensitive data exposure
- Replace <Tab title=""> with <TabItem label=""> for framework compatibility - Update all tab components to use consistent TabItem syntax - Ensure proper rendering of Flask and FastAPI code examples
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
🔭 Outside diff range comments (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)
190-199
:uuid
import missing – example will raiseNameError
uuid.uuid4()
is used later in the snippet but the module is not imported.
Readers copy-pasting this code will hit a runtime error.-import asyncio -from flask import Flask, request, session, redirect +import asyncio +import uuid +from flask import Flask, request, session, redirect
🧹 Nitpick comments (2)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (2)
66-78
: Remove hard-codedCODE_VERIFIER
from the example.env
CODE_VERIFIER
should be generated per-request during the PKCE flow; publishing a static value can mislead users
into thinking it is required or safe to store. Either drop the line entirely or add a comment explicitly warning
that it is only for illustrative purposes.-# PKCE helper (auto-generated by the SDK if omitted) -CODE_VERIFIER=YOUR_CODE_VERIFIER
686-701
: Add a note about secret handling for M2M credentialsThe snippet shows plain-text client secrets in
.env
.
A brief reminder to store these securely (e.g. secrets manager, CI variables) helps prevent accidental commits of
sensitive data.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
(8 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)
Learnt from: marcosmartini
PR: kinde-oss/documentation#253
File: src/content/docs/properties/work-with-properties/property-groups.mdx:13-13
Timestamp: 2024-11-12T06:00:08.396Z
Learning: In the project documentation, the `/kinde-apis/management` and `/kinde-apis/frontend` pages use a third-party API reference and client that loads a Single Page Application (SPA). Therefore, links to sections within these pages are valid, even if they appear to point to non-existent sections in static analysis, and should not be flagged.
🔇 Additional comments (4)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (4)
82-85
: Management API vars look goodThe example now aligns with the renamed variables and clearly scopes them under a dedicated heading.
103-116
: Tabbed framework example reads wellUsing Docusaurus
<Tabs>
/<TabItem>
improves usability and keeps the snippet DRY.
No further action required.
149-180
: Automatic-route example OKThe wrapper shows minimal setup for both Flask and FastAPI and matches the earlier snippet.
Looks good to ship.
60-63
: No lingering references to deprecated env vars in docsRan
rg -n "MGMT_API_CLIENT_(ID|SECRET)" src/content/docs
and found no matches. All examples now useKINDE_MANAGEMENT_CLIENT_ID
/KINDE_MANAGEMENT_CLIENT_SECRET
. No further cleanup needed.
Description (required)
Includes updates and examples for the management and M2M examples.
Related issues & labels (optional)
Summary by CodeRabbit