mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
sdk/python: add first-class login support (#23093)
## Why The Python SDK can already create threads and run turns, but authentication still has to be arranged outside the SDK. App-server already exposes account login, account inspection, logout, and `account/login/completed` notifications, so SDK users currently have to work around a missing public client layer for a core setup step. This change makes authentication a normal SDK workflow while preserving the backend flow shape: API-key login completes immediately, and interactive ChatGPT flows return live handles that complete later through app-server notifications. ## What changed - Added public sync and async auth methods on `Codex` / `AsyncCodex`: - `login_api_key(...)` - `login_chatgpt()` - `login_chatgpt_device_code()` - `account(...)` - `logout()` - Added public browser-login and device-code handle types with attempt-local `wait()` and `cancel()` helpers. Cancellation stays on the handle instead of a root-level SDK method. - Extended the Python app-server client and notification router so login completion events are routed by `login_id` without consuming unrelated global notifications. - Kept login request/handle logic in a focused internal `_login.py` module so `api.py` remains the public facade instead of absorbing more auth plumbing. - Exported the new handle types plus curated account/login response types from the SDK surfaces. - Updated SDK docs, added sync/async login walkthrough examples, and added a notebook login walkthrough cell. ## Verification Added SDK coverage for: - API-key login, account readback, and logout through the app-server harness in both sync and async clients. - Browser login cancellation plus `handle.wait()` completion through the real app-server boundary used by the Python SDK harness. - Waiter routing that stays scoped across replaced interactive login attempts, plus async handle cancellation coverage. - Login notification demuxing, replay of early completion events, and async client delegation. - Public export/signature assertions. - Real integration-suite smoke coverage for the new examples and notebook login cell.
This commit is contained in:
@@ -26,6 +26,8 @@ when you intentionally want to run against a specific local app-server binary.
|
||||
from openai_codex import Codex
|
||||
|
||||
with Codex() as codex:
|
||||
# Call login_api_key(...) first when this app-server session is not
|
||||
# already authenticated.
|
||||
thread = codex.thread_start(model="gpt-5")
|
||||
result = thread.run("Say hello in one sentence.")
|
||||
print(result.final_response)
|
||||
@@ -35,6 +37,34 @@ with Codex() as codex:
|
||||
`result.final_response` is `None` when the turn completes without a final-answer
|
||||
or phase-less assistant message item.
|
||||
|
||||
## Login
|
||||
|
||||
Use the auth helper that matches your app:
|
||||
|
||||
```python
|
||||
from openai_codex import Codex
|
||||
|
||||
with Codex() as codex:
|
||||
codex.login_api_key("sk-...")
|
||||
account = codex.account()
|
||||
print(account.account)
|
||||
```
|
||||
|
||||
Interactive ChatGPT login returns a handle. Open the provided URL or device-code
|
||||
page, then wait for the matching completion event:
|
||||
|
||||
```python
|
||||
with Codex() as codex:
|
||||
login = codex.login_chatgpt()
|
||||
print(login.auth_url)
|
||||
completed = login.wait()
|
||||
print(completed.success)
|
||||
```
|
||||
|
||||
Use `login_chatgpt_device_code()` for device-code auth, `handle.cancel()` to
|
||||
stop an in-progress interactive login, and `logout()` to clear the active
|
||||
app-server account session.
|
||||
|
||||
## Docs map
|
||||
|
||||
- Golden path tutorial: `docs/getting-started.md`
|
||||
|
||||
Reference in New Issue
Block a user