I'm trying to deploy my first flask application and I'm running into some issues. I had my app working on my local machine with the build in flask development server, and all my dependencies were managed by pipenv. I uploaded my app to /var/www/directory_printer and ran pipenv install. Then I created a apache vhost file and pointed it to my .wsgi file:
WSGIScriptAlias / /var/www/directory_printer/directory.wsgi
In directory.wsgi, I import my app. At the beginning of my main app file, I import flask. When I try to access my app, I get a 500 error. In the apache error log I get:
ModuleNotFoundError: No module named 'flask'
If I start an interactive python shell in the directory_printer folder with the pipenv shell activated, I can import flask just fine.
I tried putting the path to my virtual env at the beginning of my directory.wsgi file:
#!/path/to/venv
but that doesn't seem to help. I'm sure I'm missing something simple, but I can't seem to see what it is. Any help would be appreciated. Thanks!
Often on Linux systems a home directory is not accessible to other users so the Apache user will not be able to read anything under the directory. Permissions can also be wrong on Python packages that have been installed making them inaccessible as well.
Ok, not sure if this is the correct answer, but it is now working for me.
First
create a .venv folder in the project root folder
then change permissions:
sudo chown www-data:www-data .venv
Then create a virtual environment and install your requirements from Pipfile as the user wsgi will run as:
sudo -su www-data python3 -m virtualenv -p python3 .venv pipenv install
This will install your virtual environment in the project folder. Check out this answer for more:
How to set PIPENV_VENV_IN_PROJECT on per-project basis
Then add this to your .wsgi folder:
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
Bottom of this page for more info:
https://flask.palletsprojects.com/en/2.0.x/deploying/mod_wsgi/
And now it works! Hopefully this will help somebody else out as well.
Related
When I want to deploy my code to Heroku using
git push heroku master
I have ImportError:Couldn't import Django.
So I try python manage.py runserver to see what is going on and it shows this in the terminal.
Full description of ImportError:Couldn't import Django.
Before I tab all the process for deploying my code to Heroku,python manage.py runserver works well (the system gives me a link to open my Web page).
Here is my requirements.txt
requirements.txt
Usually, when you deploy a python app to Heroku, you must have a requirements.txt file. I had this same error and when I added all of my dependencies to a requirements.txt file, it all worked. Best way to do this is if you are running on a virtual environment is
pip freeze > requirements.txt
I am trying to learn Flask using VScode.
The tutorial that I am following is: Python Flask Tutorial: Full-Featured Web App Part 1 - Getting Started.
I did the following things:
Created a new virtualenv in a folder using: virtualenv venv
activated it as: venv\Scripts\activate (I am on Windows 10)
After that, I created a new directory named Flask_Blog using mkdir Flask_Blog and in it, I created a new flaskblog.py file containing the following code:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return 'Hello'
Then, in the terminal of VScode, I changed my working directory in order to be in the Flask_Blog directory using cd Flask_Blog.
Now, when I am doing set FLASK_APP=flaskblog.py followed by flask run, I am getting the following error:
(venv) PS C:\Users\kashy\OneDrive\Desktop\Flask\Flask_Blog> flask run
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
Usage: flask run [OPTIONS]
Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.
But
When I do the same in the cmd prompt, the code runs and I get to see the output.
I am completely new to this. Can anyone please tell me what is the mistake I am doing in VSCode and why is it working in the cmd?
Issue raised in VsCode
Under Powershell, you have to set the FLASK_APP environment variable as follows:
$env:FLASK_APP = "webapp"
Then you should be able to run "python -m flask run" inside the hello_app folder. In other words, PowerShell manages environment variables differently, so the standard command-line "set FLASK_APP=webapp" won't work.
Try Set FLASK_APP = Full path of the folder/filename.py.
This worked for me
This worked for me on the VSCode:
$env:FLASK_APP= 'C:\Python\ex003\main:app'
I'm working on a project which used to be run on Linux for test. It's an App Engine flex project, run with gunicorn. Gunicorn does not work on Windows if I understood well, so I've been adviced to use waitress.
I also use virtualenv in my project.
So when I'm in my virtualenv, I run waitress-serve main:app (the gunicorn cmd was gunicorn -b :8080 main:app). I get an error: It had these arguments:
1. No module named flask.
I use flask. I can see the flask folder in my virtualenv folder. And when I run python then from flask import Flask I have no error.
Is there compat issue between waitress and virtualenv ? Or I'm doing something else wrong ? (already tried to delete virtualenv folder and install all the things again)
Python modules are case sensitive
Try Flask not flask.
I have my apache config set up to point to my virtualenv, but when i load the page and look at the error log it gives the following error:
from django.core.wsgi import get_wsgi_application
ImportError: No module named django.core.wsgi
apache2 000-default.conf file:
WSGIDaemonProcess project python-home=/home/django/config/env python-path=/usr/local/bfx/Databases/project
WSGIProcessGroup project
WSGIScriptAlias / /usr/local/bfx/Databases/project/project/wsgi.py
Basically, it will work if I install django, and all my django packages on my server, but what is the point of the virtual env?
Thanks
Virtualenv allows to create isolated environments. So you could create and run multiple projects with different versions of the same library without conflicts, for example.
You have to install all libraries in the server too. Virtualenv do not create a bundle nor deploy it.
I'm trying to implement Apache Basic Auth using mod_wsgi's WSGIAuthUserScript directive, and I can't figure out how to specify a python path. I'm using Django for the authentication, as detailed here, and I'm getting errors like:
Traceback (most recent call last):
File "/path-to-site/src/project/wsgi.py", line 21, in <module>
from django.contrib.auth.handlers.modwsgi import check_password
ImportError: No module named django.contrib.auth.handlers.modwsgi
My WSGIDaemonProcess directive uses the python-path option (pointing to a virtualenv's site-packages) but there doesn't seem to be a similar option for WSGIAuthUserScript. I've tried setting WSGIPythonPath, and setting the application-group option for WSGIAuthUserScript, but neither helped.
WSGIPythonPath should have worked. That or setting sys.path in the WSGI script file itself. What are you setting it to? Where is django installed? Does the user that Apache runs as have read permission down into where you have it installed?
I had similar problem, WSGIAuthUserScript does not use WSGIPythonPath or WSGIPythonHome nor process group. 2 solutions that worked for me:
Solution 1) compile mod_wsgi in your virtual env
# load your virtual environment
. bin/activate
# compiles AXXS needed by mod WSGI
pip install mod_wsgi-httpd
# Compile mod WSGI
pip install mod-wsgi
Install the mod_wsgi module in apache (CentOS & Co)
mod_wsgi-express install-module > /etc/httpd/conf.modules.d/25-wsgi.conf
Install the mod_wsgi module in apache (Debian & Co)
mod_wsgi-express install-module > /etc/apache2/mods-available/wsgi.conf
a2enmod wsgi
All your script should use your virtual env now.
Solution 2) load your venv within your auth script
python_home = "/myt_venv_path/"
sys.path.append(python_home)
# Needed by WSGIAuthUserScript
activate_this = python_home + '/bin/activate_this.py'
with open(activate_this) as venv:
exec(venv.read(), {'__file__': activate_this})