Metadata-Version: 2.4
Name: trishul-oauth-client
Version: 0.1.3
Summary: Enterprise-grade OIDC/OAuth client library for Python (FastAPI, Flask, Django)
Author-email: TrishulIAM Team <team@trishuliam.com>
Project-URL: Homepage, https://trishuliam.com
Project-URL: Repository, https://github.com/shubhamssinghs/trishul-iam
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.24.0
Requires-Dist: pyjwt[crypto]>=2.8.0
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.100.0; extra == "fastapi"
Provides-Extra: flask
Requires-Dist: flask>=2.0.0; extra == "flask"
Provides-Extra: django
Requires-Dist: django>=4.0.0; extra == "django"
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: respx>=0.20.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"

# Trishul OAuth Client for Python

An enterprise-grade, highly secure OIDC/OAuth 2.0 client library for Python. Supports standard OIDC authorization code flow with secure PKCE validation, state validation, and plug-and-play integrations for **FastAPI**, **Flask**, and **Django**.

---

## Features

- **Sync & Async Core Engine**: Fully support both sync and async frameworks out-of-the-box.
- **Secure PKCE (S256)**: Auto-generated PKCE verification pairs for absolute security against code interception attacks.
- **OIDC Discovery Configuration**: Automatic parsing and local caching of the openid-configuration metadata.
- **Cryptographic Signature Verification**: Validates ID Token signatures locally using the server's JWKS endpoint.
- **Automatic Silent Token Rotation**: Seamless refresh-token based token rotation without user disruption.
- **Out-of-the-Box Web Framework Integrations** for:
  - **FastAPI / Starlette**
  - **Flask**
  - **Django**

---

## Installation

Install from PyPI (once published):

```bash
pip install trishul-oauth-client
```

Or install with framework-specific dependency packages:

```bash
# For FastAPI
pip install "trishul-oauth-client[fastapi]"

# For Flask
pip install "trishul-oauth-client[flask]"

# For Django
pip install "trishul-oauth-client[django]"
```

---

## Quickstart

### 1. Initialize Client
```python
from trishul_oauth import TrishulOAuth, MemoryStorage

client = TrishulOAuth({
    "issuer": "https://identity.yourdomain.com",
    "clientId": "your_client_id",
    "clientSecret": "your_client_secret",
    "redirectUri": "http://localhost:8000/callback",
    "usePKCE": True,
})
```

---

## Web Framework Integrations

### 1. FastAPI / Starlette
Fully async dependency injection provider:

```python
from fastapi import FastAPI, Depends, HTTPException
from trishul_oauth import TrishulOAuth
from trishul_oauth.integrations.fastapi import TrishulSecurity

app = FastAPI()
client = TrishulOAuth({
    "issuer": "https://identity.yourdomain.com",
    "clientId": "your_client_id",
    "redirectUri": "http://localhost:8000/callback",
})

# Initialize FastAPI Security provider
security = TrishulSecurity(client)

@app.get("/api/dashboard")
async def dashboard(user = Depends(security.require_auth(scopes=["profile"]))):
    return {
        "status": "success",
        "message": f"Welcome back, {user.get('name')}!",
        "profile": user
    }
```

### 2. Flask
Clean view decorators and session injectors:

```python
from flask import Flask, session, render_template
from trishul_oauth import TrishulOAuth
from trishul_oauth.integrations.flask import FlaskOAuth

app = Flask(__name__)
app.secret_key = "your_super_secret_session_key"

client = TrishulOAuth({
    "issuer": "https://identity.yourdomain.com",
    "clientId": "your_client_id",
    "clientSecret": "your_client_secret",
    "redirectUri": "http://localhost:5000/callback",
})

oauth = FlaskOAuth(client)

@app.route("/dashboard")
@oauth.require_auth(scopes=["profile"])
def dashboard():
    # Retrieve user info from global Flask context
    user = oauth.current_user
    return f"Welcome back, {user['name']}!"
```

### 3. Django
Middleware and view decorators for robust authentication:

```python
# settings.py
INSTALLED_APPS = [
    ...
    'django.contrib.sessions',
]

MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'trishul_oauth.integrations.django.TrishulOAuthMiddleware',
]

from trishul_oauth import TrishulOAuth
TRISHUL_OAUTH_CLIENT = TrishulOAuth({
    "issuer": "https://identity.yourdomain.com",
    "clientId": "your_client_id",
    "clientSecret": "your_client_secret",
})


# views.py
from django.http import JsonResponse
from trishul_oauth.integrations.django import require_auth

@require_auth(scopes=["profile"])
def dashboard_view(request):
    user = request.trishul_user
    return JsonResponse({
        "status": "success",
        "user": user
    })
```

---

## Running Package Tests

Verify everything runs cleanly using `pytest`:

```bash
pytest tests/
```

---

## License

MIT License. See [LICENSE](LICENSE) for details.
