codex-lb 0.1.2__py3-none-any.whl

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 (80) hide show
  1. app/__init__.py +5 -0
  2. app/cli.py +24 -0
  3. app/core/__init__.py +0 -0
  4. app/core/auth/__init__.py +96 -0
  5. app/core/auth/models.py +49 -0
  6. app/core/auth/refresh.py +144 -0
  7. app/core/balancer/__init__.py +19 -0
  8. app/core/balancer/logic.py +140 -0
  9. app/core/balancer/types.py +9 -0
  10. app/core/clients/__init__.py +0 -0
  11. app/core/clients/http.py +39 -0
  12. app/core/clients/oauth.py +340 -0
  13. app/core/clients/proxy.py +265 -0
  14. app/core/clients/usage.py +143 -0
  15. app/core/config/__init__.py +0 -0
  16. app/core/config/settings.py +69 -0
  17. app/core/crypto.py +37 -0
  18. app/core/errors.py +73 -0
  19. app/core/openai/__init__.py +0 -0
  20. app/core/openai/models.py +122 -0
  21. app/core/openai/parsing.py +55 -0
  22. app/core/openai/requests.py +59 -0
  23. app/core/types.py +4 -0
  24. app/core/usage/__init__.py +185 -0
  25. app/core/usage/logs.py +57 -0
  26. app/core/usage/models.py +35 -0
  27. app/core/usage/pricing.py +172 -0
  28. app/core/usage/types.py +95 -0
  29. app/core/utils/__init__.py +0 -0
  30. app/core/utils/request_id.py +30 -0
  31. app/core/utils/retry.py +16 -0
  32. app/core/utils/sse.py +13 -0
  33. app/core/utils/time.py +19 -0
  34. app/db/__init__.py +0 -0
  35. app/db/models.py +82 -0
  36. app/db/session.py +44 -0
  37. app/dependencies.py +123 -0
  38. app/main.py +124 -0
  39. app/modules/__init__.py +0 -0
  40. app/modules/accounts/__init__.py +0 -0
  41. app/modules/accounts/api.py +81 -0
  42. app/modules/accounts/repository.py +80 -0
  43. app/modules/accounts/schemas.py +66 -0
  44. app/modules/accounts/service.py +211 -0
  45. app/modules/health/__init__.py +0 -0
  46. app/modules/health/api.py +10 -0
  47. app/modules/oauth/__init__.py +0 -0
  48. app/modules/oauth/api.py +57 -0
  49. app/modules/oauth/schemas.py +32 -0
  50. app/modules/oauth/service.py +356 -0
  51. app/modules/oauth/templates/oauth_success.html +122 -0
  52. app/modules/proxy/__init__.py +0 -0
  53. app/modules/proxy/api.py +76 -0
  54. app/modules/proxy/auth_manager.py +51 -0
  55. app/modules/proxy/load_balancer.py +208 -0
  56. app/modules/proxy/schemas.py +85 -0
  57. app/modules/proxy/service.py +707 -0
  58. app/modules/proxy/types.py +37 -0
  59. app/modules/proxy/usage_updater.py +147 -0
  60. app/modules/request_logs/__init__.py +0 -0
  61. app/modules/request_logs/api.py +31 -0
  62. app/modules/request_logs/repository.py +86 -0
  63. app/modules/request_logs/schemas.py +25 -0
  64. app/modules/request_logs/service.py +77 -0
  65. app/modules/shared/__init__.py +0 -0
  66. app/modules/shared/schemas.py +8 -0
  67. app/modules/usage/__init__.py +0 -0
  68. app/modules/usage/api.py +31 -0
  69. app/modules/usage/repository.py +113 -0
  70. app/modules/usage/schemas.py +62 -0
  71. app/modules/usage/service.py +246 -0
  72. app/static/7.css +1336 -0
  73. app/static/index.css +543 -0
  74. app/static/index.html +457 -0
  75. app/static/index.js +1898 -0
  76. codex_lb-0.1.2.dist-info/METADATA +108 -0
  77. codex_lb-0.1.2.dist-info/RECORD +80 -0
  78. codex_lb-0.1.2.dist-info/WHEEL +4 -0
  79. codex_lb-0.1.2.dist-info/entry_points.txt +2 -0
  80. codex_lb-0.1.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex-lb
3
+ Version: 0.1.2
4
+ Summary: Codex load balancer and proxy for ChatGPT accounts with usage dashboard
5
+ Author-email: Soju06 <qlskssk@gmail.com>
6
+ Maintainer-email: Soju06 <qlskssk@gmail.com>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2025 Soju06
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+ License-File: LICENSE
29
+ Keywords: chatgpt,codex,dashboard,fastapi,load-balancer,proxy,rate-limit,usage
30
+ Classifier: Development Status :: 3 - Alpha
31
+ Classifier: Environment :: Console
32
+ Classifier: Framework :: FastAPI
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Programming Language :: Python :: 3
35
+ Classifier: Programming Language :: Python :: 3 :: Only
36
+ Classifier: Programming Language :: Python :: 3.13
37
+ Classifier: Topic :: Internet :: Proxy Servers
38
+ Classifier: Topic :: Software Development :: Libraries
39
+ Classifier: Topic :: System :: Networking
40
+ Requires-Python: >=3.13
41
+ Requires-Dist: aiohttp-retry>=2.9.1
42
+ Requires-Dist: aiohttp>=3.13.2
43
+ Requires-Dist: aiosqlite>=0.22.1
44
+ Requires-Dist: cryptography>=46.0.3
45
+ Requires-Dist: fastapi[standard]>=0.128.0
46
+ Requires-Dist: greenlet>=3.3.0
47
+ Requires-Dist: pydantic-settings>=2.12.0
48
+ Requires-Dist: pydantic>=2.12.5
49
+ Requires-Dist: python-dotenv>=1.2.1
50
+ Requires-Dist: python-multipart>=0.0.21
51
+ Requires-Dist: sqlalchemy>=2.0.45
52
+ Description-Content-Type: text/markdown
53
+
54
+ # codex-lb
55
+
56
+ Load balancer for ChatGPT accounts. Pool multiple accounts, track usage, view everything in a dashboard.
57
+
58
+ <p align="center">
59
+ <img src="docs/screenshots/dashboard.jpeg" alt="Codex Load Balancer dashboard" width="100%">
60
+ </p>
61
+
62
+ ## Quick Start
63
+
64
+ ### Docker
65
+
66
+ ```bash
67
+ docker run -d --name codex-lb \
68
+ -p 2455:2455 -p 1455:1455 \
69
+ -v ~/.codex-lb:/var/lib/codex-lb \
70
+ ghcr.io/soju06/codex-lb:latest
71
+ ```
72
+
73
+ ### uvx
74
+
75
+ ```bash
76
+ uvx codex-lb
77
+ ```
78
+
79
+ Open [localhost:2455](http://localhost:2455) → Add account → Done.
80
+
81
+ ## Accounts view
82
+
83
+ ![Accounts list and details](docs/screenshots/accounts.jpeg)
84
+
85
+ ## Codex CLI & Extension Setup
86
+
87
+ Add to `~/.codex/config.toml`:
88
+
89
+ ```toml
90
+ model = "gpt-5.2-codex"
91
+ model_reasoning_effort = "xhigh"
92
+ model_provider = "codex-lb"
93
+
94
+ [model_providers.codex-lb]
95
+ name = "OpenAI" # MUST be "OpenAI" - enables /compact endpoint
96
+ base_url = "http://127.0.0.1:2455/backend-api/codex"
97
+ wire_api = "responses"
98
+ chatgpt_base_url = "http://127.0.0.1:2455"
99
+ requires_openai_auth = true # Required: enables model selection in Codex IDE extension
100
+ ```
101
+
102
+ ## Data
103
+
104
+ All data stored in `~/.codex-lb/`:
105
+ - `store.db` – accounts, usage logs
106
+ - `encryption.key` – encrypts tokens (auto-generated)
107
+
108
+ Backup this directory to preserve your accounts.
@@ -0,0 +1,80 @@
1
+ app/__init__.py,sha256=X_4Y93UbuflRBRZd65MtjsVxlZW8d9ZUyi0n83Q-Lrg,89
2
+ app/cli.py,sha256=gkIAkYOT9SbQjUDnVmwhVKZeKjL3YJCMrOjFINwBx54,544
3
+ app/dependencies.py,sha256=43XzEFcOJbfw3Wb1O-fGyLemfgu9RmYPrULUUTPst54,3933
4
+ app/main.py,sha256=JMvTfBdS8wTDNqjQ5QSdqKjjhE0CkpfkbFW6fWNMpy0,4351
5
+ app/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ app/core/crypto.py,sha256=zUz2GVqXigzXB5zX2Diq2cR41Kl37bBqxJiZmWGiIcY,1145
7
+ app/core/errors.py,sha256=go4Q5vv6_Rt8ZS230Mp436yCViEKu_xICylGF0gvGJg,1805
8
+ app/core/types.py,sha256=N4tmoqc7Ks47iZZ8C_3jFyDDVfDYZvrphaj9gQUOhjk,165
9
+ app/core/auth/__init__.py,sha256=wR52dbGd66W1haAOUXn5RMzn3bj-EeXm4vm7zqI3kHE,2815
10
+ app/core/auth/models.py,sha256=iyygu0uHK7fu8txyIyCkXmlgqYPbqEZu3IFysD1t-gk,1557
11
+ app/core/auth/refresh.py,sha256=jhYxT2mQFX4CCvuBQfYNcI53iOtWa0vSkTuZAfbpd9k,5105
12
+ app/core/balancer/__init__.py,sha256=bGy7gITRPObt6P9NdG3pg8t3qWoSW0XWoADqfNYrhdg,405
13
+ app/core/balancer/logic.py,sha256=JFQjzYFzTFRl2Ps24Me-KFZ8jVLMe3Jj5Xzm3aJzFs4,5168
14
+ app/core/balancer/types.py,sha256=gDgjlTy-NH3YhHYl2-YYpIabnckN9Q8-4cRy6S1u0K4,191
15
+ app/core/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ app/core/clients/http.py,sha256=yfFwsaIZNbSmNtyV02WnMKn00JdoNNSlSIx5xB3QY4o,987
17
+ app/core/clients/oauth.py,sha256=XgAzQVAMudBUCQ9nGKUC9N7zagSiawBdhIVmxf9HHwQ,11832
18
+ app/core/clients/proxy.py,sha256=OIgsDxyw9QREq9XT4GwC5azBR-sSpGcDCK7TTmqDTPU,9421
19
+ app/core/clients/usage.py,sha256=kG7TXqmy8IX9m4wJx5fOGDB2hqunivOU6o2xfoXCGy4,4800
20
+ app/core/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ app/core/config/settings.py,sha256=-a25z2pTQZK2f3oxQZOMuktVYTIOvmgF5iORYF6BhIY,2462
22
+ app/core/openai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ app/core/openai/models.py,sha256=SzVPqmp9IDbJTW6gLGHeLxrpAmFehJPSC4fVsqzEmQA,3344
24
+ app/core/openai/parsing.py,sha256=VuE1OyPAv1umrSbkzqa6dcjPYfk00isOVB3O0xUPLBw,1537
25
+ app/core/openai/requests.py,sha256=Nnd4ZtxUtXP-jJ7LGKpPf_JDBIFo-X9k0qMw9SyANTc,1675
26
+ app/core/usage/__init__.py,sha256=NHDQvxS4PzXr4g3hpvChTCVQqOdWRyuLLPZLzGT1J8k,5605
27
+ app/core/usage/logs.py,sha256=nQP6208cmsawCre0s7ekadyZiXofNqz18_3xBeuku-Q,1812
28
+ app/core/usage/models.py,sha256=FtBQx4Rb7jpwcqxmGXxg7RTVV17LK1QOSWaJIkaaNoQ,878
29
+ app/core/usage/pricing.py,sha256=6p8rJ26Gk61mz2t_h9sa0T7NiPDUTiNpzoDewMzT6E0,5464
30
+ app/core/usage/types.py,sha256=CbFF6JYSLvALa2P0qYuj9J9b_w53Fgjg0JOu4RzMWbI,2104
31
+ app/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ app/core/utils/request_id.py,sha256=gxafI-Se8dRQTir-HNGelMzC9S2gwYZntTkVzEqzp_I,705
33
+ app/core/utils/retry.py,sha256=E1s397Bse072sdeEZ2uri5sPAOlTIdyccB-F9jh_E64,408
34
+ app/core/utils/sse.py,sha256=ER3_7mm50BUC1CPIKoVOmQikz-vlEWKNSRDEVqzI_KA,387
35
+ app/core/utils/time.py,sha256=B6FfSe43Eq_puE6eourly1X3gajyihK2VOAwJ8M3wyI,497
36
+ app/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ app/db/models.py,sha256=JCknQCuzjHfgyuSzjHqBmeIE-0XisIAQGEhEWqmzabs,3841
38
+ app/db/session.py,sha256=9UBO4fZKWbN3ihbhNxlkFDDXBMRnlV4M0INvatAeyn0,1211
39
+ app/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ app/modules/accounts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
+ app/modules/accounts/api.py,sha256=rSkYrg3_p_JE1kHZ4xXa5lBFTdT40v1oNAmlTDGOguY,2807
42
+ app/modules/accounts/repository.py,sha256=Anq-bez4ASQHekKNdeDL25ftfYadwlst4KQhHEGS5-E,2950
43
+ app/modules/accounts/schemas.py,sha256=gtlbPg5uxM3t_V5JxCL6eP-UaU6TSE0UoX2yIpxM_a0,1659
44
+ app/modules/accounts/service.py,sha256=j7vtU2ecFrNwfPhYGitZZj1QyJmcIEmKMgS4vznkQ8g,8683
45
+ app/modules/health/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ app/modules/health/api.py,sha256=nrMCMR9BRuFhKVIivhojIJNx9m0gx36sJotnUDI1c2I,190
47
+ app/modules/oauth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
+ app/modules/oauth/api.py,sha256=Wu_DEXgN3hP9Si6MMkl6-0v_Blwjahqwtun1iP7DjVk,1877
49
+ app/modules/oauth/schemas.py,sha256=sdDKP7u9bO87lcZXjK7uSokurHPS22nN2p_jkw9iEBc,777
50
+ app/modules/oauth/service.py,sha256=LOe_kc6LBsuQbCbC6UHgMX3fImyjXI8jTkDqky4iNd0,12725
51
+ app/modules/oauth/templates/oauth_success.html,sha256=YNSGUIozcZEJQjpFtM2sgF4n8jqfbmx8LRwdXTraym4,3799
52
+ app/modules/proxy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ app/modules/proxy/api.py,sha256=BR_qNlNZg2Ft5GYQ-7AzlLlJFf6RVJmlzJzFr_KHUIc,2921
54
+ app/modules/proxy/auth_manager.py,sha256=sFcbStd-OK0g8S56z7XcSkFJ22kEirBU0fYdz2drS0o,2185
55
+ app/modules/proxy/load_balancer.py,sha256=k53RXn9v9fQPXEJ3zWbkhh_Jd82PK1tUef3ZvCdSzog,7441
56
+ app/modules/proxy/schemas.py,sha256=55pXtUCl2R_93kAPOJJ7Ji4Jn3qVu10vq2KSCCkNdp4,2748
57
+ app/modules/proxy/service.py,sha256=P5TyqZIo63Yz70LGAB5Vb5Um9Wy7Toj9qEyHJ39Qero,26018
58
+ app/modules/proxy/types.py,sha256=iqEyoO8vGr8N5oEzUSvVWCai7UZbJAU62IvO7JNS9qs,927
59
+ app/modules/proxy/usage_updater.py,sha256=t5wpn3SmPnTXceiQFF0tw-9V5oPPhP4C0anwbI7T5v0,5588
60
+ app/modules/request_logs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
+ app/modules/request_logs/api.py,sha256=6nV2Uv_hnK7WI3gNpKrgTx4MyUQIXk1QxKp40nij0Xo,1037
62
+ app/modules/request_logs/repository.py,sha256=S86lCDNVAb4N4SvZs5Cnj96ypGzV39r3syS649iOoQ8,2991
63
+ app/modules/request_logs/schemas.py,sha256=GSCi4TEWMmQ-THsQl2irRrA_msU8jzsqKSBDFn7hiJU,592
64
+ app/modules/request_logs/service.py,sha256=SuJeeFJy0qhMe6cUgQ3-zPrENoPlcNnDmTvG7aYsLmE,2386
65
+ app/modules/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
+ app/modules/shared/schemas.py,sha256=SSoWTiSeiSxD06MDn9NbZWhx12JMQtvjJMIk1Kvxwio,240
67
+ app/modules/usage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
+ app/modules/usage/api.py,sha256=jpPc2VSjmiP6DjRZvotHCh_trLINOngSyTdS7MY9fgg,1108
69
+ app/modules/usage/repository.py,sha256=DtJI4kgajW7YUJ0JKJjdNCPBXT_fdBwqDoepi9aznyA,4791
70
+ app/modules/usage/schemas.py,sha256=kh0D2IbIFkl5WTo8XPs-7AC4C8jRpyX0pF6KYQH9ifU,1579
71
+ app/modules/usage/service.py,sha256=_LQA3-L1FxIpzPoIQ-rxz3n3KjiHpTSxRimZapzwx3o,9755
72
+ app/static/7.css,sha256=9EHW2Ouff2fRXgcQbYuCuglxTFgQZGNLLTXKTS6S5aI,80687
73
+ app/static/index.css,sha256=ct1FfBg0PY7c6KxSS6A7JM_WDwdeJqhQa4pXTgyJ19Q,8786
74
+ app/static/index.html,sha256=FmWQ0l40rTBsHIR9i0ttGTzG17ePASsO2VDv6Q48CNw,24477
75
+ app/static/index.js,sha256=L6Gie0iSAHyrPLvO_QtzEis4rxhVqNe2m-g4h3lB6GU,52419
76
+ codex_lb-0.1.2.dist-info/METADATA,sha256=CrhKNJf31RrI02kIbI-ArluFeMNap1tVyHNaqrSmipc,3718
77
+ codex_lb-0.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
78
+ codex_lb-0.1.2.dist-info/entry_points.txt,sha256=SEa5T6Uz2Fhy574No6Y0XyGmYi3PXLrhu2xStJTqyI8,42
79
+ codex_lb-0.1.2.dist-info/licenses/LICENSE,sha256=cHPibxiL0TXwrUX_kNY6ym544EX1UCzKhxdaca5cFuk,1062
80
+ codex_lb-0.1.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ codex-lb = app.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Soju06
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.