У меня есть клиентское приложение Python3 Pyro4 Server, которое отлично работает при запуске из командной строки.
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))
Проблема в том, что мне нужно запустить клиент из веб-приложения, используя PHP.
Я создал joke.php
<?php
$command = escapeshellcmd('/full/path/to/client.py SquirrelMaster');
$output = shell_exec($command);
echo $output;
?>
Хотя этот код действительно работает, я сделал несколько нестандартных взломов, чтобы заставить его работать. Я взял копию моего /home/user/.local (где модули pyro4 были установлены для пользователя) и помещены в / Var / WWW / и передал право собственности на www-data.
sudo chown -R www-data.www-data /var/www/.local
Кажется, что должен быть лучший способ сделать это, и я почти уверен, что в будущем могут возникнуть проблемы, если я оставлю это так. Проблемы заключаются в том, что модули Pyro4 должны быть доступны для пользователя www-data. Итак, мой вопрос: как правильно сделать модули Pyro4 доступными для пользователя www-data в Ubuntu linux под управлением apache2?
РЕДАКТИРОВАТЬ — ДОПОЛНЕНИЕ
Я также попытался сделать следующее:
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
Затем выполните команду:
sudo -H -u www-data pip3 install pyro4 --user www-data
Но это приводит к ошибке «Не удалось найти версию, которая удовлетворяет требованию www-data (из версии:)
Не найдено подходящего распределения для www-data «
Выглядит немного как этот вопрос https://superuser.com/questions/646062/granting-write-permissions-to-www-data-group
Я хотел предложить использовать переменную окружения PYTHONPATH, чтобы указать место установки библиотеки, читаемое пользователем www-data, куда вы скопируете модули python, к которым он должен получить доступ, но я думаю, что в настоящее время это считается плохим тоном.
Наверное, лучше всего создать Python Virtualenv это доступно для пользователя www-data и установить все необходимые модули в него, используя команду pip из этого virtualenv. Возможно, вам придется использовать танец sudo / chown, чтобы все сделать правильно.
Другой способ, возможно, состоит в том, чтобы вообще не беспокоиться о вызове подпроцесса python, а использовать HTTP-шлюз Pyro. Таким образом, вы можете просто выполнить HTTP-запрос от PHP к локально запущенному процессу шлюза Pyro http, который преобразует его в правильный вызов Pyro. Я не знаю PHP, но мне кажется, что было бы легко сделать пользовательский http-запрос к серверу, работающему на каком-то локальном порте. Это также может быть быстрее, потому что вы не запускаете процессы Python для каждого вызова.
(редактировать)другим успешным рабочим решением, похоже, было следующее, где sudo используется для вызова pip под соответствующим пользователем, позволяя ему установить библиотеку в www-data
Папка библиотеки .local:
/var/www/.local
а также /var/www/.cache
папки, дачи www-data
разрешает только эти папки (а не /var/www
чтобы избежать проблем с безопасностью)sudo -H -u www-data pip3 install pyro4
--user
к команде pip, если это более старая версия, потому что я думаю, что только последние версии pip по умолчанию устанавливаются в папку lib пользователя, а не в папку lib глобального системного python. Других решений пока нет …