Skip to content

chore: Fix incorrect Management API docs in Python SDK#675

Open
Koosha-Owji wants to merge 6 commits into
kinde-oss:mainfrom
Koosha-Owji:main
Open

chore: Fix incorrect Management API docs in Python SDK#675
Koosha-Owji wants to merge 6 commits into
kinde-oss:mainfrom
Koosha-Owji:main

Conversation

@Koosha-Owji
Copy link
Copy Markdown
Contributor

@Koosha-Owji Koosha-Owji commented Mar 3, 2026

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 correct ManagementClient class with non-deprecated API class methods, accurate method signatures, proper FastAPI handler definitions, and correct token lifecycle documentation.

Summary by CodeRabbit

  • Documentation
    • Reworked Python SDK docs to emphasize a dedicated management client and explicit initialization patterns.
    • Added an "Available endpoints" section describing discoverable API properties and property-based endpoint usage.
    • Updated examples (sync frameworks, FastAPI) to show single-client construction and structured error-to-HTTP handling.
    • Expanded authentication guidance: client-credentials behavior, token validation/caching, automatic renewal, and revised best practices.

@Koosha-Owji Koosha-Owji requested a review from a team as a code owner March 3, 2026 02:33
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 3, 2026

Walkthrough

Documentation rewrites the Management API usage to a standalone ManagementClient initialized with client credentials (optionally via dotenv), replaces OAuth-wrapper examples with snake_case API properties (e.g., management.users_api.*), updates FastAPI examples, error handling to ApiException, and clarifies token lifecycle and validation behavior. (≤50 words)

Changes

Cohort / File(s) Summary
Python SDK Documentation
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
Rewrote Management API section to use ManagementClient(client_id, client_secret, domain) (dotenv optional); removed get_management() OAuth-wrapper patterns; replaced top-level async methods with discovered snake_case API properties (e.g., management.users_api.get_users(...), create_user(create_user_request=...)); changed org calls to use code where applicable; updated FastAPI example to instantiate client once and call property-based APIs from handlers; switched error examples from KindeAPIException to management ApiException with mapping to HTTPException and structured logging; clarified token client-credentials behavior (first-call acquisition, caching/reuse, re-acquisition on expiry, credential validation on first API call).

Sequence Diagram(s)

sequenceDiagram
  participant FastAPI as FastAPI App
  participant MgmtClient as ManagementClient
  participant Auth as Auth Server
  participant MgmtAPI as Management API

  FastAPI->>MgmtClient: call users_api.get_users(...)
  MgmtClient->>Auth: request token (client_credentials)  -- if no valid token cached
  Auth-->>MgmtClient: access_token (expires_at)
  MgmtClient->>MgmtAPI: GET /users with access_token
  MgmtAPI-->>MgmtClient: 200 OK (users)
  MgmtClient-->>FastAPI: return users
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble docs with a happy twitch,
ManagementClient now takes the stitch,
Snake_case paths line every lane,
Dotenv hides my secret grain,
I hop along — tokens cached again!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing incorrect Management API documentation in the Python SDK by replacing non-existent methods with correct implementation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the sdk label Mar 3, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a 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

🤖 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.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 85e89d3 and e7a6ee6.

📒 Files selected for processing (1)
  • src/content/docs/developer-tools/sdks/backend/python-sdk.mdx

Comment thread src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
Comment thread src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
@onderay onderay requested review from a team and tamalchowdhury March 4, 2026 04:42
@tamalchowdhury
Copy link
Copy Markdown
Collaborator

Kindly resolve the coderabbit issues and it should be good.

Copy link
Copy Markdown
Collaborator

@tamalchowdhury tamalchowdhury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolve the coderabbit issues and it should be ready to go.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a 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

🧹 Nitpick comments (1)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)

1566-1593: The defensive check for ApiException.status is not necessary in this context.

ApiException is OpenAPI-generated and always includes an HTTP status code when raised from a response. The e.status attribute will be populated as an integer in all normal exception flows. Adding a defensive fallback like 502 introduces 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

📥 Commits

Reviewing files that changed from the base of the PR and between e7a6ee6 and 6c7b73c.

📒 Files selected for processing (1)
  • src/content/docs/developer-tools/sdks/backend/python-sdk.mdx

Comment thread src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
@dtoxvanilla1991 dtoxvanilla1991 self-assigned this Apr 8, 2026
@dtoxvanilla1991
Copy link
Copy Markdown
Contributor

I'll resolve CAai comment tonight.

@dtoxvanilla1991 dtoxvanilla1991 removed their assignment Apr 24, 2026
@dtoxvanilla1991
Copy link
Copy Markdown
Contributor

Ok, just now looking at it and I realized it is a forked repo branch. So I skip working on this myself. @Koosha-Owji will you be addressing this any time soon? Curious to see if we can get this reviewed and merged in. Thank you

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a 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

🧹 Nitpick comments (2)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (2)

1418-1424: Minor: brittle host parsing in the dotenv example.

os.getenv("KINDE_HOST", "").replace("https://", "") only strips the https:// prefix and silently leaves any trailing slash or http:// scheme intact, which then propagates into the domain argument. For a doc snippet this is fine in the happy path, but a slightly more defensive form helps copy-paste users:

♻️ Optional tweak
-management = ManagementClient(
-    domain=os.getenv("KINDE_HOST", "").replace("https://", ""),
-    client_id=os.getenv("MGMT_API_CLIENT_ID"),
-    client_secret=os.getenv("MGMT_API_CLIENT_SECRET")
-)
+_host = os.getenv("KINDE_HOST", "").rstrip("/")
+management = ManagementClient(
+    domain=_host.removeprefix("https://").removeprefix("http://"),
+    client_id=os.getenv("MGMT_API_CLIENT_ID"),
+    client_secret=os.getenv("MGMT_API_CLIENT_SECRET"),
+)
🤖 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
1418 - 1424, The dotenv example currently builds the ManagementClient domain
with os.getenv("KINDE_HOST", "").replace("https://", ""), which is brittle;
update the snippet that constructs the domain (the value passed to
ManagementClient(domain=...)) to robustly parse KINDE_HOST (e.g., use
urllib.parse.urlparse to extract netloc if a scheme is present, or strip any
trailing slashes and both "http://" and "https://" prefixes) so the domain
passed to ManagementClient is always a clean hostname without scheme or trailing
slash.

1441-1458: Add a clarifying note about different request shapes for create_user vs update_user.

The code snippets are correct: create_user nests user data under "profile", while update_user accepts flat fields like "given_name" directly. Consider adding a one-line note explaining this difference to help readers understand why the two endpoints have different structures.

🤖 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
1441 - 1458, Add a one-line clarifying note explaining that create_user expects
a nested payload under create_user_request["profile"] (e.g., "profile":
{"given_name": ...}) while update_user takes a flat payload via
update_user_request (e.g., {"given_name": ...}); reference create_user,
create_user_request, profile, update_user, and update_user_request so readers
understand the different request shapes.
🤖 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 1494-1508: The snippet uses inconsistent parameter names for
organization identifier—get_organization(code=...) vs
update_organization(org_code=...) and delete_organization(org_code=...)—which
will confuse readers; update the example to use the same parameter name across
calls (prefer org_code for consistency) or add a short note calling out the
discrepancy; specifically change the get_organization call to use org_code or
add a sentence after the snippet explaining that get_organization accepts code
while the other methods expect org_code so copy-pasting must be adjusted.

---

Nitpick comments:
In `@src/content/docs/developer-tools/sdks/backend/python-sdk.mdx`:
- Around line 1418-1424: The dotenv example currently builds the
ManagementClient domain with os.getenv("KINDE_HOST", "").replace("https://",
""), which is brittle; update the snippet that constructs the domain (the value
passed to ManagementClient(domain=...)) to robustly parse KINDE_HOST (e.g., use
urllib.parse.urlparse to extract netloc if a scheme is present, or strip any
trailing slashes and both "http://" and "https://" prefixes) so the domain
passed to ManagementClient is always a clean hostname without scheme or trailing
slash.
- Around line 1441-1458: Add a one-line clarifying note explaining that
create_user expects a nested payload under create_user_request["profile"] (e.g.,
"profile": {"given_name": ...}) while update_user takes a flat payload via
update_user_request (e.g., {"given_name": ...}); reference create_user,
create_user_request, profile, update_user, and update_user_request so readers
understand the different request shapes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 51418105-f500-4259-b24b-9c99cec6fb8e

📥 Commits

Reviewing files that changed from the base of the PR and between 6c7b73c and e6bdb16.

📒 Files selected for processing (1)
  • src/content/docs/developer-tools/sdks/backend/python-sdk.mdx

Comment thread src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
@Koosha-Owji
Copy link
Copy Markdown
Contributor Author

@CodeRabbit resume review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

@Koosha-Owji Sure! I'll resume the review of this PR right away.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a 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)
src/content/docs/developer-tools/sdks/backend/python-sdk.mdx (1)

1589-1594: ⚠️ Potential issue | 🟡 Minor

Guard against e.status being None.

ApiException.status may be None for non-HTTP failures (e.g., transport/connection errors before a response is received). Passing None to HTTPException(status_code=...) will raise a validation error and obscure the original failure. Add a sane fallback as the prior review suggested.

Proposed fix
     except ApiException as e:
         logger.error("Kinde API error: %s %s", e.status, e.body)
-        raise HTTPException(status_code=e.status, detail="Failed to fetch user")
+        raise HTTPException(status_code=e.status or 502, detail="Failed to fetch user")
🤖 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
1589 - 1594, The ApiException handler must guard against a None status before
passing it to HTTPException: in the except ApiException as e block, compute a
fallback status (e.g., status_code = e.status if e.status is not None else 500)
and use that when raising HTTPException; keep the existing logger.error call but
include the fallback-aware status in the log/message so transport/connection
failures won't cause a validation error—update the except ApiException handler
(the block that currently logs "Kinde API error: %s %s" and raises
HTTPException) to derive and use this safe status_code.
🤖 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 1419-1424: The domain extraction for ManagementClient is fragile:
currently os.getenv("KINDE_HOST", "").replace("https://", "") only removes
"https://" and won't handle "http://", presence of a trailing slash, or other
URL forms; update the code that builds the domain for ManagementClient (where
KINDE_HOST is read) to robustly parse the host using a URL parser (e.g., parse
with urllib.parse.urlparse) or normalize by removing any "http(s)://" prefix and
trimming trailing slashes so the ManagementClient(domain=...) always receives a
clean host string; ensure you reference KINDE_HOST, the ManagementClient
initializer, and any helper used to normalize the host.

---

Duplicate comments:
In `@src/content/docs/developer-tools/sdks/backend/python-sdk.mdx`:
- Around line 1589-1594: The ApiException handler must guard against a None
status before passing it to HTTPException: in the except ApiException as e
block, compute a fallback status (e.g., status_code = e.status if e.status is
not None else 500) and use that when raising HTTPException; keep the existing
logger.error call but include the fallback-aware status in the log/message so
transport/connection failures won't cause a validation error—update the except
ApiException handler (the block that currently logs "Kinde API error: %s %s" and
raises HTTPException) to derive and use this safe status_code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: dc0c83a8-00c6-493d-a4c7-0172af1d4909

📥 Commits

Reviewing files that changed from the base of the PR and between e6bdb16 and 271c335.

📒 Files selected for processing (1)
  • src/content/docs/developer-tools/sdks/backend/python-sdk.mdx

Comment thread src/content/docs/developer-tools/sdks/backend/python-sdk.mdx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants