applyed linting

This commit is contained in:
Saifeddine ALOUI
2025-01-04 02:23:39 +01:00
parent 518a8a726a
commit b15c398889
5 changed files with 182 additions and 104 deletions

View File

@@ -1088,6 +1088,10 @@ lollms-lightrag-server --model mistral-nemo --port 8080 --working-dir ./custom_r
# Using specific models (ensure they are installed in your LoLLMs instance)
lollms-lightrag-server --model mistral-nemo:latest --embedding-model bge-m3 --embedding-dim 1024
# Using specific models and an authentication key
lollms-lightrag-server --model mistral-nemo:latest --embedding-model bge-m3 --embedding-dim 1024 --key ky-mykey
```
#### Ollama RAG Server

View File

@@ -20,19 +20,12 @@ from dotenv import load_dotenv
import inspect
import json
from fastapi.responses import StreamingResponse
from fastapi import FastAPI, HTTPException
import os
from typing import Optional
from fastapi import FastAPI, Depends, HTTPException, Security
from fastapi import Depends, Security
from fastapi.security import APIKeyHeader
import os
import argparse
from typing import Optional
from fastapi.middleware.cors import CORSMiddleware
from starlette.status import HTTP_403_FORBIDDEN
from fastapi import HTTPException
load_dotenv()
@@ -106,8 +99,12 @@ def parse_args():
help="Logging level (default: INFO)",
)
parser.add_argument('--key', type=str, help='API key for authentication. This protects lightrag server against unauthorized access', default=None)
parser.add_argument(
"--key",
type=str,
help="API key for authentication. This protects lightrag server against unauthorized access",
default=None,
)
return parser.parse_args()
@@ -170,11 +167,13 @@ class InsertResponse(BaseModel):
message: str
document_count: int
def get_api_key_dependency(api_key: Optional[str]):
if not api_key:
# If no API key is configured, return a dummy dependency that always succeeds
async def no_auth():
return None
return no_auth
# If API key is configured, use proper authentication
@@ -183,13 +182,11 @@ def get_api_key_dependency(api_key: Optional[str]):
async def api_key_auth(api_key_header_value: str | None = Security(api_key_header)):
if not api_key_header_value:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="API Key required"
status_code=HTTP_403_FORBIDDEN, detail="API Key required"
)
if api_key_header_value != api_key:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="Invalid API Key"
status_code=HTTP_403_FORBIDDEN, detail="Invalid API Key"
)
return api_key_header_value
@@ -209,16 +206,18 @@ def create_app(args):
format="%(levelname)s:%(message)s", level=getattr(logging, args.log_level)
)
# Check if API key is provided either through env var or args
api_key = os.getenv("LIGHTRAG_API_KEY") or args.key
# Initialize FastAPI
app = FastAPI(
title="LightRAG API",
description="API for querying text using LightRAG with separate storage and input directories"+"(With authentication)" if api_key else "",
description="API for querying text using LightRAG with separate storage and input directories"
+ "(With authentication)"
if api_key
else "",
version="1.0.0",
openapi_tags=[{"name": "api"}]
openapi_tags=[{"name": "api"}],
)
# Add CORS middleware
@@ -363,7 +362,9 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/query", response_model=QueryResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/query", response_model=QueryResponse, dependencies=[Depends(optional_api_key)]
)
async def query_text(request: QueryRequest):
try:
response = await rag.aquery(
@@ -404,7 +405,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/text", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/text",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_text(request: InsertTextRequest):
try:
await rag.ainsert(request.text)
@@ -416,7 +421,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/file", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/file",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_file(file: UploadFile = File(...), description: str = Form(None)):
try:
content = await file.read()
@@ -440,7 +449,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/batch", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/batch",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_batch(files: List[UploadFile] = File(...)):
try:
inserted_count = 0
@@ -470,7 +483,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.delete("/documents", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.delete(
"/documents",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def clear_documents():
try:
rag.text_chunks = []

View File

@@ -11,19 +11,14 @@ from pathlib import Path
import shutil
import aiofiles
from ascii_colors import trace_exception
from fastapi import FastAPI, HTTPException
import os
from typing import Optional
from fastapi import FastAPI, Depends, HTTPException, Security
from fastapi import Depends, Security
from fastapi.security import APIKeyHeader
import os
import argparse
from typing import Optional
from fastapi.middleware.cors import CORSMiddleware
from starlette.status import HTTP_403_FORBIDDEN
from fastapi import HTTPException
def parse_args():
parser = argparse.ArgumentParser(
@@ -98,8 +93,12 @@ def parse_args():
help="Logging level (default: INFO)",
)
parser.add_argument('--key', type=str, help='API key for authentication. This protects lightrag server against unauthorized access', default=None)
parser.add_argument(
"--key",
type=str,
help="API key for authentication. This protects lightrag server against unauthorized access",
default=None,
)
return parser.parse_args()
@@ -162,11 +161,13 @@ class InsertResponse(BaseModel):
message: str
document_count: int
def get_api_key_dependency(api_key: Optional[str]):
if not api_key:
# If no API key is configured, return a dummy dependency that always succeeds
async def no_auth():
return None
return no_auth
# If API key is configured, use proper authentication
@@ -175,13 +176,11 @@ def get_api_key_dependency(api_key: Optional[str]):
async def api_key_auth(api_key_header_value: str | None = Security(api_key_header)):
if not api_key_header_value:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="API Key required"
status_code=HTTP_403_FORBIDDEN, detail="API Key required"
)
if api_key_header_value != api_key:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="Invalid API Key"
status_code=HTTP_403_FORBIDDEN, detail="Invalid API Key"
)
return api_key_header_value
@@ -200,9 +199,12 @@ def create_app(args):
# Initialize FastAPI
app = FastAPI(
title="LightRAG API",
description="API for querying text using LightRAG with separate storage and input directories"+"(With authentication)" if api_key else "",
description="API for querying text using LightRAG with separate storage and input directories"
+ "(With authentication)"
if api_key
else "",
version="1.0.0",
openapi_tags=[{"name": "api"}]
openapi_tags=[{"name": "api"}],
)
# Add CORS middleware
@@ -319,7 +321,9 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/query", response_model=QueryResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/query", response_model=QueryResponse, dependencies=[Depends(optional_api_key)]
)
async def query_text(request: QueryRequest):
try:
response = await rag.aquery(
@@ -361,7 +365,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/text", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/text",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_text(request: InsertTextRequest):
try:
rag.insert(request.text)
@@ -373,7 +381,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/file", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/file",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_file(file: UploadFile = File(...), description: str = Form(None)):
try:
content = await file.read()
@@ -397,7 +409,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/batch", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/batch",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_batch(files: List[UploadFile] = File(...)):
try:
inserted_count = 0
@@ -427,7 +443,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.delete("/documents", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.delete(
"/documents",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def clear_documents():
try:
rag.text_chunks = []

View File

@@ -11,19 +11,13 @@ from pathlib import Path
import shutil
import aiofiles
from ascii_colors import trace_exception
from fastapi import FastAPI, HTTPException
import os
from typing import Optional
from fastapi import FastAPI, Depends, HTTPException, Security
from fastapi import Depends, Security
from fastapi.security import APIKeyHeader
import os
import argparse
from typing import Optional
from fastapi.middleware.cors import CORSMiddleware
from starlette.status import HTTP_403_FORBIDDEN
from fastapi import HTTPException
def parse_args():
@@ -98,7 +92,12 @@ def parse_args():
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
help="Logging level (default: INFO)",
)
parser.add_argument('--key', type=str, help='API key for authentication. This protects lightrag server against unauthorized access', default=None)
parser.add_argument(
"--key",
type=str,
help="API key for authentication. This protects lightrag server against unauthorized access",
default=None,
)
return parser.parse_args()
@@ -161,11 +160,13 @@ class InsertResponse(BaseModel):
message: str
document_count: int
def get_api_key_dependency(api_key: Optional[str]):
if not api_key:
# If no API key is configured, return a dummy dependency that always succeeds
async def no_auth():
return None
return no_auth
# If API key is configured, use proper authentication
@@ -174,13 +175,11 @@ def get_api_key_dependency(api_key: Optional[str]):
async def api_key_auth(api_key_header_value: str | None = Security(api_key_header)):
if not api_key_header_value:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="API Key required"
status_code=HTTP_403_FORBIDDEN, detail="API Key required"
)
if api_key_header_value != api_key:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="Invalid API Key"
status_code=HTTP_403_FORBIDDEN, detail="Invalid API Key"
)
return api_key_header_value
@@ -199,9 +198,12 @@ def create_app(args):
# Initialize FastAPI
app = FastAPI(
title="LightRAG API",
description="API for querying text using LightRAG with separate storage and input directories"+"(With authentication)" if api_key else "",
description="API for querying text using LightRAG with separate storage and input directories"
+ "(With authentication)"
if api_key
else "",
version="1.0.0",
openapi_tags=[{"name": "api"}]
openapi_tags=[{"name": "api"}],
)
# Add CORS middleware
@@ -216,7 +218,6 @@ def create_app(args):
# Create the optional API key dependency
optional_api_key = get_api_key_dependency(api_key)
# Create working directory if it doesn't exist
Path(args.working_dir).mkdir(parents=True, exist_ok=True)
@@ -319,7 +320,9 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/query", response_model=QueryResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/query", response_model=QueryResponse, dependencies=[Depends(optional_api_key)]
)
async def query_text(request: QueryRequest):
try:
response = await rag.aquery(
@@ -361,7 +364,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/text", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/text",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_text(request: InsertTextRequest):
try:
await rag.ainsert(request.text)
@@ -373,7 +380,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/file", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/file",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_file(file: UploadFile = File(...), description: str = Form(None)):
try:
content = await file.read()
@@ -397,7 +408,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/batch", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/batch",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_batch(files: List[UploadFile] = File(...)):
try:
inserted_count = 0
@@ -427,7 +442,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.delete("/documents", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.delete(
"/documents",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def clear_documents():
try:
rag.text_chunks = []

View File

@@ -14,19 +14,13 @@ import aiofiles
from ascii_colors import trace_exception
import nest_asyncio
from fastapi import FastAPI, HTTPException
import os
from typing import Optional
from fastapi import FastAPI, Depends, HTTPException, Security
from fastapi import Depends, Security
from fastapi.security import APIKeyHeader
import os
import argparse
from typing import Optional
from fastapi.middleware.cors import CORSMiddleware
from starlette.status import HTTP_403_FORBIDDEN
from fastapi import HTTPException
# Apply nest_asyncio to solve event loop issues
nest_asyncio.apply()
@@ -89,8 +83,12 @@ def parse_args():
help="Logging level (default: INFO)",
)
parser.add_argument('--key', type=str, help='API key for authentication. This protects lightrag server against unauthorized access', default=None)
parser.add_argument(
"--key",
type=str,
help="API key for authentication. This protects lightrag server against unauthorized access",
default=None,
)
return parser.parse_args()
@@ -153,11 +151,13 @@ class InsertResponse(BaseModel):
message: str
document_count: int
def get_api_key_dependency(api_key: Optional[str]):
if not api_key:
# If no API key is configured, return a dummy dependency that always succeeds
async def no_auth():
return None
return no_auth
# If API key is configured, use proper authentication
@@ -166,13 +166,11 @@ def get_api_key_dependency(api_key: Optional[str]):
async def api_key_auth(api_key_header_value: str | None = Security(api_key_header)):
if not api_key_header_value:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="API Key required"
status_code=HTTP_403_FORBIDDEN, detail="API Key required"
)
if api_key_header_value != api_key:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="Invalid API Key"
status_code=HTTP_403_FORBIDDEN, detail="Invalid API Key"
)
return api_key_header_value
@@ -192,16 +190,18 @@ def create_app(args):
format="%(levelname)s:%(message)s", level=getattr(logging, args.log_level)
)
# Check if API key is provided either through env var or args
api_key = os.getenv("LIGHTRAG_API_KEY") or args.key
# Initialize FastAPI
app = FastAPI(
title="LightRAG API",
description="API for querying text using LightRAG with separate storage and input directories"+"(With authentication)" if api_key else "",
description="API for querying text using LightRAG with separate storage and input directories"
+ "(With authentication)"
if api_key
else "",
version="1.0.0",
openapi_tags=[{"name": "api"}]
openapi_tags=[{"name": "api"}],
)
# Add CORS middleware
@@ -335,7 +335,9 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/query", response_model=QueryResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/query", response_model=QueryResponse, dependencies=[Depends(optional_api_key)]
)
async def query_text(request: QueryRequest):
try:
response = await rag.aquery(
@@ -377,7 +379,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/text", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/text",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_text(request: InsertTextRequest):
try:
rag.insert(request.text)
@@ -389,7 +395,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/file", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/file",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_file(file: UploadFile = File(...), description: str = Form(None)):
try:
content = await file.read()
@@ -413,7 +423,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/documents/batch", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.post(
"/documents/batch",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def insert_batch(files: List[UploadFile] = File(...)):
try:
inserted_count = 0
@@ -443,7 +457,11 @@ def create_app(args):
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.delete("/documents", response_model=InsertResponse, dependencies=[Depends(optional_api_key)])
@app.delete(
"/documents",
response_model=InsertResponse,
dependencies=[Depends(optional_api_key)],
)
async def clear_documents():
try:
rag.text_chunks = []