All checks were successful
Deploy LLM Service / deploy (push) Successful in 23s
129 lines
3.7 KiB
Python
129 lines
3.7 KiB
Python
# Copyright (c) 2026 PowerOn AG
|
|
# All rights reserved.
|
|
"""
|
|
Private-LLM Service - FastAPI Web App
|
|
Provides AI model endpoints for OCR and Vision processing via Ollama.
|
|
|
|
Models exposed:
|
|
- poweron-ocr-general (deepseek)
|
|
- poweron-vision-general (qwen2.5)
|
|
- poweron-vision-deep (granite3.2)
|
|
"""
|
|
|
|
import logging
|
|
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.staticfiles import StaticFiles
|
|
|
|
from config import CONFIG
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
|
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# ============================================================================
|
|
# Application Lifecycle
|
|
# ============================================================================
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
"""Application lifespan handler."""
|
|
logger.info("Private-LLM Service starting up...")
|
|
logger.info(f"Ollama URL: {CONFIG['ollamaUrl']}")
|
|
logger.info(f"API Key configured: {'Yes' if CONFIG['apiKey'] else 'No (development mode)'}")
|
|
from config import PDF_SUPPORT
|
|
logger.info(f"PDF Support: {'Enabled' if PDF_SUPPORT else 'Disabled'}")
|
|
yield
|
|
logger.info("Private-LLM Service shutting down...")
|
|
|
|
|
|
# ============================================================================
|
|
# FastAPI Application
|
|
# ============================================================================
|
|
|
|
app = FastAPI(
|
|
title="PowerOn Private-LLM Service",
|
|
description="AI model endpoints for OCR and Vision processing",
|
|
version="1.0.0",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
# CORS Configuration
|
|
ALLOWED_ORIGINS = [
|
|
"http://localhost:8000",
|
|
"http://localhost:8080",
|
|
"http://localhost:5000",
|
|
"http://127.0.0.1:8000",
|
|
"http://127.0.0.1:8080",
|
|
"http://127.0.0.1:5000",
|
|
]
|
|
|
|
PRODUCTION_PATTERNS = [
|
|
"poweron.swiss",
|
|
"poweron-center.net",
|
|
]
|
|
|
|
for pattern in PRODUCTION_PATTERNS:
|
|
ALLOWED_ORIGINS.extend([
|
|
f"https://{pattern}",
|
|
f"https://www.{pattern}",
|
|
f"https://api.{pattern}",
|
|
f"https://gateway.{pattern}",
|
|
f"https://app.{pattern}",
|
|
f"https://nyla.{pattern}",
|
|
f"https://playground.{pattern}",
|
|
])
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=ALLOWED_ORIGINS,
|
|
allow_origin_regex=r"https://.*\.(poweron\.swiss|poweron-center\.net)",
|
|
allow_credentials=True,
|
|
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
allow_headers=["*"],
|
|
expose_headers=["*"],
|
|
max_age=86400,
|
|
)
|
|
|
|
# Static files (for web UI)
|
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
|
|
|
|
|
# ============================================================================
|
|
# Route Registration
|
|
# ============================================================================
|
|
|
|
from routeApi import router as apiRouter
|
|
app.include_router(apiRouter)
|
|
|
|
from routeOpenAi import router as openAiRouter
|
|
app.include_router(openAiRouter)
|
|
|
|
from routeWeb import router as webRouter
|
|
app.include_router(webRouter)
|
|
|
|
|
|
# ============================================================================
|
|
# Main
|
|
# ============================================================================
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
|
|
print("\n" + "=" * 60)
|
|
print(" Private-LLM Service - KI-Dokumentenanalyse")
|
|
print(" Powered by PowerOn")
|
|
print("=" * 60)
|
|
print(f"\n Server läuft auf: http://localhost:5000")
|
|
print(f" API Docs: http://localhost:5000/docs")
|
|
print(f" Ollama URL: {CONFIG['ollamaUrl']}")
|
|
print("\n Drücke Ctrl+C zum Beenden")
|
|
print("=" * 60 + "\n")
|
|
|
|
uvicorn.run(app, host="0.0.0.0", port=5000)
|