Install guide
Other languages : español | Japan 日本語 | chinese 简体中文 | italiano | français | Serbo-Croatian |
Summary
Install
To install web.py for Python >= 3.5, download:
https://github.com/webpy/webpy/archive/0.61.tar.gz
or the get the latest dev version:
https://github.com/webpy/webpy/tarball/master
extract it and copy the web folder into a directory where your application is. Or, to make it accessible to all applications, run:
python setup.py install
Note: on some unix like systems you may need sudo
to get root privilege:
sudo python setup.py install
see recommended setup.
Another option is to use Easy Install. Once Easy Install is properly setup:
easy_install web.py
Or PIP
pip install web.py==0.61
To install web.py for Python 2.7, please use the version 0.51
, the last supported version for Python 2.
python2 -m pip install web.py==0.51
Development
web.py comes with a built-in webserver. Learn how to write an application by following the tutorial. When you have an application written, put your code into code.py
and start the server like this:
python code.py
Open your browser and go to http://localhost:8080/ to view the page. To specify another port, use python code.py 1234
.
Production
The web server that gets started when you run a web.py program is nice, but for popular sites you’re going to want something a little more serious. web.py implements WSGI and runs with everything that is compatible to it. WSGI is a common API between web servers and applications, analogous to Java’s Servlet Interface. To run web.py with CGI, FastCGI or SCGI you will need to install flup (download here), which provides WSGI interfaces for those APIs.
For all the CGI variants, add this to the top of your code.py
:
#!/usr/bin/env python
And run chmod +x code.py
to make it executable.
Nginx
- uWSGI service deployment through Nginx on Linux
- mod_wsgi deployment through Nginx
- Fastcgi deployment through Nginx
Lighttpd
.. with FastCGI
FastCGI with lighttpd is the recommended way of using web.py in production. reddit.com handles millions of hits this way.
Your lighttpd config can be something like:
server.modules = ("mod_fastcgi", "mod_rewrite")
server.document-root = "/path/to/root/"
fastcgi.server = ( "/code.py" =>
(( "socket" => "/tmp/fastcgi.socket",
"bin-path" => "/path/to/root/code.py",
"max-procs" => 1
))
)
url.rewrite-once = (
"^/favicon.ico$" => "/static/favicon.ico",
"^/static/(.*)$" => "/static/$1",
"^/(.*)$" => "/code.py/$1"
)
With some versions of lighttpd, it is important to ensure the “check-local” property of the fastcgi.server entry is set to “false”, especially if your code.py
is located outside of the document root.
If you get error messages about not being able to import flup, install it by typing “easy_install flup” at the command line.
Since revision 145, it is necessary to set a bin-environment variable on the fastcgi configuration if your code uses redirects. If when your code redirects to http://domain.com/ and in the url bar you see http://domain.com/code.py/, you’ll need to set the environment variable. This will cause your fastcgi.server configuration above to look something like this:
fastcgi.server = ( "/code.py" =>
((
"socket" => "/tmp/fastcgi.socket",
"bin-path" => "/path/to/root/code.py",
"max-procs" => 1,
"bin-environment" => (
"REAL_SCRIPT_NAME" => ""
),
"check-local" => "disable"
))
)
Apache
.. with CGI
Add the following to httpd.conf
or apache2.conf
.
Alias /foo/static/ /path/to/static
ScriptAlias /foo/ /path/to/code.py
.. with CGI using .htaccess
CGI is easy to configure, but is not suitable for high-performance websites.
Add this to your .htaccess
:
Options +ExecCGI
AddHandler cgi-script .py
and point your browser to http://example.com/code.py/
. Don’t forget the trailing slash, otherwise you’ll see a not found
message (because the urls
list you defined do not match anything). To make things work without having to enter code.py
, enable mod_rewrite rules (see below).
Note: The way web.py
is implemented breaks the cgitb
module because it captures stdout
. I worked around the issue by using this:
import cgitb; cgitb.enable()
import sys
# ... import web etc here...
def cgidebugerror():
_wrappedstdout = sys.stdout
sys.stdout = web._oldstdout
cgitb.handler()
sys.stdout = _wrappedstdout
web.internalerror = cgidebugerror
.. with FastCGI
FastCGI is easy to configure and performs as well as mod_python.
Add this to your .htaccess
:
<Files code.py>
SetHandler fastcgi-script
</Files>
Unfortunately, unlike lighttpd, Apache gives no hint that it wants your web.py script to act as a FastCGI server so you have to tell web.py explicitly. Add this to code.py
before your if __name__ == "__main__":
line:
web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr)
and point your browser to http://example.com/code.py/
. Don’t forget the trailing slash, otherwise you’ll see a not found
message (because the urls
list you defined do not match anything). To make things work without having to enter code.py
, enable mod_rewrite rules (see below).
Walter has some additional advice.
.. with SCGI
https://www.mems-exchange.org/software/scgi/
download mod_scgi
source here: http://www.mems-exchange.org/software/files/mod_scgi/
windows apache user:
edit your httpd.conf:
LoadModule scgi_module Modules/mod_scgi.so
SCGIMount / 127.0.0.1:8080
restart apache and then start your code.py in the command below:
python code.py 127.0.0.1:8080 scgi
and open you browser,visit 127.0.0.1 It’s ok!
.. with mod_python
mod_python performs as well as FastCGI, but is not as straight-forward to configure.
For Python 2.5 do this:
cd /usr/lib/python2.5/wsgiref
# or in windows: cd /python2.5/lib/wsgiref
wget -O modpython_gateway.py http://svn.aminus.net/misc/modpython_gateway.py
# or fetch the file from that address using your browser
For Python <2.5 do this:
cd /usr/lib/python2.4/site-packages
# or in windows: cd /python2.4/lib/site-packages
svn co svn://svn.eby-sarna.com/svnroot/wsgiref/wsgiref
cd wsgiref
wget -O modpython_gateway.py http://svn.aminus.net/misc/modpython_gateway.py
# or fetch the file from that address using your browser
Rename your code.py
to something like codep.py
and add:
app = web.application(urls, globals())
main = app.wsgifunc()
In your .htaccess
, add:
AddHandler python-program .py
PythonHandler wsgiref.modpython_gateway::handler
PythonOption wsgi.application codep::main
You also probably want to add a RewriteRule
pointing /
to /codep.py/
Be sure to visit /codep.py/
with the extra /
on the end. Otherwise, you’ll see an error message like A server error occurred. Please contact the administrator.
.. with mod_wsgi
mod_wsgi is a new Apache module which typically outperforms mod_python for hosting WSGI applications, and is very easy to set up.</div>
At the end of your code.py
, add:
app = web.application(urls, globals(), autoreload=False)
application = app.wsgifunc()
mod_wsgi offers many possible ways to expose a WSGI application in Apache’s URL hierarchy, but one simple way would be to add the following to your .htaccess:
<Files code.py>
SetHandler wsgi-script
Options ExecCGI FollowSymLinks
</Files>
If you get an “ImportError: No module named web” in your apache error.log file, you could try setting the absolute path in code.py before importing web:
import sys, os
abspath = os.path.dirname(__file__)
sys.path.append(abspath)
os.chdir(abspath)
import web
Also, you might want to read the “Application Working Directory” section from Common problems with WSGI application.
It should then be accessible at http://example.com/code.py/
as usual.
mod_rewrite Rules for Apache
If you want web.py to be accessible at ‘http://example.com’ instead of ‘http://example.com/code.py/’ add the following rules to the .htaccess
file:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} !^/icons
RewriteCond %{REQUEST_URI} !^/favicon.ico$
RewriteCond %{REQUEST_URI} !^(/.*)+code.py/
RewriteRule ^(.*)$ code.py/$1 [PT]
</IfModule>
If the code.py
is in the subfolder myapp/
, adjust the RewriteBase to RewriteBase /myapp/
. If you have static files like CSS files and images to pass through, duplicate the line with the icons for each path you want to allow.