I have a flask app that are running in a local machine when runing flask run but it's not running in an AWS EC2.
Both environment have Ubuntu 16.04 and Python 2.7.
Both are running in virtualenvs created in the same way and path (only user's folder is different).
Both have the same Flask version.
Both have python-dotenv and .flaskenv file and are set to
development and debug.
Both have the same project folder (same git repo) and I flask run
in the same folder for both.
I defined the PORT in .flaskenv and I can see that the PORT defined
in there is where flask is running in both.
When I try to get the same URL, in EC2 I got an error: NoAppException: Could not import "app.initialize"
Running in local machine:
$ flask run
* Serving Flask app "app.initialize:web_app" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://0.0.0.0:5324/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 179-083-368
Log:
127.0.0.1 - - [07/Mar/2019 09:10:13] "GET /api/directors/me/info HTTP/1.0" 200 -
Running un EC2:
$ flask run
* Serving Flask app "app.initialize:web_app" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://0.0.0.0:5324/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 104-758-876
Log:
127.0.0.1 - - [07/Mar/2019 12:05:42] "GET /api/directors/me/info HTTP/1.0" 500 -
Traceback (most recent call last):
File "/home/myuser/.virtualenvs/myvenv/lib/python2.7/site-packages/flask/cli.py", line 325, in __call__
self._flush_bg_loading_exception()
File "/home/myuser/.virtualenvs/myvenv/lib/python2.7/site-packages/flask/cli.py", line 313, in _flush_bg_loading_exception
reraise(*exc_info)
File "/home/myuser/.virtualenvs/myvenv/lib/python2.7/site-packages/flask/cli.py", line 302, in _load_app
self._load_unlocked()
File "/home/myuser/.virtualenvs/myvenv/lib/python2.7/site-packages/flask/cli.py", line 317, in _load_unlocked
self._app = rv = self.loader()
File "/home/myuser/.virtualenvs/myvenv/lib/python2.7/site-packages/flask/cli.py", line 371, in load_app
app = locate_app(self, import_name, name)
File "/home/myuser/.virtualenvs/myvenv/lib/python2.7/site-packages/flask/cli.py", line 246, in locate_app
'Could not import "{name}".'.format(name=module_name)
NoAppException: Could not import "app.initialize".
For this app, I have a custom flask command and when I try to call this command for both environment, on the local machine works fine, but in EC2 I got a No such command error.
I really tried everything I found in SO about checking if things are getting imported right, packages versions and etc. In EC2, when I ipython, I can import app.initialize and I can even import models and use my app code to run things, including the command function.
Finally, if I run this app using Gunicorn in EC2, its works fine, but sometime I need to run with flask for debug (its a sandbox environment) and I need to run custom commands too.
Any idea what may be wrong in EC2?
Ty All
You need to add the path to app to the ec2's python path. If you're in the directory of the project, run export PYTHONPATH="$(pwd):$PYTHONPATH".
Basically if your project looks something like this in the file system:
/home
/myuser
/myproject
/app
__init__.py
somemodule.py
Then you want to have /home/myuser/myproject present in the environment variable PYTHONPATH.
You'll want to automate this since that environment variable will only be present in the shell you ran the command in. To do that you these are some potential options:
There may be a way for you to configure environment variables via the AWS UI (not sure).
You can create or use an image that already has PYTHONPATH set up and make sure you put your project in the path.
You can add the export command to ~/.profile if you are running a shell as the same user that will be running the application, or /etc/profile if you just want to add the path to the application for all users. Then reboot the server.
But before worrying about that, to test that the solution is correct follow these steps:
SSH into the ec2 instance
Start a python shell with python
Run this statement (it should fail due to an import error): import app.initialize
Exit the shell with exit() or ctrl-d
Export the path to app
Repeat steps 2-3, except this time they should succeed
Related
How are you meant to debug errors in Flask? Print to the console? Flash messages to the page? Or is there a more powerful option available to figure out what's happening when something goes wrong?
Running the app in debug mode will show an interactive traceback and console in the browser when there is an error. As of Flask 2.2, to run in debug mode, pass the --app and --debug options to the flask command.
$ flask --app example --debug run
Prior to Flask 2.2, this was controlled by the FLASK_ENV=development environment variable instead. You can still use FLASK_APP and FLASK_DEBUG=1 instead of the options above.
For Linux, Mac, Linux Subsystem for Windows, Git Bash on Windows, etc.:
$ export FLASK_APP=example
$ export FLASK_DEBUG=1
$ flask run
For Windows CMD, use set instead of export:
set FLASK_DEBUG=1
For PowerShell, use $env:
$env:FLASK_DEBUG = "1"
If you're using the app.run() method instead of the flask run command, pass debug=True to enable debug mode.
Tracebacks are also printed to the terminal running the server, regardless of development mode.
If you're using PyCharm, VS Code, etc., you can take advantage of its debugger to step through the code with breakpoints. The run configuration can point to a script calling app.run(debug=True, use_reloader=False), or point it at the venv/bin/flask script and use it as you would from the command line. You can leave the reloader disabled, but a reload will kill the debugging context and you will have to catch a breakpoint again.
You can also use pdb, pudb, or another terminal debugger by calling set_trace in the view where you want to start debugging.
Be sure not to use too-broad except blocks. Surrounding all your code with a catch-all try... except... will silence the error you want to debug. It's unnecessary in general, since Flask will already handle exceptions by showing the debugger or a 500 error and printing the traceback to the console.
You can use app.run(debug=True) for the Werkzeug Debugger edit as mentioned below, and I should have known.
From the 1.1.x documentation, you can enable debug mode by exporting an environment variable to your shell prompt:
export FLASK_APP=/daemon/api/views.py # path to app
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0
One can also use the Flask Debug Toolbar extension to get more detailed information embedded in rendered pages.
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
import logging
app = Flask(__name__)
app.debug = True
app.secret_key = 'development key'
toolbar = DebugToolbarExtension(app)
#app.route('/')
def index():
logging.warning("See this message in Flask Debug Toolbar!")
return "<html><body></body></html>"
Start the application as follows:
FLASK_APP=main.py FLASK_DEBUG=1 flask run
If you're using Visual Studio Code, replace
app.run(debug=True)
with
app.run()
It appears when turning on the internal debugger disables the VS Code debugger.
If you want to debug your flask app then just go to the folder where flask app is. Don't forget to activate your virtual environment and paste the lines in the console change "mainfilename" to flask main file.
export FLASK_APP="mainfilename.py"
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0
After you enable your debugger for flask app almost every error will be printed on the console or on the browser window.
If you want to figure out what's happening, you can use simple print statements or you can also use console.log() for javascript code.
To activate debug mode in flask you simply type set FLASK_DEBUG=1 on your CMD for windows, or export FLASK_DEBUG=1 on Linux terminal then restart your app and you are good to go!!
Install python-dotenv in your virtual environment.
Create a .flaskenv in your project root. By project root, I mean the folder which has your app.py file
Inside this file write the following:
FLASK_APP=myapp
FLASK_ENV=development
Now issue the following command:
flask run
When running as python app.py instead of the flask command, you can pass debug=True to app.run.
if __name__ == "__main__":
app.run(debug=True)
$ python app.py
with virtual env activate
export FLASK_DEBUG=true
you can configure
export FLASK_APP=app.py # run.py
export FLASK_ENV = "development"
to start
flask run
the result
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: xxx-xxx-xxx
and if you change
export FLASK_DEBUG=false
* Environment: development
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
For Windows users:
Open Powershell and cd into your project directory.
Use these commandos in Powershell, all the other stuff won't work in Powershell.
$env:FLASK_APP = "app"
$env:FLASK_ENV = "development"
If you have PyCharm Professional, you can create a Flask server run configuration and enable the FLASK_DEBUG checkbox. Go to Run > Edit Configurations, select or create a Flask server configuration, and enable the FLASK_DEBUG checkbox. Click OK, then click the run button.
You can install python-dotenv with
pip install python-dotenv then create a .flask_env or a .env file
The contents of the file can be:
FLASK_APP=myapp
FLASK_DEBUG=True
Use loggers and print statements in the Development Environment, you can go for sentry in case of production environments.
How are you meant to debug errors in Flask? Print to the console? Flash messages to the page? Or is there a more powerful option available to figure out what's happening when something goes wrong?
Running the app in debug mode will show an interactive traceback and console in the browser when there is an error. As of Flask 2.2, to run in debug mode, pass the --app and --debug options to the flask command.
$ flask --app example --debug run
Prior to Flask 2.2, this was controlled by the FLASK_ENV=development environment variable instead. You can still use FLASK_APP and FLASK_DEBUG=1 instead of the options above.
For Linux, Mac, Linux Subsystem for Windows, Git Bash on Windows, etc.:
$ export FLASK_APP=example
$ export FLASK_DEBUG=1
$ flask run
For Windows CMD, use set instead of export:
set FLASK_DEBUG=1
For PowerShell, use $env:
$env:FLASK_DEBUG = "1"
If you're using the app.run() method instead of the flask run command, pass debug=True to enable debug mode.
Tracebacks are also printed to the terminal running the server, regardless of development mode.
If you're using PyCharm, VS Code, etc., you can take advantage of its debugger to step through the code with breakpoints. The run configuration can point to a script calling app.run(debug=True, use_reloader=False), or point it at the venv/bin/flask script and use it as you would from the command line. You can leave the reloader disabled, but a reload will kill the debugging context and you will have to catch a breakpoint again.
You can also use pdb, pudb, or another terminal debugger by calling set_trace in the view where you want to start debugging.
Be sure not to use too-broad except blocks. Surrounding all your code with a catch-all try... except... will silence the error you want to debug. It's unnecessary in general, since Flask will already handle exceptions by showing the debugger or a 500 error and printing the traceback to the console.
You can use app.run(debug=True) for the Werkzeug Debugger edit as mentioned below, and I should have known.
From the 1.1.x documentation, you can enable debug mode by exporting an environment variable to your shell prompt:
export FLASK_APP=/daemon/api/views.py # path to app
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0
One can also use the Flask Debug Toolbar extension to get more detailed information embedded in rendered pages.
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
import logging
app = Flask(__name__)
app.debug = True
app.secret_key = 'development key'
toolbar = DebugToolbarExtension(app)
#app.route('/')
def index():
logging.warning("See this message in Flask Debug Toolbar!")
return "<html><body></body></html>"
Start the application as follows:
FLASK_APP=main.py FLASK_DEBUG=1 flask run
If you're using Visual Studio Code, replace
app.run(debug=True)
with
app.run()
It appears when turning on the internal debugger disables the VS Code debugger.
If you want to debug your flask app then just go to the folder where flask app is. Don't forget to activate your virtual environment and paste the lines in the console change "mainfilename" to flask main file.
export FLASK_APP="mainfilename.py"
export FLASK_DEBUG=1
python -m flask run --host=0.0.0.0
After you enable your debugger for flask app almost every error will be printed on the console or on the browser window.
If you want to figure out what's happening, you can use simple print statements or you can also use console.log() for javascript code.
To activate debug mode in flask you simply type set FLASK_DEBUG=1 on your CMD for windows, or export FLASK_DEBUG=1 on Linux terminal then restart your app and you are good to go!!
Install python-dotenv in your virtual environment.
Create a .flaskenv in your project root. By project root, I mean the folder which has your app.py file
Inside this file write the following:
FLASK_APP=myapp
FLASK_ENV=development
Now issue the following command:
flask run
When running as python app.py instead of the flask command, you can pass debug=True to app.run.
if __name__ == "__main__":
app.run(debug=True)
$ python app.py
with virtual env activate
export FLASK_DEBUG=true
you can configure
export FLASK_APP=app.py # run.py
export FLASK_ENV = "development"
to start
flask run
the result
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: xxx-xxx-xxx
and if you change
export FLASK_DEBUG=false
* Environment: development
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
For Windows users:
Open Powershell and cd into your project directory.
Use these commandos in Powershell, all the other stuff won't work in Powershell.
$env:FLASK_APP = "app"
$env:FLASK_ENV = "development"
If you have PyCharm Professional, you can create a Flask server run configuration and enable the FLASK_DEBUG checkbox. Go to Run > Edit Configurations, select or create a Flask server configuration, and enable the FLASK_DEBUG checkbox. Click OK, then click the run button.
You can install python-dotenv with
pip install python-dotenv then create a .flask_env or a .env file
The contents of the file can be:
FLASK_APP=myapp
FLASK_DEBUG=True
Use loggers and print statements in the Development Environment, you can go for sentry in case of production environments.
It's hard to remember when, but at one point the auto-reload function of Flask started to not work anymore in my project.
This is the output upon starting my app :
FLASK_APP = back/python/app/app.py:app
FLASK_ENV = development
FLASK_DEBUG = 1
In folder C:/path/to/project
ssh://[VirtualMachineIP]:22/root/env/bin/python3.7 -u -m flask run -h 0.0.0.0 -p 1234
* Serving Flask app 'back/python/app/app.py:app' (lazy loading)
* Environment: development
* Debug mode: on
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://[VirtualMachineIP]:1234/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 106-048-128
The development environment and Debug mode are both on. Thus, upon saving changes in a file (while the app is deployed) I get the usual message :
* Detected change in '/path/to/changed/file.py', reloading
Signaling that the app is reloading with the new code. Except it doesn't reload anything, and the message doesn't appear on any further changes until I'm forced to restart the app.
PyCharms runs on Windows and communicates via ssh to my Virtual Machine, where the code is executed. I have installed the following modules:
flask
flask-socketio
eventlet
flask-cors
Any help is welcomed. Thanks :)
The FLASK_DEBUG environment variable is badly supported, it may not behave as expected if set in code. (Quoted from the source of flask).
It suggest to use flask run in debug mode.
eg: $ flask --app hello --debug run
If it still not work, you can force to use reloader like this:
if __name__ == '__main__':
app.run(host=config.HOST, port=config.PORT, debug=True)
Take care, the app.run() must be wrapped with if __name__ == '__main__'.
doc: https://flask.palletsprojects.com/en/2.2.x/config/#DEBUG
I am running several flask apps on an Ubuntu 18.04 server with nginx and uwsgi workers in python 3.6. The overall architecture is as described in this post.
After deploying a new version of "myapp" the app quietly ceased to work. The logs generated by uwsgi show the terrifying "no python application found" error. Calling the URL resulted in an "Internal Server Error".
Calling the app directly from the terminal as the regular non-root user with python3 myapp.py in an activated virtual environment worked fine. I assumed that uwsgi calls the app as www-data and tried sudo -u www-data python3 myapp.py. Finally, the app refuses to fire up.
(env) user#server:~/projects/myapp$ python3 myapp.py
* Serving Flask app "MyApp" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
^C(env) user#server:~/projects/myapp$ sudo -u www-data python3 myapp.py
Traceback (most recent call last):
File "myapp.py", line 20, in <module>
import post
File "/home/oliver/projects/myapp/post.py", line 5, in <module>
import qrcode
ModuleNotFoundError: No module named 'qrcode'
I pip3-uninstalled and re-installed qrcode[pil] in the activated environment. I even sudo installed qrcode[pil] systemwide in an act of desperation.
So my question: is there a way to install the library qrcode[pi] in a way the script can import it as www-data? Is my assumption calling the script as www-data to debug mainly allright?
Thanks a bunch for your help!
I'm setting up my dev environment for a flask app in a docker container and during dev I want to be able to put Flask in development mode so that I can get live reloads when I change a file. I'm using volumes so that I can edit the files outside of docker. I am getting the desired behavior from Flask, on editing the flask test file it detects the file change, however, it appears to be attempting to serve trunkated files instead of the files as edited resulting in errors from the app.
Dockerfile:
FROM python:3.8.1-alpine3.11
RUN apk update && apk upgrade && apk add bash
#Set ENV Variables
ENV FLASK_APP hello.py
#Add user.
RUN adduser -D eskimotv
USER eskimotv
#Set Work directory
WORKDIR /home/eskimotv
#Install Dependencies
COPY requirements requirements
RUN python -m venv venv
RUN venv/bin/pip install --upgrade pip
RUN venv/bin/pip install -r requirements/docker.txt
#Copy project files
COPY frontend frontend
COPY migrations migrations
COPY boot.sh ./
#Deploy Project
EXPOSE 5000
#ENTRYPOINT ["./boot.sh"]
Docker-compose.yml:
version: '3'
services:
frontend:
image: bentsea/eskimotv-frontend:latest
build:
dockerfile: frontend.dockerfile
context: .
ports:
- "8000:5000"
env_file: .env
volumes:
- './boot.sh:/home/eskimotv/boot.sh'
- './hello.py:/home/eskimotv/hello.py'
- './frontend:/home/eskimotv/frontend'
#entrypoint: ./boot.sh
restart: always
Simple flask app, hello.py:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return '<h1>Hello World!</h1><p> Please work!</p>'
#app.route('/user/<name>')
def user(name):
return '<h1>Hello, {}!</h1>'.format(name)
Environtment variable FLASK_ENV is set to development. When starting up the app for the first time all my changes are displayed correctly:
If I make a very simple edit, such as changing line 10 of hello.py with a cosmetic change, such as the following:
return '<h1>Hello, {}, I made a small change to the text!</h1>'.format(name)
Flask will appropriately reload:
* Detected change in '/home/eskimotv/hello.py', reloading
* Restarting with stat
* Debugger is active!
* Debugger PIN: 234-654-899
172.21.0.1 - - [31/Dec/2019 20:00:20] "GET /user/David HTTP/1.1" 200 -
* Detected change in '/home/eskimotv/hello.py', reloading
* Restarting with stat
* Debugger is active!
* Debugger PIN: 234-654-899
However, the page will begin to produce an error rather than correctly display the page:
Sometimes it's just an EOL error that indicates that the file is truncated, sometimes it indicates this null error. Either restarting the Flask server or undoing the edits made to the file resolves the issue and the app will function normally. Restarting the server every time I make an edit is the action I was wanting to avoid.
Does anyone have any ideas what would cause the files in this volume configuration to load incorrectly and what I can do to resolve the issue to get the intended behavior of having the reload display the file as it is edited?
I don't know why the error is occurring, however it does appear to be caused by mounting a single file instead of a directory. By restructuring my app to mount only entire directories that include the files that need to be updated I was able to successfully use a workflow that allows for automatic Flask reload through Docker on file change.
For whatever reason Docker does not accurately update individual files that are mounted if they are outside of a mounted directory.
Try after you change your code to rebuild your docker.
Before making the change do
docker-compose stop
Then make the change by editing the line
return '<h1>Hello, {}, I made a small change to the text!</h1>'.format(name)
after making your change above, now do
docker-compose build
And finally
docker-compose up