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

Overview

drf-turbo

Documentation Status Updates

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

Performance

https://drf-turbo.readthedocs.io/en/latest/performance.html

Examples

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='[email protected]')



 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': '[email protected]', 'created': '2021-11-04T22:49:01.981127Z'}

Deserializing objects

data = {'username':'new_test','email':'[email protected]','created':now()}
serializer = UserSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# {'username': 'new_test', 'email': '[email protected]', '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='[email protected]')

 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': '[email protected]', '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.

You might also like...
Free and open source full-stack enterprise framework for agile development of secure database-driven web-based applications, written and programmable in Python.

Readme web2py is a free open source full-stack framework for rapid development of fast, scalable, secure and portable database-driven web-based applic

A public API written in Python using the Flask web framework to determine the direction of a road sign using AI
A public API written in Python using the Flask web framework to determine the direction of a road sign using AI

python-public-API This repository is a public API for solving the problem of the final of the AIIJC competition. The task is to create an AI for the c

A Flask API REST to access words' definition
A Flask API REST to access words' definition

A Flask API to access words' definitions

Pretty tornado wrapper for making lightweight REST API services

CleanAPI Pretty tornado wrapper for making lightweight REST API services Installation: pip install cleanapi Example: Project folders structure: . ├──

Containers And REST APIs Workshop
Containers And REST APIs Workshop

Containers & REST APIs Workshop Containers vs Virtual Machines Ferramentas Podman: https://podman.io/ Docker: https://www.docker.com/ IBM CLI: https:/

Free & open source Rest API for YTDislike

RestAPI Free & open source Rest API for YTDislike, read docs.ytdislike.com for implementing. Todo Add websockets Installation Git clone git clone http

Asita is a web application framework for python based on express-js framework.

Asita is a web application framework for python. It is designed to be easy to use and be more easy for javascript users to use python frameworks because it is based on express-js framework.

Loan qualifier app - Loan Qualifier Application Built With Python

Loan Qualifier Application This program is designed to automate the discovery pr

Trame let you weave various components and technologies into a Web Application solely written in Python.

Trame Trame aims to be a framework for building interactive applications using a web front-end in plain Python. Such applications can be used locally

Comments
  • Fixes: #7 -add performance comparison to readme

    Fixes: #7 -add performance comparison to readme

    Some changes to handle #7.

    • Surfaces key benchmark data to readme, cleans up file whitespace
    • Adds table with relative performance and semi-sorted raw data

    I wasn't sure if you needed the docs regenerated, or would do that as part of a release.

    opened by banagale 4
  • Performance comparisons / benchmarks

    Performance comparisons / benchmarks

    I saw this pop up in the django news newsletter. I could have used this on a project a while back where we wanted more performance out of serialization in DRF.

    Can someone give sort of a high level idea of what kind of performance improvements one might expect by swapping this in for what comes with DRF today?

    opened by banagale 3
  • How to use drf_turbo serializer

    How to use drf_turbo serializer

    • drf-turbo version:0.1.5
    • Python version:3.9
    • Operating System:win10

    Description

    I am trying to save data in the postgres using django with the serializer implemented in cython

    What I Did

    I followed the process you written in the documentations but the cython build i didn't know how to build and if i use dt.serializer it gives me in save no object has no attribute 'create' and if i use dr.ModelSerializer

    Paste the command(s) you ran and the output.
    If there was a crash, please include the traceback here.
    
    opened by hossamdebyene 15
Releases(v0.1.6)
Owner
Mng
Mng
Pyrin is an application framework built on top of Flask micro-framework to make life easier for developers who want to develop an enterprise application using Flask

Pyrin A rich, fast, performant and easy to use application framework to build apps using Flask on top of it. Pyrin is an application framework built o

Mohamad Nobakht 10 Jan 25, 2022
The no-nonsense, minimalist REST and app backend framework for Python developers, with a focus on reliability, correctness, and performance at scale.

The Falcon Web Framework Falcon is a reliable, high-performance Python web framework for building large-scale app backends and microservices. It encou

Falconry 9k Jan 1, 2023
REST API framework designed for human beings

Eve Eve is an open source Python REST API framework designed for human beings. It allows to effortlessly build and deploy highly customizable, fully f

eve 6.6k Jan 7, 2023
REST API framework designed for human beings

Eve Eve is an open source Python REST API framework designed for human beings. It allows to effortlessly build and deploy highly customizable, fully f

eve 6.3k Feb 17, 2021
Django Ninja - Fast Django REST Framework

Django Ninja is a web framework for building APIs with Django and Python 3.6+ type hints.

Vitaliy Kucheryaviy 3.8k Jan 2, 2023
Goblet is an easy-to-use framework that enables developers to quickly spin up fully featured REST APIs with python on GCP

GOBLET Goblet is a framework for writing serverless rest apis in python in google cloud. It allows you to quickly create and deploy python apis backed

Austen 78 Dec 27, 2022
Daniel Vaz Gaspar 4k Jan 8, 2023
Dazzler is a Python async UI/Web framework built with aiohttp and react.

Dazzler is a Python async UI/Web framework built with aiohttp and react. Create dazzling fast pages with a layout of Python components and bindings to update from the backend.

Philippe Duval 17 Oct 18, 2022
Appier is an object-oriented Python web framework built for super fast app development.

Joyful Python Web App development Appier is an object-oriented Python web framework built for super fast app development. It's as lightweight as possi

Hive Solutions 122 Dec 22, 2022
Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs

chisel Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs. Here are its fea

Craig Hobbs 2 Dec 2, 2021