Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm a PHP programmer, but I want to learn Python. I'm a bit confused with how to actually execute a script. I've created test.py in my web server root, in the file I've written:

#!/usr/bin/python
import jon.cgi as cgi
import jon.fcgi as fcgi

print "Content-type: text/html"
print "hello world"

My server is running Litespeed on CentOS 5, following the tutorial at: http://www.litespeedtech.com/support/wiki/doku.php?id=litespeed_wiki:python_fcgi I've installed Jon's CGI.

But when I navigate to the script in my browser it just prints the full code, as if it's not parsing it. Sorry if I'm asking a stupid question, I would really appreciate any help, thanks.

share|improve this question

closed as off topic by wfaulk, Magellan, MadHatter, sysadmin1138 Nov 16 '12 at 13:00

Questions on Server Fault are expected to relate to professional server, networking, or related infrastructure administration within the scope defined by the community. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about reopening questions here.If this question can be reworded to fit the rules in the help center, please edit the question.

add comment

1 Answer

A real answer needs a lot more information (relevant paths, chunks of configuration, is your *.py executable, did you restart after configuration etc) so I'm going to do the best I can, but first...

Unlike PHP which has fastCGI built into the interpreter itself, Python doesn't hide the fastCGI implementation from you. At the very basic level, this test.py sets invalid headers (\r\n newlines are mandatory) and is missing the required blank line between headers and body. These are both things that the req.set_header() and req.write() functions (as shown in the example) deal with.

Second, you have to write a fastCGI application that runs "forever" (or until it hits the maximum number of requests and the server kills it to start another). Unlike PHP, there isn't a "python-cgi" like "php-cgi" (that I'm aware of, anyway...) that will run forever and handle requests by running little bits of source code from various files.

That app will have a request handler function that is called for every request and is responsible for reading and processing the actual request. In the case of the example given, the Handler class (which is a subclass of cgi.Handler) is created and is used to construct a fastCGI server whose run() method is called to handle the "run forever" part of the question. The class has a process() member added that accepts the request and does something. This "something" is where you would have your hello world code.

Based on the configuration in the example you linked, when a browser goes to http://vhost.example.com/python/banana/apple.jpg, litespeed will attempt to connect to an existing /absolutepathto/demoapp.py process through the socket file at /tmp/lshttpd/mypythonfcgi.sock (or run the demoapp.py program then connect if necessary). Once it's connected, it uses the fastCGI protocol to tell the running app that it has a request for banana/apple.jpg via REQUEST_URI (I think. It may be /python/banana/apple.jpg or something like that. Use the example given to dump the request and see). It's up to the process() member function to figure out what to do with the banana/apple.jpg request. Unlike plain PHP, URLs will not necessarily correspond to individual pieces of source code. (Though you could write a python program that uses REQUEST_URI to execute other python programs.)

Also note that this /absolutepathto/fastcgiapp.py is traditionally outside of your server document root so that people can't accidentally download the app itself.

Now, as to why your script is being printed out instead of throwing a bad header error, giving you a blank page, or just crashing. Leading suspects are one of the three:

  1. your "/absolutepathto/test.py" isn't executable (though I'm sure this would cause an error)
  2. your virtualhost in litespeed isn't configured with your test.py as an "External App" (this could also be configured at the server level for all virtualhosts)
  3. your URI on that virtualhost isn't configured to route requests to your "External App" configured in step #2.
  4. you didn't restart litespeed after changing the configuration for #2 and #3? (not really a leading suspect but gotta ask)

If it isn't #1 or #4, update the question with your relevant litespeed configuration, and we'll go from there.

share|improve this answer
    
Thank you very much for you detailed explanation, I didn't understand all of it but it was very helpful anyway! You're right my virtualhost wasn't configured correctly, the python script now shows "Hello World" instead of the code! Thanks Again! :) –  Arran May 10 '12 at 4:26
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.