What frameworks exists that supports REST-API within python ?

1. Django REST Framework

Quoting information from site:

Some reasons you might want to use REST framework:

- The Web browsable API is a huge usability win for your developers.
- Authentication policies including packages for OAuth1a and OAuth2.
- Serialization that supports both ORM and non-ORM data sources.
- Customizable all the way down - just use regular function-based views if you don't need the more powerful features.
- Extensive documentation, and great community support.
- Used and trusted by internationally recognised companies including Mozilla, Red Hat, Heroku, and Eventbrite.

2. Flask and Bottle

Quoting information from site about Bottle:

Bottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is distributed as a single file module and has no dependencies other than the Python Standard Library.

- Routing: Requests to function-call mapping with support for clean and dynamic URLs.
- Templates: Fast and pythonic built-in template engine and support for mako, jinja2 and cheetah templates.
- Utilities: Convenient access to form data, file uploads, cookies, headers and other HTTP-related metadata.
- Server: Built-in HTTP development server and support for paste, fapws3, bjoern, gae, cherrypy or any other WSGI capable HTTP server.

3. Flask-restful

Quoting information from site :

Flask-RESTful is an extension for Flask that adds support for quickly building REST APIs. 
It is a lightweight abstraction that works with your existing ORM/libraries. 
Flask-RESTful encourages best practices with minimal setup. 
If you are familiar with Flask, Flask-RESTful should be easy to pick up.

4. Python-Eve

Quoting information from site :

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

Eve is powered by Flask, Cerberus, Events and MongoDB.
Support for SQL-Alchemy, Elasticsearch and Neo4js as alternate backends is provided by community extensions.

The codebase is thoroughly tested under Python 2.6, 2.7, 3.3, 3.4, 3.5, 3.6 and PyPy.

5. Falcon

Quoting information from site :

Falcon is a very fast, very minimal Python web framework for building microservices, app backends, and higher-level frameworks.
It is used by a growing number of organizations around the world, including Cronitor, EMC, Hurricane Electric, OpenStack, Opera Software, Wargaming, and Rackspace.

The Falcon web framework encourages the REST architectural style, meaning (among other things) that you think in terms of resources and state transitions, which map to HTTP methods.

A number of Falcon add-ons, templates, and complimentary packages are available for use in your projects.
We've listed several of these on the Falcon wiki as a starting point, but you may also wish to search PyPI for additional resources.

Falcon can be deployed in a variety of ways, depending on your needs.
The framework speaks WSGI, and works great with CPython 2.6 and 2.7, PyPy, and CPython 3.3+.

6. Cornice

Quoting information from site :

Cornice provides helpers to build & document REST-ish Web Services with Pyramid, with decent default behaviors.
It takes care of following the HTTP specification in an automated way where possible.

We designed and implemented cornice in a really simple way, so it is easy to use and you can get started in a matter of minutes.

7. Tastypie

Quoting information from site :

Tastypie is a webservice API framework for Django.
It provides a convenient, yet powerful and highly customizable, abstraction for creating REST-style interfaces.

8. Others maybe included here

What framework our Biking-Endorphines will use?

1. My selection criteria:

1.A) REST API creation
1.B) TDD support
1.C) Different type of data formats i.e. json and xml (best - out of the box)
1.D) Documentation (best - out of the box)

2. What framework looks like supports all my criteria out of the box?

Well that's not a surprise - the Django Rest Framwork passes all my criteria.

How to use Django Rest Framework?

1. Serializers.

First you need to have any type of Serializer for your objects.

In our projects example I'll use the "User" class definition for creating serializer:

class UserSerializer(serializers.Serializer):
    """
    User serializer
    """
    #pylint: disable=invalid-name
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(required=False, allow_blank=True, max_length=50)
    surname = serializers.CharField(required=False, allow_blank=True, max_length=100)
    weight = serializers.IntegerField(required=False, default=0)
    height = serializers.IntegerField(required=False, default=0)

    def create(self, validated_data):
        """
        Create and return a new `User` instance, given the validated data.
        """
        return User.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing `User` instance, given the validated data.
        """
        instance.name = validated_data.get('name', instance.name)
        instance.surname = validated_data.get('surname', instance.surname)
        instance.weight = validated_data.get('weight', instance.weight)
        instance.height = validated_data.get('height', instance.height)
        instance.save()
        return instance

But wait.... what about tests ? - Good point.

"""
Tests for API
"""
import unittest
from api.serializers import UserSerializer
from web.models import User



class TestUserSerializer(unittest.TestCase):
    "UserSerializer tests"

    def test_user_serialize_to_json(self):
        "test if serializing to JSON works"

        mocked = User()
        mocked.name = "Anselmos"
        mocked.surname = "Somlesna"
        mocked.weight = 80
        mocked.height = 175

        user_serialized = UserSerializer(mocked)
        self.assertEqual(
            (user_serialized.data),
            {'height': 175, 'surname': u'Somlesna', 'id': None, 'weight': 80, 'name': u'Anselmos'}
        )

2. Views for API.

Now lets create a View for our Serializer and then add it to our urls.py

"""
Views
"""
from rest_framework.views import APIView
from rest_framework.response import Response

from api.serializers import UserSerializer
from web.models import User


class UserList(APIView):
    """
    List all User's, or create a new snippet
    """

    def get(self, request, format=None):
        "GET"
        users = User.objects.all()
        serializer = UserSerializer(users, many=True)
        return Response(serializer.data)

Test:(yeah it's not enough for a test, but still simplest one:)

class TestUserList(unittest.TestCase):
    "UserList tests"

    def test_user_get_return_json(self):
        "test if using get returns json data"

        view = UserList.as_view()
        factory = APIRequestFactory()
        request = factory.get("/api/user/")
        force_authenticate(request)
        response = view(request)
        self.assertEquals(response.status_code, 200)

3. Urls for proper handling on outside:

In urls.py

    url(r'^api/user/$', views.UserList.as_view()),

Final result

Final result is available at this branch

Code commits done for this post:

Tools and applications used:

Acknowledgements

Accomplished:

1. REST-API for Test-Database.

What's next

1. Making API documentation - research for best API documentation!

2. How to secure biking-endorphines REST-API.

3. Badge Gathering source-code and tests.



Comments

comments powered by Disqus