(Beginner) Flask dynamic routing not working - python

I'm just starting to learn Flask but I can't even get through this beginner step. I have tried to make a dynamic URL route as below but when I go to http://127.0.0.1:5000/home for example, it says "NOT FOUND". Any help appreciated!
from flask import Flask
app = Flask(__name__)
#app.route("/") #this is the default domain
def home():
return "<h1>Hello this main page</h1>"
#app.route("/<name>")
def user(name):
return f"hi {name}"
if __name__ == "__main__":
app.run()

You forgot to set the route /home.
Try this :)
#app.route("/home")
def home():
return "<h1>Hello this main page</h1>"

Related

Flask URL not found when using blueprint [duplicate]

This question already has an answer here:
register_blueprint doesn't add route to Flask app
(1 answer)
Closed 5 years ago.
This is really strange but am facing this problem. Everything was working and i was almost done with the app but out of a sudden it stopped. I have isolated the code and i realized that when i register a blueprint and use it on a route, it fails to return saying no URL found. Here is the isolated code:
from flask import Flask, render_template, Blueprint
app = Flask(__name__)
home = Blueprint('home', __name__, static_folder='static', template_folder='template')
app.register_blueprint(home)
#home.route('/') #<---This one does not work
# #app.route('/') <--- This one works
def index():
return "This is the index route."
# return render_template('layer.html')
if __name__ == '__main__':
app.run()
Move the app.register_blueprint(home) after route defined.
from flask import Flask, Blueprint
app = Flask(__name__)
home = Blueprint('home', __name__, static_folder='static', template_folder='template')
#home.route('/')
def index():
return "This is the index route."
app.register_blueprint(home)
if __name__ == '__main__':
app.run()

Cast a dynamic Flask URL route path to string

I have a catch-all route set up in Flask and I want to parse the URL regardless of the length.
from flask import Flask
app = Flask(__name__)
app.route('/')
app.route('/<path:path>')
def main(path=None):
if path == None:
return 'foo'
else:
return 'bar'
if __name__ == '__main__':
app.run()
The problem is I'm getting a 404 Not Found error and I don't know why. The url I'm using to test is /hello/world/. Thanks in advance.
You forgot # before routing decorators. Change it this way:
#app.route('/')
#app.route('/<path:path>')
and it will work.

Flask and React routing

I'm building the Flask app with React, I ended up having a problem with routing.
The backend is responsible to be an API, hence some routes look like:
#app.route('/api/v1/do-something/', methods=["GET"])
def do_something():
return something()
and the main route which leads to the React:
#app.route('/')
def index():
return render_template('index.html')
I'm using react-router in the React app, everything works fine, react-router takes me to /something and I get the rendered view, but when I refresh the page on /something then Flask app takes care of this call and I get Not Found error.
What is the best solution? I was thinking about redirecting all calls which are not calling /api/v1/... to / it's not ideal as I will get back the home page of my app, not rendered React view.
We used catch-all URLs for this.
from flask import Flask
app = Flask(__name__)
#app.route('/', defaults={'path': ''})
#app.route('/<path:path>')
def catch_all(path):
return 'You want path: %s' % path
if __name__ == '__main__':
app.run()
You can also go an extra mile and reuse the Flask routing system to match path to the same routes as client so you can embed the data client will need as JSON inside the HTML response.
Maybe as extension to the answers before. This solved the problem for me:
from flask import send_from_directory
#app.route('/', defaults={'path': ''})
#app.route('/<path:path>')
def serve(path):
path_dir = os.path.abspath("../build") #path react build
if path != "" and os.path.exists(os.path.join(path_dir, path)):
return send_from_directory(os.path.join(path_dir), path)
else:
return send_from_directory(os.path.join(path_dir),'index.html')
For some reason, the catch-all URLs did not work for me. I found that using the flask 404 handler results in the exact same thing. It sees the url and passes it down to react where your router will handle it.
#app.errorhandler(404)
def not_found(e):
return app.send_static_file('index.html')
Just to inform handle error 404 and render_template works perfectly for me.
#app.errorhandler(404)
def not_found(e):
return render_template("index.html")
I have to combine both catch-all and 404 handler for it to work properly. I am hosting a react-app in a subpath with its own redirection handler from react-router.
#app.route('/sub-path', defaults={'path': 'index.html'})
#app.route('/sub-path/<path:path>')
def index(path):
return send_from_directory('../react-dir/build', path)
#app.errorhandler(404)
def not_found(e):
return send_from_directory('../react-dir/build','index.html')

Serving static json data to flask

I have json data in demo_data.json that I'd like to bring into a Flask app. I'm receiving a 404 on the file which I've placed in the static directory, my code is below, thanks for any thoughts in advance:
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static/')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
if __name__ == '__main__':
app.run()
return send_from_directory('/static', 'demo_data.json')
You would need to define the view to send the data.
Something similar to :
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static/')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
#app.route('data/<filename>')
def get_json(filename):
return send_from_dir
if __name__ == '__main__':
app.run()
So, you are trying to send a file? Or show a file in an url?
I assumed the later. Notice the use of url_for.
This creates a link that will show your static file.
http://127.0.0.1:5000/send and http://127.0.0.1:5000/static/demo_data.json
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/send')
def send():
return "<a href=%s>file</a>" % url_for('static', filename='demo_data.json')
if __name__ == '__main__':
app.run()
But you also might want to check out https://github.com/cranmer/flask-d3-hello-world
It looks like you have a trailing slash on your static_url_path. Removing the extra character resolved the issue. Also note the removed last line. The return call wasn't necessary and the function call after the return was a syntax error.
from flask import Flask, render_template
from flask import url_for
app = Flask(__name__, static_url_path='/static')
#app.route('/')
def home():
return render_template('home.html')
#app.route('/welcome')
def welcome():
return render_template('welcome.html')
if __name__ == '__main__':
app.run()

Flask, Blueprint, current_app

I am trying to add a function in the Jinja environment from a blueprint (a function that I will use into a template).
Main.py
app = Flask(__name__)
app.register_blueprint(heysyni)
MyBluePrint.py
heysyni = Blueprint('heysyni', __name__)
#heysyni.route('/heysyni'):
return render_template('heysyni.html', heysini=res_heysini)
Now in MyBluePrint.py, I would like to add something like :
def role_function():
return 'admin'
app.jinja_env.globals.update(role_function=role_function)
I will then be able to use this function in my template. I cannot figure out how I can access the application since
app = current_app._get_current_object()
returns the error:
working outside of request context
How can I implement such a pattern ?
The message error was actually pretty clear :
working outside of request context
In my blueprint, I was trying to get my application outside the 'request' function :
heysyni = Blueprint('heysyni', __name__)
app = current_app._get_current_object()
print(app)
#heysyni.route('/heysyni/')
def aheysyni():
return 'hello'
I simply had to move the current_app statement into the function. Finally it works that way :
Main.py
from flask import Flask
from Ablueprint import heysyni
app = Flask(__name__)
app.register_blueprint(heysyni)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(debug=True)
Ablueprint.py
from flask import Blueprint, current_app
heysyni = Blueprint('heysyni', __name__)
#heysyni.route('/heysyni/')
def aheysyni():
# Got my app here
app = current_app._get_current_object()
return 'hello'

Categories

Resources