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

1

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"

Andraandrade answered 7/1, 2017 at 1:20 Comment(6)
Your question in the last paragraph doesn't match the title. What is it exactly that you're asking?Acanthus
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.Andraandrade
as to the update with the pip command: read the command syntax more carefully. The --user option doesn't take any arguments.Acanthus
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.Andraandrade
I hope you considered the warning explained in the article I linked below in the answer, superuser.com/questions/646062/… which argued that you should not give apache (www-data user) full r/w access to /var/wwwAcanthus
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!!!! :)Andraandrade
A
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.
Acanthus answered 18/1, 2017 at 1:7 Comment(8)
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!Andraandrade
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.Andraandrade
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.Acanthus
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 github.com/infinigrove/TerminalRoastDBAndraandrade
There's a http example in the Pyro4 source distribution you can look at next to the (agreed, rather sparse) documentation. github.com/irmen/Pyro4/tree/master/examples/httpAcanthus
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.Andraandrade
I'm sorry about that, I'll try to improve things a bit for a future Pyro release.Acanthus
That would be awesome, Thanks!Andraandrade

© 2022 - 2024 — McMap. All rights reserved.