372

I'm trying to do the equivalent of Response.redirect as in C# - i.e.: redirect to a specific URL - how do I go about this?

Here is my code:

import os from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello World!' if __name__ == '__main__': # Bind to PORT if defined, otherwise default to 5000. port = int(os.environ.get('PORT', 5000)) app.run(host='0.0.0.0', port=port) 

11 Answers 11

561

You have to return a redirect:

import os from flask import Flask,redirect app = Flask(__name__) @app.route('/') def hello(): return redirect("http://www.example.com", code=302) if __name__ == '__main__': # Bind to PORT if defined, otherwise default to 5000. port = int(os.environ.get('PORT', 5000)) app.run(host='0.0.0.0', port=port) 

The default value for code is 302 so code=302 can be omitted or replaced by other redirect code (one in 301, 302, 303, 305, and 307).

See the documentation on flask docs.

Sign up to request clarification or add additional context in comments.

2 Comments

When I do this, my client hitting the endpoint receives a CORS error. Do you know an easy to get around this? I can find a lot of questions and a lot of answers, but not much clarity
This is a different problem, can you ask your own question @RylanSchaeffer ?
145
#!/usr/bin/env python # -*- coding: utf-8 -*- import os from flask import Flask, redirect, url_for app = Flask(__name__) @app.route('/') def hello(): return redirect(url_for('foo')) @app.route('/foo') def foo(): return 'Hello Foo!' if __name__ == '__main__': # Bind to PORT if defined, otherwise default to 5000. port = int(os.environ.get('PORT', 5000)) app.run(host='0.0.0.0', port=port) 

Take a look at the example in the documentation.

1 Comment

note that you are passing the function name into url_for which then builds a URL which is passed to redirect and you return that.
49

From the Flask API Documentation (v. 2.0.x):

flask.redirect(location, code=302, Response=None)

Returns a response object (a WSGI application) that, if called, redirects the client to the target location. Supported codes are 301, 302, 303, 305, and 307. 300 is not supported because it’s not a real redirect and 304 because it’s the answer for a request with a request with defined If-Modified-Since headers.

New in version 0.6: The location can now be a unicode string that is encoded using the iri_to_uri() function.

Parameters:

  • location – the location the response should redirect to.
  • code – the redirect status code. defaults to 302.
  • Response (class) – a Response class to use when instantiating a response. The default is werkzeug.wrappers.Response if unspecified.

Comments

24

I believe that this question deserves an update, just compare with other approaches.

Here's how you do redirection (3xx) from one url to another in Flask (0.12.2):

#!/usr/bin/env python from flask import Flask, redirect app = Flask(__name__) @app.route("/") def index(): return redirect('/you_were_redirected') @app.route("/you_were_redirected") def redirected(): return "You were redirected!" if __name__ == "__main__": app.run(host="0.0.0.0", port=8000, debug=True) 

Official doc here.

Comments

10
flask.redirect(location, code=302) 

Docs can be found here.

Comments

9

Flask includes the redirect function for redirecting to any url. Futhermore, you can abort a request early with an error code with abort:

from flask import abort, Flask, redirect, url_for app = Flask(__name__) @app.route('/') def hello(): return redirect(url_for('hello')) @app.route('/hello'): def world: abort(401) 

By default a black and white error page is shown for each error code.

The redirect method takes by default the code 302. A list for http status codes here.

Comments

9

its pretty easy if u just want to redirect to a url without any status codes or anything like that u can simple say

from flask import Flask, redirect app = Flask(__name__) @app.route('/') def redirect_to_link(): # return redirect method, NOTE: replace google.com with the link u want return redirect('https://google.com') 

here is the link to the Flask Docs for more explanation

Comments

5

For this you can simply use the redirect function that is included in flask

from flask import Flask, redirect app = Flask(__name__) @app.route('/') def hello(): return redirect("https://www.exampleURL.com", code = 302) if __name__ == "__main__": app.run() 

Another useful tip(as you're new to flask), is to add app.debug = True after initializing the flask object as the debugger output helps a lot while figuring out what's wrong.

Comments

5

There are two ways you can redirect to a URL in Flask.

  1. You want to for example, redirect a user to another route after he or she login, etc.
  2. You might also want to redirect a user to a route that expect some variable example: @app.route('/post/<string:post_id>')

Well, to implement flask redirect for case # 1, its simple, just do:

from flask import Flask,redirect,render_template,url_for app = Flask(__name__) @app.route('/login') def login(): # if user credentials are valid, redirect to user dashboard if login == True: return redirect(url_for(app.dashboard)) else: print("Login failed !, invalid credentials") return render_template('login.html',title="Home Page") @app.route('/dashboard') def dashboard(): return render_template('dashboard.html',title="Dashboard") 

To implement flask redirect for case #2, do the following

from flask import Flask,redirect,render_template,url_for app = Flask(__name__) @app.route('/home') def home(): # do some logic, example get post id if my_post_id: # **Note:** post_id is the variable name in the open_post route # We need to pass it as **post_id=my_post_id** return redirect(url_for(app.open_post,post_id=my_post_id)) else: print("Post you are looking for does not exist") return render_template('index.html',title="Home Page") @app.route('/post/<string:post_id>') def open_post(): return render_template('readPost.html',title="Read Post") 

Same thing can be done in view

<a href="{{url_for(app.open_post,post_id=my_post_id)}}"></a> 

Please Note: when redirecting always use the app.home or app.something.. (route or view function name) instead of using redirect("/home"). Reason is, if you modify the route example from "/home" to "/index/page" for some reason, then your code will break

Comments

2

You can use like this:

import os from flask import Flask app = Flask(__name__) @app.route('/') def hello(): # Redirect from here, replace your custom site url "www.google.com" return redirect("https://www.google.com", code=200) if __name__ == '__main__': # Bind to PORT if defined, otherwise default to 5000. port = int(os.environ.get('PORT', 5000)) app.run(host='0.0.0.0', port=port) 

Here is the referenced link to this code.

Comments

-1

How to Redirect Users / Requests in Flask

Throwing an Error inside of your API handler function will redirect your user to an error handler, which can handle redirection. Alternatively you can just call redirect like everyone else is saying, but this is another way of redirecting unauthorized users. To demonstrate what I mean, I've provided an example below.

In a case where Users should be Authorized

First lets assume you have a protected route of which you protected like this.

def handle_api_auth(func): """ **handle_api_auth** wrapper to handle public api calls authentications :param func: a function to be wrapped :return: wrapped function """ @functools.wraps(func) def auth_wrapper(*args, **kwargs): api_key: Optional[str] = request.headers.get('x-api-key') secret_token: Optional[str] = request.headers.get('x-secret-token') domain: Optional[str] = request.base_url if is_request_valid(api_key=api_key, secret=secret_token, domain=domain): return func(*args, **kwargs) # NOTE: throwing an Error Here will redirect your user to an error handler or alteratively you can just call redirect like everyone else is saying, but this is another way of redirecting unathorized users message: str = "request not authorized" raise UnAuthenticatedError(status=error_codes.un_auth_error_code, description=message) return auth_wrapper 

Definition of is_request_valid is as follows

@app_cache.cache.memoize(timeout=15 * 60, cache_none=False) # timeout equals fifteen minutes // 900 seconds def is_request_valid(api_key: str, secret: str, domain: str) -> bool: """ **is_api_key_valid** validates api keys on behalf of client api calls :param api_key: str -> api_key to check :param secret: str -> secret token :param domain: str -> domain registered for the api_key and secret_token :return: bool -> True if api_key is valid """ organization_id: str = config_instance.ORGANIZATION_ID # NOTE: lets assumy api_keys_view.get_api_key will return the api keys from some database somewhere response = api_keys_view.get_api_key(api_key=api_key, organization_id=organization_id) response_data, status_code = response response_dict = response_data.get_json() if not response_dict.get('status'): return False api_instance: dict = response_dict.get('payload') if not isinstance(api_instance, dict): return False domain: str = domain.lower().strip() # NOTE accessing the keys this way will throw ValueError if keys are not available which is what we want # Any Error which gets thrown Ridirects the Users from the path the user is on to an error handler. is_secret_valid: bool = hmac.compare_digest(api_instance['secret_token'], secret) is_domain_valid: bool = hmac.compare_digest(api_instance['domain'], domain) _request_valid: bool = is_secret_valid and is_domain_valid return not not api_instance.get('is_active') if _request_valid else False 

Define your Error Handlers like this

from flask import Blueprint, jsonify, request, redirect from werkzeug.exceptions Unauthorized error_handler = BluePrint('error_handlers', __name__) @error_handler.app_errorhandler(Unauthorized) def handle_error(e : Unauthorized) -> tuple: """default unath handler""" return jsonify(dict(message=e.description)), e.code if request.headers.get('content-type') == 'application/json' else redirect('/login') 

handle other errors the same and note that in-case the request was

not a json the user gets redirected to a login page if json the user gets sent an unathecated response then its up to the front end to handle Unath Errors..

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.