diff --git a/Pipfile b/Pipfile index f6f66b286..4ef22d6f1 100644 --- a/Pipfile +++ b/Pipfile @@ -14,12 +14,14 @@ requests = "==2.20.1" coreapi = "==2.3.3" whitenoise = "==4.1.2" pytz = "==2018.7" +drf-yasg = "*" [dev-packages] "flake8" = "*" coverage = "*" ipython = "*" autopep8 = "*" +packaging = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index 09fda139f..616240ea9 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "7eeb23c826a7cad627b63d097d320d7135c3f2d2159800a2d62a13a795fa4428" + "sha256": "648422adf916fcfeff0b93f66fb660e85da82a5fcf4944bc8d53b7cdf4eb5b82" }, "pipfile-spec": 6, "requires": { @@ -18,10 +18,10 @@ "default": { "certifi": { "hashes": [ - "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5", - "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae" + "sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", + "sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695" ], - "version": "==2019.3.9" + "version": "==2019.6.16" }, "chardet": { "hashes": [ @@ -85,6 +85,14 @@ "index": "pypi", "version": "==3.9.0" }, + "drf-yasg": { + "hashes": [ + "sha256:68fded2ffdf46e03f33e766184b7d8f1e1a5236f94acfd0c4ba932a57b812566", + "sha256:fcef74709ead2b365410be3d12afbfd0a6e49d1efe615a15a929da7e950bb83c" + ], + "index": "pypi", + "version": "==1.16.1" + }, "idna": { "hashes": [ "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", @@ -92,6 +100,12 @@ ], "version": "==2.7" }, + "inflection": { + "hashes": [ + "sha256:18ea7fb7a7d152853386523def08736aa8c32636b047ade55f7578c4edeb16ca" + ], + "version": "==0.3.1" + }, "itypes": { "hashes": [ "sha256:c6e77bb9fd68a4bfeb9d958fea421802282451a25bac4913ec94db82a899c073" @@ -161,6 +175,36 @@ "index": "pypi", "version": "==2.20.1" }, + "ruamel.yaml": { + "hashes": [ + "sha256:08aaaa74ff66565024ecabf9ba2db212712382a21c0458f9a91c623a1fa83b34", + "sha256:23f2efb872d2ebe3d5428b4f1a8f30cbf59f56e780c4981c155411ee65572673", + "sha256:38718e69270141c403b5fc539f774ed394568f8a5195b507991f5b690356facb", + "sha256:44da2be1153e173f90ad8775d4ac4237a3c06cfbb9660c1c1980271621833faa", + "sha256:4b1674a936cdae9735578d4fd64bcbc6cfbb77a1a8f7037a50c6e3874ba4c9d8", + "sha256:51d49c870aca850e652e2cd1c9bea9b52b77d13ad52b0556de496c1d264ea65f", + "sha256:63dc8c6147a4cf77efadf2ae0f34e89e03de79289298bb941b7ae333d5d4020b", + "sha256:6672798c6b52a976a7b24e20665055852388c83198d88029d3c76e2197ac221a", + "sha256:6b6025f9b6a557e15e9fdfda4d9af0b57cd8d59ff98e23a0097ab2d7c0540f07", + "sha256:7b750252e3d1ec5b53d03be508796c04a907060900c7d207280b7456650ebbfc", + "sha256:847177699994f9c31adf78d1ef1ff8f069ef0241e744a3ee8b30fbdaa914cc1e", + "sha256:8e42f3067a59e819935a2926e247170ed93c8f0b2ab64526f888e026854db2e4", + "sha256:922d9e483c05d9000256640026f277fcc0c2e1e9271d05acada8e6cfb4c8b721", + "sha256:92a8ca79f9173cca29ca9663b49d9c936aefc4c8a76f39318b0218c8f3626438", + "sha256:ab8eeca4de4decf0d0a42cb6949d354da9fc70a2d9201f0dd55186c599b2e3a5", + "sha256:bd4b60b649f4a81086f70cd56eff4722018ef36a28094c396f1a53bf450bd579", + "sha256:fc6471ef15b69e454cca82433ac5f84929d9f3e2d72b9e54b06850b6b7133cc0", + "sha256:ffc89770339191acbe5a15041950b5ad9daec7d659619b0ed9dad8c9c80c26f3" + ], + "version": "==0.15.100" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, "uritemplate": { "hashes": [ "sha256:01c69f4fe8ed503b2951bef85d996a9d22434d2431584b5b107b2981ff416fbd", @@ -186,6 +230,14 @@ } }, "develop": { + "appnope": { + "hashes": [ + "sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0", + "sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71" + ], + "markers": "sys_platform == 'darwin'", + "version": "==0.1.0" + }, "autopep8": { "hashes": [ "sha256:4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee" @@ -202,42 +254,32 @@ }, "coverage": { "hashes": [ - "sha256:0c5fe441b9cfdab64719f24e9684502a59432df7570521563d7b1aff27ac755f", - "sha256:2b412abc4c7d6e019ce7c27cbc229783035eef6d5401695dccba80f481be4eb3", "sha256:3684fabf6b87a369017756b551cef29e505cb155ddb892a7a29277b978da88b9", "sha256:39e088da9b284f1bd17c750ac672103779f7954ce6125fd4382134ac8d152d74", "sha256:3c205bc11cc4fcc57b761c2da73b9b72a59f8d5ca89979afb0c1c6f9e53c7390", - "sha256:42692db854d13c6c5e9541b6ffe0fe921fe16c9c446358d642ccae1462582d3b", "sha256:465ce53a8c0f3a7950dfb836438442f833cf6663d407f37d8c52fe7b6e56d7e8", "sha256:48020e343fc40f72a442c8a1334284620f81295256a6b6ca6d8aa1350c763bbe", - "sha256:4ec30ade438d1711562f3786bea33a9da6107414aed60a5daa974d50a8c2c351", "sha256:5296fc86ab612ec12394565c500b412a43b328b3907c0d14358950d06fd83baf", "sha256:5f61bed2f7d9b6a9ab935150a6b23d7f84b8055524e7be7715b6513f3328138e", - "sha256:6899797ac384b239ce1926f3cb86ffc19996f6fa3a1efbb23cb49e0c12d8c18c", "sha256:68a43a9f9f83693ce0414d17e019daee7ab3f7113a70c79a3dd4c2f704e4d741", "sha256:6b8033d47fe22506856fe450470ccb1d8ba1ffb8463494a15cfc96392a288c09", "sha256:7ad7536066b28863e5835e8cfeaa794b7fe352d99a8cded9f43d1161be8e9fbd", "sha256:7bacb89ccf4bedb30b277e96e4cc68cd1369ca6841bde7b005191b54d3dd1034", "sha256:839dc7c36501254e14331bcb98b27002aa415e4af7ea039d9009409b9d2d5420", - "sha256:8e679d1bde5e2de4a909efb071f14b472a678b788904440779d2c449c0355b27", "sha256:8f9a95b66969cdea53ec992ecea5406c5bd99c9221f539bca1e8406b200ae98c", "sha256:932c03d2d565f75961ba1d3cec41ddde00e162c5b46d03f7423edcb807734eab", - "sha256:93f965415cc51604f571e491f280cff0f5be35895b4eb5e55b47ae90c02a497b", "sha256:988529edadc49039d205e0aa6ce049c5ccda4acb2d6c3c5c550c17e8c02c05ba", "sha256:998d7e73548fe395eeb294495a04d38942edb66d1fa61eb70418871bc621227e", "sha256:9de60893fb447d1e797f6bf08fdf0dbcda0c1e34c1b06c92bd3a363c0ea8c609", "sha256:9e80d45d0c7fcee54e22771db7f1b0b126fb4a6c0a2e5afa72f66827207ff2f2", "sha256:a545a3dfe5082dc8e8c3eb7f8a2cf4f2870902ff1860bd99b6198cfd1f9d1f49", "sha256:a5d8f29e5ec661143621a8f4de51adfb300d7a476224156a39a392254f70687b", - "sha256:a9abc8c480e103dc05d9b332c6cc9fb1586330356fc14f1aa9c0ca5745097d19", "sha256:aca06bfba4759bbdb09bf52ebb15ae20268ee1f6747417837926fae990ebc41d", "sha256:bb23b7a6fd666e551a3094ab896a57809e010059540ad20acbeec03a154224ce", "sha256:bfd1d0ae7e292105f29d7deaa9d8f2916ed8553ab9d5f39ec65bcf5deadff3f9", - "sha256:c22ab9f96cbaff05c6a84e20ec856383d27eae09e511d3e6ac4479489195861d", "sha256:c62ca0a38958f541a73cf86acdab020c2091631c137bd359c4f5bddde7b75fd4", "sha256:c709d8bda72cf4cd348ccec2a4881f2c5848fd72903c185f363d361b2737f773", "sha256:c968a6aa7e0b56ecbd28531ddf439c2ec103610d3e2bf3b75b813304f8cb7723", - "sha256:ca58eba39c68010d7e87a823f22a081b5290e3e3c64714aac3c91481d8b34d22", "sha256:df785d8cb80539d0b55fd47183264b7002077859028dfe3070cf6359bf8b2d9c", "sha256:f406628ca51e0ae90ae76ea8398677a921b36f0bd71aab2099dfed08abd0322f", "sha256:f46087bbd95ebae244a0eda01a618aff11ec7a069b15a3ef8f6b520db523dcf1", @@ -263,19 +305,19 @@ }, "flake8": { "hashes": [ - "sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661", - "sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8" + "sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548", + "sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696" ], "index": "pypi", - "version": "==3.7.7" + "version": "==3.7.8" }, "ipython": { "hashes": [ - "sha256:54c5a8aa1eadd269ac210b96923688ccf01ebb2d0f21c18c3c717909583579a8", - "sha256:e840810029224b56cd0d9e7719dc3b39cf84d577f8ac686547c8ba7a06eeab26" + "sha256:11067ab11d98b1e6c7f0993506f7a5f8a91af420f7e82be6575fcb7a6ca372a0", + "sha256:60bc55c2c1d287161191cc2469e73c116d9b634cff25fe214a43cba7cec94c79" ], "index": "pypi", - "version": "==7.5.0" + "version": "==7.6.1" }, "ipython-genutils": { "hashes": [ @@ -286,10 +328,10 @@ }, "jedi": { "hashes": [ - "sha256:2bb0603e3506f708e792c7f4ad8fc2a7a9d9c2d292a358fbbd58da531695595b", - "sha256:2c6bcd9545c7d6440951b12b44d373479bf18123a401a52025cf98563fbd826c" + "sha256:53c850f1a7d3cfcd306cc513e2450a54bdf5cacd7604b74e42dd1f0758eaaf36", + "sha256:e07457174ef7cb2342ff94fa56484fe41cec7ef69b0059f01d3f812379cb6f7c" ], - "version": "==0.13.3" + "version": "==0.14.1" }, "mccabe": { "hashes": [ @@ -298,12 +340,20 @@ ], "version": "==0.6.1" }, + "packaging": { + "hashes": [ + "sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af", + "sha256:9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3" + ], + "index": "pypi", + "version": "==19.0" + }, "parso": { "hashes": [ - "sha256:17cc2d7a945eb42c3569d4564cdf49bde221bc2b552af3eca9c1aad517dcdd33", - "sha256:2e9574cb12e7112a87253e14e2c380ce312060269d04bd018478a3c92ea9a376" + "sha256:63854233e1fadb5da97f2744b6b24346d2750b85965e7e399bec1620232797dc", + "sha256:666b0ee4a7a1220f65d367617f2cd3ffddff3e205f3f16a0284df30e774c2a9c" ], - "version": "==0.4.0" + "version": "==0.5.1" }, "pexpect": { "hashes": [ @@ -351,10 +401,17 @@ }, "pygments": { "hashes": [ - "sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a", - "sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d" + "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", + "sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297" + ], + "version": "==2.4.2" + }, + "pyparsing": { + "hashes": [ + "sha256:1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a", + "sha256:9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03" ], - "version": "==2.3.1" + "version": "==2.4.0" }, "six": { "hashes": [ diff --git a/bothub/api/v1/serializers/category.py b/bothub/api/v1/serializers/category.py index 2a71af96e..07a1437f7 100644 --- a/bothub/api/v1/serializers/category.py +++ b/bothub/api/v1/serializers/category.py @@ -11,3 +11,4 @@ class Meta: 'name', 'icon', ] + ref_name = None diff --git a/bothub/api/v1/serializers/example.py b/bothub/api/v1/serializers/example.py index d8e3667c5..4213466ae 100644 --- a/bothub/api/v1/serializers/example.py +++ b/bothub/api/v1/serializers/example.py @@ -33,6 +33,7 @@ class Meta: 'created_at', 'value', ] + ref_name = None repository_example = serializers.PrimaryKeyRelatedField( queryset=RepositoryExample.objects, @@ -62,6 +63,7 @@ class Meta: 'entity', 'label', ] + ref_name = None repository_example = serializers.PrimaryKeyRelatedField( queryset=RepositoryExample.objects, @@ -107,6 +109,7 @@ class Meta: 'repository_update', 'deleted_in', ] + ref_name = None entities = RepositoryExampleEntitySerializer( many=True, @@ -132,6 +135,7 @@ class Meta: 'intent', 'entities', ] + ref_name = None id = serializers.PrimaryKeyRelatedField( read_only=True, @@ -186,6 +190,7 @@ class Meta: 'value', 'label', ] + ref_name = None label = serializers.SerializerMethodField() @@ -203,6 +208,7 @@ class Meta: 'value', 'entities', ] + ref_name = None repository = serializers.StringRelatedField(read_only=True) entities = serializers.SlugRelatedField( diff --git a/bothub/api/v1/serializers/repository.py b/bothub/api/v1/serializers/repository.py index ac8ad7543..7a5c6b92c 100644 --- a/bothub/api/v1/serializers/repository.py +++ b/bothub/api/v1/serializers/repository.py @@ -32,6 +32,7 @@ class Meta: 'description', 'is_private', ] + ref_name = None uuid = serializers.ReadOnlyField( style={'show': False}) @@ -86,6 +87,7 @@ class Meta: 'languages_warnings', 'created_at', ] + ref_name = None owner = serializers.PrimaryKeyRelatedField( read_only=True, @@ -172,6 +174,7 @@ class Meta: 'is_admin', 'created_at', ] + ref_name = None user__nickname = serializers.SlugRelatedField( source='user', @@ -194,6 +197,7 @@ class Meta: fields = [ 'role', ] + ref_name = None def validate(self, data): if self.instance.user == self.instance.repository.owner: diff --git a/bothub/api/v1/serializers/request.py b/bothub/api/v1/serializers/request.py index add5e9710..dad0c52e8 100644 --- a/bothub/api/v1/serializers/request.py +++ b/bothub/api/v1/serializers/request.py @@ -14,6 +14,7 @@ class Meta: 'repository', 'text', ] + ref_name = None repository = serializers.PrimaryKeyRelatedField( queryset=Repository.objects, @@ -41,6 +42,7 @@ class Meta: 'approved_by__nickname', 'created_at', ] + ref_name = None user__nickname = serializers.SlugRelatedField( source='user', @@ -58,6 +60,7 @@ class Meta: fields = [ 'approved_by' ] + ref_name = None approved_by = serializers.PrimaryKeyRelatedField( read_only=True, diff --git a/bothub/api/v1/serializers/translate.py b/bothub/api/v1/serializers/translate.py index 01fa9ce01..673a3d006 100644 --- a/bothub/api/v1/serializers/translate.py +++ b/bothub/api/v1/serializers/translate.py @@ -56,6 +56,7 @@ class Meta: 'entities', 'created_at', ] + ref_name = None original_example = serializers.PrimaryKeyRelatedField( queryset=RepositoryExample.objects, @@ -100,6 +101,7 @@ class Meta: 'has_valid_entities', 'entities', ] + ref_name = None def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/bothub/api/v1/serializers/update.py b/bothub/api/v1/serializers/update.py index 5d3f314b6..0cf667047 100644 --- a/bothub/api/v1/serializers/update.py +++ b/bothub/api/v1/serializers/update.py @@ -17,6 +17,7 @@ class Meta: 'trained_at', 'failed_at', ] + ref_name = None by__nickname = serializers.SlugRelatedField( source='by', diff --git a/bothub/api/v1/serializers/user.py b/bothub/api/v1/serializers/user.py index 7032fdcaa..b45da18ba 100644 --- a/bothub/api/v1/serializers/user.py +++ b/bothub/api/v1/serializers/user.py @@ -19,6 +19,7 @@ class Meta: 'nickname', 'password', ] + ref_name = None password = PasswordField( write_only=True, @@ -38,6 +39,7 @@ class Meta: 'name', 'locale', ] + ref_name = None class ChangePasswordSerializer(serializers.Serializer): diff --git a/bothub/api/v1/views.py b/bothub/api/v1/views.py index 2b4be701f..84311ce49 100644 --- a/bothub/api/v1/views.py +++ b/bothub/api/v1/views.py @@ -1,3 +1,6 @@ +from django.utils.decorators import method_decorator +from drf_yasg import openapi +from drf_yasg.utils import swagger_auto_schema from rest_framework.viewsets import GenericViewSet from rest_framework import mixins from rest_framework import permissions @@ -402,6 +405,19 @@ def create(self, request, *args, **kwargs): headers=headers) +@method_decorator( + name='list', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'nickname', + openapi.IN_QUERY, + description='Nickname User to find repositories', + type=openapi.TYPE_STRING + ), + ] + ) +) class SearchRepositoriesViewSet( mixins.ListModelMixin, GenericViewSet): @@ -470,6 +486,12 @@ def languagesstatus(self, request, **kwargs): 'languages_status': repository.languages_status, }) + @method_decorator( + name='list', + decorator=swagger_auto_schema( + deprecated=True, + ) + ) @action( detail=True, methods=['GET'], @@ -485,6 +507,12 @@ def authorization(self, request, **kwargs): serializer = RepositoryAuthorizationSerializer(user_authorization) return Response(serializer.data) + @method_decorator( + name='list', + decorator=swagger_auto_schema( + deprecated=True, + ) + ) @action( detail=True, methods=['GET'], @@ -537,6 +565,12 @@ def analyze(self, request, **kwargs): message = error.get('message') # pragma: no cover raise APIException(detail=message) # pragma: no cover + @method_decorator( + name='create', + decorator=swagger_auto_schema( + deprecated=True, + ) + ) @action( detail=True, methods=['POST'], @@ -612,6 +646,12 @@ class NewRepositoryExampleViewSet( permission_classes = [permissions.IsAuthenticated] +@method_decorator( + name='retrieve', + decorator=swagger_auto_schema( + deprecated=True, + ) +) class RepositoryExampleViewSet( mixins.RetrieveModelMixin, mixins.DestroyModelMixin, @@ -681,6 +721,12 @@ class RepositoryTranslatedExampleViewSet( ] +@method_decorator( + name='list', + decorator=swagger_auto_schema( + deprecated=True, + ) +) class RepositoryExamplesViewSet( mixins.ListModelMixin, GenericViewSet): @@ -710,6 +756,11 @@ class RegisterUserViewSet( class LoginViewSet(GenericViewSet): + + """ + Login Users + """ + queryset = User.objects serializer_class = LoginSerializer @@ -857,6 +908,12 @@ class Categories( pagination_class = None +@method_decorator( + name='list', + decorator=swagger_auto_schema( + deprecated=True, + ) +) class RepositoriesViewSet( mixins.ListModelMixin, GenericViewSet): @@ -900,6 +957,48 @@ class RepositoryAuthorizationViewSet( ] +@method_decorator( + name='update', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'repository__uuid', + openapi.IN_PATH, + description='Repository UUID', + type=openapi.TYPE_STRING, + required=True + ), + openapi.Parameter( + 'user__nickname', + openapi.IN_QUERY, + description='Nickname User', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) +@method_decorator( + name='partial_update', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'repository__uuid', + openapi.IN_PATH, + description='Repository UUID', + type=openapi.TYPE_STRING, + required=True + ), + openapi.Parameter( + 'user__nickname', + openapi.IN_QUERY, + description='Nickname User', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) class RepositoryAuthorizationRoleViewSet( MultipleFieldLookupMixin, mixins.UpdateModelMixin, @@ -964,6 +1063,9 @@ def list(self, request, *args, **kwargs): class RequestAuthorizationViewSet( mixins.CreateModelMixin, GenericViewSet): + """ + Request authorization in the repository + """ serializer_class = NewRequestRepositoryAuthorizationSerializer queryset = RequestRepositoryAuthorization.objects permission_classes = [ @@ -974,6 +1076,9 @@ class RequestAuthorizationViewSet( class RepositoryAuthorizationRequestsViewSet( mixins.ListModelMixin, GenericViewSet): + """ + List of all authorization requests for a repository + """ queryset = RequestRepositoryAuthorization.objects.exclude( approved_by__isnull=False) serializer_class = RequestRepositoryAuthorizationSerializer @@ -987,6 +1092,10 @@ class ReviewAuthorizationRequestViewSet( mixins.UpdateModelMixin, mixins.DestroyModelMixin, GenericViewSet): + """ + Authorizes or Removes the user who requested + authorization from a repository + """ queryset = RequestRepositoryAuthorization.objects serializer_class = ReviewAuthorizationRequestSerializer permission_classes = [ @@ -1001,6 +1110,12 @@ def update(self, *args, **kwargs): raise ValidationError(e.message) +@method_decorator( + name='list', + decorator=swagger_auto_schema( + deprecated=True, + ) +) class RepositoryEntitiesViewSet( mixins.ListModelMixin, GenericViewSet): diff --git a/bothub/api/v2/evaluate/serializers.py b/bothub/api/v2/evaluate/serializers.py index ad37cd14b..080d03715 100644 --- a/bothub/api/v2/evaluate/serializers.py +++ b/bothub/api/v2/evaluate/serializers.py @@ -28,6 +28,7 @@ class Meta: 'start', 'end', ] + ref_name = None entity = EntityValueField() @@ -49,6 +50,7 @@ class Meta: 'deleted_in', 'created_at', ] + ref_name = None entities = RepositoryEvaluateEntitySerializer( many=True, @@ -113,6 +115,7 @@ class Meta: 'created_at', 'version', ] + ref_name = None language = serializers.SerializerMethodField() @@ -162,6 +165,7 @@ class Meta: 'intent', 'score', ] + ref_name = None score = RepositoryEvaluateResultScore(read_only=True) @@ -174,6 +178,7 @@ class Meta: 'entity', 'score', ] + ref_name = None score = RepositoryEvaluateResultScore(read_only=True) entity = serializers.SerializerMethodField() @@ -198,6 +203,7 @@ class Meta: 'intent_results', 'entity_results', ] + ref_name = None log = serializers.SerializerMethodField() intents_list = serializers.SerializerMethodField() diff --git a/bothub/api/v2/evaluate/views.py b/bothub/api/v2/evaluate/views.py index 6977729b6..87e13e6d2 100644 --- a/bothub/api/v2/evaluate/views.py +++ b/bothub/api/v2/evaluate/views.py @@ -1,3 +1,6 @@ +from django.utils.decorators import method_decorator +from drf_yasg import openapi +from drf_yasg.utils import swagger_auto_schema from rest_framework.viewsets import GenericViewSet from rest_framework import mixins from rest_framework.permissions import IsAuthenticatedOrReadOnly @@ -23,6 +26,96 @@ from .permissions import RepositoryEvaluateResultPermission +@method_decorator( + name='list', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'repository_uuid', + openapi.IN_QUERY, + description='Repository UUID, calling ' + 'the parameter through url', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) +@method_decorator( + name='create', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'repository_uuid', + openapi.IN_QUERY, + description='Repository UUID, calling ' + 'the parameter through url', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) +@method_decorator( + name='retrieve', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'repository_uuid', + openapi.IN_QUERY, + description='Repository UUID, calling ' + 'the parameter through url', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) +@method_decorator( + name='update', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'repository_uuid', + openapi.IN_QUERY, + description='Repository UUID, calling ' + 'the parameter through url', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) +@method_decorator( + name='partial_update', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'repository_uuid', + openapi.IN_QUERY, + description='Repository UUID, calling ' + 'the parameter through url', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) +@method_decorator( + name='destroy', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'repository_uuid', + openapi.IN_QUERY, + description='Repository UUID, calling ' + 'the parameter through url', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) class EvaluateViewSet( mixins.ListModelMixin, mixins.CreateModelMixin, @@ -61,6 +154,42 @@ def list(self, request, *args, **kwargs): return super().list(request, *args, **kwargs) +@method_decorator( + name='retrieve', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'intent', + openapi.IN_QUERY, + description='Filter a desired intent', + type=openapi.TYPE_STRING, + required=False + ), + openapi.Parameter( + 'min', + openapi.IN_QUERY, + description='Filter Confidence Percentage', + type=openapi.TYPE_INTEGER, + required=False + ), + openapi.Parameter( + 'max', + openapi.IN_QUERY, + description='Filter Confidence Percentage', + type=openapi.TYPE_INTEGER, + required=False + ), + openapi.Parameter( + 'repository_uuid', + openapi.IN_QUERY, + description='Repository UUID, calling ' + 'the parameter through url', + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) class ResultsListViewSet( mixins.ListModelMixin, mixins.RetrieveModelMixin, diff --git a/bothub/api/v2/example/serializers.py b/bothub/api/v2/example/serializers.py index 6996bf057..d96c36e8a 100644 --- a/bothub/api/v2/example/serializers.py +++ b/bothub/api/v2/example/serializers.py @@ -18,6 +18,7 @@ class Meta: 'created_at', 'value', ] + ref_name = None repository_example = serializers.PrimaryKeyRelatedField( queryset=RepositoryExample.objects, @@ -53,6 +54,7 @@ class Meta: 'deleted_in', 'translations', ] + ref_name = None entities = RepositoryExampleEntitySerializer( many=True, diff --git a/bothub/api/v2/repository/serializers.py b/bothub/api/v2/repository/serializers.py index cf6fa99bd..94232b759 100644 --- a/bothub/api/v2/repository/serializers.py +++ b/bothub/api/v2/repository/serializers.py @@ -18,6 +18,7 @@ class Meta: 'name', 'icon', ] + ref_name = None class RepositoryEntityLabelSerializer(serializers.ModelSerializer): @@ -29,6 +30,7 @@ class Meta: 'entities', 'examples__count', ] + ref_name = None entities = serializers.SerializerMethodField() examples__count = serializers.SerializerMethodField() @@ -75,6 +77,7 @@ class Meta: 'role', 'created_at', ] + ref_name = None user__nickname = serializers.SlugRelatedField( source='user', @@ -132,6 +135,7 @@ class Meta: 'created_at', 'authorization', ] + ref_name = None language = serializers.ChoiceField( LANGUAGE_CHOICES, @@ -263,6 +267,7 @@ class Meta: 'absolute_url', ] read_only = fields + ref_name = None categories = RepositoryCategorySerializer( many=True, @@ -295,6 +300,7 @@ class Meta: 'user', 'created_at', ] + ref_name = None def create(self, validated_data): user = self.context.get('request').user @@ -321,3 +327,4 @@ class Meta: 'role', 'created_at', ] + ref_name = None diff --git a/bothub/api/v2/repository/views.py b/bothub/api/v2/repository/views.py index 3f7bd691f..1239a0e6f 100644 --- a/bothub/api/v2/repository/views.py +++ b/bothub/api/v2/repository/views.py @@ -1,3 +1,6 @@ +from django.utils.decorators import method_decorator +from drf_yasg import openapi +from drf_yasg.utils import swagger_auto_schema from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet from rest_framework import mixins, status @@ -37,6 +40,26 @@ class RepositoryViewSet( metadata_class = Metadata +@method_decorator( + name='list', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'user', + openapi.IN_QUERY, + description='Nickname User to find repositories votes', + type=openapi.TYPE_STRING + ), + openapi.Parameter( + 'repository', + openapi.IN_QUERY, + description='Repository UUID, returns a list of ' + 'users who voted for this repository', + type=openapi.TYPE_STRING + ), + ] + ) +) class RepositoryVotesViewSet( mixins.CreateModelMixin, mixins.DestroyModelMixin, @@ -104,11 +127,25 @@ class RepositoriesViewSet( ] +@method_decorator( + name='list', + decorator=swagger_auto_schema( + manual_parameters=[ + openapi.Parameter( + 'nickname', + openapi.IN_QUERY, + description="Nickname User", + type=openapi.TYPE_STRING, + required=True + ), + ] + ) +) class RepositoriesContributionsViewSet( mixins.ListModelMixin, GenericViewSet): """ - List Repositories Contributions by user, ?nickname=nickname. + List Repositories Contributions by user. """ serializer_class = RepositoryContributionsSerializer queryset = RepositoryAuthorization.objects.all() diff --git a/bothub/api/v2/request/serializers.py b/bothub/api/v2/request/serializers.py index 25467e595..ea16940b3 100644 --- a/bothub/api/v2/request/serializers.py +++ b/bothub/api/v2/request/serializers.py @@ -16,6 +16,7 @@ class Meta: 'approved_by__nickname', 'created_at', ] + ref_name = None user__nickname = serializers.SlugRelatedField( source='user', diff --git a/bothub/settings.py b/bothub/settings.py index 303bd576e..9d0067053 100644 --- a/bothub/settings.py +++ b/bothub/settings.py @@ -35,6 +35,7 @@ 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', + 'drf_yasg', 'django_filters', 'corsheaders', 'bothub.authentication', @@ -244,3 +245,19 @@ # SECURE PROXY SSL HEADER SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') + + +# Swagger + +SWAGGER_SETTINGS = { + 'USE_SESSION_AUTH': False, + 'DOC_EXPANSION': 'list', + 'APIS_SORTER': 'alpha', + 'SECURITY_DEFINITIONS': { + 'api_key': { + 'type': 'apiKey', + 'name': 'Authorization', + 'in': 'header' + }, + }, +} diff --git a/bothub/urls.py b/bothub/urls.py index b3618f061..f31b82471 100644 --- a/bothub/urls.py +++ b/bothub/urls.py @@ -1,8 +1,12 @@ from django.contrib import admin -from django.urls import path, include +from django.urls import path, include, re_path from django.conf import settings from rest_framework.documentation import include_docs_urls +from rest_framework import permissions +from drf_yasg.views import get_schema_view +from drf_yasg import openapi + from bothub.api.v1.routers import router as bothub_api_routers from bothub.api.v2 import urls as bothub_api_v2_urls from bothub.health.views import ping @@ -10,6 +14,19 @@ from bothub.common.views import download_bot_data +schema_view = get_schema_view( + openapi.Info( + title='API Documentation', + default_version='v1.0.1', + description='Documentation', + terms_of_service='https://www.google.com/policies/terms/', + contact=openapi.Contact(email='bothub@ilhasoft.com.br'), + license=openapi.License(name="GPL-3.0"), + ), + public=True, + permission_classes=(permissions.AllowAny,), +) + urlpatterns = [ path('', include(bothub_api_routers.urls)), path('api/', include(bothub_api_routers.urls)), @@ -22,7 +39,9 @@ path( 'downloadbotdata//', download_bot_data, - name='download_bot_data') + name='download_bot_data'), + re_path(r'^swagger(?P\.json|\.yaml)$', schema_view.without_ui()), + path('swagger/', schema_view.with_ui('swagger')) ] if settings.DEBUG: