I'm new to Flask and wondering if it is possible to use the same URL to display a form in html and query to display something

Ideally, I want to have the following result to happen.

If I'm going to create a query inside 138.10.2.1/sample by doing this:

http://138.10.2.1:8000/sample?psi=1&lavr=1&dsc=1&ifsc=1&ics=1&eng=3&ol1=1&ol2=1&reso=1&educ=1&listen=1&time=1&probe=1&unders=1

It will display:

*something in json format*

in the webpage

Else, if I'll just go straight to this:

http://138.10.2.1:8000/sample

It will direct me to a .html page with a form to fill or allow a user to attach a file to use and upload to display a transformed file in json format also.

Here's my code

sample.py

from flask import Flask, flash, request, redirect, url_for, make_response, send_from_directory, render_template
import convert as ps

app = Flask(__name__)

@app.route("/sample", methods=["GET", "POST"])
def query_strings():

    #This is not working: if request.method == "POST":

        args1 = request.args["psi"]
        args2 = request.args["lavr"]
        args3 = request.args["dsc"]
        args4 = request.args["ifsc"]
        args5 = request.args["ics"]
        args6 = request.args["eng"]
        args7 = request.args["ol1"]
        args8 = request.args["ol2"]
        args9 = request.args["reso"]
        args10 = request.args["educ"]
        args11 = request.args["listen"]
        args12 = request.args["time"]
        args13 = request.args["probe"]
        args14 = request.args["unders"]

        args_list = [args1, args2, args3, args4, args5, args6, args7, args8,args9, args10, args11, args12, args13, args14]


        result = ps.execute(args_list)
        response = app.response_class(
            response=result,
            status=200,
            mimetype='application/json'
        )
        return response
    #This is my html form: return render_template("form.html")
if __name__ == '__main__':
   app.run(debug = True)

Right now, what I can have is to run the query but I am getting prompted to enter the paramaters I declared if I just entered:

http://138.10.2.1:8000/sample

3 Answers

1
ghr On Best Solutions

You can check the number of arguments and return the HTML form if the length is 0 like this:

    # if there are no arguments provided, show HTML form
    if len(request.args) == 0:
        return render_template("form.html")

Also, there's no need to store each argument as a separate variable and then combine them into a list. request.args is already a dictionary so you can simply get a list of the argument names and values with:

list(request.args.keys()) # list of argument names eg. ['psi', 'lavr', 'dsc', 'ifsc'...]
list(request.args.values()) # list of argument values eg. [1, 1, 1, 1...]

You can check if the argument names match a desired set:

if set(argument_names) == {"psi","lavr","dsc","ifsc","ics","eng","ol1","ol2","reso","educ","listen","time","probe","unders"}:
        # return JSON

Overall, your code could look something like this:

from flask import Flask, request, render_template
import json

app = Flask(__name__)

@app.route("/sample", methods=["GET", "POST"])
def query_strings():
    # if there are no arguments provided, show HTML form
    if len(request.args) == 0:
        return render_template("form.html")

    argument_names = list(request.args.keys())

    # if the argument list is valid
    if set(argument_names) == {"psi","lavr","dsc","ifsc","ics","eng","ol1","ol2","reso","educ","listen","time","probe","unders"}:
        # return JSON
        response = app.response_class(
                response=json.dumps(request.args),
                status=200,
                mimetype='application/json'
        )
        return response

    return "Invalid arguments"

if __name__ == '__main__':
    app.run(debug = True)

This will:

  • show form.html if you load /sample with no arguments
  • show the arguments as JSON if you load /sample with valid arguments (eg. /sample?psi=1&lavr=1&dsc=1&ifsc=1&ics=1&eng=3&ol1=1&ol2=1&reso=1&educ=1&listen=1&time=1&probe=1&unders=1)
  • show "Invalid arguments" in any other case
0
Rajat On

Try this code, I hope it will help you. By default, it uses the GET method, so it is not working. When you click on the submit button then it calls the POST method.

from flask import Flask, flash, request, redirect, url_for, make_response, send_from_directory, render_template
import convert as ps

app = Flask(__name__)

@app.route("/sample", methods=["GET", "POST"])
def query_strings():

    if request.method == "POST":

        args1 = request.args["psi"]
        args2 = request.args["lavr"]
        args3 = request.args["dsc"]
        args4 = request.args["ifsc"]
        args5 = request.args["ics"]
        args6 = request.args["eng"]
        args7 = request.args["ol1"]
        args8 = request.args["ol2"]
        args9 = request.args["reso"]
        args10 = request.args["educ"]
        args11 = request.args["listen"]
        args12 = request.args["time"]
        args13 = request.args["probe"]
        args14 = request.args["unders"]

        args_list = [args1, args2, args3, args4, args5, args6, args7, args8,args9, args10, args11, args12, args13, args14]


        result = ps.execute(args_list)
        response = app.response_class(
            response=result,
            status=200,
            mimetype='application/json'
        )
        # return response
        return render_template("form.html", response = response)
    return render_template("form.html")

    #This is my html form: return render_template("form.html")
if __name__ == '__main__':
   app.run(debug = True)
1
alexxmagpie On

Ohh..I see..so how can I have a .html to display if I don't enter any parameters? This will allow me to attach a file inside the html form and create to POST and get the same json result

Based on your comment to the question and sample code you've posted I assume you might be looking for something like this:

@app.route("/sample", methods=["GET", "POST"])
def query_strings():
    args1 = request.args.get("psi")
    args2 = request.args.get("lavr")
    args3 = request.args.get("dsc")
    args4 = request.args.get("ifsc")
    args5 = request.args.get("ics")
    args6 = request.args.get("eng")
    args7 = request.args.get("ol1")
    args8 = request.args.get("ol2")
    args9 = request.args.get("reso")
    args10 = request.args.get("educ")
    args11 = request.args.get("listen")
    args12 = request.args.get("time")
    args13 = request.args.get("probe")
    args14 = request.args.get("unders")

    args_list = [
        args1, args2, args3, args4, args5, args6, args7, args8,
        args9, args10, args11, args12, args13, args14
    ]

    if not all(args_list):
        return render_template('form.html')
    else:
        result = ps.execute(args_list)
        response = app.response_class(
            response=result,
            status=200,
            mimetype='application/json'
        )
        return response

In this case, if you give no parameters in GET request it will render a template with html form.

Also rather than always check for request method I suggest you take a look at Flask's MethodView. Using that you can nicely split you logic onto request with arguments in the query string and form submitting with json: http://flask.pocoo.org/docs/1.0/api/#flask.views.MethodView