Getting started with Django API documentation

REST API documentation is an important step in the process of API development. Documentation makes it possible for other developers who will consume the API to understand how the API works.
Documenting APIs
In this tutorial, we are going to learn how to add documentation to our RESTful API endpoints.
Prerequisites
- Python installed on your computer.
- Virtualenv installed on your computer.
- Python and Django knowledge.
Creating the project
On the terminal execute the command below to create a working directory for our project.
$ mkdir documentation
$ cd documentation
Now that we have created a working directory and changed our path to it, create a virtual environment for the project by executing the command below.
$ virtualenv venv
$ source venv/bin/activate
Let's now install Django into our virtual environment and create our Django project by executing the commands below.
$ (venv) pip install django
$ (venv) django-admin startproject django_todo
Since we are going to use the DjangoRest framework, drf_yasg, and coreapi, we need to install these packages.
Execute the commands below to install DjangoRest framework, drf_yasg, and coreapi.
$ pip install djangorestframework
$ pip install coreapi
$ pip install -U drf-yasg[validation]
Django organizes code into applications, this makes it easier to write code that is easier to maintain. Execute the command below to create a todo
app that will hold the source code for our application.
$ ./manage.py startapp todo
Django Model
In the todo
app created above, add the code snippet below to the models.py
file. A model is a Python class that represents a table in a relational database. Django maps the models to database tables.
class Todo(models.Model):
title = models.CharField(max_length = 100)
body = models.CharField(max_length = 100)
is_completed = models.BooleanField(default=False)
date_created = models.DateField(auto_created=True)
last_modified = models.DateField(auto_now=True)
def __str___(self):
return self.title
Django serializer
Converting data from Python objects to JSON and vice versa is a challenging task. Django simplifies that process of conversion by providing a serializer
class that can be extended to perform the conversion.
In the todo
app create a Python file named serializers.py
and add the code snippets below.
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
fields = "__all__"
Django API view
Django follows the model view template (MVT) pattern. The view holds the logic that acts on the incoming HTTP requests.
In the views.py
file in the todo
app, add the code snippet below.
from rest_framework.generics import ListAPIView
from rest_framework.generics import CreateAPIView
from rest_framework.generics import DestroyAPIView
from rest_framework.generics import UpdateAPIView
from todo.serializers import TodoSerializer
from todo.models import Todo
# Create your views here.
class ListTodoAPIView(ListAPIView):
"""Lists all todos from the database"""
queryset = Todo.objects.all()
serializer_class = TodoSerializer
class CreateTodoAPIView(CreateAPIView):
"""Creates a new todo"""
queryset = Todo.objects.all()
serializer_class = TodoSerializer
class UpdateTodoAPIView(UpdateAPIView):
"""Update the todo whose id has been passed through the request"""
queryset = Todo.objects.all()
serializer_class = TodoSerializer
class DeleteTodoAPIView(DestroyAPIView):
"""Deletes a todo whose id has been passed through the request"""
queryset = Todo.objects.all()
serializer_class = TodoSerializer
Django URL
To communicate with our applications, we must provide an API endpoint URL where the client can request and submit data. In the todo
app, create a new file named urls.py
and add the code snippet below.
urlpatterns = [
path("",views.ListTodoAPIView.as_view(),name="todo_list"),
path("create/", views.CreateTodoAPIView.as_view(),name="todo_create"),
path("update/<int:pk>/",views.UpdateTodoAPIView.as_view(),name="update_todo"),
path("delete/<int:pk>/",views.DeleteTodoAPIView.as_view(),name="delete_todo")
]
In the root project urls.py
file, add the code snippet below to configure our todo
app URLs with the root project URLs.
# Swagger documentation setup
schema_view = get_schema_view(
openapi.Info(
title="Snippets API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="[email protected]"),
license=openapi.License(name="MIT License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/todo/', include("todo.urls")),
path('docs/', include_docs_urls(title='Todo Api')),
url(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]
Django settings.py
The settings.py
file should contain the configurations below. Add the packages we installed earlier to the INSTALLED_APPS
apps dictionary.
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = '9s^sq5s0pp*hd)%i2)*m3n--e-=)2tn&7i&c)o6z#l-m18jx4)'
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo',
'rest_framework',
'coreapi', # Coreapi for coreapi documentation
'drf_yasg', # drf_yasg fro Swagger documentation
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'django_todo.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
}
WSGI_APPLICATION = 'django_todo.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
Testing the documentation
Now that we have implemented the code required to generate documentation for our API, let us test it.
Note: Make sure the application is running.
Coreapi
On your browser, navigate to http://127.0.0.1:8000/docs/
to view the coreapi documentation.
Swagger
On your browser, navigate to http://127.0.0.1:8000/swagger/
to view the swagger documentation.
redoc
On your browser, navigate to http://127.0.0.1:8000/redoc
to view redoc documentation.
Conclusion
Now that you have learned how to document Django RESTful API endpoints, proceed and add descriptive notes to every API endpoint documentation.
Happy coding!
Peer Review Contributions by: Odhiambo Paul
