Update app.py
Browse files
app.py
CHANGED
|
@@ -19,6 +19,7 @@ from starlette.requests import Request
|
|
| 19 |
from starlette.responses import HTMLResponse, JSONResponse
|
| 20 |
from fastapi.responses import HTMLResponse
|
| 21 |
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
| 22 |
|
| 23 |
# Настройка логирования
|
| 24 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
@@ -71,6 +72,9 @@ app.add_middleware(
|
|
| 71 |
allow_headers=["*"],
|
| 72 |
)
|
| 73 |
|
|
|
|
|
|
|
|
|
|
| 74 |
def get_db_connection():
|
| 75 |
"""Устанавливает соединение с базой данных."""
|
| 76 |
try:
|
|
@@ -172,13 +176,8 @@ def get_movie_data_from_db(conn, movie_ids):
|
|
| 172 |
WHERE id IN %s
|
| 173 |
""", (tuple(movie_ids),))
|
| 174 |
for movie_id, movie_data, prepared_json in cur.fetchall():
|
| 175 |
-
prepared_string
|
| 176 |
-
|
| 177 |
-
f"Год: {prepared_json['Год']}\n"
|
| 178 |
-
f"Жанры: {prepared_json['Жанры']}\n"
|
| 179 |
-
f"Описание: {prepared_json['Описание']}"
|
| 180 |
-
)
|
| 181 |
-
movie_data_dict[movie_id] = (movie_data, prepared_string, prepared_json)
|
| 182 |
except Exception as e:
|
| 183 |
logging.error(f"Ошибка при получении данных фильмов из БД: {e}")
|
| 184 |
return movie_data_dict
|
|
@@ -217,8 +216,15 @@ def rerank_with_api(query, results, top_k, rerank_top_k=None, api_key=None):
|
|
| 217 |
|
| 218 |
documents = []
|
| 219 |
for movie_id, _ in results:
|
| 220 |
-
movie_data,
|
| 221 |
if movie_data:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
documents.append(prepared_string)
|
| 223 |
else:
|
| 224 |
logging.warning(f"Данные для фильма с ID {movie_id} не найдены в БД.")
|
|
@@ -323,7 +329,7 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: Optional[i
|
|
| 323 |
results = []
|
| 324 |
finally:
|
| 325 |
conn.close()
|
| 326 |
-
|
| 327 |
# Используем реранкер только если rerank_top_k не равен 0
|
| 328 |
if rerank_top_k != 0:
|
| 329 |
reranked_results, rerank_success, reranked_count = rerank_with_api(query, results, top_k, rerank_top_k, jina_api_key)
|
|
@@ -364,7 +370,7 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: Optional[i
|
|
| 364 |
|
| 365 |
formatted_results = []
|
| 366 |
for movie_id, score in reranked_results:
|
| 367 |
-
movie_data,
|
| 368 |
if movie_data:
|
| 369 |
formatted_results.append({
|
| 370 |
"movie_id": movie_id,
|
|
@@ -374,8 +380,7 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: Optional[i
|
|
| 374 |
"description": prepared_json['Описание'],
|
| 375 |
"poster_preview_url": prepared_json['Постер'],
|
| 376 |
"rating_kp": prepared_json['Рейтинг'],
|
| 377 |
-
"relevance_score": score if rerank_success else
|
| 378 |
-
movie_data_dict.get(movie_id, (None, None, None))[1] if movie_data_dict.get(movie_id, (None, None, None)) is not None else 0.0)
|
| 379 |
})
|
| 380 |
else:
|
| 381 |
logging.warning(f"Данные для фильма с ID {movie_id} не найдены в БД.")
|
|
@@ -391,9 +396,9 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: Optional[i
|
|
| 391 |
"search_time": search_time,
|
| 392 |
"total_movies": total_movies,
|
| 393 |
"searched_movies": searched_movies,
|
| 394 |
-
"returned_movies": len(formatted_results),
|
| 395 |
-
"reranked_movies": reranked_count,
|
| 396 |
-
"jina_balance": jina_balance
|
| 397 |
}, search_time
|
| 398 |
|
| 399 |
except Exception as e:
|
|
@@ -727,8 +732,13 @@ async def root():
|
|
| 727 |
const movieCard = document.createElement('div');
|
| 728 |
movieCard.className = 'movie-card';
|
| 729 |
const ratingColor = getRatingColor(movie.rating_kp);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 730 |
movieCard.innerHTML = `
|
| 731 |
-
<img src="${
|
| 732 |
<div class="movie-info">
|
| 733 |
<div class="top-info">
|
| 734 |
<span class="movie-year">${movie.year}</span>
|
|
|
|
| 19 |
from starlette.responses import HTMLResponse, JSONResponse
|
| 20 |
from fastapi.responses import HTMLResponse
|
| 21 |
from fastapi.middleware.cors import CORSMiddleware
|
| 22 |
+
from fastapi.staticfiles import StaticFiles
|
| 23 |
|
| 24 |
# Настройка логирования
|
| 25 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
|
| 72 |
allow_headers=["*"],
|
| 73 |
)
|
| 74 |
|
| 75 |
+
# Добавляем монтирование static файлов для 404.png
|
| 76 |
+
app.mount("/static", StaticFiles(directory="static"), name="static")
|
| 77 |
+
|
| 78 |
def get_db_connection():
|
| 79 |
"""Устанавливает соединение с базой данных."""
|
| 80 |
try:
|
|
|
|
| 176 |
WHERE id IN %s
|
| 177 |
""", (tuple(movie_ids),))
|
| 178 |
for movie_id, movie_data, prepared_json in cur.fetchall():
|
| 179 |
+
# Исправлено: убрано формирование prepared_string, так как оно больше не используется для вывода relevance_score
|
| 180 |
+
movie_data_dict[movie_id] = (movie_data, prepared_json)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
except Exception as e:
|
| 182 |
logging.error(f"Ошибка при получении данных фильмов из БД: {e}")
|
| 183 |
return movie_data_dict
|
|
|
|
| 216 |
|
| 217 |
documents = []
|
| 218 |
for movie_id, _ in results:
|
| 219 |
+
movie_data, prepared_json = movie_data_dict.get(movie_id, (None, None))
|
| 220 |
if movie_data:
|
| 221 |
+
# Исправлено: добавлено формирование строки, так как она используется в data
|
| 222 |
+
prepared_string = (
|
| 223 |
+
f"Название: {prepared_json['Название']}\n"
|
| 224 |
+
f"Год: {prepared_json['Год']}\n"
|
| 225 |
+
f"Жанры: {prepared_json['Жанры']}\n"
|
| 226 |
+
f"Описание: {prepared_json['Описание']}"
|
| 227 |
+
)
|
| 228 |
documents.append(prepared_string)
|
| 229 |
else:
|
| 230 |
logging.warning(f"Данные для фильма с ID {movie_id} не найдены в БД.")
|
|
|
|
| 329 |
results = []
|
| 330 |
finally:
|
| 331 |
conn.close()
|
| 332 |
+
|
| 333 |
# Используем реранкер только если rerank_top_k не равен 0
|
| 334 |
if rerank_top_k != 0:
|
| 335 |
reranked_results, rerank_success, reranked_count = rerank_with_api(query, results, top_k, rerank_top_k, jina_api_key)
|
|
|
|
| 370 |
|
| 371 |
formatted_results = []
|
| 372 |
for movie_id, score in reranked_results:
|
| 373 |
+
movie_data, prepared_json = movie_data_dict.get(movie_id, (None, None))
|
| 374 |
if movie_data:
|
| 375 |
formatted_results.append({
|
| 376 |
"movie_id": movie_id,
|
|
|
|
| 380 |
"description": prepared_json['Описание'],
|
| 381 |
"poster_preview_url": prepared_json['Постер'],
|
| 382 |
"rating_kp": prepared_json['Рейтинг'],
|
| 383 |
+
"relevance_score": score if rerank_success else 0.0 # Возвращаем 0 если реранжировка не проводилась
|
|
|
|
| 384 |
})
|
| 385 |
else:
|
| 386 |
logging.warning(f"Данные для фильма с ID {movie_id} не найдены в БД.")
|
|
|
|
| 396 |
"search_time": search_time,
|
| 397 |
"total_movies": total_movies,
|
| 398 |
"searched_movies": searched_movies,
|
| 399 |
+
"returned_movies": len(formatted_results), # Количество возвращенных фильмов
|
| 400 |
+
"reranked_movies": reranked_count, # Количество фильмов, обработанных реранкером
|
| 401 |
+
"jina_balance": jina_balance # Остаток баланса Jina AI
|
| 402 |
}, search_time
|
| 403 |
|
| 404 |
except Exception as e:
|
|
|
|
| 732 |
const movieCard = document.createElement('div');
|
| 733 |
movieCard.className = 'movie-card';
|
| 734 |
const ratingColor = getRatingColor(movie.rating_kp);
|
| 735 |
+
let posterUrl = movie.poster_preview_url;
|
| 736 |
+
if (!posterUrl) {
|
| 737 |
+
posterUrl = '/static/404.png';
|
| 738 |
+
}
|
| 739 |
+
|
| 740 |
movieCard.innerHTML = `
|
| 741 |
+
<img src="${posterUrl}" alt="${movie.name}" class="movie-poster" onerror="this.onerror=null;this.src='/static/404.png';">
|
| 742 |
<div class="movie-info">
|
| 743 |
<div class="top-info">
|
| 744 |
<span class="movie-year">${movie.year}</span>
|