views:

99

answers:

2

I want to hide the .py extension of a Python script loaded in a web browser and still have the script run. For example: typing url.dev/basics/pythonscript in the address bar fires pythonscript.py and shows the results in the browser window.

  1. The URL url.dev/basics/pythonscript fetches the static file /pythonscript.py
  2. The browser still displays the url url.dev/basics//pythonscript

Typing in url.dev/basics/pythonscript.py DOES work and the Python script results is displayed. I can also get mod_rewrite to rewrite url.dev/basics/phpscript to url.dev/basics/phpscript.php and run the PHP code successfully behind the scenes.

But url.dev/basics/pythonscript does NOT redirect to url.dev/basics/pythonscript.py (I get a 404 Not Found).

Background Info

A) PHP rewriting works: the following in an .htaccess located in url.dev/basics/ WORKS for PHP scripts:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /basics/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
</IfModule>

B) Python rewriting does NOT work: the following in an .htaccess located in url.dev/basics/ does NOT work for Python scripts (I get a 404 Not Found):

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /basics/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.py -f
RewriteRule ^(.*)$ $1.py
</IfModule>

C) I am a beginning programmer working through Exercise 2: Your first program in the Basics section of Software Engineering for Internet Applications. I am trying to follow the recommendation to use an execution environment where 'One URL = one file', but want to use Python rather than PHP. I realize that this is not the best way to build a web application down the line. It is only a convention to be used during the initial part of the course linked above.

D) I set up the Virtual Hosts development environment in OS 10.6 Snow Leopard so that I can access my development at url.dev as per 'Hacky Holidays' at adactio.com. My Python version is Python 2.6.1.

E) I plan to use Django eventually, but want to work on simpler code first if possible so I can better understand what is going on.

F) I have the following in my httpd.conf:


TypesConfig /private/etc/apache2/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddHandler cgi-script .py

and:

LoadModule php5_module        libexec/apache2/libphp5.so
LoadModule fastcgi_module     libexec/apache2/mod_fastcgi.so

G) My Apache version (seen in server log after restarting the server): Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8l DAV/2 PHP/5.3.1 mod_fastcgi/2.4.2 configured -- resuming normal operations

Looking forward to any help!

+1  A: 

If you are running on a linux box, dont use mod-rewrite - rename the script.

you can call the script - pythonscript not pythonscript.py

you add to the first line of the script pointing to your python interpreter

and set the file to be executable

with

chmod +x pythonscript 

when the file is executed - it will read the first line of the file and execute the interpeter in the first line

#!/usr/bin/python 

and then set the directory to execute the script

to make this work, you change the files in the directory executable in your .htaccess file

basics/.htaccess
-----------
Options +ExecCGI
SetHandler cgi-script
-----------

Your python script will look like this

basics/pythonscript 
-------
#!/usr/bin/python

print "STATUS: 200 OK\n\n" 


print "hello world"
------

Warning... You may get an error in your error_log file that looks like this.

[Thu Aug 05 19:26:34 2010] [alert] [client 127.0.0.1] /home/websites/testing/htdocs/basics/.htaccess: Option ExecCGI not allowed here

If that happens your webserver is not allowing the changes from your .htaccess file

Your webserver will need to be able to allow changes in your htaccess file so you may need to enable Allowoverride All in your httpd.conf file

<Directory "/">

.... 

Allowoverride All

</Directory>
George Lambert
@George Lambert: I'm running on OS X and tried your idea anyway. Still does not work (I get a 404 trying to access url.dev/basics/pythonscript). The server error log says *[Fri Aug 06 08:44:45 2010] [error] [client 127.0.0.1] Negotiation: discovered file(s) matching request: /Users/simon/Sites/url.dev/basics/p (None could be negotiated).* I did restart the server after changing .htaccess to include only the lines you wrote above. Thank you for trying, I appreciate it.
sgriffee
Why does it say "/Users/simon/Sites/url.dev/basics/p"That is not your script name... what happens when you copy the script to "p" in that directory.. can you shell exec the file in that directory with your terminalcd /Users/simon/Sites/url.dev/basics./pythonscript and then after you rename try ./p see if they both work... Once we confirm they work - we can finish your webserver configbut it is best to make sure your scripts work first..
George Lambert
@George,I was getting tired of typing 'pythonscript' and renamed it to 'p'. I apologize for not mentioning this.
sgriffee
A: 

I found the solution: I needed to add the application MIME type so that the Apache Web Server understands it should run the code.

In url.dev/basics/.htaccess add:

<IfModule mime_module>
AddType application/x-httpd-py .py
</IfModule>

Don't forget to restart Apache: sudo apachectl graceful

And it works! http://url.dev/basics/pythonscript runs the code in pythonscript.py! Note that I'm not sure if this is the best way to do it, but it works.

Here is my complete .htaccess file:

# Options +ExecCGI
# SetHandler cgi-script

<IfModule mime_module>
AddType application/x-httpd-py .py
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /basics/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.py -f
RewriteRule ^(.*)$ $1.py
</IfModule>
sgriffee