606

When the user accesses this URL running on my flask app, I want the web service to be able to handle the parameters specified after the question mark:

http://10.1.1.1:5000/login?username=alex&password=pw1

#I just want to be able to manipulate the parameters
@app.route('/login', methods=['GET', 'POST'])
def login():
    username = request.form['username']
    print(username)
    password = request.form['password']
    print(password)
Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
Alex Stone
  • 46,408
  • 55
  • 231
  • 407
  • 140
    Just a small hint for security: Don't include passwords in GET requests. https://security.stackexchange.com/questions/147188/is-it-bad-practice-to-use-get-method-as-login-username-password-for-administrato – palsch Mar 13 '17 at 15:18
  • 27
    Another small hint for security: Don't sent passwords to HTTP endpoints (only ever HTTPS) – DerMike Oct 23 '19 at 13:02

8 Answers8

886

Use request.args to get parsed contents of query string:

from flask import request

@app.route(...)
def login():
    username = request.args.get('username')
    password = request.args.get('password')
Alex Stone
  • 46,408
  • 55
  • 231
  • 407
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • 5
    How does that compare to using parameters in `app.route('/username=&password=')`? That way you don't write the request.args.get lines at all. – multigoodverse Apr 17 '20 at 14:16
  • 4
    @multigoodverse see the first comment on the question for why you shouldn't send a password via a GET (in the URL). More generally, a GET request should have a `?` at the beginning of the parameters, so you would want `app.route('/?username=&password=')`, but Flask will read everything after the question mark into `request.args` and won't interpret the variables from the route. If you wanted to get to your example route using an HTML form, you would need a bunch of extra JavaScript to make it work. Lastly, route variables are mandatory, `request.args` can be optional. – dericke Jun 03 '20 at 18:28
  • Maybe change the example a bit. I don't think you should pass passwords in the query string – vidstige Dec 01 '22 at 08:53
272

The URL parameters are available in request.args, which is an ImmutableMultiDict that has a get method, with optional parameters for default value (default) and type (type) - which is a callable that converts the input value to the desired format. (See the documentation of the method for more details.)

from flask import request

@app.route('/my-route')
def my_route():
  page = request.args.get('page', default = 1, type = int)
  filter = request.args.get('filter', default = '*', type = str)

Examples with the code above:

/my-route?page=34               -> page: 34  filter: '*'
/my-route                       -> page:  1  filter: '*'
/my-route?page=10&filter=test   -> page: 10  filter: 'test'
/my-route?page=10&filter=10     -> page: 10  filter: '10'
/my-route?page=*&filter=*       -> page:  1  filter: '*'
HackDolphin
  • 166
  • 11
qqbenq
  • 10,220
  • 4
  • 40
  • 45
190

You can also use brackets <> on the URL of the view definition and this input will go into your view function arguments

@app.route('/<name>')
def my_view_func(name):
    return name
Inbar Cheffer
  • 2,109
  • 1
  • 7
  • 8
66

If you have a single argument passed in the URL you can do it as follows

from flask import request
#url
http://10.1.1.1:5000/login/alex

from flask import request
@app.route('/login/<username>', methods=['GET'])
def login(username):
    print(username)

In case you have multiple parameters:

#url
http://10.1.1.1:5000/login?username=alex&password=pw1

from flask import request
@app.route('/login', methods=['GET'])
    def login():
        username = request.args.get('username')
        print(username)
        password= request.args.get('password')
        print(password)

What you were trying to do works in case of POST requests where parameters are passed as form parameters and do not appear in the URL. In case you are actually developing a login API, it is advisable you use POST request rather than GET and expose the data to the user.

In case of post request, it would work as follows:

#url
http://10.1.1.1:5000/login

HTML snippet:

<form action="http://10.1.1.1:5000/login" method="POST">
  Username : <input type="text" name="username"><br>
  Password : <input type="password" name="password"><br>
  <input type="submit" value="submit">
</form>

Route:

from flask import request
@app.route('/login', methods=['POST'])
    def login():
        username = request.form.get('username')
        print(username)
        password= request.form.get('password')
        print(password)
Wodin
  • 3,243
  • 1
  • 26
  • 55
38

url:

http://0.0.0.0:5000/user/name/

code:

@app.route('/user/<string:name>/', methods=['GET', 'POST'])
def user_view(name):
    print(name)

(Edit: removed spaces in format string)

Community
  • 1
  • 1
Manish Kumar
  • 554
  • 4
  • 7
5

Use request.args.get(param), for example:

http://10.1.1.1:5000/login?username=alex&password=pw1
@app.route('/login', methods=['GET', 'POST'])
def login():
    username = request.args.get('username')
    print(username)
    password = request.args.get('password')
    print(password)

Here is the referenced link to the code.

colidyre
  • 4,170
  • 12
  • 37
  • 53
RAJAHMAD MULANI
  • 139
  • 1
  • 5
-1

this should work

@app.route('/login$username=<username>$password=<password>', methods=['GET', 'POST'])
def login(username, password):
    # you can add stuff
    return f"Username: {username}\nPassword: {password}"
NOT kar1m yt
  • 188
  • 3
  • Despite the uncommon URI style, this does work when called as `/login$username=alice123$password=w0nderland` but client's requesting `http://example.com/login` might be confused when it returns a 404 error. It may be appropriate to use URL parameters or hash-routing instead. For example, the URI could be captured as `@app.route('/login?username=&password=', ... )`. – David Golembiowski Jun 08 '21 at 02:12
-2

It's really simple. Let me divide this process into two simple steps.

  1. On the html template you will declare name attribute for username and password like this:
<form method="POST">
<input type="text" name="user_name"></input>
<input type="text" name="password"></input>
</form>
  1. Then, modify your code like this:
from flask import request

@app.route('/my-route', methods=['POST'])
# you should always parse username and 
# password in a POST method not GET
def my_route():
    username = request.form.get("user_name")
    print(username)
    password = request.form.get("password")
    print(password)
    #now manipulate the username and password variables as you wish
    #Tip: define another method instead of methods=['GET','POST'], if you want to  
    # render the same template with a GET request too
Xbox One
  • 307
  • 2
  • 13
Mr.bunty
  • 15
  • 1
  • 3