- Rename files: cog_cli.py, test_cog.py, k8s/cog-*.yaml - Update all Python tool names: cog_* -> assay_* - Update FastAPI titles, MCP server names, URLs - Update K8s manifests: deployments, services, secrets, ingress - Update Docker env vars: COG_API -> ASSAY_API - Domain: cog.loop42.de -> assay.loop42.de - SQLite path: /tmp/cog_db.sqlite -> /tmp/assay_db.sqlite Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
"""assay — agent runtime.
|
|
|
|
uvicorn entrypoint: agent:app
|
|
"""
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from dotenv import load_dotenv
|
|
load_dotenv(Path(__file__).parent.parent / ".env")
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(name)s] %(message)s", datefmt="%H:%M:%S")
|
|
|
|
from fastapi import FastAPI, Request
|
|
from fastapi.responses import FileResponse
|
|
from fastapi.staticfiles import StaticFiles
|
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
|
|
from .api import register_routes
|
|
|
|
|
|
class NoCacheStaticMiddleware(BaseHTTPMiddleware):
|
|
"""Prevent browser/CDN caching of static files during development."""
|
|
async def dispatch(self, request: Request, call_next):
|
|
response = await call_next(request)
|
|
if request.url.path.startswith("/static/"):
|
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
|
|
response.headers["Pragma"] = "no-cache"
|
|
return response
|
|
|
|
STATIC_DIR = Path(__file__).parent.parent / "static"
|
|
|
|
app = FastAPI(title="assay")
|
|
|
|
# Register all API + WS routes
|
|
register_routes(app)
|
|
|
|
# Serve frontend from same process (fallback for non-split deploy)
|
|
# When running behind assay-frontend nginx, these paths won't be hit
|
|
@app.get("/")
|
|
async def index():
|
|
resp = FileResponse(STATIC_DIR / "index.html")
|
|
resp.headers["Cache-Control"] = "no-cache"
|
|
return resp
|
|
|
|
@app.get("/tests")
|
|
async def tests_page():
|
|
return FileResponse(STATIC_DIR / "tests.html")
|
|
|
|
@app.get("/callback")
|
|
async def callback():
|
|
"""OIDC callback — serves the same SPA, JS handles the code exchange."""
|
|
return FileResponse(STATIC_DIR / "index.html")
|
|
|
|
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|