I am new to python Flask, and may be trying to use Flask in a way it is not intended.
Can I call 2 routes from a 'parent' route?
@app.route("/parent_route")
# call route1 (by some means, this 'redirect' appears not to do anything)
x = redirect(url_for('/route1', methods=['GET']))
# call route2 (by some means), passing the output from route1
y = redirect(url_for('/route2', x=x, methods=['GET']))
# render the html page, passing the output from route2
return redirect(url_for("html_page", y=y))
@app.route("/route1", methods=['GET'])
# some processing, then ...
return x
@app.route("/route2/<x>", methods=['GET'])
# some processing, then ...
return y
Redirect does't actually stay within Flask. It returns a HTTP 302 response, which the client then needs to follow. There are a number of caveats associated with that. For instance, POST requests may get turned to GET and lose their payloads. This has nothing to do with Flask, but the way HTTP and browsers operate. This is also why you cannot return multiple redirects in response to a single HTTP request.
The simple and safe way to do what you want to is to extract the common code into 'regular', reusable python functions. You can then call those from as many endpoints as you want, and in any order.
def handler_for_route1():
# Your logic for route1
return x
def handler_for_route2(x):
# Your logic for route2
return y
@app.route("/parent_route")
def parent_route():
x = handler_for_route1()
y = handler_for_route2(x=x)
return redirect(url_for("html_page", y=y))
@app.route("/route1", methods=['GET'])
def route1():
return handler_for_route1()
@app.route("/route2/<x>", methods=['GET'])
def route2(x):
return handler_for_route2(x=x)
Note that the API functions are also essentially just functions. You could simply call, for instance, route1()
from within parent_route
. You would have be slightly careful with what parameters you provide for this call, however. The flask router will be providing additional information such as the request object, and if you don't know what you are doing, you can end up with strange and difficult to debug errors.
As a general practice, I tend to keep only the request related logic in the @app.route function - things like dealing with authorization, reshaping the request parameters into the correct internal data types, etc. The actual application logic I tend to prefer to keep in a separate function in a separate part of the code. This would allow you to reuse that code from other interfaces as well, such as for ex. a CLI. It also makes things a little easier to test your core business logic, when you don't need to worry about structuring HTTP requests as well.