150 lines
No EOL
4.8 KiB
Python
150 lines
No EOL
4.8 KiB
Python
from fastapi import FastAPI, HTTPException, Depends, Body, status, Response
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.responses import JSONResponse, FileResponse
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.security import OAuth2PasswordRequestForm
|
|
|
|
import uvicorn
|
|
from typing import Dict, Any
|
|
import os
|
|
import logging
|
|
from datetime import timedelta
|
|
import pathlib
|
|
|
|
# Import interfaces
|
|
from modules.gateway_interface import get_gateway_interface
|
|
from modules.lucydom_interface import get_lucydom_interface
|
|
from modules.agentservice_interface import get_agentservice_interface
|
|
|
|
# Import auth module
|
|
from auth import (
|
|
create_access_token,
|
|
get_current_active_user,
|
|
get_user_context,
|
|
ACCESS_TOKEN_EXPIRE_MINUTES
|
|
)
|
|
|
|
# Import models - generisch importieren
|
|
import modules.gateway_model as gateway_model
|
|
|
|
# Konfiguration des Loggers
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
handlers=[logging.StreamHandler()]
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
app = FastAPI(title="PowerOn | Data Platform API", description="Backend-API für die Multi-Agent Platform von ValueOn AG")
|
|
|
|
# CORS-Konfiguration für Frontend-Anfragen
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["http://localhost:8080","https://poweron-lucyagents-xxx.germanywestcentral-01.azurewebsites.net"],
|
|
allow_credentials=True,
|
|
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
allow_headers=["*"],
|
|
expose_headers=["*"],
|
|
max_age=86400 # Erhöhung des Caching für Preflight-Anfragen
|
|
)
|
|
|
|
# Statischer Folder für Frontend - mit absolutem Pfad arbeiten
|
|
base_dir = pathlib.Path(__file__).parent
|
|
static_folder = base_dir / "static"
|
|
os.makedirs(static_folder, exist_ok=True)
|
|
app.mount("/static", StaticFiles(directory=str(static_folder)), name="static")
|
|
|
|
# Add a specific route for favicon.ico
|
|
@app.get("/favicon.ico", include_in_schema=False)
|
|
async def favicon():
|
|
favicon_path = static_folder / "favicon.ico"
|
|
return FileResponse(str(favicon_path))
|
|
|
|
# Generelle Elements
|
|
@app.get("/", tags=["General"])
|
|
async def root():
|
|
"""API-Statusendpunkt"""
|
|
return {"status": "online", "message": "Data Platform API ist aktiv"}
|
|
|
|
@app.get("/api/test", tags=["General"])
|
|
async def get_test():
|
|
return "OK 1.1"
|
|
|
|
@app.options("/{full_path:path}", tags=["General"])
|
|
async def options_route(full_path: str):
|
|
return Response(status_code=200)
|
|
|
|
# Token-Endpunkt für Login
|
|
@app.post("/api/token", response_model=gateway_model.Token, tags=["General"])
|
|
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
|
|
# Gateway-Interface ohne Kontext initialisieren
|
|
gateway = get_gateway_interface()
|
|
|
|
# Benutzer authentifizieren
|
|
user = gateway.authenticate_user(form_data.username, form_data.password)
|
|
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="Ungültiger Benutzername oder Passwort",
|
|
headers={"WWW-Authenticate": "Bearer"},
|
|
)
|
|
|
|
# Token mit Mandanten-ID erstellen
|
|
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
|
access_token = create_access_token(
|
|
data={
|
|
"sub": user["username"],
|
|
"mandate_id": user["mandate_id"]
|
|
},
|
|
expires_delta=access_token_expires
|
|
)
|
|
|
|
return {"access_token": access_token, "token_type": "bearer"}
|
|
|
|
# Benutzerinfo abrufen
|
|
@app.get("/api/users/me", response_model=Dict[str, Any], tags=["General"])
|
|
async def read_users_me(current_user: Dict[str, Any] = Depends(get_current_active_user)):
|
|
return current_user
|
|
|
|
# Alle Router einbinden
|
|
from routes.mandate import router as mandate_router
|
|
app.include_router(mandate_router)
|
|
|
|
from routes.users import router as users_router
|
|
app.include_router(users_router)
|
|
|
|
from routes.attributes import router as attributes_router
|
|
app.include_router(attributes_router)
|
|
|
|
from routes.workspace import router as workspace_router
|
|
app.include_router(workspace_router)
|
|
|
|
from routes.agent import router as agent_router
|
|
app.include_router(agent_router)
|
|
|
|
from routes.file import router as file_router
|
|
app.include_router(file_router)
|
|
|
|
from routes.prompt import router as prompt_router
|
|
app.include_router(prompt_router)
|
|
|
|
from routes.workflow import router as workflow_router
|
|
app.include_router(workflow_router)
|
|
|
|
|
|
# Event handler beim Herunterfahren
|
|
@app.on_event("shutdown")
|
|
async def shutdown_event():
|
|
"""Führt Aufräumarbeiten beim Herunterfahren der Anwendung durch"""
|
|
# Holen des AgentService ohne Kontext (für Aufräumarbeiten)
|
|
agent_service = get_agentservice_interface()
|
|
|
|
# HTTP-Client des AgentService schließen
|
|
await agent_service.close()
|
|
|
|
logger.info("Anwendung wurde heruntergefahren")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True) |