codex-backend-sdk 0.1.1__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. codex_backend_sdk-0.2.0/.vscode/settings.json +3 -0
  2. codex_backend_sdk-0.2.0/PKG-INFO +190 -0
  3. codex_backend_sdk-0.2.0/README.md +164 -0
  4. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/codex_backend_sdk/__init__.py +25 -31
  5. codex_backend_sdk-0.2.0/codex_backend_sdk/codex_client.py +786 -0
  6. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/docs/backend-api.md +1 -10
  7. codex_backend_sdk-0.2.0/examples/agent.py +54 -0
  8. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/pyproject.toml +3 -3
  9. codex_backend_sdk-0.2.0/tests/test_basic.py +35 -0
  10. codex_backend_sdk-0.2.0/tests/test_conversation.py +33 -0
  11. codex_backend_sdk-0.2.0/tests/test_reasoning.py +43 -0
  12. codex_backend_sdk-0.2.0/tests/test_responses_resource.py +141 -0
  13. codex_backend_sdk-0.2.0/tests/test_structured_output.py +57 -0
  14. codex_backend_sdk-0.2.0/tests/test_tools.py +66 -0
  15. codex_backend_sdk-0.1.1/CHANGELOG.md +0 -7
  16. codex_backend_sdk-0.1.1/PKG-INFO +0 -369
  17. codex_backend_sdk-0.1.1/README.md +0 -341
  18. codex_backend_sdk-0.1.1/codex_backend_sdk/codex_client.py +0 -1084
  19. codex_backend_sdk-0.1.1/examples/agent.py +0 -356
  20. codex_backend_sdk-0.1.1/tests/test_abort.py +0 -69
  21. codex_backend_sdk-0.1.1/tests/test_account_info.py +0 -63
  22. codex_backend_sdk-0.1.1/tests/test_basic.py +0 -65
  23. codex_backend_sdk-0.1.1/tests/test_conversation.py +0 -73
  24. codex_backend_sdk-0.1.1/tests/test_realtime.py +0 -81
  25. codex_backend_sdk-0.1.1/tests/test_reasoning.py +0 -80
  26. codex_backend_sdk-0.1.1/tests/test_structured_output.py +0 -68
  27. codex_backend_sdk-0.1.1/tests/test_tools.py +0 -117
  28. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/.gitignore +0 -0
  29. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/LICENSE +0 -0
  30. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/codex_backend_sdk/oauth.py +0 -0
  31. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/codex_backend_sdk/pkce.py +0 -0
  32. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/codex_backend_sdk/storage.py +0 -0
  33. {codex_backend_sdk-0.1.1 → codex_backend_sdk-0.2.0}/tests/conftest.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ "python-envs.defaultEnvManager": "ms-python.python:pyenv"
3
+ }
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex-backend-sdk
3
+ Version: 0.2.0
4
+ Summary: Unofficial Python SDK for the ChatGPT Codex backend API
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: chatgpt,codex,llm,openai,sdk
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: >=3.9
18
+ Requires-Dist: pydantic>=2.0
19
+ Requires-Dist: requests>=2.28
20
+ Provides-Extra: dev
21
+ Requires-Dist: openai>=1.0; extra == 'dev'
22
+ Requires-Dist: pytest>=7.0; extra == 'dev'
23
+ Provides-Extra: openai
24
+ Requires-Dist: openai>=1.0; extra == 'openai'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # codex-backend-sdk
28
+
29
+ Unofficial Python SDK for the ChatGPT Codex backend API
30
+ (`chatgpt.com/backend-api/codex`).
31
+
32
+ This package mirrors the official OpenAI Python SDK shape for the API surface
33
+ that the Codex backend exposes. Use `OpenAI`, `client.responses.create(...)`,
34
+ and `client.models.list()` just as you would with `openai-python`, with
35
+ Codex-specific authentication and backend limitations under the hood.
36
+
37
+ > **Requirements:** a ChatGPT Plus, Pro, or Enterprise subscription.
38
+ > Authentication goes through ChatGPT OAuth and stores tokens in
39
+ > `~/.codex/auth.json`.
40
+
41
+ > **Disclaimer:** This is an independent, community-maintained library that
42
+ > reverse-engineers undocumented endpoints of `chatgpt.com`. It is not
43
+ > affiliated with, endorsed by, or supported by OpenAI.
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ git clone https://github.com/B4PT0R/codex-backend-sdk.git
49
+ cd codex-backend-sdk
50
+ pip install -e .
51
+ ```
52
+
53
+ ## Basic Usage
54
+
55
+ ```python
56
+ from codex_backend_sdk import OpenAI
57
+
58
+ client = OpenAI().authenticate()
59
+
60
+ response = client.responses.create(
61
+ model="gpt-5.4",
62
+ input="Explain quicksort in one paragraph.",
63
+ )
64
+
65
+ print(response.output_text)
66
+ ```
67
+
68
+ ## Streaming
69
+
70
+ ```python
71
+ stream = client.responses.create(
72
+ model="gpt-5.4",
73
+ input="Say 'hi' five times.",
74
+ stream=True,
75
+ )
76
+
77
+ for event in stream:
78
+ if event.type in {"response.output_text.delta", "response.content_part.delta"}:
79
+ delta = event.delta
80
+ print(delta if isinstance(delta, str) else delta.get("text", ""), end="")
81
+ ```
82
+
83
+ ## Models
84
+
85
+ ```python
86
+ models = client.models.list()
87
+ for model in models:
88
+ print(model.id, model.display_name, model.context_window)
89
+
90
+ info = client.models.retrieve("gpt-5.4")
91
+ ```
92
+
93
+ ## Multi-Turn Input
94
+
95
+ The Codex backend does not expose `previous_response_id`, so pass prior
96
+ input/output items explicitly.
97
+
98
+ ```python
99
+ history = [
100
+ {"role": "user", "content": "My name is Alice. Say OK."},
101
+ ]
102
+
103
+ reply1 = client.responses.create(input=history).output_text
104
+ history.append({"role": "assistant", "content": reply1})
105
+ history.append({"role": "user", "content": "What is my name?"})
106
+
107
+ reply2 = client.responses.create(input=history).output_text
108
+ print(reply2)
109
+ ```
110
+
111
+ ## Function Calling
112
+
113
+ ```python
114
+ import json
115
+
116
+ tools = [{
117
+ "type": "function",
118
+ "name": "get_weather",
119
+ "description": "Get the current weather for a city.",
120
+ "parameters": {
121
+ "type": "object",
122
+ "properties": {"city": {"type": "string"}},
123
+ "required": ["city"],
124
+ "additionalProperties": False,
125
+ },
126
+ }]
127
+
128
+ first = client.responses.create(
129
+ input="What's the weather in Paris?",
130
+ tools=tools,
131
+ )
132
+
133
+ call = next(item for item in first.output if item["type"] == "function_call")
134
+ result = {"temperature": 18, "unit": "celsius", "condition": "cloudy"}
135
+
136
+ second = client.responses.create(
137
+ input=[
138
+ call,
139
+ {
140
+ "type": "function_call_output",
141
+ "call_id": call["call_id"],
142
+ "output": json.dumps(result),
143
+ },
144
+ ],
145
+ tools=tools,
146
+ )
147
+
148
+ print(second.output_text)
149
+ ```
150
+
151
+ ## Structured Output
152
+
153
+ ```python
154
+ schema = {
155
+ "title": "person",
156
+ "type": "object",
157
+ "properties": {
158
+ "name": {"type": "string"},
159
+ "age": {"type": "integer"},
160
+ },
161
+ "required": ["name", "age"],
162
+ "additionalProperties": False,
163
+ }
164
+
165
+ response = client.responses.create(
166
+ input="Extract: Bob is 42 years old.",
167
+ text={
168
+ "format": {
169
+ "type": "json_schema",
170
+ "name": "person",
171
+ "schema": schema,
172
+ "strict": True,
173
+ }
174
+ },
175
+ )
176
+ ```
177
+
178
+ ## Codex-Specific Endpoints
179
+
180
+ Codex-only operations live under `client.codex`.
181
+
182
+ ```python
183
+ quota = client.codex.usage()
184
+ ```
185
+
186
+ The backend currently rejects some official Responses parameters, including
187
+ `temperature`, `top_p`, `max_output_tokens`, `metadata`, `user`,
188
+ `safety_identifier`, `truncation`, and `previous_response_id`. The SDK raises
189
+ `CodexBackendUnsupportedParameterError` for those instead of silently dropping
190
+ them.
@@ -0,0 +1,164 @@
1
+ # codex-backend-sdk
2
+
3
+ Unofficial Python SDK for the ChatGPT Codex backend API
4
+ (`chatgpt.com/backend-api/codex`).
5
+
6
+ This package mirrors the official OpenAI Python SDK shape for the API surface
7
+ that the Codex backend exposes. Use `OpenAI`, `client.responses.create(...)`,
8
+ and `client.models.list()` just as you would with `openai-python`, with
9
+ Codex-specific authentication and backend limitations under the hood.
10
+
11
+ > **Requirements:** a ChatGPT Plus, Pro, or Enterprise subscription.
12
+ > Authentication goes through ChatGPT OAuth and stores tokens in
13
+ > `~/.codex/auth.json`.
14
+
15
+ > **Disclaimer:** This is an independent, community-maintained library that
16
+ > reverse-engineers undocumented endpoints of `chatgpt.com`. It is not
17
+ > affiliated with, endorsed by, or supported by OpenAI.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ git clone https://github.com/B4PT0R/codex-backend-sdk.git
23
+ cd codex-backend-sdk
24
+ pip install -e .
25
+ ```
26
+
27
+ ## Basic Usage
28
+
29
+ ```python
30
+ from codex_backend_sdk import OpenAI
31
+
32
+ client = OpenAI().authenticate()
33
+
34
+ response = client.responses.create(
35
+ model="gpt-5.4",
36
+ input="Explain quicksort in one paragraph.",
37
+ )
38
+
39
+ print(response.output_text)
40
+ ```
41
+
42
+ ## Streaming
43
+
44
+ ```python
45
+ stream = client.responses.create(
46
+ model="gpt-5.4",
47
+ input="Say 'hi' five times.",
48
+ stream=True,
49
+ )
50
+
51
+ for event in stream:
52
+ if event.type in {"response.output_text.delta", "response.content_part.delta"}:
53
+ delta = event.delta
54
+ print(delta if isinstance(delta, str) else delta.get("text", ""), end="")
55
+ ```
56
+
57
+ ## Models
58
+
59
+ ```python
60
+ models = client.models.list()
61
+ for model in models:
62
+ print(model.id, model.display_name, model.context_window)
63
+
64
+ info = client.models.retrieve("gpt-5.4")
65
+ ```
66
+
67
+ ## Multi-Turn Input
68
+
69
+ The Codex backend does not expose `previous_response_id`, so pass prior
70
+ input/output items explicitly.
71
+
72
+ ```python
73
+ history = [
74
+ {"role": "user", "content": "My name is Alice. Say OK."},
75
+ ]
76
+
77
+ reply1 = client.responses.create(input=history).output_text
78
+ history.append({"role": "assistant", "content": reply1})
79
+ history.append({"role": "user", "content": "What is my name?"})
80
+
81
+ reply2 = client.responses.create(input=history).output_text
82
+ print(reply2)
83
+ ```
84
+
85
+ ## Function Calling
86
+
87
+ ```python
88
+ import json
89
+
90
+ tools = [{
91
+ "type": "function",
92
+ "name": "get_weather",
93
+ "description": "Get the current weather for a city.",
94
+ "parameters": {
95
+ "type": "object",
96
+ "properties": {"city": {"type": "string"}},
97
+ "required": ["city"],
98
+ "additionalProperties": False,
99
+ },
100
+ }]
101
+
102
+ first = client.responses.create(
103
+ input="What's the weather in Paris?",
104
+ tools=tools,
105
+ )
106
+
107
+ call = next(item for item in first.output if item["type"] == "function_call")
108
+ result = {"temperature": 18, "unit": "celsius", "condition": "cloudy"}
109
+
110
+ second = client.responses.create(
111
+ input=[
112
+ call,
113
+ {
114
+ "type": "function_call_output",
115
+ "call_id": call["call_id"],
116
+ "output": json.dumps(result),
117
+ },
118
+ ],
119
+ tools=tools,
120
+ )
121
+
122
+ print(second.output_text)
123
+ ```
124
+
125
+ ## Structured Output
126
+
127
+ ```python
128
+ schema = {
129
+ "title": "person",
130
+ "type": "object",
131
+ "properties": {
132
+ "name": {"type": "string"},
133
+ "age": {"type": "integer"},
134
+ },
135
+ "required": ["name", "age"],
136
+ "additionalProperties": False,
137
+ }
138
+
139
+ response = client.responses.create(
140
+ input="Extract: Bob is 42 years old.",
141
+ text={
142
+ "format": {
143
+ "type": "json_schema",
144
+ "name": "person",
145
+ "schema": schema,
146
+ "strict": True,
147
+ }
148
+ },
149
+ )
150
+ ```
151
+
152
+ ## Codex-Specific Endpoints
153
+
154
+ Codex-only operations live under `client.codex`.
155
+
156
+ ```python
157
+ quota = client.codex.usage()
158
+ ```
159
+
160
+ The backend currently rejects some official Responses parameters, including
161
+ `temperature`, `top_p`, `max_output_tokens`, `metadata`, `user`,
162
+ `safety_identifier`, `truncation`, and `previous_response_id`. The SDK raises
163
+ `CodexBackendUnsupportedParameterError` for those instead of silently dropping
164
+ them.
@@ -8,59 +8,53 @@ to OpenAI's Terms of Use (https://openai.com/policies/terms-of-use).
8
8
  Endpoints may change or break without notice.
9
9
 
10
10
  Quickstart:
11
- from codex_backend_sdk import CodexClient
11
+ from codex_backend_sdk import OpenAI
12
12
 
13
- client = CodexClient().authenticate() # opens browser on first run
13
+ client = OpenAI().authenticate() # opens browser on first run
14
14
  # subsequent runs load & refresh tokens automatically
15
15
 
16
- for event in client.stream("Explain quicksort"):
17
- ...
16
+ response = client.responses.create(input="Explain quicksort")
17
+ print(response.output_text)
18
18
  """
19
19
 
20
- __version__ = "0.1.1"
20
+ __version__ = "0.2.0"
21
21
 
22
22
  from .oauth import run_oauth_flow, refresh_access_token, obtain_api_key
23
23
  from .storage import load_tokens, save_tokens, TokenStore
24
24
  from .codex_client import (
25
+ CodexBackendUnsupportedParameterError,
26
+ CodexBaseModel,
25
27
  ReasoningEffort,
26
28
  ReasoningSummary,
27
- Verbosity,
28
29
  ServiceTier,
30
+ Verbosity,
29
31
  CodexClient,
30
- ModelInfo,
31
- ReasoningLevel,
32
- TextDelta,
33
- ReasoningDelta,
34
- ToolCall,
35
- OutputItem,
36
- TokenUsage,
37
- ResponseCompleted,
38
- ResponseFailed,
39
- ResponseAborted,
40
- CompactionResult,
41
- RealtimeCallResult,
32
+ OpenAI,
33
+ Model,
34
+ Response,
35
+ ResponseStreamEvent,
36
+ ResponseUsage,
37
+ SyncPage,
38
+ CompactedResponse,
42
39
  image_url,
43
40
  image_b64,
44
41
  )
45
42
 
46
43
  __all__ = [
47
44
  "CodexClient",
45
+ "OpenAI",
46
+ "CodexBackendUnsupportedParameterError",
47
+ "CodexBaseModel",
48
+ "Model",
49
+ "Response",
50
+ "ResponseStreamEvent",
51
+ "ResponseUsage",
52
+ "SyncPage",
53
+ "CompactedResponse",
48
54
  "ReasoningEffort",
49
55
  "ReasoningSummary",
50
- "Verbosity",
51
56
  "ServiceTier",
52
- "ModelInfo",
53
- "ReasoningLevel",
54
- "TextDelta",
55
- "ReasoningDelta",
56
- "ToolCall",
57
- "OutputItem",
58
- "TokenUsage",
59
- "ResponseCompleted",
60
- "ResponseFailed",
61
- "ResponseAborted",
62
- "CompactionResult",
63
- "RealtimeCallResult",
57
+ "Verbosity",
64
58
  "image_url",
65
59
  "image_b64",
66
60
  "run_oauth_flow",