Skip to content

Commit

Permalink
Merge pull request #903 from weni-ai/feature/nlp-log-export
Browse files Browse the repository at this point in the history
Feature/nlp log export
  • Loading branch information
zMardone authored Jan 22, 2024
2 parents 80a4b33 + a76d3df commit 04681a9
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 1 deletion.
60 changes: 60 additions & 0 deletions bothub/api/v2/repository/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
RepositoryVersionLanguage,
Organization,
)
from bothub.common.usecase.repositorylog.export import ExportRepositoryLogUseCase

from ..metadata import Metadata
from .filters import (
Expand Down Expand Up @@ -1359,6 +1360,65 @@ def get_queryset(self):
return super().get_queryset().sort("-created_at")


class RepositoryNLPLogExportViewSet(DocumentViewSet):
document = RepositoryNLPLogDocument
serializer_class = RepositoryNLPLogSerializer
permission_classes = [permissions.IsAuthenticated, RepositoryLogPermission]
filter_backends = [
CompoundSearchFilterBackend,
FilteringFilterBackend,
NestedFilteringFilterBackend,
]
pagination_class = LimitOffsetPagination
limit = settings.REPOSITORY_NLP_LOG_LIMIT
search_fields = ["text"]
filter_fields = {
"repository_uuid": "repository_uuid",
"language": "language",
"repository_version": "repository_version",
"repository_version_language": "repository_version_language",
"created_at": {
"field": "created_at",
"lookups": [LOOKUP_FILTER_RANGE, LOOKUP_QUERY_LTE, LOOKUP_QUERY_GTE],
},
}
nested_filter_fields = {
"intent": {"field": "nlp_log.intent.name.raw", "path": "nlp_log"},
"confidence": {
"field": "nlp_log.intent.confidence",
"path": "nlp_log",
"lookups": [LOOKUP_FILTER_RANGE, LOOKUP_QUERY_LTE, LOOKUP_QUERY_GTE],
},
}

def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
return queryset[: self.limit]

def get_queryset(self):
params = {
"repository_uuid": self.request.query_params.get("repository_uuid", None),
"repository_version": self.request.query_params.get(
"repository_version", None
),
"repository_version_language": self.request.query_params.get(
"repository_version_language", None
),
}
RepositoryNLPLogFilter(params=params, user=self.request.user)
return super().get_queryset()

def get_xlsx(self, queryset):
usecase = ExportRepositoryLogUseCase()
xlsx_response = usecase.create_xlsx_response(queryset)
return xlsx_response

def get(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
xlsx_response = self.get_xlsx(queryset)
return xlsx_response


class RepositoryQANLPLogViewSet(DocumentViewSet):
document = RepositoryQANLPLogDocument
serializer_class = RepositoryQANLPLogSerializer
Expand Down
2 changes: 2 additions & 0 deletions bothub/api/v2/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
RepositoryMigrateViewSet,
RepositoryNLPLogReportsViewSet,
RepositoryNLPLogViewSet,
RepositoryNLPLogExportViewSet,
RepositoryQANLPLogViewSet,
RepositoryTaskQueueViewSet,
RepositoryTokenByUserViewSet,
Expand Down Expand Up @@ -198,6 +199,7 @@ def get_lookup_regex(self, viewset, lookup_prefix=""):
router.register("repository/translation-export", RepositoryTranslatedExporterViewSet)
router.register("repository/version", RepositoryVersionViewSet)
router.register("repository/log", RepositoryNLPLogViewSet, basename="es-repository-log")
router.register("repository/export-log", RepositoryNLPLogExportViewSet, basename="es-repository-log-export")
router.register(
"repository/qalog", RepositoryQANLPLogViewSet, basename="es-repository-qa-log"
)
Expand Down
2 changes: 1 addition & 1 deletion bothub/api/v2/translation/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def retrieve(self, request, *args, **kwargs): # pragma: no cover
end=entity.end + count_entity,
)
count_entity += len(entity.entity.value) + 4

translated = RepositoryTranslatedExample.objects.filter(
original_example=example.pk, language=for_the_language
)
Expand Down
Empty file.
Empty file.
50 changes: 50 additions & 0 deletions bothub/common/usecase/repositorylog/export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from django.http import HttpResponse

from openpyxl import Workbook
from openpyxl.writer.excel import save_virtual_workbook


class ExportRepositoryLogUseCase:

def _create_xlsx_workbook(
self,
repository_logs
) -> Workbook:

wb = Workbook()
ws = wb.active

ws['A1'] = 'Text'
ws['B1'] = 'Created At'
ws['C1'] = 'Intent'
ws['D1'] = 'Confidence'
ws['E1'] = 'Entities'
ws['F1'] = 'Entities List'

if repository_logs is None:
return wb

row = 2
for repository_log in repository_logs:
ws['A{}'.format(row)] = repository_log.nlp_log.text
ws['B{}'.format(row)] = repository_log.created_at
ws['C{}'.format(row)] = repository_log.nlp_log.intent.name
ws['D{}'.format(row)] = repository_log.nlp_log.intent.confidence
ws['F{}'.format(row)] = repository_log.nlp_log.entities
row += 1

return wb

def create_xlsx_response(
self,
repository_logs
) -> HttpResponse:

wb = self._create_xlsx_workbook(repository_logs)
response = HttpResponse(
content=save_virtual_workbook(wb),
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
)
response['Content-Disposition'] = 'attachment; filename=repository_logs.xlsx'

return response
Empty file.
60 changes: 60 additions & 0 deletions bothub/common/usecase/repositorylog/tests/test_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import unittest
from unittest.mock import Mock
from django.http import HttpResponse
from openpyxl import Workbook
from ..export import ExportRepositoryLogUseCase


class TestExportRepositoryLogUseCase(unittest.TestCase):

def setUp(self):
self.use_case = ExportRepositoryLogUseCase()
self.mock_repository_logs = [
Mock(
nlp_log=Mock(
text='text',
intent=Mock(
name='intent',
confidence='confidence'
),
entities='entities'
), created_at='created_at'
)
]
for log in self.mock_repository_logs:
log.nlp_log.intent.name = 'intent_name'

def test_create_xlsx_workbook(self):
# Chama a função _create_xlsx_workbook
result = self.use_case._create_xlsx_workbook(self.mock_repository_logs)
self.assertIsInstance(result, Workbook)

def test_create_xlsx_response(self):
result = self.use_case.create_xlsx_response(self.mock_repository_logs)
self.assertIsInstance(result, HttpResponse)
self.assertEqual(
result['Content-Type'],
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
self.assertEqual(
result['Content-Disposition'],
'attachment; filename=repository_logs.xlsx'
)

def test_create_xlsx_workbook_with_none(self):

result = self.use_case._create_xlsx_workbook(None)
self.assertIsInstance(result, Workbook)

def test_create_xlsx_response_with_none(self):

result = self.use_case.create_xlsx_response(None)
self.assertIsInstance(result, HttpResponse)
self.assertEqual(
result['Content-Type'],
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
self.assertEqual(
result['Content-Disposition'],
'attachment; filename=repository_logs.xlsx'
)

0 comments on commit 04681a9

Please sign in to comment.