Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions django/api/tests/test_documento_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import json

from django.test import TestCase

from api.models import Documento, Etiqueta
Expand Down Expand Up @@ -257,11 +255,9 @@ def test_pesquisa_documentos_retorna_os_cinco_trechos_mais_proximos(self):
'api.views.documento_api.VectorService.buscar_contexto',
return_value=resultados,
) as buscar_contexto:
response = self.client.generic(
'GET',
response = self.client.get(
'/api/documentos/',
data=json.dumps({'contexto': ' Segurança de Redes '}),
content_type='application/json',
{'contexto': ' Segurança de Redes '},
)

self.assertEqual(response.status_code, 200)
Expand All @@ -270,16 +266,19 @@ def test_pesquisa_documentos_retorna_os_cinco_trechos_mais_proximos(self):
self.assertEqual(resposta[0]['id_documento'], self.documento.id_documento)
buscar_contexto.assert_called_once_with('segurança de redes', limite=5)

def test_pesquisa_documentos_rejeita_contexto_vazio(self):
response = self.client.generic(
'GET',
'/api/documentos/',
data=json.dumps({'contexto': ' '}),
content_type='application/json',
)
def test_pesquisa_documentos_ignora_contexto_vazio(self):
from unittest.mock import patch

self.assertEqual(response.status_code, 400)
self.assertIn('contexto', response.json()['erro'])
with patch(
'api.views.documento_api.VectorService.buscar_contexto'
) as buscar_contexto:
response = self.client.get(
'/api/documentos/',
{'contexto': ' '},
)

self.assertEqual(response.status_code, 200)
buscar_contexto.assert_not_called()

def test_cria_documento_chunk_com_embedding_valido(self):
from api.models import DocumentoChunk
Expand Down
47 changes: 20 additions & 27 deletions django/api/views/documento_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ def perform_create(self, serializer):
)

# ========================================================
# GET /api/documentos/?nome={nome}&etiquetas={etiquetas}&page={numero da pagina}
# Busca semântica opcional: contexto no body JSON
# GET /api/documentos/?nome={nome}&etiquetas={etiquetas}&contexto={contexto}&page={numero da pagina}
# Busca por nome, etiquetas ou contexto
# ========================================================
@extend_schema(
parameters=[
Expand All @@ -86,6 +86,13 @@ def perform_create(self, serializer):
description="Filtra documentos pelas etiquetas (separadas por espaço).",
required=False,
),
OpenApiParameter(
name="contexto",
type=OpenApiTypes.STR,
location=OpenApiParameter.QUERY,
description="Busca documentos pelo contexto semântico.",
required=False,
),
OpenApiParameter(
name="page",
type=OpenApiTypes.INT,
Expand All @@ -95,40 +102,26 @@ def perform_create(self, serializer):
default=1,
),
],
request={
"application/json": {
"type": "object",
"properties": {
"contexto": {
"type": "string",
"description": "Contexto usado para buscar os cinco trechos mais próximos.",
},
},
},
},
responses={
200: OpenApiResponse(description="Lista paginada de documentos."),
400: OpenApiResponse(description="Número de página inválido."),
404: OpenApiResponse(description="Página solicitada inexistente."),
},
)
def list(self, request, *args, **kwargs):
contexto = request.data.get("contexto")
contexto = request.query_params.get("contexto")
ids_documentos_contexto = None
if contexto is not None:
if not isinstance(contexto, str) or not contexto.strip():
return Response(
{"erro": "O campo contexto é obrigatório e não pode ser vazio."},
status=status.HTTP_400_BAD_REQUEST,
)
if contexto:
contexto = contexto.strip()

chunks = VectorService.buscar_contexto(
contexto.strip().lower(),
limite=5,
)
ids_documentos_contexto = list(
dict.fromkeys(chunk["id_documento_id"] for chunk in chunks)
)
if contexto:
chunks = VectorService.buscar_contexto(
contexto.lower(),
limite=5,
)
ids_documentos_contexto = list(
dict.fromkeys(chunk["id_documento_id"] for chunk in chunks)
)

nome = request.query_params.get("nome")
etiquetas = request.query_params.get("etiquetas")
Expand Down
Loading