Skip to main content

Custom Accept header routing support for Flask

Project description

https://travis-ci.org/di/flask-accept.svg?branch=master

Description

Custom Accept header routing support for Flask.

Features

Respond differently based on the MIME type accepted

Extend any given endpoint to support any additional media type.

Use custom media types to version your API

Never put a /v1/ in your URI ever again.

Dead-simple API

Yet Another Flask Decorator.

Documentation

Installation

Installing:

$ pip install flask-accept

Quickstart

Below is an example Flask app that only accepts the text/html media type:

from flask import Flask
from flask_accept import accept
app = Flask(__name__)

@app.route('/')
@accept('text/html')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

When one tries to access the endpoint without a valid Accept header:

$ curl localhost:5000 -I
HTTP/1.0 406 NOT ACCEPTABLE

With the valid header:

$ curl localhost:5000 -I -H "Accept: text/html"
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8

Adding Support for an Existing Endpoint

Given our example from before, we can add support for a different response to an additonal media type as follows:

from flask import Flask, jsonify
from flask_accept import accept
app = Flask(__name__)

@app.route('/')
@accept('text/html')
def hello_world():
    return 'Hello World!'

@hello_world.support('application/json')
def hello_world_json():
    return jsonify(result="Hello World!")

if __name__ == '__main__':
    app.run()

Now our hello_world endpoint supports JSON:

$ curl localhost:5000 -I -H "Accept: application/json"
HTTP/1.0 200 OK
Content-Type: application/json

Falling Back on a Default Endpoint

If we want to support a specific media type, but have every other request fall back to a default endpoint, we can use accept_fallback as follows:

from flask import Flask, jsonify
from flask_accept import accept, accept_fallback
app = Flask(__name__)

@app.route('/')
@accept_fallback
def hello_world():
    return 'Hello World!'

@hello_world.support('application/json')
def hello_world_json():
    return jsonify(result="Hello World!")

if __name__ == '__main__':
    app.run()

Our hello_world endpoint still supports JSON, but for any other media type (or if none is specified) it will fall back:

$ curl localhost:5000 -I
HTTP/1.0 200 OK
Content-Type: text/html

$ curl localhost:5000 -I -H "Accept: madeup/mediatype"
HTTP/1.0 200 OK
Content-Type: text/html

Use Cases

Some possible use cases for Flask-Accept.

Versioning your API

Flask-Accept let you accept any possible media type, including custom vendored media types. This is ideal for versioning an API using Accept headers only:

from flask import Flask, jsonify
from flask_accept import accept
app = Flask(__name__)

@app.route('/')
@accept('application/vnd.your_vendor.v1', 'application/vnd.your_vendor.v2')
def hello_world():
    return 'Hello World!'

@hello_world.support('application/vnd.your_vendor.v3')
def hello_world_v2():
    return 'Goodbye cruel world.'

if __name__ == '__main__':
    app.run()
$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v1"
Hello World!

$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v2"
Hello World!

$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v3"
Goodbye cruel world.

Works with Flask-RESTful Resources

The same functionality can be applied to APIs built with Flask-RESTful

from flask import Flask, jsonify
from flask_accept import accept
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)


class HelloWorldResource(Resource):
    @accept('application/vnd.your_vendor.v1', 'application/vnd.your_vendor.v2')
    def get():
        return 'Hello World!'

    @get.support('application/vnd.your_vendor.v3')
    def get_v2():
        return 'Goodbye cruel world.'


api.add_resource(HelloWorldResource, '/')

if __name__ == '__main__':
    app.run()
$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v1"
Hello World!

$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v2"
Hello World!

$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v3"
Goodbye cruel world.

Works with Flask-RESTPlus Resources

The same functionality can be applied to APIs built with Flask-RESTPlus

from flask import Flask, jsonify
from flask_accept import accept
from flask_restplus import Resource, Api
app = Flask(__name__)
api = Api(app)


class HelloWorldResource(Resource):
    @accept('application/vnd.your_vendor.v1', 'application/vnd.your_vendor.v2')
    def get():
    """
        The doc string showing in swagger
    """
        return 'Hello World!'

    @get.support('application/vnd.your_vendor.v3')
    def get_v2():
        return 'Goodbye cruel world.'


api.add_resource(HelloWorldResource, '/')

if __name__ == '__main__':
    app.run()
$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v1"
Hello World!

$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v2"
Hello World!

$ curl localhost:5000 -H "Accept: application/vnd.your_vendor.v3"
Goodbye cruel world.

Testing

To run the tests

python setup.py test

Authors

License

Open source MIT license.

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

flask_accept-0.0.6.tar.gz (4.4 kB view details)

Uploaded Source

Built Distribution

flask_accept-0.0.6-py3-none-any.whl (3.8 kB view details)

Uploaded Python 3

File details

Details for the file flask_accept-0.0.6.tar.gz.

File metadata

File hashes

Hashes for flask_accept-0.0.6.tar.gz
Algorithm Hash digest
SHA256 be48f7d805f1a9dadeabce0fd166404eda92da8d2cf1945237aff278238f4c70
MD5 12104e475169af6fbace0388d3314850
BLAKE2b-256 0a54de4111e7ef8450bbfec187cd8e066134b2b46df679b0ad59221fd421d26d

See more details on using hashes here.

File details

Details for the file flask_accept-0.0.6-py3-none-any.whl.

File metadata

File hashes

Hashes for flask_accept-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 4be4c34aa0a13bb56427e45426297858e3d189bebac415b88694e6489f61d1e0
MD5 38a2ed19eab75283cfa5c530933de9fb
BLAKE2b-256 6149947363e334a62787e10b9ccc5ce3f3578866bf56704900b53054f2778d61

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page