flask restful: passing parameters to GET request
I want to create a resource that supports GET request in following way:
/bar?key1=val1&key2=val2
I tried this code, but it is not working
app = Flask(__name__)
api = Api(app)
class BarAPI(Resource):
def get(key1, key2):
return jsonify(dict(data=[key1, key2]))
api.add_resource(BarAPI, '/bar', endpoint='bar')
Thanks!
Solution 1:
Edit: reqparse
is no longer the recommended way to do this with flask-restful!, but there is another example using marshmallow below.
The reqparse
object is deprecated. See the docs or the second example in this post for alternatives.
Use reqparse
. You can see another example in the flask-restful docs.
It performs validation on the parameters and does not require jsonify
.
from flask import Flask
from flask_restful import Resource, Api, reqparse
app = Flask(__name__)
api = Api(app)
class BarAPI(Resource):
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('key1', type=str)
parser.add_argument('key2', type=str)
return parser.parse_args()
api.add_resource(BarAPI, '/bar', endpoint='bar')
if __name__ == '__main__':
app.run(debug=True)
Another way is to use marshmallow.
You can use a Schema
class,to validate request.args
(for a PUT/POST request you might validate request.form
)
from flask import Flask, request, abort
from flask_restful import Resource, Api
from marshmallow import Schema, fields
class BarQuerySchema(Schema):
key1 = fields.Str(required=True)
key2 = fields.Str(required=True)
app = Flask(__name__)
api = Api(app)
schema = BarQuerySchema()
class BarAPI(Resource):
def get(self):
errors = schema.validate(request.args)
if errors:
abort(400, str(errors))
return 'ok'
api.add_resource(BarAPI, '/bar', endpoint='bar')
# omit of you intend to use `flask run` command
if __name__ == '__main__':
app.run(debug=True)
This example requires that both parameters be present.
Solution 2:
Flask can parse arguments through request
from flask import request
You can use following lines in the block that requires GET parameters. GET is declared in @app.route()
declaration.
args = request.args
print (args) # For debugging
no1 = args['key1']
no2 = args['key2']
return jsonify(dict(data=[no1, no2])) # or whatever is required
Solution 3:
Since reqparse
is deprecated, here is a solution using the WebArgs library:
from flask import Flask
from flask_restful import Api, Resource, abort
from webargs import fields, validate
from webargs.flaskparser import use_kwargs, parser
app = Flask(__name__)
api = Api(app)
class Foo(Resource):
args = {
'bar': fields.Str(
required=True,
validate=validate.OneOf(['baz', 'qux']),
),
}
@use_kwargs(args)
def get(self, bar):
return {'bar': bar}
api.add_resource(Foo, '/foo', endpoint='foo')
# This error handler is necessary for usage with Flask-RESTful.
@parser.error_handler
def handle_request_parsing_error(err, req, schema, *, error_status_code, error_headers):
abort(error_status_code, errors=err.messages)
if __name__ == '__main__':
app.run(debug=True)
For more examples, see the Flask-RESTful example in the WebArgs repository.