Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A better way to accept multiple request types in a single view method?

Tags:

python

flask

I'm trying to expose an API to various request methods (GET, url x-www-form-urlencoded POST, and json POST):

@app.route('/create', methods=['GET', 'POST'])
def create_file():
    if request.method == 'GET':
        n = request.args.get('n')
        t = request.args.get('t')
    if request.method == 'POST':
        if request.json:
            n = request.json['n']
            t = request.json['t']
        else:
            n = request.form['n']
            t = request.form['t']
    try:
        n = int(n)
    except:
        n = 1
    ...

The above appears too verbose. Is there a simpler or better way of writing this? Thanks.

like image 852
iandexter Avatar asked Jul 18 '13 06:07

iandexter


3 Answers

Does this look better? It is a bit cleaner in my opinion, if you can accept moving the JSON POST request to a different route (which you really should do anyway).

def _create_file(n, t):
    try:
        n = int(n)
    except:
        n = 1
    ...

@app.route('/create')
def create_file():
    n = request.args.get('n')
    t = request.args.get('t')
    return _create_file(n, t)

@app.route('/create', methods = ['POST'])
def create_file_form():
    n = request.form.get('n')
    t = request.form.get('t')
    return _create_file(n, t)

@app.route('/api/create', methods = ['POST'])
def create_file_json():
    if not request.json:
        abort(400); # bad request
    n = request.json.get('n')
    t = request.json.get('t')
    return _create_file(n, t)
like image 76
Miguel Avatar answered Nov 02 '22 07:11

Miguel


There is nothing stopping you from rewriting your code into:

@app.route('/create', methods=['GET', 'POST'])
def create_file():
    params = None
    if request.method == 'GET':
        params = request.args
    if request.method == 'POST':
        if request.json:
            params = request.json
        else:
            params = request.form

    n = params.get('n')
    t = params.get('t')

    try:
        n = int(n)
    except:
        n = 1
    ...
like image 40
twil Avatar answered Nov 02 '22 06:11

twil


Use Flask-Restful extension as suggested by others. You can then just do something like:

class CreateFile(Resource):
    def get(self):
       args = parser.parse_args()
       n,t = args['n'], args['t']

    def post(self, todo_id):
       # do post stuff

and so on...

like image 29
codegeek Avatar answered Nov 02 '22 05:11

codegeek