Skip to main content

An alternative serializer implementation for REST framework written in cython built for speed.

Project description

drf-turbo

https://img.shields.io/pypi/v/drf-turbo.svg https://img.shields.io/travis/Mng-dev-ai/drf-turbo.svg Documentation Status Updates Downloads

An alternative serializer implementation for REST framework written in cython built for speed.

NOTE: Cython is required to build this package.

Requirements

  • Django
  • Django REST Framework
  • Cython
  • forbiddenfruit
  • pyyaml(OpenAPI)
  • uritemplate(OpenAPI)
  • djangorestframework-simplejwt(OpenAPI)

Installation

$ pip install drf-turbo

Declaring Serializers

from datetime import datetime
from django.utils.timezone import now
import drf_turbo as dt

 class User:
     def __init__(self, username, email,created=None):
         self.username = username
         self.email = email
         self.created = created or datetime.now()

 user = User(username='test' , email='test@example.com')



 class UserSerializer(dt.Serializer):
     username = dt.StrField(max_length=50)
     email = dt.EmailField()
     created = dt.DateTimeField()

Serializing objects

serializer = UserSerializer(user)
serializer.data

 # {'username': 'test', 'email': 'test@example.com', 'created': '2021-11-04T22:49:01.981127Z'}

Deserializing objects

data = {'username':'new_test','email':'test2@example.com','created':now()}
serializer = UserSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# {'username': 'new_test', 'email': 'test2@example.com', 'created': datetime.datetime(2021, 11, 12, 6, 10, 44, 85118)}}

Validation

serializer = UserSerializer(data={'email': 'test'})
serializer.is_valid()
# False
serializer.errors
# {'username': ['This field is required.'], 'email': ['Enter a valid email address.'],'created': ['This field is required.']}

Field-level validation

import drf_turbo as dt

class UserSerializer(dt.Serializer):
    username = dt.StrField(max_length=50)

    def validate_username(self, value):
        if 'test' not in value.lower():
            raise dt.ValidationError("test must be in username")
        return value

Object-level validation

import drf_turbo as dt

class CampaignSerializer(dt.Serializer):
    start_date = dt.DateTimeField()
    end_date = dt.DateTimeField()

    def validate(self, data):
        if data['start_date'] > data['end_date']:
            raise dt.ValidationError("start_date must occur before end_date")
        return data

Nested Serializers

from datetime import datetime
from django.utils.timezone import now
import drf_turbo as dt

 class User:
     def __init__(self, username, email,created=None):
         self.username = username
         self.email = email
         self.created = created or datetime.now()

 user = User(username='test' , email='test@example.com')

 class UserSerializer(dt.Serializer):
     username = dt.StrField(max_length=50)
     email = dt.EmailField()
     created = dt.DateTimeField()

 class Profile :
     def __init__(self, age=25):
         self.age = age
         self.user = user

 profile = Profile()


 class ProfileSerializer(dt.Serializer):
     age = dt.IntField()
     user = UserSerializer()


 serializer = ProfileSerializer(profile)
 serializer.data

 # {'age' : 25 , 'user' : {'username': 'test', 'email': 'test@example.com', 'created': '2021-11-04T22:49:01.981127Z'}}

Filtering Output

drf-turbo provides option to enclude or exclude fields from serializer using only or exclude keywords.

serializer = UserSerializer(user,only=('id','username'))

or

serializer = ProfileSerializer(profile,exclude=('id','user__email'))

or

http://127.0.0.1:8000/user/?only=id,username

Required Fields

Make a field required by passing required=True. An error will be raised if the the value is missing from data during Deserializing.

For example:

class UserSerializer(dt.Serializer):

    username = dt.StrField(required=True,error_messages={"required":"no username"})

Specifying Defaults

It will be used for the field if no input value is supplied.

For example:

from datetime import datetime

class UserSerializer(dt.Serializer):

    birthdate = dt.DateTimeField(default=datetime(2021, 11, 05))

ModelSerializer

Mapping serializer to Django model definitions.

Features :

  • It will automatically generate a set of fields for you, based on the model.
  • It will automatically generate validators for the serializer.
  • It includes simple default implementations of .create() and .update().
class UserSerializer(dt.ModelSerializer):

    class Meta :
        model = User
        fields = ('id','username','email')

You can also set the fields attribute to the special value __all__ to indicate that all fields in the model should be used.

For example:

class UserSerializer(dt.ModelSerializer):

    class Meta :
        model = User
        fields = '__all__'

You can set the exclude attribute to a list of fields to be excluded from the serializer.

For example:

class UserSerializer(dt.ModelSerializer):

    class Meta :
        model = User
        exclude = ('email',)

Read&Write only fields

class UserSerializer(dt.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'password','password_confirmation')
        read_only_fields = ('username')
        write_only_fields = ('password','password_confirmation')

Parsers

Allow only requests with JSON content, instead of the default of JSON or form data.

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'drf_turbo.parsers.JSONParser',
    ]
}

or

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'drf_turbo.parsers.UJSONParser',
    ]
}

or

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'drf_turbo.parsers.ORJSONParser',
    ]
}

NOTE: ujson must be installed to use UJSONParser.

NOTE: orjson must be installed to use ORJSONParser.

Renderers

Use JSON as the main media type.

REST_FRAMEWORK = {
    'DEFAULT_RENDERERS_CLASSES': [
        'drf_turbo.renderers.JSONRenderer',
    ]
}

or

REST_FRAMEWORK = {
    'DEFAULT_RENDERERS_CLASSES': [
        'drf_turbo.renderers.UJSONRenderer',
    ]
}

or

REST_FRAMEWORK = {
    'DEFAULT_RENDERERS_CLASSES': [
        'drf_turbo.renderers.ORJSONRenderer',
    ]
}

NOTE: ujson must be installed to use UJSONRenderer.

NOTE: orjson must be installed to use ORJSONRenderer.

Responses

An HttpResponse subclass that helps to create a JSON-encoded response. Its default Content-Type header is set to application/json.

from rest_framework.views import APIView
import drf_turbo as dt

class UserInfo(APIView):
    def get(self,request):
        data = {"username":"test"}
        return dt.JsonResponse(data,status=200)

or

class UserInfo(APIView):
    def get(self,request):
        data = {"username":"test"}
        return dt.UJSONResponse(data,status=200)

or

class UserInfo(APIView):
    def get(self,request):
        data = {"username":"test"}
        return dt.ORJSONResponse(data,status=200)

NOTE: ujson must be installed to use UJSONResponse.

NOTE: orjson must be installed to use ORJSONResponse.

Also drf-turbo provides an easy way to return a success or error response using SuccessResponse or ErrorResponse clasess.

for example :

class UserInfo(APIView):
    def get(self,request):
        data = {"username":"test"}
        serializer = UserSerializer(data=data)
        if not serializer.is_valid():
            return dt.ErrorResponse(serializer.errors)
             # returned response :  {'message':'Bad request', data : ``serializer_errros``, 'error': True} with status = 400
        return dt.SuccessResponse(data)
        # returned response :  {'message':'Success', data : {"username":"test"} , 'error': False} with status = 200

OpenApi(Swagger)

Add drf-turbo to installed apps in settings.py

INSTALLED_APPS = [
    # ALL YOUR APPS
    'drf_turbo',
]

and then register our openapi AutoSchema with DRF.

REST_FRAMEWORK = {
    # YOUR SETTINGS
    'DEFAULT_SCHEMA_CLASS': 'drf_turbo.openapi.AutoSchema',
}

and finally add these lines in urls.py

from django.views.generic import TemplateView
from rest_framework.schemas import get_schema_view as schema_view
from drf_turbo.openapi import SchemaGenerator

urlpatterns = [
    # YOUR PATTERNS
    path('openapi', schema_view(
        title="Your Project",
        description="API for all things …",
        version="1.0.0",
        generator_class=SchemaGenerator,
        public=True,
    ), name='openapi-schema'),
    path('docs/', TemplateView.as_view(
        template_name='docs.html',
        extra_context={'schema_url':'openapi-schema'}
    ), name='swagger-ui'),
]

Now go to http://127.0.0.1:8000/docs

Credits

This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.

History

0.1.0 (2021-11-10)

  • First release on PyPI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drf-turbo-0.1.5.tar.gz (717.0 kB view hashes)

Uploaded source

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page