I561043 commited on
Commit
17c13db
·
1 Parent(s): f07d9de

add demo for ollama api service

Browse files
Files changed (1) hide show
  1. examples/lightrag_api_ollama_demo.py +160 -0
examples/lightrag_api_ollama_demo.py ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, File, UploadFile
2
+ from pydantic import BaseModel
3
+ import os
4
+ from lightrag import LightRAG, QueryParam
5
+ from lightrag.llm import ollama_embedding, ollama_model_complete
6
+ from lightrag.utils import EmbeddingFunc
7
+ from typing import Optional
8
+ import asyncio
9
+ import nest_asyncio
10
+ import aiofiles
11
+
12
+ # Apply nest_asyncio to solve event loop issues
13
+ nest_asyncio.apply()
14
+
15
+ DEFAULT_RAG_DIR = "index_default"
16
+ app = FastAPI(title="LightRAG API", description="API for RAG operations")
17
+
18
+ DEFAULT_INPUT_FILE = "book.txt"
19
+ INPUT_FILE = os.environ.get("INPUT_FILE", f"{DEFAULT_INPUT_FILE}")
20
+ print(f"INPUT_FILE: {INPUT_FILE}")
21
+
22
+ # Configure working directory
23
+ WORKING_DIR = os.environ.get("RAG_DIR", f"{DEFAULT_RAG_DIR}")
24
+ print(f"WORKING_DIR: {WORKING_DIR}")
25
+
26
+
27
+
28
+ if not os.path.exists(WORKING_DIR):
29
+ os.mkdir(WORKING_DIR)
30
+
31
+
32
+ rag = LightRAG(
33
+ working_dir=WORKING_DIR,
34
+ llm_model_func=ollama_model_complete,
35
+ llm_model_name="gemma2:9b",
36
+ llm_model_max_async=4,
37
+ llm_model_max_token_size=8192,
38
+ llm_model_kwargs={"host": "http://localhost:11434", "options": {"num_ctx": 8192}},
39
+ embedding_func=EmbeddingFunc(
40
+ embedding_dim=768,
41
+ max_token_size=8192,
42
+ func=lambda texts: ollama_embedding(
43
+ texts, embed_model="nomic-embed-text", host="http://localhost:11434"
44
+ ),
45
+ ),
46
+ )
47
+
48
+
49
+ # Data models
50
+ class QueryRequest(BaseModel):
51
+ query: str
52
+ mode: str = "hybrid"
53
+ only_need_context: bool = False
54
+
55
+
56
+ class InsertRequest(BaseModel):
57
+ text: str
58
+
59
+
60
+ class Response(BaseModel):
61
+ status: str
62
+ data: Optional[str] = None
63
+ message: Optional[str] = None
64
+
65
+
66
+ # API routes
67
+ @app.post("/query", response_model=Response)
68
+ async def query_endpoint(request: QueryRequest):
69
+ try:
70
+ loop = asyncio.get_event_loop()
71
+ result = await loop.run_in_executor(
72
+ None,
73
+ lambda: rag.query(
74
+ request.query,
75
+ param=QueryParam(
76
+ mode=request.mode, only_need_context=request.only_need_context
77
+ ),
78
+ ),
79
+ )
80
+ return Response(status="success", data=result)
81
+ except Exception as e:
82
+ raise HTTPException(status_code=500, detail=str(e))
83
+
84
+ # insert by text
85
+ @app.post("/insert", response_model=Response)
86
+ async def insert_endpoint(request: InsertRequest):
87
+ try:
88
+ loop = asyncio.get_event_loop()
89
+ await loop.run_in_executor(None, lambda: rag.insert(request.text))
90
+ return Response(status="success", message="Text inserted successfully")
91
+ except Exception as e:
92
+ raise HTTPException(status_code=500, detail=str(e))
93
+
94
+ # insert by file in payload
95
+ @app.post("/insert_file", response_model=Response)
96
+ async def insert_file(file: UploadFile = File(...)):
97
+ try:
98
+ file_content = await file.read()
99
+ # Read file content
100
+ try:
101
+ content = file_content.decode("utf-8")
102
+ except UnicodeDecodeError:
103
+ # If UTF-8 decoding fails, try other encodings
104
+ content = file_content.decode("gbk")
105
+ # Insert file content
106
+ loop = asyncio.get_event_loop()
107
+ await loop.run_in_executor(None, lambda: rag.insert(content))
108
+
109
+ return Response(
110
+ status="success",
111
+ message=f"File content from {file.filename} inserted successfully",
112
+ )
113
+ except Exception as e:
114
+ raise HTTPException(status_code=500, detail=str(e))
115
+
116
+ # insert by local default file
117
+ @app.post("/insert_default_file", response_model=Response)
118
+ @app.get("/insert_default_file", response_model=Response)
119
+ async def insert_default_file():
120
+ try:
121
+ # Read file content from book.txt
122
+ async with aiofiles.open(INPUT_FILE, "r", encoding="utf-8") as file:
123
+ content = await file.read()
124
+ print(f"read input file {INPUT_FILE} successfully")
125
+ # Insert file content
126
+ loop = asyncio.get_event_loop()
127
+ await loop.run_in_executor(None, lambda: rag.insert(content))
128
+
129
+ return Response(
130
+ status="success",
131
+ message=f"File content from {INPUT_FILE} inserted successfully",
132
+ )
133
+ except Exception as e:
134
+ raise HTTPException(status_code=500, detail=str(e))
135
+
136
+ @app.get("/health")
137
+ async def health_check():
138
+ return {"status": "healthy"}
139
+
140
+
141
+ if __name__ == "__main__":
142
+ import uvicorn
143
+ uvicorn.run(app, host="0.0.0.0", port=8020)
144
+
145
+ # Usage example
146
+ # To run the server, use the following command in your terminal:
147
+ # python lightrag_api_openai_compatible_demo.py
148
+
149
+ # Example requests:
150
+ # 1. Query:
151
+ # curl -X POST "http://127.0.0.1:8020/query" -H "Content-Type: application/json" -d '{"query": "your query here", "mode": "hybrid"}'
152
+
153
+ # 2. Insert text:
154
+ # curl -X POST "http://127.0.0.1:8020/insert" -H "Content-Type: application/json" -d '{"text": "your text here"}'
155
+
156
+ # 3. Insert file:
157
+ # curl -X POST "http://127.0.0.1:8020/insert_file" -H "Content-Type: application/json" -d '{"file_path": "path/to/your/file.txt"}'
158
+
159
+ # 4. Health check:
160
+ # curl -X GET "http://127.0.0.1:8020/health"