codex-python 0.2.0__tar.gz → 0.2.7__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.
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex-python
3
+ Version: 0.2.7
4
+ Classifier: Programming Language :: Python :: 3
5
+ Classifier: Programming Language :: Python :: 3 :: Only
6
+ Classifier: Programming Language :: Python :: 3.13
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Typing :: Typed
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Dist: pydantic>=2.11.7
11
+ License-File: LICENSE
12
+ Summary: A minimal Python library scaffold for codex-python
13
+ Keywords: codex,library,scaffold
14
+ Requires-Python: >=3.12
15
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
16
+ Project-URL: Homepage, https://github.com/gersmann/codex-python
17
+ Project-URL: Repository, https://github.com/gersmann/codex-python
18
+ Project-URL: Issues, https://github.com/gersmann/codex-python/issues
19
+
20
+ # codex-python
21
+
22
+ Native Python bindings for Codex (in‑process execution). Ships as a single package (`codex-python`) with platform wheels that include the native extension.
23
+
24
+ - Python: 3.12–3.13 (CI also attempts 3.14)
25
+ - Import name: `codex`
26
+ - PyPI: https://pypi.org/project/codex-python/
27
+
28
+ ## Install
29
+
30
+ ```
31
+ pip install codex-python
32
+ ```
33
+
34
+ If there’s no prebuilt wheel for your platform/Python, pip will build from source. You’ll need a Rust toolchain and maturin; see “Developing” below.
35
+
36
+ ## Quickstart
37
+
38
+ Run a prompt and collect structured events (typed):
39
+
40
+ ```
41
+ from codex.api import run_exec, CodexClient
42
+ from codex.config import CodexConfig, ApprovalPolicy, SandboxMode
43
+
44
+ cfg = CodexConfig(
45
+ model="gpt-5",
46
+ model_provider="openai",
47
+ approval_policy=ApprovalPolicy.ON_REQUEST,
48
+ sandbox_mode=SandboxMode.WORKSPACE_WRITE,
49
+ )
50
+
51
+ # One-shot
52
+ events = run_exec("Explain this repo", config=cfg)
53
+
54
+ # Conversation (streaming)
55
+ client = CodexClient(config=cfg)
56
+ for ev in client.start_conversation("Add a smoke test"):
57
+ print(ev.id, ev.msg)
58
+ ```
59
+
60
+ Notes
61
+ - `Event.msg` is typed as a union `EventMsg` (also available at `codex.EventMsg`).
62
+ - For raw dict streaming from the native layer, use `codex.native.start_exec_stream`.
63
+
64
+ ## Configuration (Pydantic)
65
+
66
+ Use `CodexConfig` to pass overrides mirrored from Rust `ConfigOverrides`.
67
+
68
+ ```
69
+ from codex.config import CodexConfig, ApprovalPolicy, SandboxMode
70
+
71
+ cfg = CodexConfig(
72
+ model="gpt-5",
73
+ model_provider="openai",
74
+ approval_policy=ApprovalPolicy.ON_REQUEST,
75
+ sandbox_mode=SandboxMode.WORKSPACE_WRITE,
76
+ cwd="/path/to/project",
77
+ include_apply_patch_tool=True,
78
+ )
79
+ ```
80
+
81
+ - `CodexConfig.to_dict()` emits only fields you set, with enums serialized to kebab‑case strings expected by the core.
82
+ - For tests and introspection, `codex.native.preview_config(config_overrides=..., load_default_config=...)` returns a compact snapshot of the effective configuration.
83
+
84
+ ## Troubleshooting
85
+
86
+ - “codex_native extension not installed”
87
+ - Install with `pip install codex-python` (wheel) or build locally (see below).
88
+ - maturin develop fails without a virtualenv
89
+ - Use `python -m venv .venv && source .venv/bin/activate` (or conda), or run `make dev-native` which falls back to build+pip install when no venv is present.
90
+
91
+ ## Developing
92
+
93
+ Prerequisites
94
+ - Python 3.12/3.13
95
+ - Rust toolchain (cargo)
96
+ - maturin (for native builds)
97
+ - uv (optional, for fast Python builds and dev tooling)
98
+
99
+ Common tasks
100
+ - Lint: `make lint` (ruff + mypy)
101
+ - Test: `make test` (pytest)
102
+ - Format: `make fmt`
103
+ - Build native locally: `make dev-native`
104
+ - Generate protocol types from upstream: `make gen-protocol`
105
+
106
+ Protocol types
107
+ - `make gen-protocol` generates TS types (via Codex or cargo) into `.generated/ts` and then writes Pydantic models to `codex/protocol/types.py`.
108
+ - Generated models use `model_config = ConfigDict(extra='allow')` and place it at the end of each class.
109
+
110
+ Releasing
111
+ - Bump `codex/__init__.py` and `crates/codex_native/Cargo.toml` versions.
112
+ - Update `CHANGELOG.md`.
113
+ - Tag and push: `git tag -a vX.Y.Z -m "codex-python X.Y.Z" && git push origin vX.Y.Z`.
114
+ - GitHub Actions (publish.yml) builds native wheels across platforms and an sdist, then publishes them via Trusted Publishing (OIDC).
115
+
116
+ Project layout
117
+ ```
118
+ .
119
+ ├── codex/ # Python package
120
+ ├── crates/codex_native/ # PyO3 native extension
121
+ ├── scripts/ # generators and helpers
122
+ ├── .github/workflows/ # CI, publish, native wheels
123
+ └── Makefile # common tasks
124
+ ```
125
+
126
+ Links
127
+ - Codex repo: https://github.com/openai/codex
128
+ - uv: https://docs.astral.sh/uv/
129
+ - maturin: https://www.maturin.rs/
130
+
@@ -0,0 +1,110 @@
1
+ # codex-python
2
+
3
+ Native Python bindings for Codex (in‑process execution). Ships as a single package (`codex-python`) with platform wheels that include the native extension.
4
+
5
+ - Python: 3.12–3.13 (CI also attempts 3.14)
6
+ - Import name: `codex`
7
+ - PyPI: https://pypi.org/project/codex-python/
8
+
9
+ ## Install
10
+
11
+ ```
12
+ pip install codex-python
13
+ ```
14
+
15
+ If there’s no prebuilt wheel for your platform/Python, pip will build from source. You’ll need a Rust toolchain and maturin; see “Developing” below.
16
+
17
+ ## Quickstart
18
+
19
+ Run a prompt and collect structured events (typed):
20
+
21
+ ```
22
+ from codex.api import run_exec, CodexClient
23
+ from codex.config import CodexConfig, ApprovalPolicy, SandboxMode
24
+
25
+ cfg = CodexConfig(
26
+ model="gpt-5",
27
+ model_provider="openai",
28
+ approval_policy=ApprovalPolicy.ON_REQUEST,
29
+ sandbox_mode=SandboxMode.WORKSPACE_WRITE,
30
+ )
31
+
32
+ # One-shot
33
+ events = run_exec("Explain this repo", config=cfg)
34
+
35
+ # Conversation (streaming)
36
+ client = CodexClient(config=cfg)
37
+ for ev in client.start_conversation("Add a smoke test"):
38
+ print(ev.id, ev.msg)
39
+ ```
40
+
41
+ Notes
42
+ - `Event.msg` is typed as a union `EventMsg` (also available at `codex.EventMsg`).
43
+ - For raw dict streaming from the native layer, use `codex.native.start_exec_stream`.
44
+
45
+ ## Configuration (Pydantic)
46
+
47
+ Use `CodexConfig` to pass overrides mirrored from Rust `ConfigOverrides`.
48
+
49
+ ```
50
+ from codex.config import CodexConfig, ApprovalPolicy, SandboxMode
51
+
52
+ cfg = CodexConfig(
53
+ model="gpt-5",
54
+ model_provider="openai",
55
+ approval_policy=ApprovalPolicy.ON_REQUEST,
56
+ sandbox_mode=SandboxMode.WORKSPACE_WRITE,
57
+ cwd="/path/to/project",
58
+ include_apply_patch_tool=True,
59
+ )
60
+ ```
61
+
62
+ - `CodexConfig.to_dict()` emits only fields you set, with enums serialized to kebab‑case strings expected by the core.
63
+ - For tests and introspection, `codex.native.preview_config(config_overrides=..., load_default_config=...)` returns a compact snapshot of the effective configuration.
64
+
65
+ ## Troubleshooting
66
+
67
+ - “codex_native extension not installed”
68
+ - Install with `pip install codex-python` (wheel) or build locally (see below).
69
+ - maturin develop fails without a virtualenv
70
+ - Use `python -m venv .venv && source .venv/bin/activate` (or conda), or run `make dev-native` which falls back to build+pip install when no venv is present.
71
+
72
+ ## Developing
73
+
74
+ Prerequisites
75
+ - Python 3.12/3.13
76
+ - Rust toolchain (cargo)
77
+ - maturin (for native builds)
78
+ - uv (optional, for fast Python builds and dev tooling)
79
+
80
+ Common tasks
81
+ - Lint: `make lint` (ruff + mypy)
82
+ - Test: `make test` (pytest)
83
+ - Format: `make fmt`
84
+ - Build native locally: `make dev-native`
85
+ - Generate protocol types from upstream: `make gen-protocol`
86
+
87
+ Protocol types
88
+ - `make gen-protocol` generates TS types (via Codex or cargo) into `.generated/ts` and then writes Pydantic models to `codex/protocol/types.py`.
89
+ - Generated models use `model_config = ConfigDict(extra='allow')` and place it at the end of each class.
90
+
91
+ Releasing
92
+ - Bump `codex/__init__.py` and `crates/codex_native/Cargo.toml` versions.
93
+ - Update `CHANGELOG.md`.
94
+ - Tag and push: `git tag -a vX.Y.Z -m "codex-python X.Y.Z" && git push origin vX.Y.Z`.
95
+ - GitHub Actions (publish.yml) builds native wheels across platforms and an sdist, then publishes them via Trusted Publishing (OIDC).
96
+
97
+ Project layout
98
+ ```
99
+ .
100
+ ├── codex/ # Python package
101
+ ├── crates/codex_native/ # PyO3 native extension
102
+ ├── scripts/ # generators and helpers
103
+ ├── .github/workflows/ # CI, publish, native wheels
104
+ └── Makefile # common tasks
105
+ ```
106
+
107
+ Links
108
+ - Codex repo: https://github.com/openai/codex
109
+ - uv: https://docs.astral.sh/uv/
110
+ - maturin: https://www.maturin.rs/
@@ -30,5 +30,5 @@ __all__ = [
30
30
  "CodexConfig",
31
31
  ]
32
32
 
33
- # Managed by Hatch via pyproject.toml [tool.hatch.version]
34
- __version__ = "0.2.0"
33
+ # Package version. Kept in sync with Cargo.toml via CI before builds.
34
+ __version__ = "0.2.7"
@@ -698,30 +698,6 @@ class WebSearchEndEvent(BaseModel):
698
698
  model_config = ConfigDict(extra="allow")
699
699
 
700
700
 
701
- class AskForApproval_Variant1(BaseModel):
702
- model_config = ConfigDict(extra="allow")
703
-
704
-
705
- class AskForApproval_Variant2(BaseModel):
706
- model_config = ConfigDict(extra="allow")
707
-
708
-
709
- class AskForApproval_Variant3(BaseModel):
710
- model_config = ConfigDict(extra="allow")
711
-
712
-
713
- class AskForApproval_Variant4(BaseModel):
714
- model_config = ConfigDict(extra="allow")
715
-
716
-
717
- class AuthMode_Variant1(BaseModel):
718
- model_config = ConfigDict(extra="allow")
719
-
720
-
721
- class AuthMode_Variant2(BaseModel):
722
- model_config = ConfigDict(extra="allow")
723
-
724
-
725
701
  class ClientRequest_NewConversation(BaseModel):
726
702
  method: Literal["newConversation"]
727
703
  id: RequestId
@@ -1200,14 +1176,6 @@ class EventMsg_ConversationHistory(BaseModel):
1200
1176
  model_config = ConfigDict(extra="allow")
1201
1177
 
1202
1178
 
1203
- class ExecOutputStream_Variant1(BaseModel):
1204
- model_config = ConfigDict(extra="allow")
1205
-
1206
-
1207
- class ExecOutputStream_Variant2(BaseModel):
1208
- model_config = ConfigDict(extra="allow")
1209
-
1210
-
1211
1179
  class FileChange_Variant1(BaseModel):
1212
1180
  add: dict[str, Any]
1213
1181
 
@@ -1247,30 +1215,6 @@ class InputItem_LocalImage(BaseModel):
1247
1215
  model_config = ConfigDict(extra="allow")
1248
1216
 
1249
1217
 
1250
- class InputMessageKind_Variant1(BaseModel):
1251
- model_config = ConfigDict(extra="allow")
1252
-
1253
-
1254
- class InputMessageKind_Variant2(BaseModel):
1255
- model_config = ConfigDict(extra="allow")
1256
-
1257
-
1258
- class InputMessageKind_Variant3(BaseModel):
1259
- model_config = ConfigDict(extra="allow")
1260
-
1261
-
1262
- class LocalShellStatus_Variant1(BaseModel):
1263
- model_config = ConfigDict(extra="allow")
1264
-
1265
-
1266
- class LocalShellStatus_Variant2(BaseModel):
1267
- model_config = ConfigDict(extra="allow")
1268
-
1269
-
1270
- class LocalShellStatus_Variant3(BaseModel):
1271
- model_config = ConfigDict(extra="allow")
1272
-
1273
-
1274
1218
  class ParsedCommand_Read(BaseModel):
1275
1219
  type: Literal["read"]
1276
1220
  cmd: str
@@ -1303,22 +1247,6 @@ class ParsedCommand_Unknown(BaseModel):
1303
1247
  model_config = ConfigDict(extra="allow")
1304
1248
 
1305
1249
 
1306
- class ReasoningEffort_Variant1(BaseModel):
1307
- model_config = ConfigDict(extra="allow")
1308
-
1309
-
1310
- class ReasoningEffort_Variant2(BaseModel):
1311
- model_config = ConfigDict(extra="allow")
1312
-
1313
-
1314
- class ReasoningEffort_Variant3(BaseModel):
1315
- model_config = ConfigDict(extra="allow")
1316
-
1317
-
1318
- class ReasoningEffort_Variant4(BaseModel):
1319
- model_config = ConfigDict(extra="allow")
1320
-
1321
-
1322
1250
  class ReasoningItemContent_ReasoningText(BaseModel):
1323
1251
  type: Literal["reasoning_text"]
1324
1252
  text: str
@@ -1333,30 +1261,6 @@ class ReasoningItemContent_Text(BaseModel):
1333
1261
  model_config = ConfigDict(extra="allow")
1334
1262
 
1335
1263
 
1336
- class ReasoningSummary_Variant1(BaseModel):
1337
- model_config = ConfigDict(extra="allow")
1338
-
1339
-
1340
- class ReasoningSummary_Variant2(BaseModel):
1341
- model_config = ConfigDict(extra="allow")
1342
-
1343
-
1344
- class ReasoningSummary_Variant3(BaseModel):
1345
- model_config = ConfigDict(extra="allow")
1346
-
1347
-
1348
- class ReasoningSummary_Variant4(BaseModel):
1349
- model_config = ConfigDict(extra="allow")
1350
-
1351
-
1352
- class RequestId_Variant1(BaseModel):
1353
- model_config = ConfigDict(extra="allow")
1354
-
1355
-
1356
- class RequestId_Variant2(BaseModel):
1357
- model_config = ConfigDict(extra="allow")
1358
-
1359
-
1360
1264
  class ResponseItem_Message(BaseModel):
1361
1265
  type: Literal["message"]
1362
1266
  id: str | None = None
@@ -1434,42 +1338,6 @@ class ResponseItem_Other(BaseModel):
1434
1338
  model_config = ConfigDict(extra="allow")
1435
1339
 
1436
1340
 
1437
- class ReviewDecision_Variant1(BaseModel):
1438
- model_config = ConfigDict(extra="allow")
1439
-
1440
-
1441
- class ReviewDecision_Variant2(BaseModel):
1442
- model_config = ConfigDict(extra="allow")
1443
-
1444
-
1445
- class ReviewDecision_Variant3(BaseModel):
1446
- model_config = ConfigDict(extra="allow")
1447
-
1448
-
1449
- class ReviewDecision_Variant4(BaseModel):
1450
- model_config = ConfigDict(extra="allow")
1451
-
1452
-
1453
- class Role_Variant1(BaseModel):
1454
- model_config = ConfigDict(extra="allow")
1455
-
1456
-
1457
- class Role_Variant2(BaseModel):
1458
- model_config = ConfigDict(extra="allow")
1459
-
1460
-
1461
- class SandboxMode_Variant1(BaseModel):
1462
- model_config = ConfigDict(extra="allow")
1463
-
1464
-
1465
- class SandboxMode_Variant2(BaseModel):
1466
- model_config = ConfigDict(extra="allow")
1467
-
1468
-
1469
- class SandboxMode_Variant3(BaseModel):
1470
- model_config = ConfigDict(extra="allow")
1471
-
1472
-
1473
1341
  class SandboxPolicy_Variant1(BaseModel):
1474
1342
  mode: Literal["danger-full-access"]
1475
1343
 
@@ -1521,38 +1389,6 @@ class ServerRequest_ExecCommandApproval(BaseModel):
1521
1389
  model_config = ConfigDict(extra="allow")
1522
1390
 
1523
1391
 
1524
- class StepStatus_Variant1(BaseModel):
1525
- model_config = ConfigDict(extra="allow")
1526
-
1527
-
1528
- class StepStatus_Variant2(BaseModel):
1529
- model_config = ConfigDict(extra="allow")
1530
-
1531
-
1532
- class StepStatus_Variant3(BaseModel):
1533
- model_config = ConfigDict(extra="allow")
1534
-
1535
-
1536
- class TurnAbortReason_Variant1(BaseModel):
1537
- model_config = ConfigDict(extra="allow")
1538
-
1539
-
1540
- class TurnAbortReason_Variant2(BaseModel):
1541
- model_config = ConfigDict(extra="allow")
1542
-
1543
-
1544
- class Verbosity_Variant1(BaseModel):
1545
- model_config = ConfigDict(extra="allow")
1546
-
1547
-
1548
- class Verbosity_Variant2(BaseModel):
1549
- model_config = ConfigDict(extra="allow")
1550
-
1551
-
1552
- class Verbosity_Variant3(BaseModel):
1553
- model_config = ConfigDict(extra="allow")
1554
-
1555
-
1556
1392
  class WebSearchAction_Search(BaseModel):
1557
1393
  type: Literal["search"]
1558
1394
  query: str
@@ -1594,13 +1430,6 @@ class SendUserTurnResponse(BaseModel):
1594
1430
  model_config = ConfigDict(extra="allow")
1595
1431
 
1596
1432
 
1597
- AskForApproval = (
1598
- AskForApproval_Variant1
1599
- | AskForApproval_Variant2
1600
- | AskForApproval_Variant3
1601
- | AskForApproval_Variant4
1602
- )
1603
- AuthMode = AuthMode_Variant1 | AuthMode_Variant2
1604
1433
  ClientRequest = (
1605
1434
  ClientRequest_NewConversation
1606
1435
  | ClientRequest_ListConversations
@@ -1665,28 +1494,12 @@ EventMsg = (
1665
1494
  | EventMsg_ShutdownComplete
1666
1495
  | EventMsg_ConversationHistory
1667
1496
  )
1668
- ExecOutputStream = ExecOutputStream_Variant1 | ExecOutputStream_Variant2
1669
1497
  FileChange = FileChange_Variant1 | FileChange_Variant2 | FileChange_Variant3
1670
1498
  InputItem = InputItem_Text | InputItem_Image | InputItem_LocalImage
1671
- InputMessageKind = InputMessageKind_Variant1 | InputMessageKind_Variant2 | InputMessageKind_Variant3
1672
- LocalShellStatus = LocalShellStatus_Variant1 | LocalShellStatus_Variant2 | LocalShellStatus_Variant3
1673
1499
  ParsedCommand = (
1674
1500
  ParsedCommand_Read | ParsedCommand_ListFiles | ParsedCommand_Search | ParsedCommand_Unknown
1675
1501
  )
1676
- ReasoningEffort = (
1677
- ReasoningEffort_Variant1
1678
- | ReasoningEffort_Variant2
1679
- | ReasoningEffort_Variant3
1680
- | ReasoningEffort_Variant4
1681
- )
1682
1502
  ReasoningItemContent = ReasoningItemContent_ReasoningText | ReasoningItemContent_Text
1683
- ReasoningSummary = (
1684
- ReasoningSummary_Variant1
1685
- | ReasoningSummary_Variant2
1686
- | ReasoningSummary_Variant3
1687
- | ReasoningSummary_Variant4
1688
- )
1689
- RequestId = RequestId_Variant1 | RequestId_Variant2
1690
1503
  ResponseItem = (
1691
1504
  ResponseItem_Message
1692
1505
  | ResponseItem_Reasoning
@@ -1698,22 +1511,29 @@ ResponseItem = (
1698
1511
  | ResponseItem_WebSearchCall
1699
1512
  | ResponseItem_Other
1700
1513
  )
1701
- ReviewDecision = (
1702
- ReviewDecision_Variant1
1703
- | ReviewDecision_Variant2
1704
- | ReviewDecision_Variant3
1705
- | ReviewDecision_Variant4
1706
- )
1707
- Role = Role_Variant1 | Role_Variant2
1708
- SandboxMode = SandboxMode_Variant1 | SandboxMode_Variant2 | SandboxMode_Variant3
1709
1514
  SandboxPolicy = SandboxPolicy_Variant1 | SandboxPolicy_Variant2 | SandboxPolicy_Variant3
1710
1515
  ServerNotification = ServerNotification_AuthStatusChange | ServerNotification_LoginChatGptComplete
1711
1516
  ServerRequest = ServerRequest_ApplyPatchApproval | ServerRequest_ExecCommandApproval
1712
- StepStatus = StepStatus_Variant1 | StepStatus_Variant2 | StepStatus_Variant3
1713
- TurnAbortReason = TurnAbortReason_Variant1 | TurnAbortReason_Variant2
1714
- Verbosity = Verbosity_Variant1 | Verbosity_Variant2 | Verbosity_Variant3
1715
1517
  WebSearchAction = WebSearchAction_Search | WebSearchAction_Other
1716
1518
 
1519
+ AskForApproval = (
1520
+ Literal["never"] | Literal["on-failure"] | Literal["on-request"] | Literal["untrusted"]
1521
+ )
1522
+ AuthMode = Literal["apikey"] | Literal["chatgpt"]
1523
+ ExecOutputStream = Literal["stderr"] | Literal["stdout"]
1524
+ InputMessageKind = Literal["environment_context"] | Literal["plain"] | Literal["user_instructions"]
1525
+ LocalShellStatus = Literal["completed"] | Literal["in_progress"] | Literal["incomplete"]
1526
+ ReasoningEffort = Literal["high"] | Literal["low"] | Literal["medium"] | Literal["minimal"]
1527
+ ReasoningSummary = Literal["auto"] | Literal["concise"] | Literal["detailed"] | Literal["none"]
1528
+ RequestId = int | str
1529
+ ReviewDecision = (
1530
+ Literal["abort"] | Literal["approved"] | Literal["approved_for_session"] | Literal["denied"]
1531
+ )
1532
+ Role = Literal["assistant"] | Literal["user"]
1533
+ SandboxMode = Literal["danger-full-access"] | Literal["read-only"] | Literal["workspace-write"]
1534
+ StepStatus = Literal["completed"] | Literal["in_progress"] | Literal["pending"]
1535
+ TurnAbortReason = Literal["interrupted"] | Literal["replaced"]
1536
+ Verbosity = Literal["high"] | Literal["low"] | Literal["medium"]
1717
1537
  ConversationId = str
1718
1538
  GitSha = str
1719
1539
  JsonValue = Any