I'm trying to run Python within a sandbox using WSGI and Apache.
I created the virtual environment:
virtualenv /var/www/demo-environment --python /usr/bin/python3.3
I also created the following /var/www/demo.py file:
#!/usr/bin/env python
import sys
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return "Running " + str(sys.version_info)
Finally, I changed Apache configuration like this:
WSGIPythonPath /var/www/demo-environment/lib/python3.3/site-packages/
WSGIDaemonProcess example.com python-path=/var/www/demo-environment/lib/python3.3/site-packages/
WSGIProcessGroup example.com
WSGIScriptAlias / /var/www/demo.py
When going to the home page of the website, it shows the following contents: Running sys.version_info(major=2, minor=7, micro=5, releaselevel='final', serial=0), indicating that while Python works, it is not called within a virtual environment.
Since this is the wrong way to enable virtualenv, which is the right one?
Just use the setting WSGIPythonHome to specify the root of your env:
WSGIPythonHome /home/grapsus/work/python/env
WSGIScriptAlias /demo /home/grapsus/work/python/demo.py
I modified your script to print sys.path:
Running ['/home/grapsus/work/python/env/lib/python2.7', ...
Related
Python3.8 has a new feature where you can set PYTHONPYCACHEPREFIX environment variable to a dir path so that the pycache uses a separate parallel filesystem tree, rather than the default __pycache__ subdirectories within each source directory:
https://docs.python.org/3/whatsnew/3.8.html#parallel-filesystem-cache-for-compiled-bytecode-files
I've set this environment variable:
export PYTHONPYCACHEPREFIX="$HOME/.cache/pycache/"
This works corectly with python3.8 via the command line directly, but it doesn't work for a python3.8 WSGI web application. How do you get this working with a WSGI web application? Here is an example of my WSGI web application:
# apache.conf Load python3.8 mod_wsgi (installed mod_wsgi by Python3.8 pip)
LoadModule wsgi_module /path/to/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so
# Vhost
<VirtualHost *:80>
ServerName example1.example.com
# The Python-home runs Python3.8 in venv
WSGIDaemonProcess example1 processes=2 threads=15 display-name=%{GROUP} python-home=/home/ubuntu/web-apps/example1/venv
WSGIProcessGroup example1
WSGIScriptAlias / /home/ubuntu/web-apps/example1/web/app.wsgi
<Directory /home/ubuntu/web-apps/example1/web>
Options -Indexes +FollowSymLinks
Require all granted
</Directory>
</VirtualHost>
# example1/web/app.wsgi
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../")))
from web.app import application
# example1/web/app.py
# Will return "Hello. Python version is 3.8.0"
import sys
def application(environ, start_response):
status = '200 OK'
header = [('Content-type', 'text/html; charset=utf-8')]
content = f"Hello. Python version is {sys.version}"
start_response(status, header)
content = content.encode('utf-8')
return [content]
I have looked everywhere and tried many suggested solutions, still without the required result: to run a python file from my lamp server. I can not seem to integrate all the pieces of the puzzle ... Complicating the story is that many solutions either use old apache version (<2.4), which changed the config files significantly. No more httpd.conf! so this executing-a-python-script-in-apache2 does not help; But also the python version being > 3 complicates matters.
specs:
linux Kubuntu, apache 2.4, python 3.5
apache is running
website files are in root/var/www/html/, I have sudo access to this folder.
apache2 cgi module enabled: a2enmod cgi
the python 3.5 path is usr/bin/env python3
the python script, simplest of scripts, has been made executable
#!/usr/bin/env python3
print ("Content-type: text/html\n")
print ("Hello world!")
lets boil it down to the simplest case: I would like to have apache interpret the spark.py script and spit out the html: "Hello world!"
Questions:
is the script file correct as is?
which config files do I need to change and what do I need to add to these config files?
I know for security reasons, you should not have apache run script in your root dir.
The python documentation for modwsgi seems to fit what you are asking for. The following webpage has a really simple example and the necessary configuration for a python3-apache2 setup.
http://modwsgi.readthedocs.io/en/develop/user-guides/quick-configuration-guide.html
You will need to install the mod_wsgi for the configuration to work. Take note of the different "_" underscore and "-" dash character used in apt and pip3.
$ sudo apt install apache2-dev libapache2-mod-wsgi-py3
$ sudo pip3 install mod_wsgi
libapache2-mod-wsgi-py3 and mod_wsgi seems to be the same thing. However, my test deployment only works after installing mod_wsgi. Could be configuration issue. The following are the details of the configuration I have tested on Ubuntu 16.04.2.
Application file /home/user/wsgi_sample/hello.wsgi:
def application(environ, start_response):
status = '200 OK'
output = b'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Apache2 configuration /etc/apache2/sites-available/000-test.conf
<VirtualHost *:80>
ServerName testmachine
<Directory /home/user/wsgi_sample>
Order allow,deny
Allow from all
Require all granted
</Directory>
WSGIScriptAlias /hello /home/user/wsgi_sample/hello.wsgi
</VirtualHost>
Enable the site in apache2.
sudo a2ensite 000-test.conf
Open your browser to testmachine/hello.
wsgi may also be deployed on Apache2 using passenger. It demands a slighter longer configuration. Ask a new question if passenger/python3 is desired.
Yes, your minimum code seem correct. The Apache config information is answered here
https://stackoverflow.com/a/57531411/4084546
I cannot for the life of me figure of why this flask application I'm trying to launch is not working. I am running it on a $5 Digital Ocean droplet. Here's (hopefully) everything you need to know about it:
Directory layout (contained within /var/www/):
FlaskApp
FlaskApp
__init__.py
static
templates
venv
flaskapp.wsgi
__init__.py:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "yay it worked"
if __name__ == "__main__":
app.run()
flaskapp.wsgi:
#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/FlaskApp/")
from FlaskApp import app as application
application.secret_key = 'Add your secret key'
FlaskApp.conf (contained in /etc/apache2/sites-availble):
<VirtualHost *:80>
ServerName the.ip.blah.blah
ServerAdmin admin#mywebsite.com
WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi
<Directory /var/www/FlaskApp/FlaskApp/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/FlaskApp/FlaskApp/static
<Directory /var/www/FlaskApp/FlaskApp/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
venv was created from calling virtualenv venv within /var/www/FlaskApp/FlaskApp/. I installed flask in venv using pip install flask after entering venv using source venv/bin/activate.
Wsgi has been enabled (a2enmod wsgi). FlaskApp.conf was enabled (a2ensite FlaskApp). And, finally, I restarted apache many times, but to no success (service apache2 restart).
I was following this guide on how to set up a flask application.
Here is a screenshot of what my error looks like:
Any help on getting this to work would be greatly appreciated.
Thanks in advance.
EDIT: I found the problem: ImportError: No module named flask. This is a little strange since I did do pip install flask within the virtualenv. When I just open a python console session in the virtualenv and try import flask I get no error, so not sure what's going on.
Also, how is this application even using venv? I don't see it getting accessed anywhere so how is it even using it? Perhaps this is why i'm getting the ImportError, because I only have flask installed on the virtualenv but it's not being used?
The problem is essentially that you are installing Flask, and possibly other required libraries, in a virtual environment but the python (wsgi interface) is running with the system python which does not have these extra libraries installed.
I have very little recent experience running Python on Apache (I come from an era of mod_python and cgi), but apparently one way to handle this is to use the site package to add the site-packages from your venv to the Python that is executed. This would go in your .wsgi file.
import site
site.addsitedir('/path/to/your/venv/lib/pythonX.X/site-packages')
I think the best way to solve your problem is to add tell your wsgi file about your virtual environment and activate it:
put the following code in your your flaskapp.wsgi
activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
and restart apache.
hope it will help!
find more here
I have a website running on apache-python2(virtualenv)-flask stack on Arch linux server. It seems that wsgi application is not picking up the python from virtualenv, and instead uses system's python.
web/test.py
import sys
print(sys.version)
Result in: error_log
3.4.3 (default, Mar 25 2015, 17:13:50)
The default python on the server is
$ python --version
Python 3.4.3
The virtual environment I intend to use has python2
$ virtualenv -p /usr/bin/python2.7 flask
$ source flask/bin/activate
$ python --version
Python 2.7.10
The virtualhost apache file:
/etc/httpd/conf/vhosts/msw.com
<VirtualHost *:80>
ServerName msw.com
ServerAlias www.msw.com
ServerAdmin webmaster#localhost
WSGIDaemonProcess msw user=live group=live threads=5 python-path=/home/live/msw/flask/lib/python2.7/site-packages
WSGIScriptAlias / /home/live/msw/msw.wsgi
<Directory /home/live/msw>
#Header set Access-Control-Allow-Origin "*"
WSGIScriptReloading On
WSGIProcessGroup msw
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
Options All
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
The wsgi file:
/home/live/msw/msw.wsgi
import sys
activate_this = '/home/live/msw/flask/bin/activate_this.py'
#execfile(activate_this, dict(__file__=activate_this))
with open(activate_this) as f:
code = compile(f.read(), activate_this, 'exec')
exec(code, dict(__file__=activate_this))
sys.path.insert(0, '/home/live/msw/web')
sys.path.insert(0, '/home/live/msw')
from web import msw as application
Why is mod_wsgi not picking up virtualenv's python? What am I doing wrong?
I eventually figured it out. The official arch-linux documentation is a bit confusing, mod_wsgi. It tries to imply that mod_wsgi installation will work for both Python2/3. However, mod_wsgi still ends up using system's Python3. I solved the problem by installing mod_wsgi2 which is specific to Python2.
pacman -S mod_wsgi2
Ι have developed a Django project and uploaded it to a cloud VΜ. Currently i have access to it through 8080 port.
python manage.py runserver 0.0.0.0:8080
If i enter the url without the 8080 port, it shows the "it works" page. How can i set my Django project to run by default on 80 port?
I am using Ubuntu 12.04 server
As docs say, runserver isn't meant as a deployment server. It also mentions that you probably can't start it on port 80 unless you run it as root.
Here is the kind of file you will need to put in /etc/apache2/sites-enabled, you need to adjust the paths in it. You also need to load mod_wsgi which you can do via apt-get.
<VirtualHost 192.168.1.14:80>
ServerAdmin youremail#whatever.com
ServerName www.whatever.com
ServerAlias whatever.com
Alias /robots.txt /home/dimitris/Python/mysite/site_media/robots.txt
Alias /favicon.ico /home/dimitris/Python/mysite/site_media/favicon.png
Alias /static/ /home/dimitris/Python/mysite/site_media/static
WSGIDaemonProcess mysite user=dimitris processes=1 threads=5
WSGIProcessGroup mysite
WSGIScriptAlias / /home/dimitris/Python/mysite/deploy/mysqite_wsgi.py
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel debug
ErrorLog ${APACHE_LOG_DIR}/mysite.error.log
CustomLog ${APACHE_LOG_DIR}/mysite.access.log combined
ServerSignature Off
</VirtualHost>
Most of this assumes you are running in a virtualenv, that means you will need a wsgi file to get things running. The above file sets up apache to run your "wsgi" file which looks something like this:
import os
from os.path import abspath, dirname, join
import sys
with open("/tmp/mysite.sys.path", "w") as f:
for i in sys.path:
f.write(i+"\n")
#redirect sys.stdout to sys.stderr for libraries that use
#print statements for optional import exceptions.
sys.stdout = sys.stderr
sys.path.insert(0, abspath(join(dirname(__file__), "../../")))
sys.path.insert(0, abspath(join(dirname(__file__), "../../lib/python2.7/site-packages/")))
from django.conf import settings
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
mod_wsgi, then opens this one file and executes it. application is the part that waits for requests from the webserver, and the rest behaves just like runserver except it can be multi-process and multi-threaded.
In the terminal while in a virtual environment, run:
sudo ./manage.py runserver 80
You will be asked for your password and it will run the server on port 80.