Metadata-Version: 2.4
Name: actiongate-postgres
Version: 0.1.0
Summary: Shared PostgreSQL store adapter for ActionGate, BudgetGate, RuleGate, and AuditGate
Author: actiongate-oss
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: psycopg[pool]>=3.1
Provides-Extra: actiongate
Requires-Dist: actiongate>=0.2; extra == 'actiongate'
Provides-Extra: all
Requires-Dist: actiongate>=0.2; extra == 'all'
Requires-Dist: auditgate>=0.2; extra == 'all'
Requires-Dist: budgetgate>=0.2; extra == 'all'
Requires-Dist: rulegate>=0.2; extra == 'all'
Provides-Extra: auditgate
Requires-Dist: auditgate>=0.2; extra == 'auditgate'
Provides-Extra: budgetgate
Requires-Dist: budgetgate>=0.2; extra == 'budgetgate'
Provides-Extra: dev
Requires-Dist: actiongate>=0.2; extra == 'dev'
Requires-Dist: auditgate>=0.2; extra == 'dev'
Requires-Dist: budgetgate>=0.2; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: rulegate>=0.2; extra == 'dev'
Provides-Extra: rulegate
Requires-Dist: rulegate>=0.2; extra == 'rulegate'
Description-Content-Type: text/markdown

# actiongate-postgres

Shared PostgreSQL store adapter for [ActionGate](https://github.com/actiongate-oss/actiongate),
[BudgetGate](https://github.com/actiongate-oss/budgetgate),
[RuleGate](https://github.com/actiongate-oss/rulegate), and
[AuditGate](https://github.com/actiongate-oss/auditgate).

Uses **psycopg (psycopg3)** with connection pooling. One pool shared across all gate stores.

## Install

```bash
pip install actiongate-postgres

# Install with specific gate support:
pip install actiongate-postgres[actiongate]
pip install actiongate-postgres[all]  # all four gates
```

## Quickstart

```python
import psycopg
from actiongate import Engine, Gate, Policy
from actiongate_postgres import ConnectionManager, ActionGatePostgresStore, create_tables

# Create shared pool
mgr = ConnectionManager("postgresql://localhost/mydb")

# Create tables (idempotent)
with mgr.pool.connection() as conn:
    create_tables(conn)

# Wire store to engine
store = ActionGatePostgresStore(mgr)
engine = Engine(store=store)

engine.register(Gate("api", "send_email", "user-42"), Policy(max_calls=5, window=60))
result = engine.check(Gate("api", "send_email", "user-42"))
print(result)  # Decision(status=ALLOW, ...)

mgr.close()
```

### Async

```python
from actiongate_postgres import AsyncConnectionManager, AsyncActionGatePostgresStore

async with AsyncConnectionManager("postgresql://localhost/mydb") as mgr:
    store = AsyncActionGatePostgresStore(mgr)
    # use with async engine...
```

### Multiple Gates, One Pool

```python
from actiongate_postgres import (
    ConnectionManager,
    ActionGatePostgresStore,
    BudgetGatePostgresStore,
    AuditGatePostgresStore,
    create_tables,
)

mgr = ConnectionManager("postgresql://localhost/mydb")

with mgr.pool.connection() as conn:
    create_tables(conn)

ag_store = ActionGatePostgresStore(mgr)
bg_store = BudgetGatePostgresStore(mgr)
audit_store = AuditGatePostgresStore(mgr)
```

## Testing

```bash
# Start PostgreSQL
docker compose up -d

# Run tests
DATABASE_URL="postgresql://actiongate:actiongate@localhost/actiongate_test" pytest tests/ -v
```

## License

Apache-2.0
