skip to Main Content

(Important) Disclaimer: I know it’s probably not a good idea, that Python is not like PHP, and that the “natural” way to do web with Python is more by using a framework like Bottle, Flask, Django (that I already use), etc. But still, just out of curiosity, I’d like to see how the following is possible.


When Apache + PHP are installed, we can access a page like http://www.example.com/index.php. Internally, Apache probably passes the request to PHP which executes code, produces a text output, which is then served by Apache.

Question: how could we do something similar in Python? i.e. by accessing http://www.example.com/index.py, Apache would call the script index.py:

print("<html><body>Hello world</body></html>")

and then Apache would serve this page to the client.


NB:

  • Calling http://www.example.com/index.py?foo=bar could even give the params to the Python script in sys.argv

  • I already did it like this: http://www.example.com/index.php:

    <?php 
    $out = shell_exec("python index.py"); 
    echo($out); 
    ?>
    

    which then calls the Python script and produces the output. It works, but I’d like to do it without PHP.

  • Said in another way, is there something like mod_php for Python?

3

Answers


  1. Chosen as BEST ANSWER

    I finally managed to do it thanks to the other answer:

    1. Do:

      apt-get install libapache2-mod-python
      
    2. Then create or open the .htaccess file in your website folder, and add

      AddHandler mod_python .py
      PythonHandler mod_python.publisher
      
    3. Then create a file test.py:

      def index(req):
          return("<html><body>Hello world</body></html>")
      
    4. Now accessing www.example.com/test.py works!


    NB:

    • def index(req) is really required: using another name will make it fail.

    • I don't know why, but it's not possible to set AddHandler mod_python .py in a .htaccess, I only managed to do it globally for a <VirtualHost>. Does someone have an idea about how to do it directly in the .htaccess?

    • if mod_python is already installed but not enabled, you have to do:

      a2enmod python               
      service apache2 restart    
      

      but this is done automatically when installing libapache2-mod-python.

    • This is needed in the Apache VirtualHost's Directory: AllowOverride All, Require all granted, to allow handlers to be added directly in a .htaccess file. Without it, an alternative is to add the directives AddHandler ... directly in the VirtualHost definition.


  2. There exists a similar mod for python, but it’s not as widely used and does not seem to have been updated for a few years.

    Note: A common way of doing things is using apache/nginx as a web server, and uwsgi as an application server, with the web server redirecting to the application server for non-static content urls.

    Login or Signup to reply.
  3. There is one more module apache can able to server python apart from mod_python which is mod_wsgi you may have tried it already if not this can be done like below.

    First install if not already installed

    sudo apt-get install libapache2-mod-wsgi -y
    

    Create vhost

    <VirtualHost *:8081>
    
        #ServerName www.example.com
        #ServerAlias example.com
        ServerAdmin webmaster@localhost
    
        DocumentRoot /var/www/html/wsgi
    
        <Directory /var/www/html/wsgi>
        <IfVersion < 2.4>
            Order allow,deny
            Allow from all
        </IfVersion>
        <IfVersion >= 2.4>
            Require all granted
        </IfVersion>
        </Directory>
    
        WSGIScriptAlias /myapp /var/www/html/wsgi/index.py #path to file
    
        <Directory /var/www/html/wsgi>
        <IfVersion < 2.4>
            Order allow,deny
            Allow from all
        </IfVersion>
        <IfVersion >= 2.4>
            Require all granted
        </IfVersion>
        </Directory>
    
    </VirtualHost>
    

    Create index.py

    def application(environ, start_response):
        status = '200 OK'
        output = b'<h2>Hello World!</h2>'
    
        response_headers = [('Content-type', 'text/html'),
                            ('Content-Length', str(len(output)))]
        start_response(status, response_headers)
    
        return [output]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search