Metadata-Version: 2.4
Name: goguard-sdk
Version: 0.2.0
Summary: GoGuard SDK for Python — behavioral API security in 3 lines of code
Home-page: https://github.com/goguard/sdk-python
Author: GoGuard
Author-email: hello@goguard.dev
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# goguard

API security for Python. One line of code blocks fake signups, bot traffic, credential stuffing, and phone fraud.

[![PyPI version](https://img.shields.io/pypi/v/goguard.svg)](https://pypi.org/project/goguard/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

## Install

```bash
pip install goguard
```

## Setup

### Flask

```python
from flask import Flask
from goguard import GoGuard

app = Flask(__name__)
guard = GoGuard(api_key="sk_live_...")
app = guard.protect(app)

@app.route("/signup", methods=["POST"])
def signup():
    # only legitimate requests reach here
    return {"ok": True}
```

### FastAPI

```python
from fastapi import FastAPI
from goguard import GoGuard

app = FastAPI()
guard = GoGuard(api_key="sk_live_...")
app = guard.protect_asgi(app)

@app.post("/signup")
async def signup():
    # only legitimate requests reach here
    return {"ok": True}
```

### Django

```python
# settings.py
MIDDLEWARE = ["goguard.DjangoMiddleware", ...]
GOGUARD_API_KEY = "sk_live_..."
```

No other code changes needed. Works with **any** WSGI/ASGI framework — Flask, FastAPI, Django, Starlette, Falcon, Sanic.

## What it blocks

| Category | Attacks stopped |
|----------|----------------|
| **Email fraud** | Disposable domains, plus-tag tricks, Gmail dot tricks, fake domains (no MX) |
| **Phone fraud** | VoIP/virtual numbers, suspicious country codes, phone-country mismatch |
| **Credential stuffing** | Automated login attempts across multiple IPs |
| **Bots & scrapers** | Sequential crawling, timing-based detection, high GET ratio |
| **Rate abuse** | Per-IP and per-fingerprint sliding window limits |
| **Known threats** | IP blocklists, watchlists, threat intelligence feeds |
| **Anomalies** | ML-based anomaly scoring per customer baseline |
| **Custom rules** | Your own block/challenge rules via the dashboard |

## Configuration

```python
guard = GoGuard(
    api_key="sk_live_...",          # required

    mode="block",                    # "block" | "monitor" (default: "block")
    exclude_paths=["/health"],       # skip these paths
    timeout=1.5,                     # seconds before fail-open (default: 1.5)
    fail_open=True,                  # never break your app (default: True)

    # toggle auto-protection (all on by default)
    protect_email=True,
    protect_phone=True,
    protect_login=True,

    on_block=lambda environ, reason: print(f"Blocked: {reason}"),
    on_error=lambda err: print(f"GoGuard: {err}"),
)
```

## Enrichment data (optional)

If you want access to the analysis results:

### Flask

```python
@app.route("/signup", methods=["POST"])
def signup():
    enrichment = request.environ.get("goguard.enrichment", {})
    email = enrichment.get("email", {}).get("normalized", request.json["email"])
    # "v.i.c.t.i.m@gmail.com" → "victim@gmail.com"
```

### FastAPI

```python
@app.post("/signup")
async def signup(req: Request, body: SignupBody):
    enrichment = getattr(req.state, "goguard_enrichment", {}) or {}
    email = enrichment.get("email", {}).get("normalized", body.email)
```

| Field | Type | Description |
|-------|------|-------------|
| `enrichment["email"]` | `dict` | Present if email detected in body |
| `enrichment["phone"]` | `dict` | Present if phone detected in body |
| `enrichment["stuffing"]` | `dict` | Present on login paths |
| `goguard.request_id` | `str` | Unique request ID |
| `goguard.fingerprint` | `str` | Device fingerprint |
| `goguard.verdict` | `Verdict` | `{ action, reason, confidence }` |

## Advanced: analysis methods

For deeper fraud investigation (audit scripts, admin tools), use `GoGuardClient` directly:

```python
from goguard import GoGuardClient, GoGuardConfig

client = GoGuardClient(GoGuardConfig(api_key="sk_live_..."))
```

**Find fake account clusters in your database:**

```python
result = client.detect_email_abuse(
    ["john@gmail.com", "j.o.h.n@gmail.com", "john+1@gmail.com"]
)
# {"is_abuse": True, "total_fake_accounts": 2, "clusters": [...]}
```

**Detect phone number cycling:**

```python
result = client.detect_phone_cycling([
    {"phone": "+14155551111", "timestamp": 1711600000000},
    {"phone": "+447911123456", "timestamp": 1711600060000},
])
# {"is_cycling": True, "unique_phones": 2, "unique_countries": 2}
```

**Single email/phone analysis:**

```python
email = client.analyze_email("test+1@mailinator.com")
# {"is_disposable": True, "normalized": "test@mailinator.com", "risk_score": 0.7}

phone = client.analyze_phone("+37255001234")
# {"is_suspicious_country": True, "country_name": "Estonia", "risk_score": 0.3}
```

## Response headers

| Header | Value |
|--------|-------|
| `X-GoGuard-Request-Id` | Unique request ID |
| `X-GoGuard-Action` | `allow`, `block`, or `challenge` |

## Requirements

- Python 3.9+
- `httpx >= 0.27.0`

## Links

- [Dashboard](https://app.goguard.dev)
- [Node.js SDK](https://www.npmjs.com/package/@goguard/node)
- [Go SDK](https://github.com/goguard/sdk-go)

## License

MIT
