@Evgeny_A

Какой лучший способ передачи данных между PHP и Python скриптами?

Приветствую.

Есть у меня такое:

  1. Python скрипт, который занимает много места в оперативке и которому нужно ~10 секунд, чтобы загрузится
  2. PHP скрипт, который принимает POST запрос, но не может выполнить работу Python скрипта

Как это должно работать:

  1. Python скрипт должен висеть запущенным и ждать данные от PHP скрипта (строку JSON)
  2. PHP скрипт принимает файл, присланный формой на сайте с помощью POST запроса
  3. PHP скрипт проверяет, чтобы файл соответствовал всем требованиям и если ок, то передает JSON в Python
  4. Python скрипт делает работу над файлом и возвращает результат (строка JSON)

Вопрос: какой самый надежный и простой способ организовать их общение в Linux?

Решения, которые я пробовал, но которые мне не симпатичны:

  1. PHP скрипт отправляет данные в Python скрипт с помощью exec("python3.7 script.py $string 2>&1", $output)$? но в этом случае Python скрипт каждый раз грузится с нуля, что очень долго. Это точно не подходит.
  2. Смог создать сервер из script.py, который ждет GET запрос на порту IP:9090 и все работает приемлемо, но мне кажется это замусоренным решением и хочется верить, что можно как-то подружить скрипты на уровне процессов linux (и это быстрее, отказоустойчивее, проще в реализации)

Может кто поделится опытом и видением?
  • Вопрос задан
  • 375 просмотров
Решения вопроса 2
xmoonlight
@xmoonlight Куратор тега PHP
https://sitecoder.blogspot.com
Cокеты unix. (не TCP-порты!)
Ответ написан
@Evgeny_A Автор вопроса
Решение, найденное с подсказки xmoonlight

Значит в PHP файл пихаем это:

$sock = stream_socket_client('unix:///tmp/echo.sock', $errno, $errst); 
fwrite($sock, $type); 
$response = fread($sock, 1024); 
fclose($sock);

А в Python файл пихаем это:

# Адрес файла, который будет мостиком для общения между PHP и Python
SERVER_PATH = '/tmp/echo.sock'

# Если файл уже есть, его надо удалять
if os.path.exists(SERVER_PATH):

    os.remove(SERVER_PATH)

# Создаем новый UNIX сервер
server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server_socket.bind(SERVER_PATH)
server_socket.listen()

while True:

    client, adress = server_socket.accept()
    message = client.recv(1024)
    # Печатаем входящее сообщение
    print('received:', message.decode("utf-8"))
    # Отправляем ответ 
    client.send('This is my Response!'.encode())

client.close()
server_socket.close()
print('UNIX сервер закрыт!')

Запускаем Python файл из под того же пользователя, что и PHP файл и вуаля, все работает.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
firedragon
@firedragon
Senior .NET developer
Вы изобрели микросервис :)
А так решение хорошее. Возможно только стоит завернуть его в сервис.
И добавить менеджер очереди.

1. запрос старт длительной задачи, отдаете taskid
2. запрос с taskid, выдает ее статус и путь к результату (опрашиваете с нужной периодичностью)

https://habr.com/ru/company/southbridge/blog/255845/
Если уж так беспокоит безопасность то прибиндите его на 127.0.0.1

Смог создать сервер из script.py, который ждет GET запрос на порту IP:9090 и все работает приемлемо, но мне кажется это замусоренным решением и хочется верить, что можно как-то подружить скрипты на уровне процессов linux (и это быстрее, отказоустойчивее, проще в реализации)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы