Skip to content

Commit

Permalink
fix: Add detailed api docs to the RESTFul APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Chen committed Apr 21, 2022
1 parent 1fe74fe commit b34de61
Show file tree
Hide file tree
Showing 12 changed files with 215 additions and 64 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Change Log
Unreleased
~~~~~~~~~~
[2.3.3] - 2022-04-21
~~~~~~~~~~~~~~~~~~~~
* Leverage edx-api-doc-tools to provide better swagger documentation for the RESTFul API endpoints
* Updated internal documentation. Added to the readme and a new docs context

[2.3.2] - 2022-03-11
Expand Down
2 changes: 1 addition & 1 deletion edx_name_affirmation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
Django app housing name affirmation logic.
"""

__version__ = '2.3.2'
__version__ = '2.3.3'

default_app_config = 'edx_name_affirmation.apps.EdxNameAffirmationConfig' # pylint: disable=invalid-name
4 changes: 2 additions & 2 deletions edx_name_affirmation/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ def test_histories(self):
"""
Test the model history is recording records as expected
"""
verified_name_history = self.verified_name.history.all().order_by('history_date') # pylint: disable=no-member
verified_name_history = self.verified_name.history.all().order_by('history_date')
assert len(verified_name_history) == 1
idv_attempt_id = 34455
self.verified_name.status = VerifiedNameStatus.APPROVED
self.verified_name.verification_attempt_id = idv_attempt_id
self.verified_name.save()
verified_name_history = self.verified_name.history.all().order_by('history_date') # pylint: disable=no-member
verified_name_history = self.verified_name.history.all().order_by('history_date')
assert len(verified_name_history) == 2

first_history_record = verified_name_history[0]
Expand Down
109 changes: 73 additions & 36 deletions edx_name_affirmation/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Name Affirmation HTTP-based API endpoints
"""

from edx_api_doc_tools import path_parameter, query_parameter, schema
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from rest_framework import status as http_status
from rest_framework.authentication import SessionAuthentication
Expand Down Expand Up @@ -44,29 +44,27 @@ class AuthenticatedAPIView(APIView):
class VerifiedNameView(AuthenticatedAPIView):
"""
Endpoint for a VerifiedName.
/edx_name_affirmation/v1/verified_name?username=xxx
Supports:
HTTP POST: Creates a new VerifiedName.
HTTP GET: Returns an existing VerifiedName (by username or requesting user)
HTTP PATCH: Update the status of a VerifiedName
HTTP DELETE: Delete a VerifiedName
HTTP POST
Creates a new VerifiedName.
Expected POST data: {
"username": "jdoe",
"verified_name": "Jonathan Doe"
"profile_name": "Jon Doe"
"verification_attempt_id": (Optional)
"proctored_exam_attempt_id": (Optional)
"status": (Optional)
}
HTTP GET
** Scenarios **
?username=jdoe
returns an existing verified name object matching the username
"""
@schema(
parameters=[
query_parameter('username', str, 'The username of which verified name records might be associated'),
],
responses={
200: 'The verified_name record associated with the username provided',
403: 'User lacks required permission. Only an edX staff user can invoke this API',
404: 'The verified_name record associated with the username provided does not exist.'
},
)
def get(self, request):
"""
Get most recent verified name for the request user or for the specified username
For example: /edx_name_affirmation/v1/verified_name?username=jdoe
Example response: {
"username": "jdoe",
"verified_name": "Jonathan Doe",
Expand All @@ -76,23 +74,6 @@ class VerifiedNameView(AuthenticatedAPIView):
"status": "approved",
"use_verified_name_for_certs": False,
}
HTTP PATCH
* Update the status of a VerifiedName
Example PATCH data: {
"username": "jdoe",
"verification_attempt_id" OR "proctored_exam_attempt_id": 123,
"status": "approved",
}
HTTP DELETE
* Delete a VerifiedName
/edx_name_affirmation/v1/verified_name/{id}
"""
def get(self, request):
"""
Get most recent verified name for the request user or for the specified username
"""
username = request.GET.get('username')
if username and not request.user.is_staff:
Expand All @@ -113,9 +94,25 @@ def get(self, request):
serialized_data['use_verified_name_for_certs'] = should_use_verified_name_for_certs(user)
return Response(serialized_data)

@schema(
body=VerifiedNameSerializer(),
responses={
200: 'The verified_name record associated with the username provided is successfully created',
403: 'User lacks required permission. Only an edX staff user can invoke this API',
400: 'The posted data have conflicts with already stored verified name'
},
)
def post(self, request):
"""
Create verified name
Creates a new VerifiedName.
Expected POST data: {
"username": "jdoe",
"verified_name": "Jonathan Doe"
"profile_name": "Jon Doe"
"verification_attempt_id": (Optional)
"proctored_exam_attempt_id": (Optional)
"status": (Optional)
}
"""
username = request.data.get('username')
if username != request.user.username and not request.user.is_staff:
Expand Down Expand Up @@ -146,9 +143,22 @@ def post(self, request):
data = serializer.errors
return Response(status=response_status, data=data)

@schema(
body=UpdateVerifiedNameSerializer(),
responses={
200: 'The verified_name record associated with the username provided is successfully edited',
403: 'User lacks required permission. Only an edX staff user can invoke this API',
400: 'The edit action failed validation rules'
},
)
def patch(self, request):
"""
Update verified name status
Example PATCH data: {
"username": "jdoe",
"verification_attempt_id" OR "proctored_exam_attempt_id": 123,
"status": "approved",
}
"""
if not request.user.is_staff:
return Response(
Expand Down Expand Up @@ -182,6 +192,16 @@ def patch(self, request):

return Response(status=response_status, data=data)

@schema(
parameters=[
path_parameter('verified_name_id', str, 'The database id of the verified_name to be deleted'),
],
responses={
204: 'The verified_name record associated with the id is successfully deleted from data store',
403: 'User lacks required permission. Only an edX staff user can invoke this API',
404: 'The verified_name record associated with the id provided does not exist.'
},
)
def delete(self, request, verified_name_id):
"""
Delete verified name
Expand Down Expand Up @@ -212,6 +232,15 @@ class VerifiedNameHistoryView(AuthenticatedAPIView):
Supports:
HTTP GET: Return a list of VerifiedNames for the given user.
"""
@schema(
parameters=[
query_parameter('username', str, 'The username of which verified name records might be associated'),
],
responses={
200: 'The verified_name record associated with the username provided is successfully edited',
403: 'User lacks required permission. Only an edX staff user can invoke this API',
},
)
def get(self, request):
"""
Get a list of verified name objects for the given user, ordered by most recently created.
Expand Down Expand Up @@ -250,6 +279,14 @@ class VerifiedNameConfigView(AuthenticatedAPIView):
"use_verified_name_for_certs": True
}
"""
@schema(
body=VerifiedNameConfigSerializer(),
responses={
201: 'The verified_name configuration record is successfully created',
403: 'User lacks required permission. Only an edX staff user can invoke this API',
400: 'The POSTed data failed validation rules',
},
)
def post(self, request):
"""
Create VerifiedNameConfig
Expand Down
1 change: 1 addition & 0 deletions requirements/base.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ django-model-utils # Provides TimeStampedModel abstract base class
djangorestframework
django-simple-history # Provides historical records on models

edx-api-doc-tools # Doc tools to generate swagger docs for APIs
edx-celeryutils
edx-django-utils>=3.12.0
edx-drf-extensions
Expand Down
37 changes: 35 additions & 2 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# make upgrade
#
amqp==5.1.0
amqp==5.1.1
# via kombu
asgiref==3.5.0
# via django
Expand Down Expand Up @@ -35,6 +35,12 @@ click-repl==0.2.0
# via celery
code-annotations==1.3.0
# via edx-toggles
coreapi==2.3.3
# via drf-yasg
coreschema==0.0.4
# via
# coreapi
# drf-yasg
cryptography==36.0.2
# via pyjwt
django==3.2.13
Expand All @@ -46,6 +52,8 @@ django==3.2.13
# django-model-utils
# djangorestframework
# drf-jwt
# drf-yasg
# edx-api-doc-tools
# edx-celeryutils
# edx-django-utils
# edx-drf-extensions
Expand Down Expand Up @@ -73,9 +81,15 @@ djangorestframework==3.13.1
# -r requirements/base.in
# django-config-models
# drf-jwt
# drf-yasg
# edx-api-doc-tools
# edx-drf-extensions
drf-jwt==1.19.2
# via edx-drf-extensions
drf-yasg==1.20.0
# via edx-api-doc-tools
edx-api-doc-tools==1.6.0
# via -r requirements/base.in
edx-celeryutils==1.2.1
# via -r requirements/base.in
edx-django-utils==4.6.0
Expand All @@ -96,8 +110,14 @@ future==0.18.2
# pyjwkest
idna==3.3
# via requests
inflection==0.5.1
# via drf-yasg
itypes==1.2.0
# via coreapi
jinja2==3.1.1
# via code-annotations
# via
# code-annotations
# coreschema
jsonfield==3.1.0
# via edx-celeryutils
kombu==5.2.4
Expand All @@ -106,6 +126,8 @@ markupsafe==2.1.1
# via jinja2
newrelic==7.10.0.175
# via edx-django-utils
packaging==21.3
# via drf-yasg
pbr==5.8.1
# via stevedore
prompt-toolkit==3.0.29
Expand All @@ -124,6 +146,8 @@ pyjwt[crypto]==2.3.0
# edx-drf-extensions
pymongo==3.12.3
# via edx-opaque-keys
pyparsing==3.0.8
# via packaging
python-dateutil==2.8.2
# via edx-drf-extensions
python-slugify==6.1.1
Expand All @@ -137,8 +161,13 @@ pyyaml==6.0
# via code-annotations
requests==2.27.1
# via
# coreapi
# edx-drf-extensions
# pyjwkest
ruamel-yaml==0.17.21
# via drf-yasg
ruamel-yaml-clib==0.2.6
# via ruamel-yaml
semantic-version==2.9.0
# via edx-drf-extensions
six==1.16.0
Expand All @@ -156,6 +185,10 @@ stevedore==3.5.0
# edx-opaque-keys
text-unidecode==1.3
# via python-slugify
uritemplate==4.1.1
# via
# coreapi
# drf-yasg
urllib3==1.26.9
# via requests
vine==5.0.0
Expand Down
2 changes: 1 addition & 1 deletion requirements/celery50.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# make upgrade
#
amqp==5.1.0
amqp==5.1.1
# via kombu
billiard==3.6.4.0
# via celery
Expand Down
2 changes: 1 addition & 1 deletion requirements/ci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ idna==3.3
# via requests
packaging==21.3
# via tox
platformdirs==2.5.1
platformdirs==2.5.2
# via virtualenv
pluggy==0.13.1
# via
Expand Down
Loading

0 comments on commit b34de61

Please sign in to comment.