Custom Accept
header routing support for Flask.
- 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.
Installing:
$ pip install flask-accept
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
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
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
Some possible use cases for Flask-Accept.
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.
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.
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.
To run the tests
python setup.py test
Open source MIT license.