Metadata-Version: 2.4
Name: actiongate-fastapi
Version: 0.1.0
Summary: Gate FastAPI routes through ActionGate primitives.
Project-URL: Homepage, https://github.com/actiongate-oss/actiongate-fastapi
Project-URL: Documentation, https://github.com/actiongate-oss/actiongate-fastapi#readme
Project-URL: Repository, https://github.com/actiongate-oss/actiongate-fastapi
Author-email: ActionGate OSS <actiongate-oss@users.noreply.github.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: actiongate,ai-agents,fastapi,middleware,rate-limiting
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: actiongate>=0.2.0
Requires-Dist: fastapi>=0.100.0
Provides-Extra: all
Requires-Dist: auditgate>=0.1.0; extra == 'all'
Requires-Dist: budgetgate>=0.2.0; extra == 'all'
Requires-Dist: rulegate>=0.2.0; extra == 'all'
Provides-Extra: audit
Requires-Dist: auditgate>=0.1.0; extra == 'audit'
Provides-Extra: budget
Requires-Dist: budgetgate>=0.2.0; extra == 'budget'
Provides-Extra: dev
Requires-Dist: httpx>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: rules
Requires-Dist: rulegate>=0.2.0; extra == 'rules'
Description-Content-Type: text/markdown

# actiongate-fastapi

Gate FastAPI routes through [ActionGate](https://github.com/actiongate-oss/actiongate) primitives.

```
pip install actiongate-fastapi
```

## Route decorator

```python
from fastapi import FastAPI
from actiongate import Engine, Gate, Policy
from actiongate_fastapi import gated_route

app = FastAPI()
ag = Engine()

@app.post("/search")
@gated_route(
    actiongate=ag,
    gate=Gate("api", "search", "global"),
    policy=Policy(max_calls=100, window=60),
)
async def search(query: str):
    return {"results": do_search(query)}
```

Returns 429 for rate limit and budget blocks. Returns 403 for policy violations.

## Dependency injection

```python
from fastapi import Depends
from actiongate_fastapi import gate_dependency

require_gate = gate_dependency(actiongate=ag)

@app.post("/search")
async def search(
    query: str,
    _=Depends(require_gate(
        gate=Gate("api", "search"),
        policy=Policy(max_calls=100, window=60),
    )),
):
    return {"results": do_search(query)}
```

## Add more gates

```
pip install actiongate-fastapi[all]
```

```python
from actiongate import Engine as AG, Gate, Policy
from budgetgate import Engine as BG, Ledger, Budget
from rulegate import Engine as RG, Rule, Ruleset, Context
from actiongate_fastapi import gated_route
from decimal import Decimal

ag, bg, rg = AG(), BG(), RG()

def no_pii(ctx: Context) -> bool:
    return "ssn" not in str(ctx.kwargs).lower()

@app.post("/search")
@gated_route(
    actiongate=ag,
    gate=Gate("api", "search", "global"),
    policy=Policy(max_calls=100, window=60),
    budgetgate=bg,
    ledger=Ledger("api", "search", "global"),
    budget=Budget(max_spend=Decimal("50.00"), window=3600),
    cost=Decimal("0.01"),
    rulegate=rg,
    rule=Rule("api", "search"),
    ruleset=Ruleset(predicates=(no_pii,)),
)
async def search(query: str):
    return {"results": do_search(query)}
```

Gates evaluate in order: ActionGate → BudgetGate → RuleGate → execute → AuditGate.

## License

Apache-2.0. ActionGate and BudgetGate are Apache-2.0. RuleGate and AuditGate are BSL-1.1.
