yangdx
commited on
Commit
Β·
0f6618e
1
Parent(s):
e7edd68
Centralize env reading
Browse files- lightrag/api/config.py +10 -0
- lightrag/api/lightrag_server.py +8 -2
- lightrag/api/run_with_gunicorn.py +17 -25
- lightrag/api/utils_api.py +5 -14
lightrag/api/config.py
CHANGED
@@ -5,7 +5,12 @@ Configs for the LightRAG API.
|
|
5 |
import os
|
6 |
import argparse
|
7 |
import logging
|
|
|
8 |
|
|
|
|
|
|
|
|
|
9 |
|
10 |
class OllamaServerInfos:
|
11 |
# Constants for emulated Ollama model information
|
@@ -297,6 +302,11 @@ def parse_args() -> argparse.Namespace:
|
|
297 |
|
298 |
# Select Document loading tool (DOCLING, DEFAULT)
|
299 |
args.document_loading_engine = get_env_value("DOCUMENT_LOADING_ENGINE", "DEFAULT")
|
|
|
|
|
|
|
|
|
|
|
300 |
|
301 |
# For JWT Auth
|
302 |
args.auth_accounts = get_env_value("AUTH_ACCOUNTS", "")
|
|
|
5 |
import os
|
6 |
import argparse
|
7 |
import logging
|
8 |
+
from dotenv import load_dotenv
|
9 |
|
10 |
+
# use the .env that is inside the current folder
|
11 |
+
# allows to use different .env file for each lightrag instance
|
12 |
+
# the OS environment variables take precedence over the .env file
|
13 |
+
load_dotenv(dotenv_path=".env", override=False)
|
14 |
|
15 |
class OllamaServerInfos:
|
16 |
# Constants for emulated Ollama model information
|
|
|
302 |
|
303 |
# Select Document loading tool (DOCLING, DEFAULT)
|
304 |
args.document_loading_engine = get_env_value("DOCUMENT_LOADING_ENGINE", "DEFAULT")
|
305 |
+
|
306 |
+
# Add environment variables that were previously read directly
|
307 |
+
args.cors_origins = get_env_value("CORS_ORIGINS", "*")
|
308 |
+
args.summary_language = get_env_value("SUMMARY_LANGUAGE", "en")
|
309 |
+
args.whitelist_paths = get_env_value("WHITELIST_PATHS", "/health,/api/*")
|
310 |
|
311 |
# For JWT Auth
|
312 |
args.auth_accounts = get_env_value("AUTH_ACCOUNTS", "")
|
lightrag/api/lightrag_server.py
CHANGED
@@ -167,10 +167,10 @@ def create_app(args):
|
|
167 |
app = FastAPI(**app_kwargs)
|
168 |
|
169 |
def get_cors_origins():
|
170 |
-
"""Get allowed origins from
|
171 |
Returns a list of allowed origins, defaults to ["*"] if not set
|
172 |
"""
|
173 |
-
origins_str =
|
174 |
if origins_str == "*":
|
175 |
return ["*"]
|
176 |
return [origin.strip() for origin in origins_str.split(",")]
|
@@ -321,6 +321,9 @@ def create_app(args):
|
|
321 |
# namespace_prefix=args.namespace_prefix,
|
322 |
auto_manage_storages_states=False,
|
323 |
max_parallel_insert=args.max_parallel_insert,
|
|
|
|
|
|
|
324 |
)
|
325 |
else: # azure_openai
|
326 |
rag = LightRAG(
|
@@ -351,6 +354,9 @@ def create_app(args):
|
|
351 |
# namespace_prefix=args.namespace_prefix,
|
352 |
auto_manage_storages_states=False,
|
353 |
max_parallel_insert=args.max_parallel_insert,
|
|
|
|
|
|
|
354 |
)
|
355 |
|
356 |
# Add routes
|
|
|
167 |
app = FastAPI(**app_kwargs)
|
168 |
|
169 |
def get_cors_origins():
|
170 |
+
"""Get allowed origins from global_args
|
171 |
Returns a list of allowed origins, defaults to ["*"] if not set
|
172 |
"""
|
173 |
+
origins_str = global_args.cors_origins
|
174 |
if origins_str == "*":
|
175 |
return ["*"]
|
176 |
return [origin.strip() for origin in origins_str.split(",")]
|
|
|
321 |
# namespace_prefix=args.namespace_prefix,
|
322 |
auto_manage_storages_states=False,
|
323 |
max_parallel_insert=args.max_parallel_insert,
|
324 |
+
addon_params={
|
325 |
+
"language": args.summary_language
|
326 |
+
},
|
327 |
)
|
328 |
else: # azure_openai
|
329 |
rag = LightRAG(
|
|
|
354 |
# namespace_prefix=args.namespace_prefix,
|
355 |
auto_manage_storages_states=False,
|
356 |
max_parallel_insert=args.max_parallel_insert,
|
357 |
+
addon_params={
|
358 |
+
"language": args.summary_language
|
359 |
+
},
|
360 |
)
|
361 |
|
362 |
# Add routes
|
lightrag/api/run_with_gunicorn.py
CHANGED
@@ -7,14 +7,9 @@ import os
|
|
7 |
import sys
|
8 |
import signal
|
9 |
import pipmaster as pm
|
10 |
-
from lightrag.api.utils_api import
|
11 |
from lightrag.kg.shared_storage import initialize_share_data, finalize_share_data
|
12 |
-
from
|
13 |
-
|
14 |
-
# use the .env that is inside the current folder
|
15 |
-
# allows to use different .env file for each lightrag instance
|
16 |
-
# the OS environment variables take precedence over the .env file
|
17 |
-
load_dotenv(dotenv_path=".env", override=False)
|
18 |
|
19 |
|
20 |
def check_and_install_dependencies():
|
@@ -59,20 +54,17 @@ def main():
|
|
59 |
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
|
60 |
signal.signal(signal.SIGTERM, signal_handler) # kill command
|
61 |
|
62 |
-
# Parse all arguments using parse_args
|
63 |
-
args = parse_args(is_uvicorn_mode=False)
|
64 |
-
|
65 |
# Display startup information
|
66 |
-
display_splash_screen(
|
67 |
|
68 |
print("π Starting LightRAG with Gunicorn")
|
69 |
-
print(f"π Worker management: Gunicorn (workers={
|
70 |
print("π Preloading app: Enabled")
|
71 |
print("π Note: Using Gunicorn's preload feature for shared data initialization")
|
72 |
print("\n\n" + "=" * 80)
|
73 |
print("MAIN PROCESS INITIALIZATION")
|
74 |
print(f"Process ID: {os.getpid()}")
|
75 |
-
print(f"Workers setting: {
|
76 |
print("=" * 80 + "\n")
|
77 |
|
78 |
# Import Gunicorn's StandaloneApplication
|
@@ -128,31 +120,31 @@ def main():
|
|
128 |
|
129 |
# Set configuration variables in gunicorn_config, prioritizing command line arguments
|
130 |
gunicorn_config.workers = (
|
131 |
-
|
132 |
)
|
133 |
|
134 |
# Bind configuration prioritizes command line arguments
|
135 |
-
host =
|
136 |
-
port =
|
137 |
gunicorn_config.bind = f"{host}:{port}"
|
138 |
|
139 |
# Log level configuration prioritizes command line arguments
|
140 |
gunicorn_config.loglevel = (
|
141 |
-
|
142 |
-
if
|
143 |
else os.getenv("LOG_LEVEL", "info")
|
144 |
)
|
145 |
|
146 |
# Timeout configuration prioritizes command line arguments
|
147 |
gunicorn_config.timeout = (
|
148 |
-
|
149 |
)
|
150 |
|
151 |
# Keepalive configuration
|
152 |
gunicorn_config.keepalive = int(os.getenv("KEEPALIVE", 5))
|
153 |
|
154 |
# SSL configuration prioritizes command line arguments
|
155 |
-
if
|
156 |
"true",
|
157 |
"1",
|
158 |
"yes",
|
@@ -160,12 +152,12 @@ def main():
|
|
160 |
"on",
|
161 |
):
|
162 |
gunicorn_config.certfile = (
|
163 |
-
|
164 |
-
if
|
165 |
else os.getenv("SSL_CERTFILE")
|
166 |
)
|
167 |
gunicorn_config.keyfile = (
|
168 |
-
|
169 |
)
|
170 |
|
171 |
# Set configuration options from the module
|
@@ -190,13 +182,13 @@ def main():
|
|
190 |
# Import the application
|
191 |
from lightrag.api.lightrag_server import get_application
|
192 |
|
193 |
-
return get_application(
|
194 |
|
195 |
# Create the application
|
196 |
app = GunicornApp("")
|
197 |
|
198 |
# Force workers to be an integer and greater than 1 for multi-process mode
|
199 |
-
workers_count = int(
|
200 |
if workers_count > 1:
|
201 |
# Set a flag to indicate we're in the main process
|
202 |
os.environ["LIGHTRAG_MAIN_PROCESS"] = "1"
|
|
|
7 |
import sys
|
8 |
import signal
|
9 |
import pipmaster as pm
|
10 |
+
from lightrag.api.utils_api import display_splash_screen, check_env_file
|
11 |
from lightrag.kg.shared_storage import initialize_share_data, finalize_share_data
|
12 |
+
from .config import global_args
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
|
15 |
def check_and_install_dependencies():
|
|
|
54 |
signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
|
55 |
signal.signal(signal.SIGTERM, signal_handler) # kill command
|
56 |
|
|
|
|
|
|
|
57 |
# Display startup information
|
58 |
+
display_splash_screen(global_args)
|
59 |
|
60 |
print("π Starting LightRAG with Gunicorn")
|
61 |
+
print(f"π Worker management: Gunicorn (workers={global_args.workers})")
|
62 |
print("π Preloading app: Enabled")
|
63 |
print("π Note: Using Gunicorn's preload feature for shared data initialization")
|
64 |
print("\n\n" + "=" * 80)
|
65 |
print("MAIN PROCESS INITIALIZATION")
|
66 |
print(f"Process ID: {os.getpid()}")
|
67 |
+
print(f"Workers setting: {global_args.workers}")
|
68 |
print("=" * 80 + "\n")
|
69 |
|
70 |
# Import Gunicorn's StandaloneApplication
|
|
|
120 |
|
121 |
# Set configuration variables in gunicorn_config, prioritizing command line arguments
|
122 |
gunicorn_config.workers = (
|
123 |
+
global_args.workers if global_args.workers else int(os.getenv("WORKERS", 1))
|
124 |
)
|
125 |
|
126 |
# Bind configuration prioritizes command line arguments
|
127 |
+
host = global_args.host if global_args.host != "0.0.0.0" else os.getenv("HOST", "0.0.0.0")
|
128 |
+
port = global_args.port if global_args.port != 9621 else int(os.getenv("PORT", 9621))
|
129 |
gunicorn_config.bind = f"{host}:{port}"
|
130 |
|
131 |
# Log level configuration prioritizes command line arguments
|
132 |
gunicorn_config.loglevel = (
|
133 |
+
global_args.log_level.lower()
|
134 |
+
if global_args.log_level
|
135 |
else os.getenv("LOG_LEVEL", "info")
|
136 |
)
|
137 |
|
138 |
# Timeout configuration prioritizes command line arguments
|
139 |
gunicorn_config.timeout = (
|
140 |
+
global_args.timeout if global_args.timeout * 2 else int(os.getenv("TIMEOUT", 150 * 2))
|
141 |
)
|
142 |
|
143 |
# Keepalive configuration
|
144 |
gunicorn_config.keepalive = int(os.getenv("KEEPALIVE", 5))
|
145 |
|
146 |
# SSL configuration prioritizes command line arguments
|
147 |
+
if global_args.ssl or os.getenv("SSL", "").lower() in (
|
148 |
"true",
|
149 |
"1",
|
150 |
"yes",
|
|
|
152 |
"on",
|
153 |
):
|
154 |
gunicorn_config.certfile = (
|
155 |
+
global_args.ssl_certfile
|
156 |
+
if global_args.ssl_certfile
|
157 |
else os.getenv("SSL_CERTFILE")
|
158 |
)
|
159 |
gunicorn_config.keyfile = (
|
160 |
+
global_args.ssl_keyfile if global_args.ssl_keyfile else os.getenv("SSL_KEYFILE")
|
161 |
)
|
162 |
|
163 |
# Set configuration options from the module
|
|
|
182 |
# Import the application
|
183 |
from lightrag.api.lightrag_server import get_application
|
184 |
|
185 |
+
return get_application(global_args)
|
186 |
|
187 |
# Create the application
|
188 |
app = GunicornApp("")
|
189 |
|
190 |
# Force workers to be an integer and greater than 1 for multi-process mode
|
191 |
+
workers_count = int(global_args.workers)
|
192 |
if workers_count > 1:
|
193 |
# Set a flag to indicate we're in the main process
|
194 |
os.environ["LIGHTRAG_MAIN_PROCESS"] = "1"
|
lightrag/api/utils_api.py
CHANGED
@@ -10,12 +10,10 @@ from ascii_colors import ASCIIColors
|
|
10 |
from lightrag.api import __api_version__ as api_version
|
11 |
from lightrag import __version__ as core_version
|
12 |
from fastapi import HTTPException, Security, Request, status
|
13 |
-
from dotenv import load_dotenv
|
14 |
from fastapi.security import APIKeyHeader, OAuth2PasswordBearer
|
15 |
from starlette.status import HTTP_403_FORBIDDEN
|
16 |
from .auth import auth_handler
|
17 |
-
from .config import ollama_server_infos
|
18 |
-
from ..prompt import PROMPTS
|
19 |
|
20 |
|
21 |
def check_env_file():
|
@@ -36,14 +34,8 @@ def check_env_file():
|
|
36 |
return True
|
37 |
|
38 |
|
39 |
-
#
|
40 |
-
|
41 |
-
# the OS environment variables take precedence over the .env file
|
42 |
-
load_dotenv(dotenv_path=".env", override=False)
|
43 |
-
|
44 |
-
# Get whitelist paths from environment variable, only once during initialization
|
45 |
-
default_whitelist = "/health,/api/*"
|
46 |
-
whitelist_paths = os.getenv("WHITELIST_PATHS", default_whitelist).split(",")
|
47 |
|
48 |
# Pre-compile path matching patterns
|
49 |
whitelist_patterns: List[Tuple[str, bool]] = []
|
@@ -195,7 +187,7 @@ def display_splash_screen(args: argparse.Namespace) -> None:
|
|
195 |
ASCIIColors.white(" ββ Workers: ", end="")
|
196 |
ASCIIColors.yellow(f"{args.workers}")
|
197 |
ASCIIColors.white(" ββ CORS Origins: ", end="")
|
198 |
-
ASCIIColors.yellow(f"{
|
199 |
ASCIIColors.white(" ββ SSL Enabled: ", end="")
|
200 |
ASCIIColors.yellow(f"{args.ssl}")
|
201 |
if args.ssl:
|
@@ -252,10 +244,9 @@ def display_splash_screen(args: argparse.Namespace) -> None:
|
|
252 |
ASCIIColors.yellow(f"{args.embedding_dim}")
|
253 |
|
254 |
# RAG Configuration
|
255 |
-
summary_language = os.getenv("SUMMARY_LANGUAGE", PROMPTS["DEFAULT_LANGUAGE"])
|
256 |
ASCIIColors.magenta("\nβοΈ RAG Configuration:")
|
257 |
ASCIIColors.white(" ββ Summary Language: ", end="")
|
258 |
-
ASCIIColors.yellow(f"{summary_language}")
|
259 |
ASCIIColors.white(" ββ Max Parallel Insert: ", end="")
|
260 |
ASCIIColors.yellow(f"{args.max_parallel_insert}")
|
261 |
ASCIIColors.white(" ββ Max Embed Tokens: ", end="")
|
|
|
10 |
from lightrag.api import __api_version__ as api_version
|
11 |
from lightrag import __version__ as core_version
|
12 |
from fastapi import HTTPException, Security, Request, status
|
|
|
13 |
from fastapi.security import APIKeyHeader, OAuth2PasswordBearer
|
14 |
from starlette.status import HTTP_403_FORBIDDEN
|
15 |
from .auth import auth_handler
|
16 |
+
from .config import ollama_server_infos, global_args
|
|
|
17 |
|
18 |
|
19 |
def check_env_file():
|
|
|
34 |
return True
|
35 |
|
36 |
|
37 |
+
# Get whitelist paths from global_args, only once during initialization
|
38 |
+
whitelist_paths = global_args.whitelist_paths.split(",")
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
# Pre-compile path matching patterns
|
41 |
whitelist_patterns: List[Tuple[str, bool]] = []
|
|
|
187 |
ASCIIColors.white(" ββ Workers: ", end="")
|
188 |
ASCIIColors.yellow(f"{args.workers}")
|
189 |
ASCIIColors.white(" ββ CORS Origins: ", end="")
|
190 |
+
ASCIIColors.yellow(f"{args.cors_origins}")
|
191 |
ASCIIColors.white(" ββ SSL Enabled: ", end="")
|
192 |
ASCIIColors.yellow(f"{args.ssl}")
|
193 |
if args.ssl:
|
|
|
244 |
ASCIIColors.yellow(f"{args.embedding_dim}")
|
245 |
|
246 |
# RAG Configuration
|
|
|
247 |
ASCIIColors.magenta("\nβοΈ RAG Configuration:")
|
248 |
ASCIIColors.white(" ββ Summary Language: ", end="")
|
249 |
+
ASCIIColors.yellow(f"{args.summary_language}")
|
250 |
ASCIIColors.white(" ββ Max Parallel Insert: ", end="")
|
251 |
ASCIIColors.yellow(f"{args.max_parallel_insert}")
|
252 |
ASCIIColors.white(" ββ Max Embed Tokens: ", end="")
|