0

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"

infinigrove
  • 489
  • 1
  • 7
  • 16
  • Your question in the last paragraph doesn't match the title. What is it exactly that you're asking? – Irmen de Jong Jan 16 '17 at 20:28
  • I need to run a python script that use the pyro4 module from PHP. The PHP script is run by the Apache web server user www-data. The problem that I have seems to be making the python pyro4 modules available for the www-data user. The title was the short version of the question and the last paragraph is the longer more detailed version of the question. I updated the title to better match the last paragraph. Hopefully that helps and thank you for looking. – infinigrove Jan 16 '17 at 20:58
  • as to the update with the pip command: read the command syntax more carefully. The --user option doesn't take any arguments. – Irmen de Jong Jan 18 '17 at 23:13
  • Yes, you are correct, thanks. I did figure out another way to install the pyro4 modules for the www-data user but it also involves some potentially dangerous hackery. However, it is a more acceptable solution to me for what I'm trying to do. I plan to post that answer shortly. – infinigrove Jan 18 '17 at 23:30
  • I hope you considered the warning explained in the article I linked below in the answer, http://superuser.com/questions/646062/granting-write-permissions-to-www-data-group which argued that you should not give apache (www-data user) full r/w access to /var/www – Irmen de Jong Jan 18 '17 at 23:58
  • 1
    YES!! `sudo -H -u www-data pip3 install pyro4` does the job. That extra `--user www-data` was causing the problem. I am NOT changing the permissions for /var/www. I'm creating /var/www/.local and /var/www/.cache and giving www-data permissions for those folders ONLY. If you would like to update your answer with this solution then I will give you credit for coming up with an acceptable answer. You have been very helpful! Thank You!!!! :) – infinigrove Jan 19 '17 at 00:04

1 Answers1

1

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.
Community
  • 1
  • 1
Irmen de Jong
  • 2,739
  • 1
  • 14
  • 26
  • I did try running the 'pip install' command as user www-data and setting the home directory as /var/www but it failed. I don't recall the error now. I was thinking about trying it again and updating my question but haven't had a chance to try it yet. I took a brief look at the info and links that you posted and this may work for me. I will give this a try tomorrow and let you know. Thanks! – infinigrove Jan 18 '17 at 03:13
  • I just updated my question with the `pip install` command that I though should work but didn't. I'm trying to avoid Virtualenv if possible but may go that route. Also, I did look at the Pyro HTTP gateway but it seems to be poorly documented and over kill for what I'm trying to accomplish. I'm already running Apache on my server and prefer not to run another HTTP server. – infinigrove Jan 18 '17 at 18:09
  • The pyro http gateway is running via an embedded http server, and is only running locally. But I can understand your reasons to avoid having to run too many different things. – Irmen de Jong Jan 18 '17 at 23:11
  • The JokeGen is an old example from older version of Python and Pyro that I modified to work with the newer version. If there was a very simple minimal example for the pyro http gateway using JokeGen or similar then I would probably go that route. I'm a LAMP guy and not much of a Python coder. What I'm really trying to do is build a web front end for https://github.com/infinigrove/TerminalRoastDB – infinigrove Jan 18 '17 at 23:24
  • There's a http example in the Pyro4 source distribution you can look at next to the (agreed, rather sparse) documentation. https://github.com/irmen/Pyro4/tree/master/examples/http – Irmen de Jong Jan 18 '17 at 23:55
  • Yes, I tried running that example but couldn't even figure out how to get it to run. Tried looking at the source but it looked like more trouble than it's worth for what I'm trying to do. – infinigrove Jan 19 '17 at 00:07
  • 1
    I'm sorry about that, I'll try to improve things a bit for a future Pyro release. – Irmen de Jong Jan 19 '17 at 00:14
  • That would be awesome, Thanks! – infinigrove Jan 19 '17 at 00:21