Подключение к удаленному экземпляру IPython

Я хотел бы запустить экземпляр IPython на одном компьютере и подключиться к нему (по локальной сети) из другого процесса (для запуска некоторых команд Python). Я понимаю, что это возможно с zmq: http://ipython.org/ipython-doc/dev/development/ipythonzmq.html .

Однако я не могу найти документацию о том, как это сделать и возможно ли это вообще.

Любая помощь будет оценена по достоинству!


РЕДАКТИРОВАТЬ

Я хотел бы иметь возможность подключаться к экземпляру ядра IPython и отправлять ему команды python. Однако это не следует делать с помощью графического инструмента (qtconsole), но я хочу иметь возможность подключаться к этому экземпляру ядра из другого скрипта Python...

e.g.

внешний.py

somehow_connect_to_ipython_kernel_instance
instance.run_command("a=6")

person Ohad    schedule 02.04.2012    source источник
comment
Связано: stackoverflow.com/questions/18146558/   -  person    schedule 01.04.2015


Ответы (5)


Если вы хотите запустить код в ядре из другой программы Python, проще всего подключить Менеджер ядра блокировки. Лучшим примером этого на данный момент является клиент vim-ipython Пола Иванова или собственный терминальный клиент.

Суть:

  • Ядра ipython записывают файлы подключения JSON в IPYTHONDIR/profile_<name>/security/kernel-<id>.json, которые содержат информацию, необходимую различным клиентам для подключения и выполнения кода.
  • KernelManagers — это объекты, которые используются для связи с ядрами (выполнение кода, получение результатов и т. д.). *

Рабочий пример:

В оболочке выполните ipython kernel (или ipython qtconsole, если вы хотите поделиться ядром с уже работающим графическим интерфейсом):

$> ipython kernel
[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing kernel-6759.json

Это написало файл «kernel-6759.json».

Затем вы можете запустить этот фрагмент Python, чтобы подключить KernelManager и запустить некоторый код:

from IPython.lib.kernel import find_connection_file
from IPython.zmq.blockingkernelmanager import BlockingKernelManager

# this is a helper method for turning a fraction of a connection-file name
# into a full path.  If you already know the full path, you can just use that
cf = find_connection_file('6759')

km = BlockingKernelManager(connection_file=cf)
# load connection info and init communication
km.load_connection_file()
km.start_channels()

def run_cell(km, code):
    # now we can run code.  This is done on the shell channel
    shell = km.shell_channel
    print
    print "running:"
    print code

    # execution is immediate and async, returning a UUID
    msg_id = shell.execute(code)
    # get_msg can block for a reply
    reply = shell.get_msg()

    status = reply['content']['status']
    if status == 'ok':
        print 'succeeded!'
    elif status == 'error':
        print 'failed!'
        for line in reply['content']['traceback']:
            print line

run_cell(km, 'a=5')
run_cell(km, 'b=0')
run_cell(km, 'c=a/b')

Результат прогона:

running:
a=5
succeeded!

running:
b=0
succeeded!

running:
c=a/b
failed!
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
/Users/minrk/<ipython-input-11-fb3f79bd285b> in <module>()
----> 1 c=a/b

ZeroDivisionError: integer division or modulo by zero

см. спецификацию сообщения для получения дополнительной информации о том, как интерпретировать ответ. При необходимости данные stdout/err и display будут поступать через km.iopub_channel, и вы можете использовать msg_id, возвращаемый shell.execute(), чтобы связать вывод с данным выполнением.

PS: приношу свои извинения за качество документации этих новых функций. Нам нужно много писать.

person minrk    schedule 02.04.2012
comment
Большое спасибо за отличный ответ! Именно то, что я искал. Можно ли получить вывод команды, запущенной в ядре? например: a=2.. напечатать a, а затем получить 2? - person Ohad; 03.04.2012
comment
И можно ли вызвать IPython.frontend.terminal.embed.InteractiveShellEmbed(), чтобы открыть его как ядро? - person Ohad; 03.04.2012
comment
вывод поступает через iopub_channel. Как я уже упоминал выше, спецификация сообщений детализирует эти сообщения, а консоль vim-ipython и ipython демонстрирует, как справляться с этими сообщениями. Что касается встраивания, я думаю, вы просите это дополнение, которое следует объединить вскоре. - person minrk; 04.04.2012
comment
Это отлично сработало для меня с IPython 2.2.0, мне просто нужно было заменить BlockingKernelManager на IPython.kernel.blocking.client.BlockingKernelClient, и тот же вызов метода работает. Спасибо! - person talumbau; 30.09.2014

Если вы просто хотите подключиться интерактивно, вы можете использовать переадресацию SSH. Я еще не нашел этого нигде в Stack Overflow, но этот вопрос ближе всего. Этот ответ был протестирован на Ipython 0.13. Я получил информацию из этот пост в блоге.

  1. Запустите ipython kernel на удаленной машине:

    user@remote:~$ ipython3 kernel
    [IPKernelApp] To connect another client to this kernel, use:
    [IPKernelApp] --existing kernel-25333.json
    
  2. Посмотрите на файл kernel-25333.json:

    user@remote:~$ cat ~/.ipython/profile_default/security/kernel-25333.json 
    {
      "stdin_port": 54985, 
      "ip": "127.0.0.1", 
      "hb_port": 50266, 
      "key": "da9c7ae2-02aa-47d4-8e67-e6153eb15366", 
      "shell_port": 50378, 
      "iopub_port": 49981
    }
    
  3. Настройте переадресацию портов на локальной машине:

    user@local:~$ ssh user@remote -f -N -L 54985:127.0.0.1:54985
    user@local:~$ ssh user@remote -f -N -L 50266:127.0.0.1:50266
    user@local:~$ ssh user@remote -f -N -L 50378:127.0.0.1:50378
    user@local:~$ ssh user@remote -f -N -L 49981:127.0.0.1:49981
    
  4. Скопируйте файл kernel-25333.json на локальный компьютер:

    user@local:~$ rsync -av user@remote:.ipython/profile_default/security/kernel-25333.json ~/.ipython/profile_default/security/kernel-25333.json
    
  5. Запустите ipython на локальной машине, используя новое ядро:

    user@local:~$ ipython3 console --existing kernel-25333.json
    Python 3.2.3 (default, Oct 19 2012, 19:53:16)
    Type "copyright", "credits" or "license" for more information.
    
    IPython 0.13.1.rc2 -- An enhanced Interactive Python.
    ?         -> Introduction and overview of IPython's features.
    %quickref -> Quick reference.
    help      -> Python's own help system.
    object?   -> Details about 'object', use 'object??' for extra details.
    
    
    In [1]: import socket; print(socket.gethostname())
    remote
    
person gerrit    schedule 07.03.2013
comment
Если кто-то не знает, где находится файл json (как и я): его можно найти, запустив jupyter --runtime-dir - person holastello; 14.05.2018

Обновите ответ minrk после разделения на jupyter. С jupyter_client (4.1.1) самый простой код выглядит примерно так:

import jupyter_client

cf=jupyter_client.find_connection_file('6759')
km=jupyter_client.BlockingKernelClient(connection_file=cf)
km.load_connection_file()

km.execute('a=5')

Обратите внимание, что:

  • jupyter_client.BlockingKernelClient также имеет псевдоним jupyter_client.client.BlockingKernelClient.
  • оболочка (km.shell_channel) больше не имеет методов execute() и get_msg().

В настоящее время довольно сложно найти обновленную документацию; пока ничего на http://jupyter-client.readthedocs.org/en/latest/ для BlockingKernelClient. Некоторый код в https://github.com/jupyter/jupyter_kernel_test. Любая ссылка приветствуется.

person S. Bougnoux    schedule 04.03.2016
comment
Очень хороший ответ! - person Sung Kim; 14.09.2019
comment
Чувак, это потрясающе! Это одновременно очень просто и эффективно. Мне это нравится! - person milembar; 28.08.2020

Приведенные выше ответы немного устарели. Решение для последней версии ipython намного проще, но не документировано в одном месте. Поэтому я подумал, что задокументирую это здесь.

Решение для подключения из любой ОС к ядру ipython, работающему на Windows

Если клиент или сервер — это linux или другая операционная система, просто измените расположение kernel-1234.json соответствующим образом на основе Где находится kernel-1234.json в Jupyter под Windows?

  1. При запуске ядра на базе Windows убедитесь, что ipykernel установлено с помощью pip install ipykernel
  2. Запустите ipykernel с помощью ipython kernel -f kernel-1234.json
  3. Найдите файл kernel-1234.json на своем компьютере Windows. Файл, вероятно, будет иметь другой номер, а не 1234, и, скорее всего, будет расположен в папке «C:\Users\me\AppData\Roaming\jupyter\runtime\kernel-1234.json»: https://stackoverflow.com/a/48332006/4752883
  4. Установите Jupyter Console (или Jupyter Qtconsole/ноутбук), используя pip install jupyter-console или pip install qtconsole https://jupyter-console.readthedocs.io/en/latest/
  5. Если вы используете Windows, выполните ipconfig, чтобы узнать IP-адрес вашего сервера Windows. (В Linux введите ifconfig в командной строке). В файле kernel-1234.json измените IP-адрес с 127.0.0.1 на IP-адрес вашего сервера. Если вы подключаетесь с другого сервера Windows, скопируйте файл kernel-1234.json на локальный компьютер и запишите путь.
  6. Перейдите в папку, содержащую kernel-1234.json, и запустите Jupyter Console с помощью jupyter console --existing kernel-1234.json.
person alpha_989    schedule 18.01.2018
comment
В моей установке Windows у меня нет ipykernel, вместо этого у меня есть jupyter-kernel. При запуске отображается: Connection file: <path>\kernel-<guid>.json. В этом файле указано "ip": "127.0.0.1", поэтому я не понимаю, как использование этого файла на клиентской машине может быть использовано на другой машине, пытающейся использовать это ядро? Когда я меняю 127.0.0.1 на IP-адрес машины, на которой работает jupyter-kernel (например, 10.0.0.122), консоль Jupyter повторяет kernel died каждые 3 секунды. - person David Ching; 28.02.2018
comment
да. ты прав. Когда я писал это, я запускал клиент и сервер на одной машине. Фактически, когда вы запускаете блокнот Jupyter, клиент и сервер работают на одном компьютере, поэтому 127.0.0.1 работает нормально. Если вам нужно запустить клиент и сервер на разных машинах, вам необходимо 1. убедиться, что ip сервера виден с клиента. 2. в kernel-1234.json обязательно измените IP-адрес на тот, на который настроен ваш клиент. - person alpha_989; 28.02.2018
comment
Не уверен на 100%, но ip, который вы упомянули 10.0.0.122, не похож на ip, который будет виден клиенту. Вы пытались пропинговать свой сервер с помощью ping 10.0.0.122, чтобы проверить, виден ли сервер с клиента? а брандмауэра нет или что-то блокирует соединение? - person alpha_989; 28.02.2018
comment
Что вы установили на своем сервере и на своем клиенте? - person alpha_989; 28.02.2018
comment
Да, пинг работает. Обе машины находятся в одной локальной сети (10.0.x.x и 192.168.x.x являются общими локальными адресами локальной сети). Исходный вопрос специально задавался о доступе к IPython на машине в локальной сети. - person David Ching; 28.02.2018
comment
Прямо сейчас я запускаю сервер и клиент в формате Bridge Networking, поэтому это работает на подключениях по локальной сети. Вы также заметите там несколько портов, упомянутых в файле json. Эти порты должны быть видны/открыты. Используете ли вы какие-либо брандмауэры на вашем клиенте и сервере? - person alpha_989; 01.03.2018
comment
Также у меня была опечатка в приведенном выше решении, если вы запускаете ipython kernel, вам нужно запустить его с тем же файлом kernel-1234.json. Файл kernel-1234.json должен иметь тот же IP-адрес. - person alpha_989; 01.03.2018
comment
Можете ли вы попробовать выполнить инструкции, используя ipykernel, используя файл с IP-адресом сервера и убедившись, что брандмауэр не запущен? Когда я делаю pip list на своем сервере, я не вижу jupyter-kernel. Также я не вижу его здесь в качестве ядра: github.com/jupyter/jupyter /wiki/Jupyter-kernels. Когда я пытаюсь pip install jupyter-kernel, он ничего не устанавливает. Так что я не уверен, что вы бежите .. - person alpha_989; 01.03.2018
comment
Спасибо, на сервере запуск ipython kernel --ip 10.0.1.122 (чтобы явно указать его IP-адрес) приводит к тому, что файл .json, который он создает, содержит этот IP-адрес, а не 127.0.0.1), кроме того, он заставляет брандмауэр Windows предлагать открыть необходимые порты. Затем на клиентской машине работает запуск клиента с использованием того же файла .json. Похоже, дистрибутивы Python только начинают переименовывать клиентские части IPython в Jupyter; у моего дистрибутива Anaconda были оба. Когда я запустил ipython qtconsole на клиенте, он предупредил, что я должен начать использовать jupyter qtconsole. Большое спасибо! - person David Ching; 01.03.2018

Если вы используете Anaconda, в OS X файл JSON хранится по адресу

/Пользователи/[имя пользователя]/Библиотека/Jupyter/среда выполнения/

В Windows:

c:\Users[имя пользователя]\AppData\Roaming\jupyter\runtime\

person 32768    schedule 11.01.2016
comment
... и c:\Users[имя пользователя]\AppData\Roaming\jupyter\runtime\ в Windows - person 32768; 11.01.2016
comment
Это отвечает на вопрос? OP хочет запустить экземпляр IPython на одном компьютере и подключиться к нему (по локальной сети) из другого процесса. - person Wai Ha Lee; 11.01.2016
comment
@WaiHaLee, я думаю, что это действительно важная часть решения вопроса. Начинающего может сбить с толку расположение файла kernel-1234.json. Полное решение с последней версией ipython/ipykernel: stackoverflow.com/a/48332182/4752883 - person alpha_989; 02.03.2018