Skip to content

Commit

Permalink
Merge 59b0b5a into d35a660
Browse files Browse the repository at this point in the history
  • Loading branch information
dyohan9 committed Sep 2, 2019
2 parents d35a660 + 59b0b5a commit 1e4bc0d
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 10 deletions.
4 changes: 4 additions & 0 deletions bothub/api/v2/repository/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,3 +595,7 @@ class Meta:
source='by',
slug_field='nickname',
read_only=True)


class RepositoryUpload(serializers.Serializer):
pass
50 changes: 50 additions & 0 deletions bothub/api/v2/repository/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
from django.utils.decorators import method_decorator
from django_filters.rest_framework import DjangoFilterBackend
from django.shortcuts import get_object_or_404
Expand All @@ -7,10 +8,12 @@
from drf_yasg.utils import swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.exceptions import ValidationError
from rest_framework.exceptions import UnsupportedMediaType
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
from rest_framework import parsers
from rest_framework import status
from rest_framework import permissions
from rest_framework.permissions import IsAuthenticatedOrReadOnly
Expand Down Expand Up @@ -41,6 +44,7 @@
from .serializers import AnalyzeTextSerializer
from .serializers import EvaluateSerializer
from .serializers import RepositoryUpdateSerializer
from .serializers import RepositoryUpload
from .permissions import RepositoryPermission
from .permissions import RepositoryAdminManagerAuthorization
from .permissions import RepositoryExamplePermission
Expand Down Expand Up @@ -475,6 +479,52 @@ def create(self, request, *args, **kwargs):
self.permission_classes = [permissions.IsAuthenticated]
return super().create(request, *args, **kwargs)

@action(
detail=True,
methods=['POST'],
url_name='repository-upload-examples',
parser_classes=[parsers.MultiPartParser],
serializer_class=RepositoryUpload)
def upload_examples(self, request, **kwargs):
try:
repository = get_object_or_404(
Repository,
pk=request.data.get('repository')
)
except DjangoValidationError:
raise PermissionDenied()

user_authorization = repository.get_user_authorization(request.user)
if not user_authorization.can_write:
raise PermissionDenied()

f = request.FILES.get('file')
try:
json_data = json.loads(f.read().decode())
except json.decoder.JSONDecodeError:
raise UnsupportedMediaType('json')

count_added = 0
not_added = []

for data in json_data:
response_data = data
response_data['repository'] = request.data.get('repository')
serializer = RepositoryExampleSerializer(
data=response_data,
context={'request': request}
)
if serializer.is_valid():
serializer.save()
count_added += 1
else:
not_added.append(data)

return Response({
'added': count_added,
'not_added': not_added
})

def perform_destroy(self, obj):
if obj.deleted_in:
raise APIException(_('Example already deleted'))
Expand Down
2 changes: 1 addition & 1 deletion bothub/api/v2/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def get_lookup_regex(self, viewset, lookup_prefix=''):


router = Router()
router.register('repository', RepositoryViewSet)
router.register('repository/repository-info', RepositoryViewSet)
router.register('repository/repository-votes', RepositoryVotesViewSet)
router.register('repository/repositories', RepositoriesViewSet)
router.register(
Expand Down
101 changes: 92 additions & 9 deletions bothub/api/v2/tests/test_repository.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import uuid

from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from django.test import RequestFactory
from django.test.client import MULTIPART_CONTENT
Expand Down Expand Up @@ -126,7 +127,7 @@ def request(self, data, token=None):
} if token else {}

request = self.factory.post(
'/v2/repository/',
'/v2/repository/repository-info/',
data,
**authorization_header)

Expand Down Expand Up @@ -190,7 +191,7 @@ def request(self, repository, token=None):
} if token else {}

request = self.factory.get(
'/v2/repository/{}/'.format(repository.uuid),
'/v2/repository/repository-info/{}/'.format(repository.uuid),
**authorization_header)

response = RepositoryViewSet.as_view({'get': 'retrieve'})(
Expand Down Expand Up @@ -235,7 +236,7 @@ def request(self, repository, data={}, token=None):
} if token else {}

request = self.factory.patch(
'/v2/repository/{}/'.format(repository.uuid),
'/v2/repository/repository-info/{}/'.format(repository.uuid),
self.factory._encode_data(data, MULTIPART_CONTENT),
MULTIPART_CONTENT,
**authorization_header)
Expand Down Expand Up @@ -294,7 +295,7 @@ def request(self, repository, token=None):
} if token else {}

request = self.factory.get(
'/v2/repository/{}/'.format(repository.uuid),
'/v2/repository/repository-info/{}/'.format(repository.uuid),
**authorization_header)

response = RepositoryViewSet.as_view({'get': 'retrieve'})(
Expand Down Expand Up @@ -343,7 +344,7 @@ def request(self, repository, token=None):
} if token else {}

request = self.factory.get(
'/v2/repository/{}/'.format(repository.uuid),
'/v2/repository/repository-info/{}/'.format(repository.uuid),
**authorization_header)

response = RepositoryViewSet.as_view({'get': 'retrieve'})(
Expand Down Expand Up @@ -1453,6 +1454,88 @@ def test_entity_has_valid_label(self):
label)


class RepositoryExampleUploadTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()

self.owner, self.owner_token = create_user_and_token('owner')
self.user, self.user_token = create_user_and_token()

self.repository = Repository.objects.create(
owner=self.owner,
name='Testing',
slug='test',
language=languages.LANGUAGE_EN)

def request(self, token):
authorization_header = {
'HTTP_AUTHORIZATION': 'Token {}'.format(token.key),
}
examples = b'''[
{
"text": "yes",
"language": "en",
"entities": [{
"label": "yes",
"entity": "_yes",
"start": 0,
"end": 3
}],
"intent": "greet"
},
{
"text": "alright",
"language": "en",
"entities": [{
"label": "yes",
"entity": "_yes",
"start": 0,
"end": 3
}],
"intent": "greet"
}
]'''

uploaded_file = SimpleUploadedFile(
'examples.json',
examples,
'multipart/form-data'
)

request = self.factory.post(
'/v2/repository/example/upload_examples/',
{
'file': uploaded_file,
'repository': str(self.repository.uuid)
}, format='multipart',
**authorization_header)
response = RepositoryExampleViewSet.as_view(
{'post': 'upload_examples'})(request)
response.render()
content_data = json.loads(response.content)
return (response, content_data,)

def test_okay(self):
response, content_data = self.request(self.owner_token)
self.assertEqual(
content_data.get('added'),
2
)
self.assertEqual(
len(content_data.get('not_added')),
0
)
self.assertEqual(
response.status_code,
status.HTTP_200_OK)

def test_permission_denied(self):
response, content_data = self.request(self.user_token)
self.assertEqual(
response.status_code,
status.HTTP_403_FORBIDDEN)


class RepositoryExampleDestroyTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()
Expand Down Expand Up @@ -1953,7 +2036,7 @@ def request(self, repository, token):
'HTTP_AUTHORIZATION': 'Token {}'.format(token.key),
}
request = self.factory.get(
'/v2/repository/{}/'.format(
'/v2/repository/repository-info/{}/'.format(
str(repository.uuid)),
**authorization_header)
response = RepositoryViewSet.as_view(
Expand Down Expand Up @@ -2003,7 +2086,7 @@ def test_languages_status(self):
'HTTP_AUTHORIZATION': 'Token {}'.format(self.user_token.key),
}
request = self.factory.get(
'/v2/repository/{}/languagesstatus/'.format(
'/v2/repository/repository-info/{}/languagesstatus/'.format(
self.repository.uuid),
**authorization_header)
response = RepositoryViewSet.as_view(
Expand Down Expand Up @@ -2087,7 +2170,7 @@ def request(self, repository, token):
'HTTP_AUTHORIZATION': 'Token {}'.format(token.key),
}
request = self.factory.get(
'/v2/repository/{}/train/'.format(
'/v2/repository/repository-info/{}/train/'.format(
str(repository.uuid)),
**authorization_header)
response = RepositoryViewSet.as_view({'get': 'train'})(request)
Expand Down Expand Up @@ -2126,7 +2209,7 @@ def request(self, repository, token, data):
'HTTP_AUTHORIZATION': 'Token {}'.format(token.key),
}
request = self.factory.post(
'/v2/repository/{}/analyze/'.format(
'/v2/repository/repository-info/{}/analyze/'.format(
str(repository.uuid)),
data,
**authorization_header)
Expand Down

0 comments on commit 1e4bc0d

Please sign in to comment.