- Notifications
You must be signed in to change notification settings - Fork5
Flask extension that takes care of API representation and authentication.
License
marselester/flask-api-utils
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Flask-API-Utils helps you to create APIs. It makes responses in appropriateformats, for instance, JSON. All you need to do is to return dictionaryfrom your views. Another useful feature is an authentication.The library supportsHawk HTTP authentication scheme andFlask-Loginextension. To sum up, there is anAPI example project.
ResponsiveFlask tends to make responses based onAcceptrequest-header (RFC 2616). If a view function does not return a dictionary,then response will be processed as usual. Here is an example.
fromapi_utilsimportResponsiveFlaskapp=ResponsiveFlask(__name__)@app.route('/')defhello_world():return {'hello':'world'}defdummy_xml_formatter(*args,**kwargs):return'<hello>world</hello>'xml_mimetype='application/vnd.company+xml'app.response_formatters[xml_mimetype]=dummy_xml_formatterif__name__=='__main__':app.run()
It's assumed that file was saved asapi.py
:
$python api.py * Running on http://127.0.0.1:5000/
Here are curl examples with differentAccept headers:
$curl http://127.0.0.1:5000/ -iHTTP/1.0 200 OKContent-Type: application/jsonContent-Length: 22Server: Werkzeug/0.9.4 Python/2.7.5Date: Sat, 07 Dec 2013 14:01:14 GMT{ "hello": "world"}$curl http://127.0.0.1:5000/ -H'Accept: application/vnd.company+xml' -iHTTP/1.0 200 OKContent-Type: application/vnd.company+xml; charset=utf-8Content-Length: 20Server: Werkzeug/0.9.4 Python/2.7.5Date: Sat, 07 Dec 2013 14:01:50 GMT<hello>world</hello>$curl http://127.0.0.1:5000/ -H'Accept: blah/*' -iHTTP/1.0 406 NOT ACCEPTABLEContent-Type: application/jsonContent-Length: 83Server: Werkzeug/0.9.4 Python/2.7.5Date: Sat, 07 Dec 2013 14:02:23 GMT{ "mimetypes": [ "application/json", "application/vnd.company+xml" ]}
You can set HTTP error handler by using@app.default_errorhandlerdecorator. Note that it might override already defined error handlers,so you should declare it before them.
fromflaskimportrequestfromapi_utilsimportResponsiveFlaskapp=ResponsiveFlask(__name__)@app.default_errorhandlerdefwerkzeug_default_exceptions_handler(error):error_info_url= ('http://developer.example.com/errors.html#error-code-{}' ).format(error.code)response= {'code':error.code,'message':str(error),'info_url':error_info_url, }returnresponse,error.code@app.errorhandler(404)defpage_not_found(error):return {'error':'This page does not exist'},404classMyException(Exception):pass@app.errorhandler(MyException)defspecial_exception_handler(error):return {'error':str(error)}@app.route('/my-exc')defhello_my_exception():raiseMyException('Krivens!')@app.route('/yarr')defhello_bad_request():request.args['bad-key']if__name__=='__main__':app.run()
Let's try to curl this example. First response shows that we redefineddefault{'code': 400, 'message': '400: Bad Request'}
error format.Next ones show that you can handle specific errors as usual.
$curl http://127.0.0.1:5000/yarr -iHTTP/1.0 400 BAD REQUESTContent-Type: application/jsonContent-Length: 125Server: Werkzeug/0.9.4 Python/2.7.5Date: Sun, 29 Dec 2013 14:26:30 GMT{ "code": 400, "info_url": "http://developer.example.com/errors.html#error-code-400", "message": "400: Bad Request"}$curl http://127.0.0.1:5000/ -iHTTP/1.0 404 NOT FOUNDContent-Type: application/jsonContent-Length: 41Server: Werkzeug/0.9.4 Python/2.7.5Date: Sun, 29 Dec 2013 14:28:46 GMT{ "error": "This page does not exist"}$curl http://127.0.0.1:5000/my-exc -iHTTP/1.0 200 OKContent-Type: application/jsonContent-Length: 25Server: Werkzeug/0.9.4 Python/2.7.5Date: Sun, 29 Dec 2013 14:27:33 GMT{ "error": "Krivens!"}
Hawk extension provides API authentication for Flask.
Hawk is an HTTP authentication scheme using a message authentication code(MAC) algorithm to provide partial HTTP request cryptographic verification.
The extension is based onMohawk, so make sure you have installed it.
$pip install mohawk
Usage example:
fromflaskimportFlaskfromapi_utilsimportHawkapp=Flask(__name__)hawk=Hawk(app)@hawk.client_key_loaderdefget_client_key(client_id):# In a real project you will likely use some storage.ifclient_id=='Alice':return'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn'else:raiseLookupError()@app.route('/')@hawk.auth_requireddefindex():return'hello world'if__name__=='__main__':app.run()
$curl http://127.0.0.1:5000/ -iHTTP/1.0 401 UNAUTHORIZED...
Cookie based authentication is disabled by default.SetHAWK_ALLOW_COOKIE_AUTH = True
to enable it. AlsoHawk supportsresponse signing, enable itHAWK_SIGN_RESPONSE = True
if you need it.
Following configuration keys are used byMohawk library.
HAWK_ALGORITHM='sha256'HAWK_ACCEPT_UNTRUSTED_CONTENT=FalseHAWK_LOCALTIME_OFFSET_IN_SECONDS=0HAWK_TIMESTAMP_SKEW_IN_SECONDS=60
CheckMohawk documentation for more information.
It can be convenient to globally turn off authentication when unit testingby settingHAWK_ENABLED = False
.
Tests are run by:
$pip install -r requirements.txt$tox
About
Flask extension that takes care of API representation and authentication.
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.