flask-restful / flask-restful Goto Github PK
View Code? Open in Web Editor NEWSimple framework for creating REST APIs
Home Page: http://flask-restful.readthedocs.io
License: BSD 3-Clause "New" or "Revised" License
Simple framework for creating REST APIs
Home Page: http://flask-restful.readthedocs.io
License: BSD 3-Clause "New" or "Revised" License
When installing flask-restful from PIP and using reqparse, it complains about not having the package 'six' installed. Installing it manually solves it, but I suppose this should be marked as a dependency ?
I notice it even downloads six, but for some reason, it does not install it properly.
When Blueprint is used instead of standard flask app, restful.abort return HTML rather than JSON
blueprint = Blueprint('apis', __name__)
api = Api(blueprint)
I need to add the following code to make it work:
app.handle_user_exception = api.handle_error
Not sure is there a more elegant solution. I tried overriding blueprint.app_handle_error, blueprint.app_errorhandler, doesn't seems to work.
Couldn't find a way to access Flask app from blueprint, accessing Flask.current_app in Api class throws RuntimeError('working outside of application context')
In Flask you can use the url_for
function to get the URL for a particular function. This doesn't directly work with Flask-RESTful Resource
s, or at least I don't know how to go about this. Perhaps this could be documented somewhere?
According to the Flask documentation we should get exceptions in our test_client()
if we set testing = True
:
http://flask.pocoo.org/docs/api/#flask.Flask.test_client
However, Flask-RESTful will stlll give only the {u'status': 500, u'message': u'Internal Server Error'}
response when an uncatched exception occurs. Only when you set debug = True
it will show the errors too.
I think because debug = True
is the default behaviour of a Flask application, only for the test_client()
it works differently in Flask. So maybe to prevent confusion, Flask-RESTful should also check the testing
variable?
There is a 0.2.5 release on pypi and in the changelog but not in the github releases system. Just fyi.
I am looking for one important thing, which I don't think is there yet in the library (or might be, but I didn't find it), is the way to implement HATEOAS. Do you guys have an recommendations about it?
The use case where I see it would be really interesting is when I have collection of model instances and I need to create a paginated front-end, then if server creates the urls with first, next, prev, last, urls in the payload, that would be awesome
something as mentioned here - http://stackoverflow.com/questions/501013/restful-design-paging-collections
Thank you again for lot of good work
In the full code example given in the documentation (http://flask-restful.readthedocs.org/en/latest/quickstart.html#full-example), there is this line of comment:
# TodoList
# shows a list of all todos, and lets you POST to add new tasks
However, the examples on creating new tasks below actually uses PUT to create new tasks. Furthermore, the example in the docs is different from another example in the code base (https://github.com/twilio/flask-restful/blob/master/examples/todo.py) which contains the actual POST implementation.
I can make quick pull request to either remove the POST comment or to change the docs to use the example code in the code base for correctness but I'm unsure which is the preferred example in the documentation.
When using foo = fields.Nested(foo_fields)
and the object being marshaled has a None value for the associated field, you get an empty object in your representation. It would be nice to have the option to have the field be null
in JSON instead.
Hi,
I'm using Flask-RESTful for my new project and what's best way to validate POST data with JSON object?
flask.ext.restful.reqparse is hardcoded to use Flask request object.
Are there any other libraries that can do similar level of validation and return cleaned dictionary?
Thanks.
It would be nice to support automatic handling/adding of CORS headers.
Hi there,
I've just noticed we are having a strange behavior with the trailing slash:
this is a simple Flask demo, the one at http://flask.pocoo.org/docs/quickstart/ with a different url:
$ curl -I http://127.0.0.1:5000/hello/ HTTP/1.0 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 12 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Tue, 09 Apr 2013 15:05:19 GMT $ curl -I http://127.0.0.1:5000/hello HTTP/1.0 301 MOVED PERMANENTLY Content-Type: text/html; charset=utf-8 Content-Length: 263 Location: http://127.0.0.1:5000/hello/ Server: Werkzeug/0.8.3 Python/2.7.3 Date: Tue, 09 Apr 2013 15:05:21 GMT
my flask-restful API:
$ curl -I http://127.0.0.1:5000/objects/ HTTP/1.0 200 OK Content-Type: application/json Content-Length: 2 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Tue, 09 Apr 2013 15:07:10 GMT $ curl -I http://127.0.0.1:5000/objects HTTP/1.0 301 MOVED PERMANENTLY Content-Type: application/json Content-Length: 47 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Tue, 09 Apr 2013 15:07:29 GMT
As you can see it's a redirect without the Location header.
Regards,
Giorgio
This question feels similar to Issue #18 and concerns how to split up bigger flask-restful projects.
I'm pretty new to both flask and flask-restful but it looks like Blueprints are the way to go. Unfortunately I had to add a couple of lines to avoid complaints about error handling which sort of smell. Here they are in context:
In todo.py:
todo_bp = Blueprint('todo_api', __name__)
todo_bp.handle_exception = None
todo_bp.handle_user_exception = None
todo_api = Api(todo_bp)
This works, but like I say doesn't seem right.
I've also extended the TODOS example from this repository to demonstrate how I was splitting an app across three files. Would it help to share this and if so, what is the best way? If you can help me get it right, it might be nice to add it as another example?
Cheers,
Ben
should be retrieve_next_page
- or removed altogether since it's not documented anywhere and adds the pycrypto dependency...
If you add a resource with the same name from different modules, flask-restful gives them the same endpoint. Both paths will then route to the same Resource class and will cause errors.
import v1
import v2
app = Flask(__name__)
api = restful.Api(app)
api.add_resource(v1.TodoList, '/v1/todos')
api.add_resource(v2.TodoList, '/v2/todos/<string:todo_id>')
The workaround is to explicitly give them endpoint names.
api.add_resource(v1.TodoList, '/v1/todos', endpoint="v1.todolist")
api.add_resource(v2.TodoList, '/v2/todos/<string:todo_id>', endpoint="v2.todolist")
With the sphinxcontrib.autohttp.flask
extension, one can automatically generate documents as follows:
.. autoflask:: main:app
:undoc-static:
However, it seems docstrings under RESTful functions like get
, post
, or delete
do not appear on auto-generated documents.
Refer this page for more details.
It's not possible to install flask-restful using pip install flask-restful
without an internet connection.
Something about the way flask-restful's dependencies are listed:
pip freeze
from finding flask-restful's requirements (mock, blinker, nose)None of the other packages that are requirments in my project (e.g. Flask, NLTK) have this problem, so perhaps flask-restful's dependencies are listed or handled in a nonstandard way.
Or maybe I'm just installing it wrong, and I there is a way I don't know about that allows installing it with pip in way that ignore's the setup_requires
argument in setup.py
.
I'm trying to add Sentry (https://www.getsentry.com/) to my flask-restful apps.
It should work in a transparent way, but I can see only exceptions manually sent to Sentry.
Here is the Sentry setup:
http://raven.readthedocs.org/en/latest/config/flask.html#setup
Should I consider it as a bug?
Hello,
I've been struggling for a couple hours to override the default JSONEncoder. I started by trying the Flask method of setting Flask.json_encoder. After stepping through the code, it looks like Flask-Restful discards that setting altogether.
I also tried using @api.representation('application/json') with the example from the "Response Formats" section of the docs. Within the function body, I called the standard json.dumps with a custom JSONEncoder-derived class. That resulted in a recursive loop that I didn't dig much deeper into.
I'd prefer to avoid using output parameters since what I'm really trying to do is blindly pass data from database back to the caller. Any ideas here?
-Scott
Hi @kevinburke
My resource_fields is
resource_fields = {
'uuid': fields.String,
'name': fields.String,
'created_on': fields.DateTime,
'amount': fields.Float,
'debit': fields.Boolean,
'category': fields.String # this is actually an sqlalchemy object
}
Currently, my response payload looks something like
{
'category': '<Category: 34eb8825-e991-47e4-aae3-65e435dafc2f: food: parent>', #currently string
'uuid': 'a2901253-12ac-4b9c-8748-513594864974',
'created_on': 'Tue, 16Apr201303: 35: 09-0000',
'amount': '10.0',
'debit': True,
'name': 'Costco'
}
How can I return category as nested object rather than String? like
{
'category': {
'uuid': '34eb8825-e991-47e4-aae3-65e435dafc2f',
'name': 'food',
'parent': 'parent'
}
'uuid': 'a2901253-12ac-4b9c-8748-513594864974',
'created_on': 'Tue, 16Apr201303: 35: 09-0000',
'amount': '10.0',
'debit': True,
'name': 'Costco'
}
What the title says.
I'm fairly new to flask, but I suspect the way flask-restful takes over the exception handler of the application object it is provided is wrong.
If my understanding is correct, I suspect the larger underlying design decision is that flask-restful is meant to work with an app (and requires one to be initialized) rather than as a blueprint.
Using restful's abort command restful.abort(401)
results in a standard username/password dialog box.
The unauthorized method in restful.utils should either have an option to be turned off
I write a flask-restful application, how can I deploy it in the real world?
Hi All,
I'm just wondering if anyone has deployed flask restful service on IIS? Is there any guide around this area ?
Thanks,
Ahad
$ pip install flask-restful
$ python
>>> from flask.ext.restful import fields
Traceback (most recent call last):
File "testcase.py", line 1, in <module>
from flask.ext.restful import fields
File "/home/saml/py/lib/python3.3/site-packages/flask_restful/fields.py", line 2, in <module>
import six
ImportError: No module named 'six'
Hello. I've been trying to get Sentry (www.getsentry.com) up and running with Flask-Restful, but since it already handles errors so well, there's no way to trigger Sentry. What would be the best approach for tracking various errors (400s, 500s, etc.) in a centralized manner? Thanks!
Hi,
I've installed restful and almost eveything works but I may forgot something as this code below runs and when I make a GET request with python my query argument is None.
I've read the sentence about arguments set to None if not set in the Request but I don't understand what you mean by "set in the request itself".
Thanks.
Python code for a get request
>>> get('http://localhost:5000/sync/bla',data={'query':'bla'}).json()
{u'args': {u'content': None, u'query': None}, u'mid': u'bla', u'you called': u'get'}
Server code
from flask import Flask
from flask.ext.restful import reqparse, abort, Api, Resource
app = Flask(__name__)
api = Api(app)
parser = reqparse.RequestParser()
parser.add_argument('query',type=str)
parser.add_argument('content',type=str)
class Sync(Resource):
def get(self, mid):
args = parser.parse_args()
return {'you called': 'get', 'mid': mid, 'args': args}
def post(self, mid):
args = parser.parse_args()
return {'you called': 'post', 'mid': mid, 'args': args}
def delete(self, mid):
args = parser.parse_args()
return {'you called': 'delete', 'mid': mid, 'args': args}
def put(self, mid):
args = parser.parse_args()
return {'you called': 'put', 'mid': mid, 'args': args}
api.add_resource(Sync, '/sync')
api.add_resource(Sync, '/sync/<string:mid>')
if __name__ == '__main__':
app.run(debug=True)
When parsing args with location set to 'json', I get an AttributeError
File "/Users/ke/.virtualenvs/quest/lib/python2.7/site-packages/flask_restful/reqparse.py", line 91, in parse
values = source.getall(name)
AttributeError: 'dict' object has no attribute 'getall'
But when I use the request.json dictionary instead, I can access the args.
My code :
parser = reqparse.RequestParser()
parser.add_argument('last_name', location='json')
args = parser.parse_args()
print(args['last_name'])
I have a method_decorator that adds CORS headers to each request, but is not being called for the OPTIONS method because is not explicitly defined. To hack this into working I had to add an empty method:
def options(self):
pass
Please see this isse and this PR that implements this petit hack.
Thanks.
marshal_with
works only for methods returning simple objects, but lacks support for other (normally valid) return values from views, such as tuples.
Example (raises an exception):
class SmurfListResource(Resource):
@marshal_with(fields)
def post(self):
smurf = Smurf(**parser.parse_args())
smurf.save()
return smurf, 202, {'Location': url_for('smurf', smurf_id=smurf.id, _external=True)}
It has to be done this way, which is non-declarative, less clear by first sight, and introduces unncecessary extra typing if all your other views can be decorated as above:
class SmurfListResource(Resource):
def post(self):
smurf = Smurf(**parser.parse_args())
smurf.save()
data = marshal(smurf, fields)
return data, 202, {'Location': url_for('smurf', smurf_id=smurf.id, _external=True)}
At least, it could be documented decorator does not accept such return values. I spent quite a time by wandering why my code does not work (error TypeError: 'int' object has no attribute '__getitem__'
raised from deep internals of Flask-RESTful does not say much...).
There are two issues here:
If I'm defining outputs for my error messages, I don't want Flask-Restful to add a non-overridable text to my potentially public facing output. It's just confusing. If I pass a message kwarg to abort it shouldn't append data to that message.
Bug in finding "close matches" when using url params
My Code:
abort(404, message="user {} not found".format(args['with_id']))
The output:
curl localhost:5003/foo/z4s6hp33im0h?with_id=123
{
"message": "user 123 not found. You have requested this URI [/foo/z4s6hp33im0h] but did you mean /foo/<key> ?"
}
Not that it's a huge issue for most people, but the Api
class is not designed according to Armin's extension guidelines. This is specific to the usage of self.app
within the Api
class. Per the extensions guidelines (Just above the _app_ctx_stack section):
As you noticed, init_app does not assign app to self. This is intentional! Class based
Flask extensions must only store the application on the object when the application
was passed to the constructor. This tells the extension: I am not interested in using
multiple applications.When the extension needs to find the current application and it does not have a
reference to it, it must either use the current_app context local or change the API in
a way that you can pass the application explicitly.
Instead, current_app
should be used in the Api.handle_error
function and, unfortunately, the API exposed to add resources would need to be changed since it relies on self.app
as well.
My first idea would be to add a resources
parameter to the constructor and init_app
functions, although I am not sure if this would work for most users of this extension.
Hello @RobSpectre @cummack @devinrader @dougblack @frankstratton
I have a following situation where I have User
Resource and it needs following endpoints
GET /users/uuid/
# returns user
GET /users/uuid/financialmonthdetails
# returns a map like
{
'time_from': some_time,
'time_to': some_time,
'remaining_days': some_days
}
Question
How can I have two @GET
endpoints in same resource class?
Thank you
What about adding support for requests in JSON format?
I could even contribute to it, if you help and point me to the right way to do it, because I'm approaching Flask for the first time in this period.
Regards,
Giorgio
I ran into an issue trying to marshal an SQLAlchemy instance with related/nested fields, I suspect it could impact other dynamic objects.
In my case, I have a Book
has a relation to Author
and has a book.author
related field. Marshalling a book instance with the fields dict {'title': fields.String, 'author': fields.Nested({'name': fields.String})}
may or may not succeed depending on whether the author
field was already accessed on this book instance. The reason is that nesting occurs after the call to to_marshallable_type
(as can be seen here), and to_marshallable_type
takes an object's __dict__
when encountering an object it doesn't know how to marshall.
Commonly, when loading instances from the database, SQLAlchemy will only load related instances from the database and populate them into the instance's __dict__
on first access (you could argue that this is an issue with SQLAlchemy, which would have done better to have left a proxy object in the object's __dict__
in the first case). When you try to marshal the object, the nesting will depend on whether the instance's __dict__
was already populated or not.
Specifically in the case of SQLAlchemy, the problem can be solved by configuring the ORM differently or by forcing relations to be eagerly loaded. Also, I'm not 100% sure if this is something that can or should be fixed (the best idea I had was to do the nested field fetched before calling to_marshallable_type
, and handle the recursion in to_marshallable_type
).
Either way, since Flask and SQLAlchemy are pretty common together I thought it best to let you know and document this peculiarity here.
I have some POST/PUT calls with a blank body that come back with a 400 error. Is there a way to prevent this? Thanks!
rfc822 will take a datetime and return you a formatted string, there should be an operation to reverse this formatting change.
Looks like PyPi hasn't been updated for a couple months and I'd love to get some fixes from master in. Thanks!
Hi,
I was testing out flask today and noticed that the default object type returned from PyMongo specifically (flask.ext.pymongo) could not parse objects with ObjectID and some date types.
There is a library in bson called json_util that can serialize eveything dumps can and everything from a mongodb document.
So I was wondering if you would consider using that, i am testing it in my code locally now. I may even try return an array or object depending on the size of the mongo result.
from __future__ import absolute_import
from flask import make_response, current_app
<<<from bson import json_util>>>
from json import dumps
# This dictionary contains any kwargs that are to be passed to the json.dumps
# function, used below.
settings = {}
def output_json(data, code, headers=None):
"""Makes a Flask response with a JSON encoded body"""
# If we're in debug mode, and the indent is not set, we set it to a
# reasonable value here. Note that this won't override any existing value
# that was set. We also set the "sort_keys" value.
local_settings = settings.copy()
if current_app.debug:
local_settings.setdefault('indent', 4)
local_settings.setdefault('sort_keys', True)
# We also add a trailing newline to the dumped JSON if the indent value is
# set - this makes using `curl` on the command line much nicer.
dumped = dumps(data, <<<default=json_util.default,>>> **local_settings)
if 'indent' in local_settings:
dumped += '\n'
resp = make_response(dumped, code)
resp.headers.extend(headers or {})
return resp
In the dependencies,
blinker==1.2
is defined. Blinker 1.3 is already out and this threw an install error, I had to manually downgrade. Are there any reasons why the old version is required?
I have a couple of flask projects which use jython.
Unfortunately, jython is still way behind CPython -- we're on 2.5.3 still. There are efforts
in moving Jython to 2.7, but this will not land anytime soon.
Is there any chance in supporting 2.5?
Mistake in docs?
In "Output Fields" section, "Complex Structures" subsection:
json.dumps(marshal(data, fields))
must be:
json.dumps(marshal(data, resource_fields))
Isn't?
I couldn't find mailinglist or forum.
So, I'm posting a question here.
I want a resource that only responds to GET requests with html response:
class Foo(restful.Resource):
def output_html(self, some_python_object, code, headers=None):
return Response(render(some_python_object), mimetype='text/html', headers=headers, status_code=code)
def get(self):
return some_python_object
representations = {'text/html': output_html}
But I get this:
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <some.python.Object object at 0x7fc6870f0b90> is not JSON serializable
I want resource Foo
to respond with text/html
only regardless of client's Accept
header.
How can I make such resource?
Heya! Frequently I have an endpoint with GET/POST such as /users.json. The get call returns all users and the POST call creates a new one.
Now, I want to require some fields in the POST call but not the GET call. Is there a way to currently do this? If not, could we make it do so? Thanks!
-GS
Consider the following
I have resources User
and Transaction
A User
has one to many Transaction
. I was trying to design the endpoint similar to following but something I do is not right
api.add_resource(UserResource, '/users/<uuid>', '/users/<uuid>/transactions')
class UserResource(restful.Resource):
# /users/<uuid> match here
def get(self, uuid):
return {'method': 'get user -> uuid'}
# /users/<uuid>/transactions should match here
def get(self, uuid, **kwargs):
return {'method': 'get user transactions -> uuid'}
def post(self, uuid):
return {'method': 'post user -> uuid'}
def put(self, uuid):
return {'method': 'put user -> uuid'}
def delete(self, uuid):
return {'method': 'delete user -> uuid'}
When I test this, I get
hhimanshu@air14:18:22 ⮀ ~PYTHONPATH ⮀ ⭠ restful± ⮀ curl -X GET http://127.0.0.1:5000/users/uuid/transactions
{"method": "get user transactions -> uuid"} hhimanshu@air14:21:03 ⮀ ~PYTHONPATH ⮀ ⭠ restful± ⮀ curl -X GET http://127.0.0.1:5000/users/uuid
{"method": "get user transactions -> uuid"}
It always routes me into get which is shown in comments
Is there a way I can route my endpoints to different get, put, post and delete methods in same resource based on how my endpoints look?
GET /users/uuid/transactions # all transactions for a user
GET /users/uuid/transactions/yyyy # user transactions for year yyyy
GET /users/uuid/transactions/yyyy/mm # user transactions for year yyyy, month mm
GET /users/uuid/transactions/yyyy/mm/dd # user transactions for year yyyy, month mm and day dd
What do you recommend would be the best way to use Flask-RESTful in this case?
Hi,
I looked at the source code and am wondering what is the suggested way to add custom headers to the API responses.
Thanks for any pointer.
I can't find any indication in the packaging or source code of this project what the license terms are. As a result, I have to assume that I do not have permission to copy or use this software.
Can you please add some license terms to the project, if only a simple permissive license? If you're trying to rebel against the entire institution of copyright, something like WTFPL would do, otherwise I'd recommend going with the BSD 3-Clause license to match Flask.
In Api's init method the app's error handlers are replaced with the restful ones. Over parts of the application are then subject to these handlers, too.
I subclassed Api to differntiate between parts of the application in the error handlers, see this Gist: https://gist.github.com/arsgeografica/4948282
Might be a good idea generally?
Hey @kevinburke !
Based on the example
def authenticate(func):
@wraps(func)
def wrapper(*args, **kwargs):
if not getattr(func, 'authenticated', True):
return func(*args, **kwargs)
acct = basic_authentication() # custom account lookup function
if acct:
return func(*args, **kwargs)
restful.abort(401)
return wrapper
class Resource(restful.Resource):
method_decorators = [authenticate] # applies to all inherited resources
my rest endpoint looks like
class UserResource(RestResource):
def get(self, uuid):
return {'method': 'get user -> ' + uuid}
and I call it like
curl -X GET http://127.0.0.1:5000/users/validUUID
Now when my every request is authenticated, I see if a valid acct
object exists and if it exists, I delegate the control to endpoint
Question:
Since I am actually making one database call to find out acct
object, is it possible to pass in that to the endpoint when a valid acct
is located?
This way two things happen
a.) I know the call is authenticated
b.) I reuse the acct
object which I can use for my further work, rather than making the DB call again and get the acct
object from validUUID again
How can I achieve this using Flask-RESTful?
Hey there,
It would be kinda cool if we could pretty-print returned json (by setting the "indent" parameter on json.dumps here). I really like being able to explore APIs that do this - especially from the command line.
One simple method would be to add a settings variable to the flask_restful.representations.json
module that you can directly set, e.g. like this:
import flask_restful.representations.json
flask_restful.representations.json.settings['indent'] = 4
If this sounds like something that would be allowed, I'd be happy to send a pull request.
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.