How do I properly call a Python Pyro client using PHP and Apache web server?

938 views Asked by At

I have a Python3 Pyro4 server client app that works great when run from command line.

server.py

import Pyro4

@Pyro4.expose
class JokeGen(object):
    def __init__(self):
        self.jokevar = "Joke"

    def joke(self, name):
        return "Sorry "+name+", I don't know any jokes."

def main():
    Pyro4.Daemon.serveSimple(
            {
                JokeGen: "example.jokegen"
            },
            ns = True)

if __name__=="__main__":
    main()

client.py

#!/usr/bin/env python3
import Pyro4
import sys

person_to_joke = sys.argv[1]

joke_control = Pyro4.Proxy("PYRONAME:example.jokegen")

print (joke_control.joke(person_to_joke))

The problem is I need to run the client from a web app using PHP.
I have created a joke.php

<?php
$command = escapeshellcmd('/full/path/to/client.py SquirrelMaster');
$output = shell_exec($command);
echo $output;
?>

While this code does actually work I did some non-standard hacking to make it work. I took a copy of my /home/user/.local (where the pyro4 modules have been installed for user) and placed it in /var/www/ and gave ownership to www-data.

sudo chown -R www-data.www-data /var/www/.local

It seems like there must be a better way to do this and I'm pretty sure there will be potentially issues in the future if I leave things this way. The issues seems to be that the Pyro4 modules need to be available for the www-data user. So my question is, What is the proper way to make Pyro4 modules available to the www-data user on Ubuntu linux running apache2?

EDIT - ADDITION

I also tried doing the following:

sudo mkdir /var/www/.local
sudo mkdir /var/www/.cache
sudo chown www-data.www-data /var/www/.local
sudo chown www-data.www-data /var/www/.cache

Then run the command:

sudo -H -u www-data pip3 install pyro4 --user www-data

But this results the error "Could not find a version that satisfies the requirement www-data (from versions: ) No matching distribution found for www-data"

1

There are 1 answers

8
Irmen de Jong On BEST ANSWER

Looks a bit like this question https://superuser.com/questions/646062/granting-write-permissions-to-www-data-group

I wanted to suggest using the PYTHONPATH environment variable to point to a library install location readable by the www-data user where you'd copy the python modules it needs to acces, but I think this is considered bad form nowadays.

Probably best is to create a Python Virtualenv that is accessible for the www-data user and install all required modules into that, using the pip command from that virtualenv. You may have to use some sudo/chown dance to get this right still.

Another way perhaps is to not bother with calling a python subprocess at all, but use Pyro's HTTP gateway. That way you can simply do a HTTP request from PHP to a locally running Pyro http gateway process, which will translate it into a proper Pyro call. I don't know PHP but it seems to me that it should be easy to make a custom http request to a server running on some localhost port. This may be faster as well because you're not starting up python processes for every call.

(edit): another succesfully working solution seemed to be the following, where sudo is used to invoke pip under the appropriate user, letting it install the library into www-data's .local library folder:

  • create /var/www/.local and /var/www/.cache folders, giving www-data permissons to these folders only (and not /var/www to avoid security issues)
  • invoke sudo -H -u www-data pip3 install pyro4 You may still need to add --user to the pip command if it's an older version, because I think that only recent pip versions install to the user's lib folder by default instead of to the global system python's lib folder.