<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.nginx.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.nginx.org/index.php?title=SimplePythonFCGI&amp;feed=atom&amp;action=history</id>
		<title>SimplePythonFCGI - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.nginx.org/index.php?title=SimplePythonFCGI&amp;feed=atom&amp;action=history"/>
		<link rel="alternate" type="text/html" href="http://wiki.nginx.org/index.php?title=SimplePythonFCGI&amp;action=history"/>
		<updated>2013-06-19T10:35:09Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.19.0</generator>

	<entry>
		<id>http://wiki.nginx.org/index.php?title=SimplePythonFCGI&amp;diff=84&amp;oldid=prev</id>
		<title>MichaelLustfield: moved NginxSimplePythonFCGI to SimplePythonFCGI:&amp;#32;Removing Nginx prefix from page titles</title>
		<link rel="alternate" type="text/html" href="http://wiki.nginx.org/index.php?title=SimplePythonFCGI&amp;diff=84&amp;oldid=prev"/>
				<updated>2010-09-22T19:32:43Z</updated>
		
		<summary type="html">&lt;p&gt;moved &lt;a href=&quot;/NginxSimplePythonFCGI&quot; class=&quot;mw-redirect&quot; title=&quot;NginxSimplePythonFCGI&quot;&gt;NginxSimplePythonFCGI&lt;/a&gt; to &lt;a href=&quot;/SimplePythonFCGI&quot; title=&quot;SimplePythonFCGI&quot;&gt;SimplePythonFCGI&lt;/a&gt;: Removing Nginx prefix from page titles&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Dispatching TurboGears Python via FCGI ==&lt;br /&gt;
&lt;br /&gt;
This confirmed to run on Mac OS X 10.4.7 under Turbogears 0.9.9 and 1.1a (so, no reason not to run under the 1.0b release).&lt;br /&gt;
&lt;br /&gt;
Information was drawn from the Turbogears trac wiki (http://trac.turbogears.org/turbogears/wiki/NginxIntegration) which show how to use Nginx to proxy to TG, and the nearby [NginxFcgiExample]  page, the latter detailing the PHP/FCGI process.&lt;br /&gt;
&lt;br /&gt;
This is for Nginx/FCGI/Turbogears&lt;br /&gt;
&lt;br /&gt;
=== Conventions ===&lt;br /&gt;
&lt;br /&gt;
Substitute thoughout with the values relevant to your own set-up:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;${HOST} = localhost&amp;lt;/code&amp;gt; - (or whatever you choose)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;${PORT} = 8080&amp;lt;/code&amp;gt; - (or whatever you choose)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;${NGINX} = /usr/local/nginx&amp;lt;/code&amp;gt; - location of nginx installation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;${PROJECTBASE} /opt/projects/wiki20&amp;lt;/code&amp;gt; - location of Turbogears project&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;${PROJECTNAME} wiki20&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting the required files ==&lt;br /&gt;
&lt;br /&gt;
Two files are required to be created: '''${NGINX}/scripts/fcgi.py''' and '''${NGINX}/scripts/${PROJECTNAME}.fcgi'''.&lt;br /&gt;
&lt;br /&gt;
To create '''${NGINX}/scripts/fcgi.py''' ...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir ${NGINX}/scripts&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -o ${NGINX}/scripts/fcgi.py http://www.saddi.com/software/py-lib/py-lib/fcgi.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create '''${NGINX}/scripts/${PROJECTNAME}.fcgi''' ...&lt;br /&gt;
&lt;br /&gt;
Copy and paste the following to '''${NGINX}/scripts/${PROJECTNAME}.fcgi'''. Edit the file, navigate to the&lt;br /&gt;
'''&amp;quot;USER EDIT SECTION&amp;quot;''' and replace each instance of '''${PROJECTBASE}''' and $'''{PROJECTNAME}''' with&lt;br /&gt;
the corresponding values for your project.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;geshi lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
#&lt;br /&gt;
# File name: project.fcgi&lt;br /&gt;
#&lt;br /&gt;
# This module provides the glue for running TurboGears applications behind&lt;br /&gt;
# FastCGI-enabled web servers. The code in this module depends on the fastcgi&lt;br /&gt;
# module downloadable from here:&lt;br /&gt;
#&lt;br /&gt;
# http://www.saddi.com/software/py-lib/py-lib/fcgi.py&lt;br /&gt;
#&lt;br /&gt;
# NOTE: The fcgi.py file needs to be placed in a location that is on the&lt;br /&gt;
# system path, such as the same the directory as the tg_fastcgi.py file&lt;br /&gt;
# or in the base directory of the TG app code.&lt;br /&gt;
#&lt;br /&gt;
# To configure this module, please edit the three variables in the &amp;quot;USER EDIT&lt;br /&gt;
# SECTION&amp;quot; before starting the TG application. Also remember to edit the&lt;br /&gt;
# top of this file with the correct Python installation information.&lt;br /&gt;
&lt;br /&gt;
import cherrypy&lt;br /&gt;
import sys&lt;br /&gt;
import os&lt;br /&gt;
from os.path import *&lt;br /&gt;
import pkg_resources&lt;br /&gt;
import turbogears&lt;br /&gt;
&lt;br /&gt;
pkg_resources.require(&amp;quot;TurboGears&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# -- START USER EDIT SECTION&lt;br /&gt;
# -- Users must edit this section --&lt;br /&gt;
code_dir = '${PROJECTBASE}' # (Required) The base directory of the TG app code.&lt;br /&gt;
root_class_name = '${PROJECTNAME}.controllers.Root' # (Required) The fully qualified Root class name.&lt;br /&gt;
project_module_name = '${PROJECTNAME}.config' # (Required) The config module name.&lt;br /&gt;
log_dir = '' # (Optional) The log directory. Default = code_dir.&lt;br /&gt;
# -- END USER EDIT SECTION&lt;br /&gt;
&lt;br /&gt;
class VirtualPathFilter(object):&lt;br /&gt;
    def on_start_resource(self):&lt;br /&gt;
        if not cherrypy.config.get('virtual_path_filter.on', False):&lt;br /&gt;
     return&lt;br /&gt;
 prefix = cherrypy.config.get('virtual_path_filter.prefix', '')&lt;br /&gt;
 if not prefix:&lt;br /&gt;
     return&lt;br /&gt;
&lt;br /&gt;
 path = cherrypy.request.object_path&lt;br /&gt;
 if path == prefix:&lt;br /&gt;
     path = '/'&lt;br /&gt;
 elif path.startswith(prefix):&lt;br /&gt;
     path = path[len(prefix):]&lt;br /&gt;
 else:&lt;br /&gt;
     raise cherrypy.NotFound(path)&lt;br /&gt;
 cherrypy.request.object_path = path&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def tg_init():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Checks for the required data and initializes the application. &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    global code_dir&lt;br /&gt;
    global root_class_name&lt;br /&gt;
    global log_dir&lt;br /&gt;
    global project_module_name&lt;br /&gt;
    last_mark = 0&lt;br /&gt;
&lt;br /&gt;
    # Input checks&lt;br /&gt;
    if not code_dir or not isdir(code_dir):&lt;br /&gt;
        raise ValueError(&amp;quot;&amp;quot;&amp;quot;The code directory setting is missing.&lt;br /&gt;
                            The fastcgi code will be unable to find&lt;br /&gt;
                            the TG code without this setting.&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if not root_class_name:&lt;br /&gt;
        raise ValueError(&amp;quot;&amp;quot;&amp;quot;The fully qualified root class name must&lt;br /&gt;
                            be provided.&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    last_mark = root_class_name.rfind('.')&lt;br /&gt;
    &lt;br /&gt;
    if last_mark &amp;lt; 1 or last_mark + 1 == len(root_class_name):&lt;br /&gt;
        raise ValueError(&amp;quot;&amp;quot;&amp;quot;The user-defined class name is invalid.&lt;br /&gt;
                            Please make sure to include a fully&lt;br /&gt;
                            qualified class name for the root_class&lt;br /&gt;
                            value (e.g. wiki20.controllers.Root).&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    sys.path.append(code_dir)&lt;br /&gt;
&lt;br /&gt;
    # Change the directory so the TG log file will not be written to the&lt;br /&gt;
    # web app root.&lt;br /&gt;
    if log_dir and isdir(log_dir):&lt;br /&gt;
        os.chdir(log_dir)&lt;br /&gt;
    else:&lt;br /&gt;
        os.chdir(code_dir)&lt;br /&gt;
        log_dir = code_dir&lt;br /&gt;
&lt;br /&gt;
    sys.stdout = open(join(log_dir, 'stdout.log'),'a')&lt;br /&gt;
    sys.stderr = open(join(log_dir, 'stderr.log'),'a')&lt;br /&gt;
&lt;br /&gt;
    if exists(join(code_dir, &amp;quot;setup.py&amp;quot;)):&lt;br /&gt;
        turbogears.update_config(configfile=join(code_dir, &amp;quot;dev.cfg&amp;quot;),modulename=project_module_name)&lt;br /&gt;
    else:&lt;br /&gt;
        turbogears.update_config(configfile=join(code_dir, &amp;quot;prod.cfg&amp;quot;),modulename=project_module_name)&lt;br /&gt;
&lt;br /&gt;
    # Set environment to production to disable auto-reload and&lt;br /&gt;
    # add virutal path information.&lt;br /&gt;
    cherrypy.config.update({&lt;br /&gt;
        'global': {'server.environment': 'production'},&lt;br /&gt;
     '/' : { 'virtual_path_filter.on' : True,&lt;br /&gt;
     'virtual_path_filter.prefix' : '/bel.fcgi' }&lt;br /&gt;
  })&lt;br /&gt;
&lt;br /&gt;
    # Parse out the root class information for Cherrypy Root class.&lt;br /&gt;
    package_name = root_class_name[:last_mark]&lt;br /&gt;
    class_name = root_class_name[last_mark+1:]&lt;br /&gt;
    _temp = __import__(package_name, globals(), locals(), [class_name], -1)&lt;br /&gt;
    Root = getattr(_temp, class_name)&lt;br /&gt;
    Root._cp_filters = [VirtualPathFilter()]&lt;br /&gt;
    cherrypy.root = Root()&lt;br /&gt;
&lt;br /&gt;
# Main section -&lt;br /&gt;
# Initialize the application, then start the server.&lt;br /&gt;
tg_init()&lt;br /&gt;
&lt;br /&gt;
from fcgi import WSGIServer&lt;br /&gt;
cherrypy.server.start(initOnly=True, serverClass=None)&lt;br /&gt;
&lt;br /&gt;
from cherrypy._cpwsgi import wsgiApp&lt;br /&gt;
WSGIServer(application=wsgiApp).run()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/geshi&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adjust the TurboGears configuration ==&lt;br /&gt;
&lt;br /&gt;
Edit the '''${PROJECTBASE}/dev.cfg''' or '''${PROJECTBASE}/prod.cfg''' file (whichever you are using), uncomment the '''server.socket_port''' assignment and change ${PORT} to a value of your choice (make sure nothing else is running on that port, Tomcat defaults to 8080, as does Jetty. Save yourself some time and check first with a '''telnet localhost 8080''', you should see ''Connection refused'').&lt;br /&gt;
&lt;br /&gt;
The relevant lines in prod/dev.cfg are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
server.socket_port=${PORT}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Spawning a FastCGI TurboGears process ==&lt;br /&gt;
&lt;br /&gt;
The lighttpd &amp;quot;spawn-fcgi&amp;quot; script is useful: download, compile and install lighttpd. Then (replacing '''${HOST}''' and '''${PORT}''' values appropriately), execute the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/usr/local/bin/spawn-fcgi -a ${HOST} -p ${PORT} -u nobody -f ${NGINX}/scripts/${PROJECTNAME}.fcgi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Nginx configuration ==&lt;br /&gt;
&lt;br /&gt;
Save the following into '''${NGINX}/conf/fastcgi_params'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;geshi lang=&amp;quot;nginx&amp;quot;&amp;gt;&lt;br /&gt;
#fastcgi.conf&lt;br /&gt;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;&lt;br /&gt;
fastcgi_param SERVER_SOFTWARE nginx;&lt;br /&gt;
&lt;br /&gt;
fastcgi_param QUERY_STRING $query_string;&lt;br /&gt;
fastcgi_param REQUEST_METHOD $request_method;&lt;br /&gt;
fastcgi_param CONTENT_TYPE $content_type;&lt;br /&gt;
fastcgi_param CONTENT_LENGTH $content_length;&lt;br /&gt;
&lt;br /&gt;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;&lt;br /&gt;
fastcgi_param REQUEST_URI $request_uri;&lt;br /&gt;
fastcgi_param DOCUMENT_URI $document_uri;&lt;br /&gt;
fastcgi_param DOCUMENT_ROOT $document_root;&lt;br /&gt;
fastcgi_param SERVER_PROTOCOL $server_protocol;&lt;br /&gt;
&lt;br /&gt;
fastcgi_param REMOTE_ADDR $remote_addr;&lt;br /&gt;
fastcgi_param REMOTE_PORT $remote_port;&lt;br /&gt;
fastcgi_param SERVER_ADDR $server_addr;&lt;br /&gt;
fastcgi_param SERVER_PORT $server_port;&lt;br /&gt;
fastcgi_param SERVER_NAME $server_name;&lt;br /&gt;
&amp;lt;/geshi&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the following to the server section of the '''${NGINX}/conf/nginx.conf''' configuration file, changing '''${HOST}''' and '''${PORT}''' as appropriate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;geshi lang=&amp;quot;nginx&amp;quot;&amp;gt;&lt;br /&gt;
  # static files&lt;br /&gt;
  location ~ ^/(images|javascript|js|css|flash|media|static)/ {&lt;br /&gt;
    root ${PROJECTBASE}/${PROJECTNAME}/static;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  location = /favicon.ico {&lt;br /&gt;
    root ${PROJECTBASE}/${PROJECTNAME}/static/images;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  # pass all requests to FastCGI TG server listening on ${HOST}:${PORT}&lt;br /&gt;
  #&lt;br /&gt;
  location / {&lt;br /&gt;
    fastcgi_pass ${HOST}:${PORT};&lt;br /&gt;
    fastcgi_index index;&lt;br /&gt;
    fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;&lt;br /&gt;
    include conf/fastcgi_params;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/geshi&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starting nginx ==&lt;br /&gt;
&lt;br /&gt;
Start nginx with '''${NGINX}/sbin/nginx'''. Point your browser to &amp;lt;code&amp;gt;http://${HOST}:${PORT}/&amp;lt;/code&amp;gt;, your Turboears project should be serving via FastCGI. If so ... congratulations.&lt;br /&gt;
&lt;br /&gt;
== Performance test software ==&lt;br /&gt;
&lt;br /&gt;
Basic but usefully free http://www.hpl.hp.com/research/linux/httperf/&lt;br /&gt;
&lt;br /&gt;
=== Note ===&lt;br /&gt;
[I left the IP address as 0.0.0.0 because it worked for me, whereas 127.0.0.1 did not. If you're experiencing difficulties connecting to 0.0.0.0:8080, these are both alternative options; localhost:8080, 127.0.0.1:8080.] &lt;br /&gt;
&lt;br /&gt;
Good luck.&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>MichaelLustfield</name></author>	</entry>

	</feed>