opex792 commited on
Commit
857b65b
·
verified ·
1 Parent(s): 36923ec

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -19
app.py CHANGED
@@ -13,7 +13,7 @@ from sklearn.preprocessing import normalize
13
  from concurrent.futures import ThreadPoolExecutor
14
  import requests
15
  from fastapi import FastAPI, HTTPException, Query
16
- from typing import List
17
  import uvicorn
18
  from starlette.requests import Request
19
  from starlette.responses import HTMLResponse, JSONResponse
@@ -46,7 +46,7 @@ logging.info("Модель загружена успешно.")
46
 
47
  # Jina AI Reranker API
48
  JINA_API_URL = 'https://api.jina.ai/v1/rerank'
49
- JINA_API_KEY = os.environ.get("JINA_API_KEY")
50
  if JINA_API_KEY is None:
51
  raise ValueError("JINA_API_KEY environment variable not set.")
52
  JINA_RERANKER_MODEL = "jina-reranker-v2-base-multilingual"
@@ -173,14 +173,14 @@ def get_movie_data_from_db(conn, movie_ids):
173
  logging.error(f"Ошибка при получении данных фильмов из БД: {e}")
174
  return movie_data_dict
175
 
176
- def get_jina_ai_balance():
177
  """Получает остаток баланса Jina AI."""
178
  try:
179
  headers = {
180
  'Content-Type': 'application/json'
181
  }
182
  params = {
183
- 'api_key': JINA_API_KEY
184
  }
185
  response = requests.get(JINA_DASHBOARD_API_URL, headers=headers, params=params)
186
  response.raise_for_status()
@@ -190,10 +190,15 @@ def get_jina_ai_balance():
190
  logging.error(f"Ошибка при запросе к API баланса Jina AI: {e}")
191
  return None
192
 
193
- def rerank_with_api(query, results, top_k, rerank_top_k=None):
194
  """Переранжирует результаты с помощью Jina AI Reranker API."""
195
  logging.info(f"Начало переранжирования для запроса: '{query}'")
196
 
 
 
 
 
 
197
  # Получаем данные фильмов из БД
198
  conn = get_db_connection()
199
  movie_ids = [movie_id for movie_id, _ in results]
@@ -208,14 +213,16 @@ def rerank_with_api(query, results, top_k, rerank_top_k=None):
208
  else:
209
  logging.warning(f"Данные для фильма с ID {movie_id} не найдены в БД.")
210
 
 
 
211
  headers = {
212
  'Content-Type': 'application/json',
213
- 'Authorization': f'Bearer {JINA_API_KEY}'
214
  }
215
  data = {
216
  "model": JINA_RERANKER_MODEL,
217
  "query": query,
218
- "top_n": rerank_top_k or top_k * 2,
219
  "documents": documents
220
  }
221
  logging.info(f"Отправка данных на реранжировку (documents count): {len(data['documents'])}, top_n: {data['top_n']}")
@@ -236,13 +243,13 @@ def rerank_with_api(query, results, top_k, rerank_top_k=None):
236
  logging.warning("Ответ от API не содержит ключа 'results'.")
237
 
238
  logging.info("Переранжирование завершено.")
239
- return reranked_results, True, data["top_n"]
240
 
241
  except requests.exceptions.RequestException as e:
242
  logging.error(f"Ошибка при запросе к API реранжировщика: {e}")
243
- return results, False, data["top_n"]
244
 
245
- def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None):
246
  """Внутренняя функция для поиска фильмов по запросу (используется и в Gradio, и в API)."""
247
  start_time = time.time()
248
 
@@ -295,14 +302,18 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None
295
  results = []
296
  finally:
297
  conn.close()
298
-
299
- # Переранжируем результаты с помощью API
300
- reranked_results, rerank_success, reranked_count = rerank_with_api(query, results, top_k, rerank_top_k)
 
 
 
 
 
301
 
302
  if not rerank_success:
303
  logging.warning("Переранжировка не удалась, ис��ользуются сырые результаты.")
304
  reranked_results = results[:top_k] # Используем срез для ограничения количества результатов
305
- reranked_count = 0
306
  else:
307
  reranked_results = reranked_results[:top_k]
308
 
@@ -350,7 +361,7 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None
350
  search_time = time.time() - start_time
351
  logging.info(f"Поиск выполнен за {search_time:.2f} секунд.")
352
 
353
- jina_balance = get_jina_ai_balance()
354
 
355
  return {
356
  "status": "success",
@@ -377,12 +388,35 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None
377
  }, 0
378
 
379
  @app.get("/search/", response_model=dict)
380
- async def api_search_movies(query: str = Query(..., description="Поисковый запрос"),
381
  top_k: int = Query(25, description="Количество возвращаемых результатов"),
382
- rerank_top_k: int = Query(None, description="Количество фильмов для передачи в реранкер (если не указано, то top_k*2)")):
383
- """API endpoint для поиска фильмов."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  try:
385
- results, _ = search_movies_internal(query, top_k, rerank_top_k)
386
  return results
387
  except Exception as e:
388
  raise HTTPException(status_code=500, detail=str(e))
 
13
  from concurrent.futures import ThreadPoolExecutor
14
  import requests
15
  from fastapi import FastAPI, HTTPException, Query
16
+ from typing import List, Optional
17
  import uvicorn
18
  from starlette.requests import Request
19
  from starlette.responses import HTMLResponse, JSONResponse
 
46
 
47
  # Jina AI Reranker API
48
  JINA_API_URL = 'https://api.jina.ai/v1/rerank'
49
+ JINA_API_KEY = os.environ.get("JINA_API_KEY") # Используем переменную окружения
50
  if JINA_API_KEY is None:
51
  raise ValueError("JINA_API_KEY environment variable not set.")
52
  JINA_RERANKER_MODEL = "jina-reranker-v2-base-multilingual"
 
173
  logging.error(f"Ошибка при получении данных фильмов из БД: {e}")
174
  return movie_data_dict
175
 
176
+ def get_jina_ai_balance(api_key: str):
177
  """Получает остаток баланса Jina AI."""
178
  try:
179
  headers = {
180
  'Content-Type': 'application/json'
181
  }
182
  params = {
183
+ 'api_key': api_key
184
  }
185
  response = requests.get(JINA_DASHBOARD_API_URL, headers=headers, params=params)
186
  response.raise_for_status()
 
190
  logging.error(f"Ошибка при запросе к API баланса Jina AI: {e}")
191
  return None
192
 
193
+ def rerank_with_api(query, results, top_k, rerank_top_k=None, api_key=None):
194
  """Переранжирует результаты с помощью Jina AI Reranker API."""
195
  logging.info(f"Начало переранжирования для запроса: '{query}'")
196
 
197
+ # Если rerank_top_k равен 0, не используем реранкер
198
+ if rerank_top_k == 0:
199
+ logging.info("Переранжирование отключено (rerank_top_k = 0).")
200
+ return results, False, 0
201
+
202
  # Получаем данные фильмов из БД
203
  conn = get_db_connection()
204
  movie_ids = [movie_id for movie_id, _ in results]
 
213
  else:
214
  logging.warning(f"Данные для фильма с ID {movie_id} не найдены в БД.")
215
 
216
+ reranked_count = min(rerank_top_k or top_k*2, len(documents))
217
+
218
  headers = {
219
  'Content-Type': 'application/json',
220
+ 'Authorization': f'Bearer {api_key or JINA_API_KEY}'
221
  }
222
  data = {
223
  "model": JINA_RERANKER_MODEL,
224
  "query": query,
225
+ "top_n": rerank_top_k or top_k*2,
226
  "documents": documents
227
  }
228
  logging.info(f"Отправка данных на реранжировку (documents count): {len(data['documents'])}, top_n: {data['top_n']}")
 
243
  logging.warning("Ответ от API не содержит ключа 'results'.")
244
 
245
  logging.info("Переранжирование завершено.")
246
+ return reranked_results, True, reranked_count
247
 
248
  except requests.exceptions.RequestException as e:
249
  logging.error(f"Ошибка при запросе к API реранжировщика: {e}")
250
+ return results, False, reranked_count
251
 
252
+ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: Optional[int] = None, jina_api_key: Optional[str] = None):
253
  """Внутренняя функция для поиска фильмов по запросу (используется и в Gradio, и в API)."""
254
  start_time = time.time()
255
 
 
302
  results = []
303
  finally:
304
  conn.close()
305
+
306
+ # Используем реранкер только если rerank_top_k не равен 0
307
+ if rerank_top_k != 0:
308
+ reranked_results, rerank_success, reranked_count = rerank_with_api(query, results, top_k, rerank_top_k, jina_api_key)
309
+ else:
310
+ reranked_results = results
311
+ rerank_success = False
312
+ reranked_count = 0
313
 
314
  if not rerank_success:
315
  logging.warning("Переранжировка не удалась, ис��ользуются сырые результаты.")
316
  reranked_results = results[:top_k] # Используем срез для ограничения количества результатов
 
317
  else:
318
  reranked_results = reranked_results[:top_k]
319
 
 
361
  search_time = time.time() - start_time
362
  logging.info(f"Поиск выполнен за {search_time:.2f} секунд.")
363
 
364
+ jina_balance = get_jina_ai_balance(jina_api_key or JINA_API_KEY)
365
 
366
  return {
367
  "status": "success",
 
388
  }, 0
389
 
390
  @app.get("/search/", response_model=dict)
391
+ async def api_search_movies(query: str = Query(..., description="Поисковый запрос"),
392
  top_k: int = Query(25, description="Количество возвращаемых результатов"),
393
+ rerank_top_k: Optional[int] = Query(None, description="Количество фильмов для передачи в реранкер (если не указано, то top_k*2)"),
394
+ jina_api_key: Optional[str] = Query(None, description="API ключ Jina AI (если не указан, используется значение из переменной окружения JINA_API_KEY)")):
395
+ """
396
+ API endpoint для поиска фильмов.
397
+
398
+ Parameters
399
+ ----------
400
+ query : str
401
+ Поисковый запрос.
402
+ top_k : int, optional
403
+ Количество возвращаемых результатов, по умолчанию 25.
404
+ rerank_top_k : Optional[int], optional
405
+ Количество фильмов для передачи в реранкер.
406
+ Если 0 - реранкер не используется.
407
+ Если не указано, то используется top_k*2.
408
+ По умолчанию None.
409
+ jina_api_key : Optional[str], optional
410
+ API ключ Jina AI. Если не указан, используется значение из переменной окружения JINA_API_KEY.
411
+ По умолчанию None.
412
+
413
+ Returns
414
+ -------
415
+ dict
416
+ Словарь с результатами поиска.
417
+ """
418
  try:
419
+ results, _ = search_movies_internal(query, top_k, rerank_top_k, jina_api_key)
420
  return results
421
  except Exception as e:
422
  raise HTTPException(status_code=500, detail=str(e))