opex792 commited on
Commit
ea9d397
·
verified ·
1 Parent(s): f7984b2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -12
app.py CHANGED
@@ -51,6 +51,9 @@ 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"
53
 
 
 
 
54
  # Имена таблиц
55
  embeddings_table = "movie_embeddings"
56
  query_cache_table = "query_cache"
@@ -170,6 +173,23 @@ def get_movie_data_from_db(conn, movie_ids):
170
  logging.error(f"Ошибка при получении данных фильмов из БД: {e}")
171
  return movie_data_dict
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  def rerank_with_api(query, results, top_k, rerank_top_k=None):
174
  """Переранжирует результаты с помощью Jina AI Reranker API."""
175
  logging.info(f"Начало переранжирования для запроса: '{query}'")
@@ -195,10 +215,10 @@ def rerank_with_api(query, results, top_k, rerank_top_k=None):
195
  data = {
196
  "model": JINA_RERANKER_MODEL,
197
  "query": query,
198
- "top_n": rerank_top_k or top_k*2,
199
  "documents": documents
200
  }
201
- logging.info(f"Отправка данных на реранжировку (documents count): {len(data['documents'])}")
202
 
203
  try:
204
  response = requests.post(JINA_API_URL, headers=headers, json=data)
@@ -216,11 +236,11 @@ def rerank_with_api(query, results, top_k, rerank_top_k=None):
216
  logging.warning("Ответ от API не содержит ключа 'results'.")
217
 
218
  logging.info("Переранжирование завершено.")
219
- return reranked_results, True
220
 
221
  except requests.exceptions.RequestException as e:
222
  logging.error(f"Ошибка при запросе к API реранжировщика: {e}")
223
- return results, False
224
 
225
  def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None):
226
  """Внутренняя функция для поиска фильмов по запросу (используется и в Gradio, и в API)."""
@@ -250,6 +270,9 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None
250
  logging.error(f"Ошибка при сохранении эмбеддинга запроса: {e}")
251
  conn.rollback()
252
 
 
 
 
253
  # Используем косинусное расстояние для поиска
254
  try:
255
  with conn.cursor() as cur:
@@ -263,7 +286,7 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None
263
  FROM "{embeddings_table}" m, query_embedding
264
  ORDER BY similarity DESC
265
  LIMIT %s
266
- """, (query_crc32, int(top_k * 2)))
267
 
268
  results = cur.fetchall()
269
  logging.info(f"Найдено {len(results)} предварительных результатов поиска.")
@@ -274,11 +297,12 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None
274
  conn.close()
275
 
276
  # Переранжируем результаты с помощью API
277
- reranked_results, rerank_success = rerank_with_api(query, results, top_k, rerank_top_k)
278
-
279
  if not rerank_success:
280
  logging.warning("Переранжировка не удалась, используются сырые результаты.")
281
- reranked_results = results[:top_k] # Используем срез для ограничения количества результатов
 
282
  else:
283
  reranked_results = reranked_results[:top_k]
284
 
@@ -317,7 +341,8 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None
317
  "year": movie_data['year'],
318
  "genres": [genre['name'] for genre in movie_data['genres']],
319
  "description": movie_data.get('description', ''),
320
- "relevance_score": score if rerank_success else (movie_data_dict.get(movie_id, (None, None))[1] if movie_data_dict.get(movie_id, (None, None)) is not None else 0.0) # Сохраняем similarity, если нет реранжировки
 
321
  })
322
  else:
323
  logging.warning(f"Данные для фильма с ID {movie_id} не найдены в БД.")
@@ -325,19 +350,30 @@ def search_movies_internal(query: str, top_k: int = 25, rerank_top_k: int = None
325
  search_time = time.time() - start_time
326
  logging.info(f"Поиск выполнен за {search_time:.2f} секунд.")
327
 
 
 
328
  return {
329
  "status": "success",
330
  "results": formatted_results,
331
  "search_time": search_time,
332
  "total_movies": total_movies,
333
- "searched_movies": searched_movies
 
 
 
334
  }, search_time
335
 
336
  except Exception as e:
337
  logging.error(f"Ошибка при выполнении поиска: {e}")
338
  return {
339
  "status": "error",
340
- "message": str(e)
 
 
 
 
 
 
341
  }, 0
342
 
343
  @app.get("/search/", response_model=dict)
@@ -603,4 +639,4 @@ async def root():
603
 
604
  # Запускаем FastAPI
605
  if __name__ == "__main__":
606
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
51
  raise ValueError("JINA_API_KEY environment variable not set.")
52
  JINA_RERANKER_MODEL = "jina-reranker-v2-base-multilingual"
53
 
54
+ # Jina AI Dashboard API
55
+ JINA_DASHBOARD_API_URL = 'https://embeddings-dashboard-api.jina.ai/api/v1/api_key/user'
56
+
57
  # Имена таблиц
58
  embeddings_table = "movie_embeddings"
59
  query_cache_table = "query_cache"
 
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()
187
+ data = response.json()
188
+ return data['wallet']['total_balance']
189
+ except requests.exceptions.RequestException as e:
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}'")
 
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']}")
222
 
223
  try:
224
  response = requests.post(JINA_API_URL, headers=headers, json=data)
 
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)."""
 
270
  logging.error(f"Ошибка при сохранении эмбеддинга запроса: {e}")
271
  conn.rollback()
272
 
273
+ # Определяем количество фильмов для запроса из БД
274
+ db_limit = rerank_top_k or top_k * 2
275
+
276
  # Используем косинусное расстояние для поиска
277
  try:
278
  with conn.cursor() as cur:
 
286
  FROM "{embeddings_table}" m, query_embedding
287
  ORDER BY similarity DESC
288
  LIMIT %s
289
+ """, (query_crc32, int(db_limit)))
290
 
291
  results = cur.fetchall()
292
  logging.info(f"Найдено {len(results)} предварительных результатов поиска.")
 
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
 
 
341
  "year": movie_data['year'],
342
  "genres": [genre['name'] for genre in movie_data['genres']],
343
  "description": movie_data.get('description', ''),
344
+ "relevance_score": score if rerank_success else (
345
+ movie_data_dict.get(movie_id, (None, None))[1] if movie_data_dict.get(movie_id,(None, None)) is not None else 0.0) # Сохраняем similarity, если нет реранжировки
346
  })
347
  else:
348
  logging.warning(f"Данные для фильма с ID {movie_id} не найдены в БД.")
 
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",
357
  "results": formatted_results,
358
  "search_time": search_time,
359
  "total_movies": total_movies,
360
+ "searched_movies": searched_movies,
361
+ "returned_movies": len(formatted_results), # Количество возвращенных фильмов
362
+ "reranked_movies": reranked_count, # Количество фильмов, обработанных реранкером
363
+ "jina_balance": jina_balance # Остаток баланса Jina AI
364
  }, search_time
365
 
366
  except Exception as e:
367
  logging.error(f"Ошибка при выполнении поиска: {e}")
368
  return {
369
  "status": "error",
370
+ "message": str(e),
371
+ "search_time": 0,
372
+ "total_movies": 0,
373
+ "searched_movies": 0,
374
+ "returned_movies": 0,
375
+ "reranked_movies": 0,
376
+ "jina_balance": None
377
  }, 0
378
 
379
  @app.get("/search/", response_model=dict)
 
639
 
640
  # Запускаем FastAPI
641
  if __name__ == "__main__":
642
+ uvicorn.run(app, host="0.0.0.0")