174 lines
No EOL
5.5 KiB
Python
174 lines
No EOL
5.5 KiB
Python
import os
|
|
os.environ["NUMEXPR_MAX_THREADS"] = "12"
|
|
|
|
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 logging
|
|
from logging.handlers import RotatingFileHandler
|
|
from datetime import timedelta
|
|
import pathlib
|
|
|
|
from modules.utility import APP_CONFIG
|
|
from modules.gateway_interface import get_gateway_interface
|
|
|
|
|
|
|
|
# Import auth module
|
|
from modules.auth import (
|
|
create_access_token,
|
|
get_current_active_user,
|
|
get_user_context,
|
|
ACCESS_TOKEN_EXPIRE_MINUTES
|
|
)
|
|
|
|
# Import models - generisch importieren zur INITIALISIERUNG, auch wenn dummy!
|
|
import modules.gateway_model as gateway_model
|
|
import modules.lucydom_interface as lucydom_model
|
|
|
|
|
|
# SETUP LOGGING
|
|
|
|
# Get log level from config (default to INFO if not found)
|
|
log_level_name = APP_CONFIG.get("APP_LOG_LEVEL", "INFO")
|
|
log_level = getattr(logging, log_level_name)
|
|
|
|
# Configure handlers based on config
|
|
handlers = []
|
|
|
|
# Add console handler if enabled
|
|
if APP_CONFIG.get("Logging_CONSOLE_ENABLED", True):
|
|
console_handler = logging.StreamHandler()
|
|
handlers.append(console_handler)
|
|
|
|
# Add file handler if enabled
|
|
if APP_CONFIG.get("Logging_FILE_ENABLED", True):
|
|
log_file = APP_CONFIG.get("APP_LOG_FILE", "app.log")
|
|
rotation_size = int(APP_CONFIG.get("Logging_ROTATION_SIZE", 10485760)) # Default: 10MB
|
|
backup_count = int(APP_CONFIG.get("Logging_BACKUP_COUNT", 5))
|
|
|
|
file_handler = RotatingFileHandler(
|
|
log_file,
|
|
maxBytes=rotation_size,
|
|
backupCount=backup_count
|
|
)
|
|
handlers.append(file_handler)
|
|
|
|
# Configure the logger
|
|
logging.basicConfig(
|
|
level=log_level,
|
|
format=APP_CONFIG.get("Logging_FORMAT", "%(asctime)s - %(levelname)s - %(name)s - %(message)s"),
|
|
datefmt=APP_CONFIG.get("Logging_DATE_FORMAT", "%Y-%m-%d %H:%M:%S"),
|
|
handlers=handlers
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# START APP
|
|
|
|
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.5"
|
|
|
|
@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/user/me", response_model=Dict[str, Any], tags=["General"])
|
|
async def read_user_me(current_user: Dict[str, Any] = Depends(get_current_active_user)):
|
|
return current_user
|
|
|
|
# Alle Router einbinden
|
|
from routes.attributes import router as attributes_router
|
|
app.include_router(attributes_router)
|
|
|
|
from routes.mandates import router as mandate_router
|
|
app.include_router(mandate_router)
|
|
|
|
from routes.users import router as user_router
|
|
app.include_router(user_router)
|
|
|
|
from routes.files import router as file_router
|
|
app.include_router(file_router)
|
|
|
|
from routes.prompts import router as prompt_router
|
|
app.include_router(prompt_router)
|
|
|
|
from routes.workflows 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"""
|
|
logger.info("Anwendung wurde heruntergefahren")
|
|
|
|
#if __name__ == "__main__":
|
|
# uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True) |