Calcifer0323 commited on
Commit
a9ab2f8
·
1 Parent(s): 9ca349e

Add reindex endpoints for updating entity embeddings

Browse files

- Added POST /reindex endpoint for single entity reindexing
- Added POST /reindex-batch endpoint for batch reindexing
- Updated root endpoint to show new reindex endpoints
- Improved documentation with clear use cases for create vs update operations

Files changed (1) hide show
  1. main.py +108 -2
main.py CHANGED
@@ -195,8 +195,10 @@ async def root():
195
  "description": "Генерирует эмбеддинги. Хранение на стороне Go Backend + pgvector.",
196
  "endpoints": {
197
  "POST /embed": "Эмбеддинг из готового текста",
198
- "POST /prepare-and-embed": "Подготовка полей + эмбеддинг (ОСНОВНОЙ)",
199
- "POST /batch": "Пакетная обработка",
 
 
200
  "GET /health": "Проверка здоровья",
201
  "GET /model-info": "Информация о модели для pgvector"
202
  },
@@ -380,3 +382,107 @@ LIMIT 10;
380
  """.strip()
381
  }
382
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  "description": "Генерирует эмбеддинги. Хранение на стороне Go Backend + pgvector.",
196
  "endpoints": {
197
  "POST /embed": "Эмбеддинг из готового текста",
198
+ "POST /prepare-and-embed": "Подготовка полей + эмбеддинг (создание)",
199
+ "POST /reindex": "Переиндексация объекта (обновление)",
200
+ "POST /batch": "Пакетная обработка (создание)",
201
+ "POST /reindex-batch": "Пакетная переиндексация (обновление)",
202
  "GET /health": "Проверка здоровья",
203
  "GET /model-info": "Информация о модели для pgvector"
204
  },
 
382
  """.strip()
383
  }
384
  }
385
+
386
+
387
+ # ============== Reindex Endpoint ==============
388
+
389
+ class ReindexRequest(BaseModel):
390
+ """
391
+ Запрос на переиндексацию объекта.
392
+
393
+ Используется когда пользователь обновил лида/объект и нужно
394
+ пересоздать эмбеддинг.
395
+ """
396
+ entity_id: str = Field(..., description="ID объекта для переиндексации")
397
+ entity_type: str = Field(default="lead", description="Тип: 'lead' или 'property'")
398
+ title: str = Field(default="", description="Название")
399
+ description: str = Field(default="", description="Описание")
400
+ requirement: Optional[Dict[str, Any]] = Field(default=None, description="Требования (JSON)")
401
+ price: Optional[float] = Field(default=None, description="Цена")
402
+ district: Optional[str] = Field(default=None, description="Район")
403
+ rooms: Optional[int] = Field(default=None, description="Количество комнат")
404
+ area: Optional[float] = Field(default=None, description="Площадь")
405
+ address: Optional[str] = Field(default=None, description="Адрес")
406
+
407
+
408
+ class ReindexResponse(BaseModel):
409
+ """Ответ на переиндексацию."""
410
+ entity_id: str
411
+ entity_type: str
412
+ embedding: List[float]
413
+ dimensions: int
414
+ prepared_text: str
415
+ message: str = Field(default="Reindex successful. Update embedding in your database.")
416
+
417
+
418
+ @app.post("/reindex", response_model=ReindexResponse)
419
+ async def reindex_entity(request: ReindexRequest):
420
+ """
421
+ Переиндексация объекта (лида или недвижимости).
422
+
423
+ ⭐ Используйте когда пользователь ОБНОВИЛ данные объекта.
424
+
425
+ Сценарий:
426
+ 1. Пользователь создал лида → POST /prepare-and-embed → сохранили embedding
427
+ 2. Пользователь ИЗМЕНИЛ лида → POST /reindex → получили новый embedding
428
+ 3. Go Backend обновляет embedding в PostgreSQL
429
+
430
+ Пример запроса:
431
+ ```json
432
+ {
433
+ "entity_id": "lead-123",
434
+ "entity_type": "lead",
435
+ "title": "Обновлённый заголовок",
436
+ "description": "Новое описание",
437
+ "price": 12000000,
438
+ "district": "Арбат",
439
+ "rooms": 4
440
+ }
441
+ ```
442
+
443
+ Go Backend должен выполнить:
444
+ ```sql
445
+ UPDATE leads SET embedding = $1, updated_at = NOW() WHERE lead_id = $2
446
+ ```
447
+ """
448
+ if model is None:
449
+ raise HTTPException(status_code=503, detail="Model not loaded")
450
+
451
+ prepared = prepare_text(
452
+ title=request.title,
453
+ description=request.description,
454
+ requirement=request.requirement,
455
+ price=request.price,
456
+ district=request.district,
457
+ rooms=request.rooms,
458
+ area=request.area,
459
+ address=request.address
460
+ )
461
+
462
+ if not prepared:
463
+ raise HTTPException(status_code=400, detail="All fields are empty - nothing to reindex")
464
+
465
+ embedding = model.encode(prepared, convert_to_numpy=True)
466
+
467
+ return ReindexResponse(
468
+ entity_id=request.entity_id,
469
+ entity_type=request.entity_type,
470
+ embedding=embedding.tolist(),
471
+ dimensions=len(embedding),
472
+ prepared_text=prepared,
473
+ message=f"Reindex successful for {request.entity_type} '{request.entity_id}'. Update embedding in your database."
474
+ )
475
+
476
+
477
+ @app.post("/reindex-batch", response_model=BatchResponse)
478
+ async def reindex_batch(request: BatchRequest):
479
+ """
480
+ Пакетная переиндексация нескольких объектов.
481
+
482
+ Используйте когда нужно переиндексировать много объектов после
483
+ массового обновления или изменения модели.
484
+
485
+ В��утренне вызывает тот же batch_process, но с понятным названием.
486
+ """
487
+ return await batch_process(request)
488
+