Getting Started
Quickstart Guide
We are going to create a simple blog application with a gRPC service.
The blog application will have the following models: User and Post.
Prerequisites
You will need to install the following packages:
Python (>= 3.8)
Installation
Install the package via pip:
pip install django-socio-grpc
Creating a New Project
Now you can create the project by running the following command :
django-admin startproject tutorial
Add now the following lines to the INSTALLED_APPS section of your tutorial/settings.py file:
INSTALLED_APPS = [
...
'django_socio_grpc',
]
Adding a New App
Then create a new app. First, cd into the project directory:
cd tutorial
Create the new app:
python manage.py startapp quickstart
This will create a new directory called quickstart inside your project directory including python files.
Add the new app to the INSTALLED_APPS section of your tutorial/settings.py file:
INSTALLED_APPS = [
...
'quickstart',
]
Finally migrate the database:
python manage.py migrate
Defining models
Models are created in the same way as in Django (Django documentation) . Each model is assigned to a table in the database. It inherits from a Python class django.db.models.Model. Each attribute represents a field in the table. The API for accessing the database is the same as Django’s (Query creation).
#quickstart/models.py from django.db import models class User(models.Model): full_name = models.CharField(max_length=70) class Post(models.Model): pub_date = models.DateField() headline = models.CharField(max_length=200) content = models.TextField() user = models.ForeignKey(User, on_delete=models.CASCADE)
Defining serializers
In this example, our serializers inherit from ModelProtoSerializer, which is simply an inheritance of DRF’s ModelSerializer. For more extensive use, you can use all the DRF serializer methods: Django REST framework serializers.
#quickstart/serializers.py from django_socio_grpc import proto_serializers from rest_framework import serializers from quickstart.models import User, Post class UserProtoSerializer(proto_serializers.ModelProtoSerializer): # This line is written here as an example, # but can be removed as the serializer integrates all the fields in the model full_name = serializers.CharField(allow_blank=True) class Meta: model = User fields = "__all__" class PostProtoSerializer(proto_serializers.ModelProtoSerializer): pub_date = serializers.DateTimeField(read_only=True) user = serializers.PrimaryKeyRelatedField( queryset=User.objects.all(), pk_field=serializers.UUIDField(format="hex_verbose"), ) class Meta: model = Post fields = "__all__"
Defining gRPC services
Whereas DRF uses APIView, Django Socio gRPC uses Service. With the exception of the gRPC internal layer, a Service is made to work in the same way as a generic DRF APIView.
Django Socio gRPC Framework also supports both sync and async. In this quickstart, we will make an asynchronous service.
Following the same logic as DRF, Django Socio gRPC uses class-based services.
DSG mixins make it easy to declare one or several of the CRUD actions. Please refer to the Mixin section for more information.
In the the following example we will create 2 services.
UserService, will be a read-only service (AsyncReadOnlyModelService), meaning that it will have 2 gRPC actions: List and Retrieve.
PostService, will be a read-write service (AsyncModelService), meaning that it will have 6: List, Retrieve, Create, Update, PartialUpdate, Destroy.
#quickstart/services.py from django_filters.rest_framework import DjangoFilterBackend from rest_framework.pagination import PageNumberPagination from django_socio_grpc import generics from quickstart.models import User, Post from quickstart.serializer import UserProtoSerializer, PostProtoSerializer class UserService(generics.AsyncReadOnlyModelService): queryset = User.objects.all() serializer_class = UserProtoSerializer class PostService(generics.AsyncModelService): queryset = Post.objects.all() serializer_class = PostProtoSerializer
Note:
DSG Generic services and mixins are based on DRF Generic views and mixins.
In DSG :
from django.contrib.auth.models import User from quickstart.serializers import UserProtoSerializer from django_socio_grpc import generics class MyListService(generics.ListCreateService): queryset = User.objects.all() serializer_class = UserProtoSerializer
In DRF :
from django.contrib.auth.models import User from quickstart.serializers import UserProtoSerializer from rest_framework import generics class MyListService(generics.ListCreateAPIView): queryset = User.objects.all() serializer_class = UserProtoSerializer
Register services
You need to register your services in a handler function.
This handler will be the entrypoint for your whole app.
In this quickstart, we will register our services in the quickstart/handlers.py file.
# quickstart/handlers.py from django_socio_grpc.services.app_handler_registry import AppHandlerRegistry from quickstart.services import UserService, PostService def grpc_handlers(server): app_registry = AppHandlerRegistry("quickstart", server) app_registry.register(UserService) app_registry.register(PostService)
Set its path as the ROOT_HANDLERS_HOOK of the GRPC_FRAMEWORK settings:
# quickstart/settings.py ... GRPC_FRAMEWORK = { "ROOT_HANDLERS_HOOK" : 'quickstart.handlers.grpc_handlers', ... }
Generate the app’s Protobuf files and gRPC stubs
Run this command :
python manage.py generateproto
This will generate a folder called grpc at the root of your Django app.
It contains the three files describing your new gRPC service:
quickstart_pb2_grpc.py
quickstart_pb2.py
quickstart.proto
DSG generate all the file needed by gRPC. Meaning that you don’t need to deal with protofile manually.
Assign newly generated classes
In the quickstart/grpc/quickstart.proto file,
you can find the generation of the structure of responses and requests.
For each serializer, you will find the basic Response message name and the ListResponse message name.
Serializers need to be assigned to these gRPC messages, which are defined in the pb2 file.
You need to import the messages in the serializers.py file and assign them to the serializers.
#quickstart/serializers.py ... from quickstart.grpc.quickstart_pb2 import ( UserResponse, UserListResponse, PostResponse, PostListResponse, ) class UserProtoSerializer(proto_serializers.ModelProtoSerializer): ... class Meta: ... proto_class = UserResponse proto_class_list = UserListResponse class PostProtoSerializer(proto_serializers.ModelProtoSerializer): ... class Meta: ... proto_class = PostResponse proto_class_list = PostListResponse
Running the Server
You can now run the server with the following command:
python manage.py grpcrunaioserver --dev
The server is now running on port 50051 by default. See How To to see how to call this server with python or web client.