Как я копирую функцию Python в удаленную машину и затем выполняю ее?

Я пытаюсь создать конструкцию в Python 3, который позволит мне легко выполнять функцию на удаленной машине. Принятие я уже получил Python tcp сервер, который выполнит функции, которые это получает, работая на удаленном сервере, я в настоящее время смотрю на использование декоратора как

@execute_on(address, port)

Это создало бы необходимый контекст, требуемый выполнить функцию, которую он украшает, и затем отправьте функцию и контекст к tcp серверу на удаленной машине, которая затем выполняет его. Во-первых, действительно ли это несколько нормально? И если не Вы могли бы рекомендовать лучший подход? Я сделал некоторый поиск с помощью Google, но не нашел ничего, что удовлетворяет эти потребности.

У меня есть быстрая и грязная реализация для tcp сервера и клиента, настолько абсолютно уверенного, что это будет работать. Я могу получить строковое представление функция (например, func) передаваемый декоратору

import inspect
string = inspect.getsource(func)

который может затем быть отправлен на сервер, где он может быть выполнен. Проблема, как я получаю всю контекстную информацию, которой функция требует для выполнения? Например, если func определяется следующим образом,

import MyModule
def func():
    result = MyModule.my_func()

MyModule должен будет быть доступен func или в глобальном контексте или в funcs локальном контексте на удаленном сервере. В этом случае это относительно тривиально, но это может стать настолько более сложным в зависимости от того, когда и как используются операторы импорта. Существует ли легкий и изящный способ сделать это в Python? Лучшее, которое я придумал в данный момент, пользуется ast библиотекой для вытаскивания всех операторов импорта, с помощью осмотреть модуля для получения строковых представлений тех модулей и затем восстанавливая весь контекст на удаленном сервере. Не особенно изящный и я вижу много места для ошибки.

Спасибо за внимание

7
задан Hugh 3 June 2010 в 00:16
поделиться

5 ответов

Подход, который вы описываете, чрезвычайно рискован, если удаленный сервер каким-то образом не очень сильно защищен или "чрезвычайно изолированная" (например, "тюрьма" BSD) - любой, кто может отправлять ей функции, сможет запускать там произвольный код.

Предполагая, что у вас есть система аутентификации, которой вы полностью доверяете, возникает проблема "хрупкости", которую вы осознали - функция может зависеть от любых глобальных переменных, определенных в ее модуле в момент выполнения (которые могут отличаться от тех, которые вы можете обнаружение путем проверки: определение набора импортированных модулей и глобальных объектов во время выполнения является полной по Тьюрингу проблемой).

Вы можете решить проблему глобальных переменных, сериализуя глобальные переменные функции, а также саму функцию, в то время, когда вы отправляете ее на удаленное выполнение (независимо от того, сериализуете ли вы все это в виде читаемой строки или иным образом, это второстепенная проблема). Но это по-прежнему оставляет вас с проблемой импорта, выполняемого внутри функции.

Если вы не хотите наложить некоторые ограничения на «удаленную» функцию, такие как «отсутствие импорта внутри функции (и функций, вызываемых из нее)», я думаю, вы могли бы иметь переопределение сервера __ import __ (встроенная функция, которая используется всеми операторами импорта и предназначена для переопределения для особых нужд, таких как ваши ;-), чтобы запросить дополнительный модуль у отправляющего клиента (из Конечно, для этого необходимо, чтобы упомянутый клиент обладал «подобными серверу» возможностями в том смысле, что он должен иметь возможность отвечать на такие «модульные запросы» с сервера).

Не могли бы вы наложить некоторые ограничения на удаленные функции, чтобы вернуть эту задачу в сферу здравомыслия ...?

2
ответ дан 7 December 2019 в 12:15
поделиться

Какова ваша конечная цель? Из вашего описания я не вижу причин, по которым вы не можете просто создать простой класс обмена сообщениями и отправить его экземпляры, чтобы дать команду удаленному компьютеру делать что-то…?

Что бы вы ни делали, ваша удаленная машина будет нужен исходный код Python для выполнения, так почему бы не распространить код здесь, а затем запустить его? Вы могли бы создать простой сервер, который будет принимать некоторые исходные файлы Python, извлекать их, импортировать соответствующие модули, а затем запускать команду?

0
ответ дан 7 December 2019 в 12:15
поделиться

Вас может заинтересовать проект execnet .

execnet предоставляет тщательно протестированные средства для простого взаимодействия с интерпретаторами Python независимо от версии, платформы и сетевых барьеров. Он имеет минимальный и быстрый API, предназначенный для следующих целей:

  • распределение задач между локальными или удаленными процессорами
  • запись и развертывание гибридных многопроцессорных приложений
  • запись скриптов для администрирования множества сред выполнения

http: //codespeak.net/execnet/example/test_info.html#get-information-from-remote-ssh-account

Я видел его демонстрацию. Но сам никогда не пользовался.

2
ответ дан 7 December 2019 в 12:15
поделиться

Из вашего вопроса не ясно, есть ли какое-то системное ограничение/требование для решения вашей проблемы таким образом. Если нет, то могут быть гораздо более простые и быстрые способы сделать это, используя какую-то инфраструктуру обмена сообщениями.

Например, вы можете рассмотреть возможность использования [Celery][1]

[1]: http://ask.github.com/celery/getting-started/introduction.html удовлетворит ваши потребности.

1
ответ дан 7 December 2019 в 12:15
поделиться

Это, вероятно, будет сложно сделать, и вы столкнетесь с проблемами безопасности, аргументами и т. Д. Может быть, вы можете просто удаленно запустить интерпретатор Python, которому можно передать код с помощью сокета или службы HTTP, вместо того, чтобы делать это для функции на уровне функции?

0
ответ дан 7 December 2019 в 12:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: