144 lines
5.8 KiB
Python
144 lines
5.8 KiB
Python
from fastapi import FastAPI, HTTPException
|
||
from pydantic import BaseModel
|
||
from fastapi.middleware.cors import CORSMiddleware
|
||
|
||
from new_parser_test import parse_request
|
||
from geocoder import validate_address
|
||
from database import search_database
|
||
from route import build_route
|
||
from ouput_chat import RouteDescriber
|
||
|
||
app = FastAPI(title="AI API")
|
||
|
||
# ======== FASTAPI СХЕМЫ ==========
|
||
|
||
class ChatRequest(BaseModel):
|
||
user_input: str
|
||
conversation_history: list | None = None
|
||
|
||
class ChatResponse(BaseModel):
|
||
success: bool
|
||
need_more_info: bool
|
||
# result теперь может содержать как промежуточные данные парсера,
|
||
# так и финальный маршрут с описанием
|
||
result: dict
|
||
conversation_history: list
|
||
error: str | None = None
|
||
|
||
# =================================
|
||
|
||
@app.post("/chat", response_model=ChatResponse)
|
||
def chat_endpoint(request: ChatRequest):
|
||
try:
|
||
# 1. Вызываем парсер, чтобы извлечь информацию из диалога
|
||
parser_response = parse_request(request.user_input, request.conversation_history)
|
||
|
||
# 2. Проверяем условие: парсер отработал успешно и больше информации не нужно
|
||
if parser_response["success"] and not parser_response["need_more_info"]:
|
||
# --- Логика построения маршрута ---
|
||
|
||
parsed_data = parser_response["result"]
|
||
tags = parsed_data.get("tags")
|
||
print(tags)
|
||
user_address = parsed_data.get("user_location")
|
||
print(user_address)
|
||
user_time = parsed_data.get("time")
|
||
print(user_time)
|
||
conversation_history = parser_response["conversation_history"]
|
||
|
||
# Валидация адреса
|
||
val_output = validate_address('addresses.sqlite', user_address)
|
||
if not val_output or not val_output['valid']:
|
||
return ChatResponse(
|
||
success=False,
|
||
need_more_info=False,
|
||
result={},
|
||
conversation_history=conversation_history,
|
||
error=f"Не удалось распознать адрес: {user_address}. Пожалуйста, попробуйте указать его точнее."
|
||
)
|
||
|
||
user_position = [
|
||
val_output['coordinates']['lat'],
|
||
val_output['coordinates']['lon']
|
||
]
|
||
|
||
# Поиск точек в базе данных
|
||
found_points, mapping = search_database('output.json', tags)
|
||
if not found_points:
|
||
return ChatResponse(
|
||
success=False,
|
||
need_more_info=False,
|
||
result={},
|
||
conversation_history=conversation_history,
|
||
error="К сожалению, я не смог найти подходящих мест по вашему запросу."
|
||
)
|
||
|
||
print(mapping)
|
||
|
||
# Построение маршрута
|
||
n_nodes = len(mapping)
|
||
allow_extend = any(v[1] for v in mapping.values())
|
||
|
||
route_otp = None
|
||
if allow_extend:
|
||
while n_nodes <= 5 and (route_otp := build_route(found_points, mapping, user_position, user_time, n_nodes,strategy='random') or route_otp): n_nodes += 1
|
||
else:
|
||
route_otp= build_route(found_points, mapping, user_position, user_time, n_nodes,strategy='random')
|
||
|
||
if not route_otp:
|
||
return ChatResponse(
|
||
success=False,
|
||
need_more_info=False,
|
||
result={},
|
||
conversation_history=conversation_history,
|
||
error="Не удалось построить маршрут с указанными параметрами. Попробуйте изменить запрос."
|
||
)
|
||
|
||
route, places = route_otp
|
||
route.insert(0, user_position)
|
||
|
||
# Генерация описания маршрута
|
||
describer = RouteDescriber()
|
||
description = describer.generate_route_description(places, conversation_history)
|
||
|
||
# Финальный успешный ответ с маршрутом
|
||
return ChatResponse(
|
||
success=True,
|
||
need_more_info=False,
|
||
result={
|
||
"route": route,
|
||
"description": description,
|
||
"places": places
|
||
},
|
||
conversation_history=conversation_history,
|
||
error=None
|
||
)
|
||
|
||
else:
|
||
# 3. Если парсеру нужно больше информации или он завершился неуспешно,
|
||
# просто возвращаем его ответ пользователю.
|
||
# `ChatResponse` и словарь от `parse_request` имеют одинаковую структуру.
|
||
return ChatResponse(**parser_response)
|
||
|
||
except Exception as e:
|
||
# Отлавливаем любые другие непредвиденные ошибки
|
||
# В рабочей среде здесь лучше добавить логирование
|
||
print(f"An unexpected error occurred: {e}")
|
||
raise HTTPException(status_code=500, detail="Произошла внутренняя ошибка сервера.")
|
||
|
||
|
||
origins = [
|
||
"http://localhost",
|
||
"http://localhost:5173",
|
||
"https://gorkycode.nikidze.ru"
|
||
]
|
||
|
||
app.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=origins,
|
||
allow_credentials=True,
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
max_age=3600
|
||
)
|