Reputation: 8498
I'm writing a bunch of examples of how to use Flask
and currently I want to be able to just write
@app.route("/")
def redirectora():
redirect("redirected")
@app.route("/targeta", methods=["GET", "POST"])
def redirecteda():
return "Redirected!"
app.run(host="0.0.0.0", port=5000)
in my cells but I have to include
app = Flask("the_flask_module")
in every cell (otherwise if I run the cell twice I get an assertion error about trying to add a route twice).
I would really like to be able to run code before the cell is run (so I don't have to write app =
60 times) but I'm not finding any signals or hooks for notebooks.
Does anyone know how run code before any cell is run?
Upvotes: 1
Views: 886
Reputation: 122232
The answer given by shad is the right one for the scenario outlined but the wrong one for the question as phrased (and what I was searching for when landing here). For anyone else who is looking for the right way to run code before a cell runs in ipython, check out the events api.
For example how the autoreload extension works
def load_ipython_extension(ip):
"""Load the extension in IPython."""
auto_reload = AutoreloadMagics(ip)
ip.register_magics(auto_reload)
ip.events.register("pre_run_cell", auto_reload.pre_run_cell)
ip.events.register("post_execute", auto_reload.post_execute_hook)
Upvotes: 1
Reputation: 1820
Every time you make a call to app = Flask('the_flask_module'), you're creating a new Flask app instance. If you had this at the top of every cell, then every time you execute a cell, you would wipe out the previous Flask app instance that you had. For example, if you did this:
app = Flask('my_app')
@app.route('/targeta')
def targeta():
return 'targeta'
app = Flask('my_app')
@app.route('/targetb')
def targeta():
return 'targetb'
app.run(host="0.0.0.0", port=5000)
/targeta would return a 404.
If this is the behaviour you want, i.e. that every cell should be an independent Flask endpoint, then you could achieve this by creating your own decorator that creates a new app object for whatever function you decorate, as follows:
class route(object):
def __init__(self, path, **kwargs):
self.path = path
self.kwargs = kwargs
def __call__(self, func):
app = Flask('my_flask_app')
app.add_url_rule(self.path, func.func_name, func, **self.kwargs)
app.run(host="0.0.0.0", port=5000)
If the behaviour you're looking for is to be allowed to use @app.route more than once without receiving an assertion error, you could create your own decorator that calls add_url_rule and swallows the exception:
class route(object):
def __init__(self, path, **kwargs):
self.path = path
self.kwargs = kwargs
def __call__(self, func):
try:
app.add_url_rule(self.path, func.func_name, func, **self.kwargs)
except AssertionError, e:
pass
In both cases, you would decorate your function as follows:
@route('/targeta')
def targeta():
return 'targeta'
Assuming that you're doing this for tutorial or presentation purposes, you'll want to put the decorator code in a setup section of your notebook so that it is transparent why you've done this.
Upvotes: 1