Initial commit: API gateway with admin console

- FastAPI async gateway with httpx proxying to multiple upstreams
- SQLite database with SQLAlchemy ORM
- Admin console: manage services, users, API keys, endpoint access
- Per-key, per-endpoint granular access control
- OpenAPI document sync and caching (5-minute TTL)
- Request/response logging with full transaction inspection
- In-memory rate limiting (per-key, fixed-window)
- Tiered log retention (7d payloads, 90d rows, incremental vacuum)
- TLS verification toggle per service (for self-signed certificates)
- Service connectivity validation with automatic endpoint refresh
- Request browser with filters and deep-link inspection
- Docker setup with persistent volume
- Modal forms for create/edit flows

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Samuel Amar
2026-07-29 14:00:22 +02:00
co-authored by Claude Haiku 4.5
commit 77d7a50fa9
31 changed files with 2927 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
from fastapi import Depends, HTTPException, Request, status
from fastapi.responses import RedirectResponse
from sqlalchemy.orm import Session
from app import config, security
from app.database import get_db
from app.models import User
class LoginRequired(HTTPException):
"""Raised when there is no valid session; handled by redirecting to /admin/login."""
def __init__(self):
super().__init__(status_code=status.HTTP_303_SEE_OTHER)
def login_redirect_handler(request: Request, exc: LoginRequired):
return RedirectResponse("/admin/login", status_code=303)
def current_user(request: Request, db: Session = Depends(get_db)) -> User:
token = request.cookies.get(config.SESSION_COOKIE)
user_id = security.read_session_token(token) if token else None
if user_id is None:
raise LoginRequired()
user = db.get(User, user_id)
if user is None or not user.is_active:
raise LoginRequired()
return user