Metadata-Version: 2.4
Name: gpt-budget-guard
Version: 0.1.0
Summary: Budget checks for OpenAI API costs, locally and in GitHub Actions.
Author: GPT Budget Guard contributors
License-Expression: MIT
Project-URL: Homepage, https://github.com/yw947698428/gpt-budget-guard
Project-URL: Repository, https://github.com/yw947698428/gpt-budget-guard
Project-URL: Issues, https://github.com/yw947698428/gpt-budget-guard/issues
Keywords: openai,gpt,budget,cost,github-actions,finops
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: tzdata>=2024.1
Provides-Extra: dev
Requires-Dist: pytest<9,>=8; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Dynamic: license-file

# GPT Budget Guard

**OpenAI API spend gate for CI.** Run a read-only check locally against a
captured Costs API response, or add one GitHub Actions step that fails a job
when observed spend exceeds policy.

[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-3776ab.svg)](https://www.python.org/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

## Why this exists

OpenAI API bills are easiest to control when a repository has a deterministic,
reviewable check. GPT Budget Guard keeps that check small:

- reads aggregate cost buckets, not prompts, responses, or conversation text;
- reports today, month-to-date, and a simple end-of-month projection;
- exits non-zero when observed spend exceeds a configured budget;
- writes Markdown to a GitHub Actions job summary and machine-readable outputs;
- has no daemon, database, telemetry, or vendor proxy.

ChatGPT subscription quotas and private web-app counters are deliberately out of
scope. This project uses the supported organization Costs API rather than
scraping cookies or undocumented endpoints.

This is an **observed-spend CI gate**, not a real-time circuit breaker. It does
not monitor ChatGPT/Codex subscription quotas, model rate limits, or requests in
flight; the Costs API can lag the request that caused a charge.

## Quick start

Python 3.11+ is required. A first run needs no API key:

```bash
python -m pip install -e .
gpt-budget-guard demo
```

After the first tagged PyPI release, the install line can be shortened to
`python -m pip install gpt-budget-guard`.

From a source checkout, the synthetic API-shaped fixture is also available:

```bash
python -m pip install -e ".[dev]"
gpt-budget-guard check \
  --input examples/sample-costs.json \
  --daily-budget 5 \
  --monthly-budget 30 \
  --warning-percent 90 \
  --as-of 2026-08-16T12:00:00Z \
  --format markdown
```

The command prints a report and returns `0` for `PASS` or `WARN`, and `1` for
`FAIL`. Add `--fail-on-warning` when warnings should also block a job.

Example output:

```text
GPT Budget Guard: WARN
Today: USD 0.00 / USD 5.00
Month: USD 25.75 / USD 30.00
Forecast: USD 49.89
- The current pace projects 49.89 for the month, above the monthly budget.
```

A report can contain more than one reason when an actual threshold and the
projection warning are both true.

## GitHub Actions

Create an organization admin key using the [OpenAI organization admin-key
settings](https://platform.openai.com/settings/organization/admin-keys), then
store it in the repository's encrypted secrets as `OPENAI_ADMIN_KEY`. The key
is read from the process environment and is never accepted as a command-line
argument or written to the report. Review the [organization usage API
reference](https://platform.openai.com/docs/api-reference/usage) and rotate the
key if it is ever exposed.

```yaml
name: AI budget

on:
  schedule:
    - cron: "17 6 * * *"
  workflow_dispatch:

jobs:
  budget:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: yw947698428/gpt-budget-guard@v0.1.0
        with:
          daily-budget: "10"
          monthly-budget: "200"
          warning-percent: "80"
          fail-on-warning: "false"
        env:
          OPENAI_ADMIN_KEY: ${{ secrets.OPENAI_ADMIN_KEY }}
```

The action appends a Markdown summary and exposes `status`, `today_usd`,
`month_usd`, and `projected_month_usd` as step outputs. It makes no write
request to OpenAI.

If an organization admin key is not available, export a response from the
Costs API and run the fixture mode instead:

```bash
gpt-budget-guard check --input costs.json --monthly-budget 200
```

## Policy file

For repeatable local and CI runs, copy `.gpt-budget.toml.example` to
`.gpt-budget.toml`, adjust the limits, and commit the resulting policy file:

```toml
[budget]
daily_usd = 10
monthly_usd = 200
warning_percent = 80
timezone = "UTC"
```

CLI flags override the file. Environment variables
`GPT_BUDGET_DAILY_USD`, `GPT_BUDGET_MONTHLY_USD`,
`GPT_BUDGET_WARNING_PERCENT`, and `GPT_BUDGET_TIMEZONE` are also supported.

## Live mode

```bash
$env:OPENAI_ADMIN_KEY = "..."       # PowerShell
gpt-budget-guard check --live --monthly-budget 200 --format terminal
```

Use a least-privileged organization admin key dedicated to automation. The
request is a read-only `GET` to the official Costs endpoint, with a bounded
date range and a 20-second timeout. The live path is intentionally separated
from fixture mode so tests and pull requests can run without secrets.

## Data model

The input fixture follows the bucket/result shape returned by the OpenAI
organization Costs API. Each result needs an `amount.value`; `project_id` and
`line_item` are optional and preserved for future breakdowns. The evaluator
uses `Decimal` arithmetic and localizes bucket start times with `zoneinfo` so
month boundaries are explicit and testable.

## Security and privacy

- No prompts, responses, request bodies, or API keys are stored.
- Reports contain aggregate currency amounts and dates only.
- The live command reads `OPENAI_ADMIN_KEY` at runtime and never prints it.
- Fixture mode is the recommended path for pull requests and local testing.
- This project is not affiliated with OpenAI; “OpenAI” and “GPT” are used to
  describe the API data it accepts.

See [SECURITY.md](SECURITY.md) for private vulnerability reports.

Maintainers preparing an OpenAI OSS application can use the honest,
placeholder-based [application worksheet](docs/codex-for-oss-application.md).

## Development

```bash
python -m venv .venv
python -m pip install -e ".[dev]"
python -m pytest
python -m ruff check .
```

The test suite uses synthetic fixtures only. See [CONTRIBUTING.md](CONTRIBUTING.md)
for the release checklist and [docs/rules.md](docs/rules.md) for the policy
semantics.

## Roadmap

- project and line-item breakdowns in the job summary;
- optional Slack/Webhook notifications generated by the caller;
- reusable parsers for exported usage files from other LLM providers;
- signed release artifacts and a Windows standalone binary.

## License

MIT. See [LICENSE](LICENSE).
