Local Codex usage dashboard with Streamlit, CLI output, and change-based history collection.
English | 简体中文
codex-usage-ui reads your local Codex / ChatGPT auth state, fetches usage data from the Codex usage endpoint, and renders a local dashboard for current limits and history charts.
- Streamlit dashboard with
实时总览,历史趋势, and原始 JSONtabs - local SQLite history storage with change-based sampling
- auto collector started by
run.shfor interval-based background sampling - standalone collector for long-running background collection
- human-readable CLI summary with Unicode progress bars
- support for custom auth and history database paths
- no external backend required
Requirements:
- Python 3.9+
- a valid local Codex / ChatGPT login
Login first if needed:
codex login chatgptClone and start:
git clone https://github.com/onewesong/codex-usage-ui.git
cd codex-usage-ui
./run.shOn first run, run.sh will:
- create
.venv - install
requirements.txt - start Streamlit on
http://127.0.0.1:8501
Use a different port if needed:
PORT=8511 ./run.shStart the dashboard:
./run.shFrom this version on, running ./run.sh will automatically start the background collector, so you do not need to open the page first.
Start the standalone collector:
./run-collector.shRun one collection cycle and exit:
./run-collector.sh --oncePrint a human-readable summary:
python3 get-codex-usage.py --humanPrint raw JSON only:
python3 get-codex-usage.py --json-onlyHistory charts are built from local samples, not from a server-side history API.
By default, running ./run.sh will start a background collector automatically.
For long-running tracking, you can still use the standalone collector if you prefer:
./run-collector.shDefault behavior:
- run once immediately after startup
- collect every
300seconds by default - save a new data point only when the snapshot changes
- keep checking even if no new point is saved
History Trend -> 采集状态shows the auto-collector state, PID, log path, and latest source- collection starts as soon as
./run.shis running, even before any browser session opens
The following fields are used to decide whether a series changed:
used_percentallowedlimit_reachedreset_at
Run with a custom interval:
./run-collector.sh --interval-seconds 60Run once and emit JSON:
./run-collector.sh --once --jsonHuman-readable output:
python3 get-codex-usage.py --humanExample:
GET https://chatgpt.com/backend-api/wham/usage
订阅计划: pro
[配额使用详情]
- 主窗口(5小时)
已使用 25%
进度条 █████░░░░░░░░░░░░░░░ 25%
重置剩余 约3小时后重置
重置时间 2026-03-19 00:16:06
Raw JSON:
python3 get-codex-usage.py --json-onlyThe CLI does not continuously collect history by itself. Use run-collector.sh for long-running tracking.
CODEX_AUTH_PATH: override the default auth file path instead of~/.codex/auth.jsonCODEX_HOME: override the default Codex home directory instead of~/.codexPORT: override the default Streamlit port8501CODEX_USAGE_DB_PATH: override the default history database path instead of~/.codex-usage-ui/history.sqlite3CODEX_USAGE_AUTO_COLLECTOR: enable or disable the background collector started byrun.sh, default1CODEX_USAGE_AUTO_COLLECTOR_INTERVAL_SECONDS: interval for the auto collector, default300
Examples:
CODEX_AUTH_PATH=/path/to/auth.json ./run.shCODEX_HOME=/path/to/.codex CODEX_USAGE_DB_PATH=/path/to/history.sqlite3 ./run-collector.shCODEX_USAGE_AUTO_COLLECTOR=0 ./run.shCODEX_USAGE_AUTO_COLLECTOR_INTERVAL_SECONDS=60 ./run.sh- Load auth from
CODEX_AUTH_PATHor~/.codex/auth.json - Load config from
CODEX_HOME/config.tomlor~/.codex/config.toml - Request the usage endpoint
- Normalize snapshot data into time series
- Compare each series with the latest saved sample
- Write a new point only when the key fields changed
- Render current status and local history charts in Streamlit
Core files:
codex_usage.py: auth loading, HTTP requests, response formattinghistory_store.py: SQLite persistence and change-based history writescodex_usage_app.py: Streamlit UIcollect_history.py: standalone collectorget-codex-usage.py: CLI entrypoint
- this project relies on your local Codex / ChatGPT login state
- the first history chart usually has too few points until more samples accumulate
- the UI can write history, and
run.shnow also starts a background collector by default - if you prefer a separately managed process, disable auto collection and keep using
run-collector.sh