tokens clean
This commit is contained in:
parent
70bfdc0342
commit
d52f39b4ee
13 changed files with 164 additions and 115 deletions
|
|
@ -60,28 +60,22 @@ app.add_middleware(
|
|||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# Verzeichnis für hochgeladene Dateien erstellen
|
||||
UPLOAD_DIR = os.path.join(os.getcwd(), "uploads")
|
||||
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
||||
|
||||
# Komponenten des Frontends
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
|
||||
|
||||
# API - ENDPUNKTE
|
||||
|
||||
# Statischer Folder für Frontend
|
||||
os.makedirs(os.path.join(os.getcwd(), "static"), exist_ok=True)
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
|
||||
# Generelle Elements
|
||||
@app.get("/", tags=["General"])
|
||||
async def root():
|
||||
"""API-Statusendpunkt"""
|
||||
return {"status": "online", "message": "Data Platform API ist aktiv"}
|
||||
|
||||
|
||||
# Test Element
|
||||
@app.get("/api/test", tags=["Test"])
|
||||
@app.get("/api/test", tags=["General"])
|
||||
async def get_test():
|
||||
return "OK 1.0"
|
||||
|
||||
|
||||
# Token-Endpunkt für Login
|
||||
@app.post("/token", response_model=Token)
|
||||
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
|
||||
|
|
@ -265,7 +259,7 @@ async def upload_file(
|
|||
# Generiere eine eindeutige ID für die Datei
|
||||
file_id = str(uuid.uuid4())
|
||||
file_ext = os.path.splitext(file.filename)[1]
|
||||
file_path = os.path.join(UPLOAD_DIR, f"{file_id}{file_ext}")
|
||||
file_path = os.path.join(get_agent_service(mandate_id, user_id).upload_dir, f"{file_id}{file_ext}")
|
||||
|
||||
# Datei speichern
|
||||
with open(file_path, "wb") as f:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Optional, Dict, Any
|
||||
from fastapi import Depends, HTTPException, status
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
|
|
@ -6,12 +6,15 @@ from jose import JWTError, jwt
|
|||
import logging
|
||||
from interface_gateway import get_gateway_interface
|
||||
from model_gateway import User, Token
|
||||
import configload
|
||||
|
||||
|
||||
# Konfigurationsvariablen
|
||||
SECRET_KEY = "dein-geheimer-schlüssel" # In Produktion aus Umgebungsvariablen laden!
|
||||
ALGORITHM = "HS256"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES = 600
|
||||
# Get Config Data
|
||||
config=configload.load_config()
|
||||
SECRET_KEY = config.get('Access', 'SECRET_KEY')
|
||||
ALGORITHM = config.get('Access', 'ALGORITHM')
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES = int(config.get('Access', 'ACCESS_TOKEN_EXPIRE_MINUTES'))
|
||||
|
||||
|
||||
# OAuth2 Setup
|
||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
||||
|
|
@ -34,9 +37,9 @@ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -
|
|||
to_encode = data.copy()
|
||||
|
||||
if expires_delta:
|
||||
expire = datetime.utcnow() + expires_delta
|
||||
expire = datetime.now(timezone.utc) + expires_delta
|
||||
else:
|
||||
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
expire = datetime.now(timezone.utc) + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
|
||||
to_encode.update({"exp": expire})
|
||||
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
[OpenAI]
|
||||
API_KEY = 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
|
||||
API_URL = https://api.openai.com/v1/chat/completions
|
||||
MODEL_NAME = gpt-4o
|
||||
|
||||
[Application]
|
||||
DEBUG = True
|
||||
UPLOAD_DIR = ./uploads
|
||||
RESULTS_DIR = ./results
|
||||
|
||||
[Access]
|
||||
SECRET_KEY = dein-geheimer-schlüssel
|
||||
ALGORITHM = HS256
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES = 300
|
||||
|
||||
[OpenAI]
|
||||
API_KEY = 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
|
||||
API_URL = https://api.openai.com/v1/chat/completions
|
||||
MODEL_NAME = gpt-4o
|
||||
|
||||
[WebScraping]
|
||||
TIMEOUT = 10
|
||||
MAX_URLS = 3
|
||||
|
|
|
|||
11
gwserver/configload.py
Normal file
11
gwserver/configload.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import configparser
|
||||
import os
|
||||
|
||||
# Konfiguration aus config.ini laden
|
||||
def load_config():
|
||||
config = configparser.ConfigParser()
|
||||
config_path = os.path.join(os.path.dirname(__file__), 'config.ini')
|
||||
if not os.path.exists(config_path):
|
||||
exit("No config file")
|
||||
config.read(config_path)
|
||||
return config
|
||||
|
|
@ -56,17 +56,20 @@ class JSONDatabaseConnector:
|
|||
|
||||
# Wenn die Tabelle bereits im Cache ist, verwende den Cache
|
||||
if table in self._tables_cache:
|
||||
logger.info(f"Lade Tabelle {table} aus Cache")
|
||||
return self._tables_cache[table]
|
||||
|
||||
# Ansonsten lade die Datei
|
||||
try:
|
||||
if os.path.exists(path):
|
||||
logger.info(f"Lade Tabelle {table} aus JSON {path}")
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
self._tables_cache[table] = data
|
||||
return data
|
||||
else:
|
||||
# Wenn die Datei nicht existiert, erstelle eine leere Tabelle
|
||||
logger.info(f"Neue Tabelle {table}")
|
||||
self._tables_cache[table] = []
|
||||
self._save_table(table, [])
|
||||
return []
|
||||
|
|
|
|||
9
gwserver/data_gateway/mandates.json
Normal file
9
gwserver/data_gateway/mandates.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Root",
|
||||
"language": "de",
|
||||
"mandate_id": 1,
|
||||
"user_id": 1
|
||||
}
|
||||
]
|
||||
13
gwserver/data_gateway/users.json
Normal file
13
gwserver/data_gateway/users.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[
|
||||
{
|
||||
"id": 1,
|
||||
"mandate_id": 1,
|
||||
"username": "admin",
|
||||
"email": "admin@example.com",
|
||||
"full_name": "Administrator",
|
||||
"disabled": false,
|
||||
"language": "de",
|
||||
"hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$tJYSAmDs/T+HEALg3Nsbww$2HnCW69CkCkk82fgRhzjYtdNu3b9G7NmSJZmbUQVDOs",
|
||||
"user_id": 1
|
||||
}
|
||||
]
|
||||
|
|
@ -3,84 +3,47 @@ import uuid
|
|||
import os
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import configparser
|
||||
import re
|
||||
from typing import List, Dict, Any, Optional
|
||||
from datetime import datetime
|
||||
import sys
|
||||
import httpx
|
||||
from fastapi import HTTPException
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
import configload as configload
|
||||
|
||||
|
||||
# Logger konfigurieren
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Konfiguration aus config.ini laden
|
||||
def load_config():
|
||||
config = configparser.ConfigParser()
|
||||
config_path = os.path.join(os.path.dirname(__file__), 'config.ini')
|
||||
|
||||
# Standardkonfiguration
|
||||
default_config = {
|
||||
"openai": {
|
||||
"api_key": "VOKEY",
|
||||
"api_url": "https://api.openai.com/v1/chat/completions",
|
||||
"model_name": "gpt-4o"
|
||||
},
|
||||
"application": {
|
||||
"debug": "True",
|
||||
"upload_dir": "./uploads",
|
||||
"results_dir": "./results"
|
||||
},
|
||||
"webscraping": {
|
||||
"timeout": "10",
|
||||
"max_urls": "3",
|
||||
"max_content_length": "3000",
|
||||
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
|
||||
}
|
||||
}
|
||||
|
||||
if not os.path.exists(config_path):
|
||||
logger.warning(f"Konfigurationsdatei nicht gefunden: {config_path}")
|
||||
return default_config
|
||||
|
||||
try:
|
||||
config.read(config_path)
|
||||
|
||||
# Konfiguration aus der Datei lesen
|
||||
# Konfigurationsdaten laden
|
||||
def load_config_data():
|
||||
config=configload.load_config()
|
||||
result = {
|
||||
"openai": {
|
||||
"api_key": config.get('OpenAI', 'API_KEY', fallback=default_config["openai"]["api_key"]),
|
||||
"api_url": config.get('OpenAI', 'API_URL', fallback=default_config["openai"]["api_url"]),
|
||||
"model_name": config.get('OpenAI', 'MODEL_NAME', fallback=default_config["openai"]["model_name"])
|
||||
"api_key": config.get('OpenAI', 'API_KEY'),
|
||||
"api_url": config.get('OpenAI', 'API_URL'),
|
||||
"model_name": config.get('OpenAI', 'MODEL_NAME')
|
||||
},
|
||||
"application": {
|
||||
"debug": config.get('Application', 'DEBUG', fallback=default_config["application"]["debug"]),
|
||||
"upload_dir": config.get('Application', 'UPLOAD_DIR', fallback=default_config["application"]["upload_dir"]),
|
||||
"results_dir": config.get('Application', 'RESULTS_DIR', fallback=default_config["application"]["results_dir"])
|
||||
"debug": config.get('Application', 'DEBUG'),
|
||||
"upload_dir": config.get('Application', 'UPLOAD_DIR'),
|
||||
"results_dir": config.get('Application', 'RESULTS_DIR')
|
||||
},
|
||||
"webscraping": {
|
||||
"timeout": config.get('WebScraping', 'TIMEOUT', fallback=default_config["webscraping"]["timeout"]),
|
||||
"max_urls": config.get('WebScraping', 'MAX_URLS', fallback=default_config["webscraping"]["max_urls"]),
|
||||
"max_content_length": config.get('WebScraping', 'MAX_CONTENT_LENGTH', fallback=default_config["webscraping"]["max_content_length"]),
|
||||
"user_agent": config.get('WebScraping', 'USER_AGENT', fallback=default_config["webscraping"]["user_agent"])
|
||||
"timeout": config.get('WebScraping', 'TIMEOUT'),
|
||||
"max_urls": config.get('WebScraping', 'MAX_URLS'),
|
||||
"max_content_length": config.get('WebScraping', 'MAX_CONTENT_LENGTH'),
|
||||
"user_agent": config.get('WebScraping', 'USER_AGENT')
|
||||
}
|
||||
}
|
||||
|
||||
# Debug-Modus einstellen
|
||||
if result["application"]["debug"].lower() == "true":
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.debug("Debug-Modus aktiviert")
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Laden der Konfiguration: {e}")
|
||||
return default_config
|
||||
|
||||
|
||||
class AgentService:
|
||||
|
|
@ -101,7 +64,7 @@ class AgentService:
|
|||
self.user_id = user_id
|
||||
|
||||
# Konfiguration laden
|
||||
self.config = load_config()
|
||||
self.config = load_config_data()
|
||||
|
||||
# Verzeichnisse aus der Konfiguration übernehmen
|
||||
self.results_dir = self.config["application"]["results_dir"]
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
# Password-Hashing
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
pwd_context = CryptContext(schemes=["argon2"], deprecated="auto")
|
||||
|
||||
|
||||
class GatewayInterface:
|
||||
|
|
@ -33,8 +33,9 @@ class GatewayInterface:
|
|||
self.user_id = user_id if user_id is not None else 1 # Admin-Benutzer als Standard
|
||||
|
||||
# Datenverzeichnis
|
||||
self.data_folder = "/data_gateway"
|
||||
self.data_folder = "data_gateway"
|
||||
os.makedirs(self.data_folder, exist_ok=True)
|
||||
logger.info("db for data_gateway atteached")
|
||||
|
||||
# Datenmodell-Modul importieren
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class LucyDOMInterface:
|
|||
self.user_id = user_id
|
||||
|
||||
# Datenverzeichnis
|
||||
self.data_folder = "/data_lucydom"
|
||||
self.data_folder = "data_lucydom"
|
||||
os.makedirs(self.data_folder, exist_ok=True)
|
||||
|
||||
# Datenmodell-Modul importieren
|
||||
|
|
|
|||
|
|
@ -26,6 +26,12 @@ class Mandate(BaseModel):
|
|||
description="Label für die Klasse"
|
||||
)
|
||||
|
||||
# Labels für Attribute
|
||||
field_labels: Dict[str, Label] = {
|
||||
"id": Label(default="ID", translations={}),
|
||||
"name": Label(default="Name des Mandanten", translations={"en": "Mandate name", "fr": "Nom du mandat"}),
|
||||
"language": Label(default="Sprache", translations={"en": "Language", "fr": "Langue"})
|
||||
}
|
||||
|
||||
class User(BaseModel):
|
||||
"""Datenmodell für einen Benutzer"""
|
||||
|
|
@ -58,9 +64,13 @@ class UserInDB(User):
|
|||
"""Erweiterte Benutzerklasse mit Passwort-Hash"""
|
||||
hashed_password: str = Field(description="Hash des Benutzerpassworts")
|
||||
|
||||
label: Label = Field(
|
||||
default=Label(default="Benutzer Zugriff", translations={"en": "User Access", "fr": "Accès de l'utilisateur"}),
|
||||
description="Label für die Klasse"
|
||||
)
|
||||
|
||||
# Zusätzliches Label für das Passwort-Feld
|
||||
field_labels: Dict[str, Label] = {
|
||||
**User.field_labels,
|
||||
"hashed_password": Label(default="Passwort-Hash", translations={"en": "Password hash", "fr": "Hachage de mot de passe"})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ email-validator>=2.0.0 # For email validation
|
|||
# Authentication and Security
|
||||
python-jose>=3.3.0 # For JWT
|
||||
passlib>=1.7.4 # For password hashing
|
||||
bcrypt>=4.0.1 # For password hashing
|
||||
argon2-cffi # For password hashing
|
||||
cryptography>=40.0.2 # Required by jose
|
||||
|
||||
# Utilities
|
||||
|
|
@ -55,9 +55,9 @@ aiofiles>=23.1.0 # Async file operations
|
|||
|
||||
# AI and NLP
|
||||
openai>=0.27.4 # OpenAI API client
|
||||
nltk>=3.8.1 # Natural Language Toolkit
|
||||
scikit-learn>=1.2.2 # For machine learning utilities
|
||||
spacy>=3.5.2 # For advanced NLP
|
||||
#nltk>=3.8.1 # Natural Language Toolkit
|
||||
#scikit-learn>=1.2.2 # For machine learning utilities
|
||||
#spacy>=3.5.2 # For advanced NLP
|
||||
|
||||
# Visualization (for generating reports)
|
||||
matplotlib>=3.7.1
|
||||
|
|
|
|||
83
start.sh
83
start.sh
|
|
@ -1,21 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Farben für die Ausgabe
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
# Erkennen des Betriebssystems
|
||||
case "$(uname -s)" in
|
||||
CYGWIN*|MINGW*|MSYS*|Windows*)
|
||||
OS="Windows"
|
||||
VENV_PATH="gwserver/venv/Scripts"
|
||||
ACTIVATE_CMD="$VENV_PATH/activate"
|
||||
;;
|
||||
*)
|
||||
OS="Unix"
|
||||
VENV_PATH="gwserver/venv/bin"
|
||||
ACTIVATE_CMD="$VENV_PATH/activate"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -e "${GREEN}Data Platform - Multi-Agent Service${NC}"
|
||||
echo -e "${BLUE}Startskript für gwserver${NC}"
|
||||
echo "----------------------------------------"
|
||||
|
||||
# Verzeichnisstruktur erstellen, falls sie nicht existiert
|
||||
mkdir -p gwserver/data
|
||||
mkdir -p gwserver/uploads
|
||||
mkdir -p gwserver/results
|
||||
mkdir -p gwserver/static
|
||||
echo "Erkanntes Betriebssystem: $OS"
|
||||
|
||||
# Prüfen, ob Python installiert ist
|
||||
PYTHON_CMD=""
|
||||
if command -v python3 &>/dev/null; then
|
||||
PYTHON_CMD="python3"
|
||||
elif command -v python &>/dev/null; then
|
||||
|
|
@ -35,7 +37,11 @@ fi
|
|||
|
||||
# Virtuelle Umgebung aktivieren
|
||||
echo "Aktiviere virtuelle Umgebung..."
|
||||
source gwserver/venv/bin/activate 2>/dev/null || . gwserver/venv/bin/activate
|
||||
if [ "$OS" = "Windows" ]; then
|
||||
source "$ACTIVATE_CMD" 2>/dev/null || . "$ACTIVATE_CMD" 2>/dev/null || echo "Warnung: Aktivierung der virtuellen Umgebung fehlgeschlagen. Fahre fort..."
|
||||
else
|
||||
source "$ACTIVATE_CMD" 2>/dev/null || . "$ACTIVATE_CMD" 2>/dev/null || echo "Warnung: Aktivierung der virtuellen Umgebung fehlgeschlagen. Fahre fort..."
|
||||
fi
|
||||
|
||||
# Abhängigkeiten installieren
|
||||
echo "Installiere Abhängigkeiten..."
|
||||
|
|
@ -43,20 +49,38 @@ pip install -r requirements.txt
|
|||
|
||||
# gwserver als Hintergrundprozess starten
|
||||
echo "Starte gwserver-Server..."
|
||||
cd gwserver
|
||||
uvicorn app:app --reload --host 0.0.0.0 --port 8000 &
|
||||
GWSERVER_PID=$!
|
||||
cd ..
|
||||
|
||||
echo "----------------------------------------"
|
||||
# START CORE
|
||||
cd gwserver
|
||||
if [ "$OS" = "Windows" ]; then
|
||||
# Windows: starte in einem separaten Prozess
|
||||
start uvicorn app:app --reload --host 0.0.0.0 --port 8000
|
||||
# Keine PID-Erfassung nötig unter Windows mit 'start'
|
||||
GWSERVER_PID=""
|
||||
else
|
||||
# Unix: starte im Hintergrund und erfasse PID
|
||||
uvicorn app:app --reload --host 0.0.0.0 --port 8000 &
|
||||
GWSERVER_PID=$!
|
||||
fi
|
||||
# END CORE
|
||||
|
||||
cd ..
|
||||
echo "gwserver API läuft auf: http://localhost:8000"
|
||||
echo "API-Dokumentation: http://localhost:8000/docs"
|
||||
echo -e "${BLUE}Drücke STRG+C, um Server zu beenden${NC}"
|
||||
echo "Drücke STRG+C, um Server zu beenden"
|
||||
|
||||
# Funktion zum Beenden der Server bei STRG+C
|
||||
cleanup() {
|
||||
echo -e "\n${GREEN}Beende Server...${NC}"
|
||||
kill $GWSERVER_PID
|
||||
echo -e "\nBeende Server..."
|
||||
if [ "$OS" = "Windows" ]; then
|
||||
# Windows: Taskkill für uvicorn
|
||||
taskkill //F //IM uvicorn.exe 2>/dev/null || echo "Konnte uvicorn nicht beenden"
|
||||
else
|
||||
# Unix: Verwende die erfasste PID
|
||||
if [ -n "$GWSERVER_PID" ]; then
|
||||
kill $GWSERVER_PID 2>/dev/null || echo "Konnte Prozess $GWSERVER_PID nicht beenden"
|
||||
fi
|
||||
fi
|
||||
echo "Server wurden beendet"
|
||||
exit 0
|
||||
}
|
||||
|
|
@ -65,4 +89,17 @@ cleanup() {
|
|||
trap cleanup SIGINT
|
||||
|
||||
# Warten auf Benutzeraktion
|
||||
wait
|
||||
if [ "$OS" = "Windows" ]; then
|
||||
# Unter Windows: Warte auf Eingabe
|
||||
read -p "Drücke Enter zum Beenden..." dummy
|
||||
cleanup
|
||||
else
|
||||
# Unter Unix: Warte auf Prozess
|
||||
if [ -n "$GWSERVER_PID" ]; then
|
||||
wait $GWSERVER_PID
|
||||
else
|
||||
# Fallback: einfach warten
|
||||
read -p "Drücke Enter zum Beenden..." dummy
|
||||
cleanup
|
||||
fi
|
||||
fi
|
||||
Loading…
Reference in a new issue