Flask Internal server error when rendering static files - flask

I am new to Flask and I am encountering a problem: when I return a message, such as:
app_setup.py
#app.route("/")
def hello():
return '''Hello World!'''
it works fine. However, when I try to render a static html file such as:
app_setup.py
#app.route("/")
def hello():
return render_template('static/index.html')
it gives me an Internal Server Error. How can i fix this?
N.B: I am running Flask with uWSGI and Nginx in Docker.
main.py
from flask import *
app = Flask(__name__)
app.config['TEMPLATES_AUTO_RELOAD'] = True
from .core import app_setup
if __name__ == "__main__":
# Only for debugging while developing
app.run(host='0.0.0.0', debug=True, port=80)

Templates typically come out of a templates/ subdirectory of the app, which is where render_templates() looks for them. (Things get slightly more complicated when you're using blueprints, but safe that thought, since you aren't.)
Create a templates directory, and move index.html there. Then
return render_template('index.html')

By default, the render_templates() go look for your static template file into the /templates subdirectory of your app. A good approach would be to create a templates directory, and move the static index.html there.
Although, if you do want to set a new directory to template static files, you could try the following when initializing the app:
import os
tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
# ...
app = Flask('myapp', template_folder=tmpl_dir)

Related

Using Flask-HTTPAuth when serving a static folder

I'm using Flask to serve a static folder:
from flask import Flask, send_from_directory
from flask_httpauth import HTTPBasicAuth
app = Flask(__name__,
static_url_path='',
static_folder='html_files')
...
#app.route('/')
#auth.login_required
def send_html_files():
return send_from_directory('html_files', 'main.html')
I used the first example in Flask-HTTPAuth docs in order to add basic authentication to my website. Just a regular username and password is enough for me.
The problem is that the authentication dialog is not showing when the user go directly to http://localhost:5000/a/b/c (it works on http://localhost:5000/)
What is the proper way of doing this? On the other hand, what is the quick and dirty way?
#app.route('/') matches your root path only.
Try something like this to match every path:
#app.route('/<path:filename>')
#auth.login_required
def send_html_files(filename):
return send_from_directory('html_files', filename)

Cannot import module to begin basic Flask app

So I'm following a beginners tutorial on Flask and for whatever reason am getting an error on what is essentially the very first step.
I first created an "app" directory where I created a python file for "init.py" which contains the following code:
from flask import Flask
app = Flask(__name__)
from app import routes
I then created a "routes.py" python file in the same directory:
from app import app
#app.route('/')
#app.route('/index')
def index():
return "Hello, World!"
Finally (and this is where the problem stems from), I created a python file named "microblog.py" which is located in the same folder as the "app" directory:
from app import app
I then go to my virtual environment and run (using cmd windows):
set FLASK_APP=microblog.py
So far so good, however when I try to run the following code in cmd:
flask run
I get the following error:
ImportError: cannot import name 'app' from 'app' (C:\Users\Grae_\microblog\app\__init__.py)
If any further clarification is needed, here are my file locations:
C:\Users\Grae_\microblog
C:\Users\Grae_\microblog\app
C:\Users\Grae_\microblog\__init__.py
C:\Users\Grae_\microblog\routes.py
C:\Users\Grae_\microblog\venv
C:\Users\Grae_\microblog\microblog.py
Apologies if this is really obvious, I'm just obviously very new to Flask and have been stuck on this for a while.
Thanks
The issue here is on python package "app". The directory should have a file named __init__.py instead of init.py.
For example, you rename the file init.py to __init__.py and replace content with below code it should work
from flask import Flask
app = Flask(__name__)
def start():
from app import routes
start()
You can do something like this:-
test.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "Index!"
#app.route("/hello")
def hello():
return "Hello World!"
#app.route("/members")
def members():
return "Members"
#app.route("/members/<string:name>/")
def getMember(name):
return name</string:name>
if __name__ == "__main__":
app.run()
In command prompt, run the command-
python test.py
Try the URLs in your browser:
http://127.0.0.1:5000/
http://127.0.0.1:5000/hello
http://127.0.0.1:5000/members
http://127.0.0.1:5000/members/Karan/

Getting 404 upon splitting up a file in flask

My flask app runs fine.
But, when I split it up into 3 parts, the imported one displays a 404.
Here is the file structure:
myproject/
run.py
appy/
__init__.py
index.py
.
#run.py
from appy import app
if __name__ == '__main__
app.run()
.
#__init.py
from flask import Flask
app = Flask('appy')
from appy import index
#app.route("/h")
def hello():
return "Hello"
.
#index.py
from appy import app
#app.route("/s")
def shello():
return "Shello"
localhost/h runs fine returning Hello.
localhost/s gives 404.
Also, everything runs fine when merged into a single file.
Please suggest a way to do it correctly.
You're running into a circular import error. You are importing app into index.py but you are also importing index.py into __init__.py.
If you want to have everything in a different file the best way to do it is make your init.py file empty, and create a differently named file for the contents of index.py
Then from your new "init.py" file (with a new name) import the contents of index, and then run the app.
Should work now.

Flask-Ask not working when using runserver pattern

Trying to add flask-Ask to an existing flask website that uses the runserver pattern where app setup done in init but app.run is called in runserver
/myapp
/myapp
__init__.py
views.py
alexa_views.py
runserver.py
This pattern works fine for Flask ( its recommended for larger apps) but Flask-Ask is failing silently when app.run(debug=True) is called from runserver.py.
If I call app.run(debug=True) in _init__.py and run that then Flask-Ask works fine and Alexa responds.
Any ideas?
code:
alexa_views.py
from flask import blueprints
from flask_ask import Ask, statement
askblueprint = blueprints.Blueprint('alexa', __name__, url_prefix='/alexa')
ask = Ask(blueprint=askblueprint)
#ask.launch
def launch():
return statement (' it works')
init.py
from flask import Flask, blueprints
from myapp.alexa_views import askblueprint
app = Flask(__name__)
app.register_blueprint(askblueprint)
# lots of other unrelated configuration here - db etc
# running app here causes Flask-Ask to work!
# if __name__ == '__main__':
# app.run(debug=True)
# late import of views to break circular import
import myapp.views
runserver.py
# running this starts website normally but Flask-Ask does nothing
from myapp import app
if __name__ == '__main__':
app.run(debug=True)
I am going to close this.
The problem does exist in my real app but this simple example now works fine so I will have to dig deeper to find something I can demonstrate.
Bill

Making use of CherryPy as webserver for flask application

I have a simple flask application that works really well. I've been developing it separately from the main desktop application, I want to "plugin" the flask application into the main application. I also want to use cherrypy as the webserver as the default webserver that comes with flask is not production ready. I am not sure how to get both these to work together. My flask application code looks like this
from flask import Flask, render_template,send_from_directory
from scripts_data import test_data
from schedule_data import scheduledata
import os
app=Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/scripts')
def scripts():
test_data=t_data()
return render_template('scripts.html',data_scripts=test_data)
#app.route('/sch')
def schedules():
data_schedule=s_data()
return render_template('schedules.html',table_data=data_schedule)
if __name__=='__main__':
app.run(debug=True)
so obviously as I want to integrate into the main application I can't use app.run. Its not clear how to swap out the flask webserver for the Cherrypy Webserver
I have seen the following
from flask import Flask
import cherrypy
app = Flask(__name__)
app.debug = True
Class setup_webserver(object):
#app.route("/")
def hello():
return "Hello World!"
def run_server():
# Mount the WSGI callable object (app) on the root directory
cherrypy.tree.graft(app, '/')
# Set the configuration of the web server
cherrypy.config.update({
'engine.autoreload_on': True,
'log.screen': True,
'server.socket_port': 5000,
'server.socket_host': '0.0.0.0'
})
# Start the CherryPy WSGI web server
cherrypy.engine.start()
cherrypy.engine.block()
Class start_it_all(object)
import setup_webserver
setup_webserver.run_server()
But when I start the webserver and go to the site (0.0.0.0:5000) I get a 404?
I don't get the 404 when its just flask on its own. All I want to do is swap out the flask built-in webserver for the cherrpy webserver. I don't want to use cherrypy for anything else, as Flask will be the framework
Any suggestions? I'm on Windows and using python 2.7