|
import os |
|
import sys |
|
import threading |
|
import time |
|
import requests |
|
from requests.exceptions import ConnectionError |
|
|
|
os.environ['MPLCONFIGDIR'] = os.path.join(os.getcwd(), 'cache', 'matplotlib') |
|
os.makedirs(os.environ['MPLCONFIGDIR'], exist_ok=True) |
|
|
|
import gradio as gr |
|
import uvicorn |
|
from fastapi import FastAPI |
|
from fastapi.responses import HTMLResponse |
|
|
|
|
|
current_dir = os.path.abspath(os.path.dirname(__file__)) |
|
if current_dir not in sys.path: |
|
sys.path.insert(0, current_dir) |
|
|
|
|
|
from api.fastapi_server import app as fastapi_app |
|
|
|
def wait_for_fastapi(timeout=30, interval=0.5): |
|
"""Wait for FastAPI server to start""" |
|
start_time = time.time() |
|
while time.time() - start_time < timeout: |
|
try: |
|
response = requests.get("http://127.0.0.1:7860/health") |
|
if response.status_code == 200: |
|
print("FastAPI server is ready!") |
|
return True |
|
except ConnectionError: |
|
time.sleep(interval) |
|
return False |
|
|
|
|
|
|
|
|
|
def run_fastapi(): |
|
import multiprocessing |
|
multiprocessing.Process(target=uvicorn.run, args=(fastapi_app,), kwargs={"host": "0.0.0.0", "port": 7860}).start() |
|
|
|
|
|
|
|
fastapi_thread = threading.Thread(target=run_fastapi, daemon=True) |
|
fastapi_thread.start() |
|
|
|
|
|
if not wait_for_fastapi(): |
|
print("Failed to start FastAPI server") |
|
sys.exit(1) |
|
|
|
|
|
def respond(message, history, conversation_id=None): |
|
"""Handle chat messages and update conversation history""" |
|
if not message: |
|
return history, conversation_id |
|
|
|
try: |
|
|
|
response = requests.post( |
|
"http://127.0.0.1:7860/chat", |
|
json={"message": message, "conversation_id": conversation_id} |
|
) |
|
|
|
if response.status_code == 200: |
|
data = response.json() |
|
|
|
history = history + [(message, data["response"])] |
|
return history, data["conversation_id"] |
|
else: |
|
error_message = f"Error: {response.status_code} - {response.text}" |
|
history = history + [(message, error_message)] |
|
return history, conversation_id |
|
|
|
except Exception as e: |
|
error_message = f"Error connecting to API: {str(e)}" |
|
history = history + [(message, error_message)] |
|
return history, conversation_id |
|
|
|
def build_kb(): |
|
try: |
|
response = requests.post("http://127.0.0.1:7860/build-kb") |
|
if response.status_code == 200: |
|
return f"Success: {response.json()['message']}" |
|
else: |
|
return f"Error: {response.status_code} - {response.text}" |
|
except Exception as e: |
|
return f"API connection error: {str(e)}" |
|
|
|
def get_kb_size(): |
|
"""Calculate actual knowledge base size from files""" |
|
vector_store_path = "vector_store" |
|
try: |
|
total_size = 0 |
|
for file in ["index.faiss", "index.pkl"]: |
|
file_path = os.path.join(vector_store_path, file) |
|
if os.path.exists(file_path): |
|
total_size += os.path.getsize(file_path) |
|
return total_size / (1024 * 1024) |
|
except Exception: |
|
return None |
|
|
|
|
|
def check_kb_status(): |
|
try: |
|
response = requests.get("http://127.0.0.1:7860/status") |
|
if response.status_code == 200: |
|
data = response.json() |
|
if data["knowledge_base_exists"]: |
|
kb_info = data["kb_info"] |
|
version = kb_info.get('version', 'N/A') |
|
|
|
|
|
actual_size = get_kb_size() |
|
size_text = f"{actual_size:.2f} MB" if actual_size is not None else "N/A" |
|
|
|
return f"✅ База знаний готова к работе\nВерсия: {version}\nРазмер: {size_text}" |
|
else: |
|
|
|
if os.path.exists(os.path.join("vector_store", "index.faiss")): |
|
actual_size = get_kb_size() |
|
size_text = f"{actual_size:.2f} MB" if actual_size is not None else "N/A" |
|
return f"✅ База знаний найдена на диске\nРазмер: {size_text}\nТребуется перезагрузка сервера" |
|
return "❌ База знаний не создана. Нажмите кнопку 'Create/Update Knowledge Base'" |
|
except Exception as e: |
|
|
|
if os.path.exists(os.path.join("vector_store", "index.faiss")): |
|
actual_size = get_kb_size() |
|
size_text = f"{actual_size:.2f} MB" if actual_size is not None else "N/A" |
|
return f"⚠️ Ошибка соединения, но база знаний существует\nРазмер: {size_text}" |
|
return f"❌ Ошибка проверки статуса: {str(e)}" |
|
|
|
def clear_history(): |
|
"""Reset chat history and conversation ID""" |
|
return [], None |
|
|
|
|
|
demo = gr.Blocks(title="Status Law Assistant", theme=gr.themes.Soft()) |
|
with demo: |
|
|
|
conversation_id = gr.State(None) |
|
|
|
gr.Markdown("# 🤖 Status Law Assistant") |
|
|
|
with gr.Row(): |
|
|
|
with gr.Column(scale=3): |
|
chatbot = gr.Chatbot( |
|
label="Conversation", |
|
height=600, |
|
show_label=False, |
|
bubble_full_width=False |
|
) |
|
with gr.Row(): |
|
msg = gr.Textbox( |
|
label="Enter your question here", |
|
placeholder="Type your message and press Enter...", |
|
scale=4 |
|
) |
|
submit_btn = gr.Button("Send", variant="primary", scale=1) |
|
|
|
|
|
with gr.Column(scale=1): |
|
gr.Markdown("### Knowledge Base Controls") |
|
build_kb_btn = gr.Button("Create/Update Knowledge Base", variant="primary") |
|
check_status_btn = gr.Button("Check Status") |
|
kb_status = gr.Textbox( |
|
label="Knowledge Base Status", |
|
value="Checking status...", |
|
interactive=False |
|
) |
|
|
|
gr.Markdown("### Chat Controls") |
|
clear_btn = gr.Button("Clear Chat History") |
|
|
|
|
|
with gr.Accordion("ℹ️ How to use", open=False): |
|
gr.Markdown(""" |
|
1. First, click **Create/Update Knowledge Base** button |
|
2. Wait for confirmation message |
|
3. Enter your question in the text field and press Enter or "Send" button |
|
4. Use "Clear Chat History" to start a new conversation |
|
""") |
|
|
|
|
|
msg.submit(respond, [msg, chatbot, conversation_id], [chatbot, conversation_id]) |
|
submit_btn.click(respond, [msg, chatbot, conversation_id], [chatbot, conversation_id]) |
|
clear_btn.click(clear_history, None, [chatbot, conversation_id]) |
|
build_kb_btn.click(build_kb, inputs=None, outputs=kb_status) |
|
check_status_btn.click(check_kb_status, inputs=None, outputs=kb_status) |
|
|
|
|
|
app = gr.mount_gradio_app(fastapi_app, demo, path="/") |
|
|
|
if __name__ == "__main__": |
|
|
|
import uvicorn |
|
uvicorn.run(app, host="0.0.0.0", port=7860) |
|
|
|
|