Skip to main content

Build Status

Flask JsonTools

JSON API tools for Flask

Table of Contents

  • View Utilities

    • @jsonapi

      • JsonResponse

      • make_json_response()

  • FlaskJsonClient

  • Class-Based Views

    • MethodView

    • RestfulView

View Utilities

@jsonapi

Decorate a view function that talks JSON.

Such function can return:

  • tuples of (response, status[, headers]): to set custom status code and optionally - headers

  • Instances of `JsonResponse <#jsonresponse>`__

  • The result of helper function `make_json_response <#make_json_response>`__

Example:

from flask.ext.jsontools import jsonapi

@app.route('/users')
@jsonapi
def list_users():
    return [
        {'id': 1, 'login': 'kolypto'},
        #...
    ]

@app.route('/user/<int:id>', methods=['DELETE'])
def delete_user(id):
    return {'error': 'Access denied'}, 403

JsonResponse

Extends `flask.Request <http://flask.pocoo.org/docs/api/#incoming-request-data>`__ and encodes the response with JSON. Views decorated with `@jsonapi <#jsonapi>`__ return these objects.

Arguments:

Methods:

  • preprocess_response_data(response): Override to get custom response behavior.

  • get_json(): Get the original response data.

  • __getitem__(key): Get an item from the response data

The extra methods allows to reuse views:

from flask.ext.jsontools import jsonapi

@app.route('/user', methods=['GET'])
@jsonapi
def list_users():
    return [ { 1: 'first', 2: 'second' } ]

@app.route('/user/<int:id>', methods=['GET'])
@jsonapi
def get_user(id):
    return list_users().get_json()[id]  # Long form
    return list_users()[id]  # Shortcut

make_json_response()

Helper function that actually preprocesses view return value into `JsonResponse <#jsonresponse>`__.

Accepts rv as any of:

  • tuple of (response, status[, headers])

  • Object to encode as JSON

FlaskJsonClient

FlaskJsonClient is a JSON-aware test client: it can post JSON and parse JSON responses into `JsonResponse <#jsonresponse>`__.

from myapplication import Application
from flask.ext.jsontools import FlaskJsonClient

def JsonTest(unittest.TestCase):
    def setUp(self):
        self.app = Application(__name__)
        self.app.test_client_class = FlaskJsonClient

    def testCreateUser(self):
        with self.app.test_client() as c:
            rv = c.post('/user/', json={'name': 'kolypto'})
            # rv is JsonResponse
            rv.status_code
            rv.get_json()['user']  # Long form for the previous
            rv['user']  # Shortcut for the previous

Formatting Utils

DynamicJSONEncoder

In python, de-facto standard for encoding objects of custom classes is the __json__() method which returns the representation of the object.

DynamicJSONEncoder is the implementation of this protocol: if an object has the __json__() method, its result if used for the representation.

You’ll definitely want to subclass it to support other types, e.g. dates and times:

from flask.ext.jsontools import DynamicJSONEncoder

class ApiJSONEncoder(DynamicJSONEncoder):
    def default(self, o):
        # Custom formats
        if isinstance(o, datetime.datetime):
            return o.isoformat(' ')
        if isinstance(o, datetime.date):
            return o.isoformat()
        if isinstance(o, set):
            return list(o)

        # Fallback
        return super(DynamicJSONEncoder, self).default(o)

Now, just install the encoder to your Flask:

from flask import Flask

app = Flask(__name__)
app.json_encoder = DynamicJSONEncoder

JsonSerializableBase

Serializing SqlAlchemy models to JSON is a headache: if an attribute is present on an instance, this does not mean it’s loaded from the database.

JsonSerializableBase is a mixin for SqlAlchemy Declarative Base that adds a magic __json__() method, compatible with `DynamicJSONEncoder <#dynamicjsonencoder>`__. When serializing, it makes sure that entity serialization will never issue additional requests.

Example:

from sqlalchemy.ext.declarative import declarative_base
from flask.ext.jsontools import JsonSerializableBase

Base = declarative_base(cls=(JsonSerializableBase,))

class User(Base):
    #...

Now, you can safely respond with SqlAlchemy models in your JSON views, and jsontools will handle the rest :)

Class-Based Views

Module flask.ext.jsontools.views contains a couple of classes that allow to build class-based views which dispatch to different methods.

In contrast to MethodView, this gives much higher flexibility.

MethodView

Using MethodView class for methods, decorate them with @methodview(), which takes the following arguments:

  • methods=(): Iterable of HTTP methods to use with this method.

  • ifnset=None: Conditional matching. List of route parameter names that should not be set for this method to match.

  • ifset=None: Conditional matching. List of route parameter names that should be set for this method to match.

This allows to map HTTP methods to class methods, and in addition define when individual methods should match.

Quick example:

from flask.ext.jsontools import jsonapi, MethodView, methodview

class UserView(MethodView):
    # Canonical way to specify decorators for class-based views
    decorators = (jsonapi, )

    @methodview
    def list(self):
        """ List users """
        return db.query(User).all()

    @methodview
    def get(self, user_id):
        """ Load a user by id """
        return db.query(User).get(user_id)

userview = CrudView.as_view('user')
app.add_url_rule('/user/', view_func=userview)
app.add_url_rule('/user/<int:user_id>', view_func=userview)

Now, GET HTTP method is routed to two different methods depending on conditions. Keep defining more methods to get good routing :)

To simplify the last step of creating the view, there’s a helper:

UserView.route_as_view(app, 'user', ('/user/', '/user/<int:user_id>'))

RestfulView

Since MethodView is mostly useful to expose APIs over collections of entities, there is a RESTful helper which automatically decorates some special methods with @methodview.

View method

HTTP method

URL

list()

GET

/

create()

POST

/

get()

GET

/<pk>

replace()

PUT

/<pk>

update()

POST

/<pk>

delete()

DELETE

/<pk>

By subclassing RestfulView and implementing some of these methods, you’ll get a complete API endpoint with a single class.

It’s also required to define the list of primary key fields by defining the primary_key property:

from flask.ext.jsontools import jsonapi, RestfulView

class User(RestfulView):
    decorators = (jsonapi, )
    primary_key = ('id',)

    #region Operation on the collection

    def list():
        return db.query(User).all()

    def create():
        db.save(user)
        return user

    #endregion

    #region Operation on entities

    def get(id):
        return db.query(User).get(id)

    def replace(id):
        db.save(user, id)

    def update(id):
        db.save(user)

    def delete(id):
        db.delete(user)

    #endregion

When a class like this is defined, its metaclass goes through the methods and decorates them with @methodview. This way, list() gets @methodview('GET', ifnset=('id',)), and get() gets @methodview('GET', ifset=('id',)).

Metadata

Release files for flask-jsontools-slippers 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flask-jsontools-slippers 0.1.6
File Size Uploaded Provenance Actions
flask_jsontools_slippers-0.1.6.tar.gz 19.0 kB Without provenance Details for flask_jsontools_slippers-0.1.6.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for flask-jsontools-slippers 0.1.6
File Interpreter ABI Platform Actions
flask_jsontools_slippers-0.1.6-py2.py3-none-any.whl Python 2, Python 3 none any Details for flask_jsontools_slippers-0.1.6-py2.py3-none-any.whl

Total release size: 39.6 kB

Release files / flask_jsontools_slippers-0.1.6.tar.gz

Download URL flask_jsontools_slippers-0.1.6.tar.gz
Size 19.0 kB
Tags Source
SHA-256 checksum
How to use checksums
63717b875c7159ca4de6aec31bf203ccf8137edaaf0e5851f61093bfb231057b
BLAKE2b-256 checksum
How to use checksums
3ba7154125c246c593bf4f6788a226fc82d1f45573c81a5130d5ae40376b05c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / flask_jsontools_slippers-0.1.6-py2.py3-none-any.whl

Download URL flask_jsontools_slippers-0.1.6-py2.py3-none-any.whl
Size 20.5 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
1a538418ebcaa0b2140a7eadae982158db92f84aec49dc2f48f5fb7533bd69f1
BLAKE2b-256 checksum
How to use checksums
6c1d12f5448d3543ab0dd0e90428aa6f8164ef79996a0e543ef7c4cc00bfd487
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Security for flask-jsontools-slippers 0.1.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page