मुझे वर्तमान IPython / Jupyter नोटबुक नाम कैसे मिलेगा


85

मैं IPython नोटबुक चलाते समय वर्तमान नोटबुक नाम प्राप्त करने का प्रयास कर रहा हूं। मुझे पता है कि मैं इसे नोटबुक के शीर्ष पर देख सकता हूं। मैं जैसा हूं उसके बाद कुछ वैसा ही हूं

currentNotebook = IPython.foo.bar.notebookname()

मुझे एक चर में नाम प्राप्त करने की आवश्यकता है।


आप इसके साथ क्या करने की कोशिश कर रहे हैं? डिज़ाइन के अनुसार, कर्नेल (कोड को चलाने वाला बिट) फ्रंटएंड के बारे में नहीं जानता (बिट जो नोटबुक खोलता है)।
थॉमस के

7
नमस्ते, मैं इसे लेटेक्स / पीडीएफ निर्माण प्रक्रिया में नोटबुक को स्वचालित करने के लिए nbconvert के साथ उपयोग करना चाहता हूं। मेरी नोटबुक दूर से चलती हैं। कक्षा के छात्रों के बाद अपने परिणामों का एक पीडीएफ संस्करण डाउनलोड कर सकते हैं।
कबूतर

1
P.Toccaceli का जवाब जुपिटरलैब (1.1.4) (नोटबुक 5.6.0) के हाल के संस्करणों के साथ अच्छी तरह से काम करता है और इसे जावास्क्रिप्ट की आवश्यकता नहीं होती है।
joelostblom


कुछ ने काम किया और एक पाइप पैकेज बनाया: pypi.org/project/ipynbname द्वारा स्थापितpip install ipynbname
NeoTT

जवाबों:


24

जैसा कि पहले ही उल्लेख किया गया है कि आप वास्तव में ऐसा करने में सक्षम नहीं हैं, लेकिन मुझे कोई रास्ता नहीं मिला। यह एक ज्वलंत हैक है, लेकिन इस पर बिल्कुल भी भरोसा नहीं करते हैं:

import json
import os
import urllib2
import IPython
from IPython.lib import kernel
connection_file_path = kernel.get_connection_file()
connection_file = os.path.basename(connection_file_path)
kernel_id = connection_file.split('-', 1)[1].split('.')[0]

# Updated answer with semi-solutions for both IPython 2.x and IPython < 2.x
if IPython.version_info[0] < 2:
    ## Not sure if it's even possible to get the port for the
    ## notebook app; so just using the default...
    notebooks = json.load(urllib2.urlopen('http://127.0.0.1:8888/notebooks'))
    for nb in notebooks:
        if nb['kernel_id'] == kernel_id:
            print nb['name']
            break
else:
    sessions = json.load(urllib2.urlopen('http://127.0.0.1:8888/api/sessions'))
    for sess in sessions:
        if sess['kernel']['id'] == kernel_id:
            print sess['notebook']['name']
            break

मैंने कम से कम एक साधारण परीक्षण के साथ IPython 2.0 में "काम" करने वाले समाधान को शामिल करने के लिए अपने उत्तर को अपडेट किया। अगर एक ही कर्नेल से जुड़े कई नोटबुक हैं, तो यह सही उत्तर देने की गारंटी नहीं है।


कनेक्शन_फाइल_पैथ = कर्नेल.गेट_कनेक्शन_फाइल () अब काम नहीं करता है, फ़ाइल नाम आवश्यक है।
प्यूरेल

2
कुछ अपडेट: from IPython.lib import kernelअब के बजाय यह सिर्फ है from IPython import kernel। शब्दकोशों में कुंजी 'नाम' का उपयोग करने के बजाय, कुंजी 'पथ' का उपयोग करें
ट्रिस्टन रीड

1
जैसा कि स्वयं उत्तरदाता द्वारा विज्ञापित किया गया है, यह उत्तर नवीनतम IPython के लिए काम नहीं करता है। मैंने एक संस्करण बनाया है जो Python 3.5 में IPython 4.2.0 के साथ काम करने के लिए लगता है: gist.github.com/mbdevpl/f97205b73610dd30254652e7817f99cb
mbdevor

1
संस्करण के रूप में 4.3.0, आपको एक टोकन प्रदान करने की आवश्यकता है। इसका उपयोग करके पुनः प्राप्त किया जा सकता है notebook.notebookapp.list_running_servers()
विगत

1
यदि आपके पास कई सर्वर चल रहे हैं, तो आप जांच सकते हैं कि कर्नेल की मूल प्रक्रिया किस पोर्ट पर चल रही है, जो आपको बताएगी कि किस सर्वर से कनेक्ट होना है (या आप बस हर स्थानीय ज्यूपिटर सर्वर से कनेक्ट कर सकते हैं और चेक कर सकते हैं कि कौन सा कर्नेल चल रहा है)।
विगत

40

मेरे पास निम्नलिखित है जो IPython 2.0 के साथ काम करता है। मैंने देखा कि नोटबुक का नाम पेज 'data-notebook-name'के <body>टैग में विशेषता के मूल्य के रूप में संग्रहीत है । इस प्रकार यह विचार सबसे पहले है कि जावास्क्रिप्ट को विशेषता को पुनः प्राप्त करने के लिए कहा जाए - javascripts को मैजिक के लिए एक कोडेक्स धन्यवाद से लाया जा सकता %%javascriptहै। फिर पायथन कर्नेल को कॉल के माध्यम से जावास्क्रिप्ट चर तक पहुंचना संभव है, एक पायनियर चर सेट करता है। चूंकि यह अंतिम चर कर्नेल से जाना जाता है, इसलिए इसे अन्य कोशिकाओं में भी एक्सेस किया जा सकता है।

%%javascript
var kernel = IPython.notebook.kernel;
var body = document.body,  
    attribs = body.attributes;
var command = "theNotebook = " + "'"+attribs['data-notebook-name'].value+"'";
kernel.execute(command);

एक पायथन कोड सेल से

print(theNotebook)

बाहर []: HowToGetTheNameOfTheNoteBook.ipynb

इस समाधान में एक दोष यह है कि जब कोई नोटबुक का शीर्षक (नाम) बदलता है, तो यह नाम तुरंत अपडेट नहीं किया जाता है (शायद किसी प्रकार का कैश है) और एक्सेस प्राप्त करने के लिए नोटबुक को फिर से लोड करना आवश्यक है नया नाम।

[संपादित करें] प्रतिबिंब पर, <body>टैग के बजाय नोटबुक के नाम के लिए इनपुट फ़ील्ड देखने के लिए एक अधिक कुशल समाधान है । स्रोत को देखते हुए, यह प्रतीत होता है कि इस फ़ील्ड में आईडी "नोटबुक_नाम" है। तब इस मूल्य को ए द्वारा पकड़ना संभव है document.getElementById()और फिर ऊपर के समान दृष्टिकोण का पालन करें। कोड, अभी भी जावास्क्रिप्ट जादू का उपयोग कर बन जाता है

%%javascript
var kernel = IPython.notebook.kernel;
var thename = window.document.getElementById("notebook_name").innerHTML;
var command = "theNotebook = " + "'"+thename+"'";
kernel.execute(command);

फिर, एक ipython cell से,

In [11]: print(theNotebook)
Out [11]: HowToGetTheNameOfTheNoteBookSolBis

पहले समाधान के विपरीत, नोटबुक के नाम के संशोधनों को तुरंत अपडेट किया जाता है और नोटबुक को ताज़ा करने की आवश्यकता नहीं होती है।


शायद मुझे कुछ याद आया, लेकिन आप अजगर से जावास्क्रिप्ट कोड कैसे लेते हैं?
आर्टजोम बी

7
यह भी जावास्क्रिप्ट वस्तु के लिए लागू प्रदर्शन विधि का उपयोग करके अजगर के भीतर से जावास्क्रिप्ट को कॉल करना संभव है जैसेdef getname(): display(Javascript('IPython.notebook.kernel.execute("theNotebook = " + "\'"+IPython.notebook.notebook_name+"\'");'))
जैकब

नोटबुक का पथ प्राप्त करने के लिए मैं इसे कैसे संशोधित करूं?
पेड्रो एम डुटर्टे

@PedroMDuarte: आप उस मूल्य को प्राप्त करने के लिए उपरोक्त लिपि में 'तत्कालीन' के लिए जावास्क्रिप्ट में IPython.notebook.notebook_path का उपयोग कर सकते हैं।
ट्रिस्टन रीड

1
जेएस चालबाजी के बिना नोटबुक पथ प्राप्त करने के लिए:globals()['_dh'][0]
रोगाणु

38

पिछले उत्तरों में जोड़ना,

एक सेल में नोटबुक नाम चलाने के लिए:

%%javascript
IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')

यह आपको nb_name में फ़ाइल नाम देता है

फिर पूर्ण पथ प्राप्त करने के लिए आप एक अलग सेल में निम्नलिखित का उपयोग कर सकते हैं:

import os
nb_full_path = os.path.join(os.getcwd(), nb_name)

1
इसका उपयोग IPython.notebook.notebook_nameकरके किया जा सकता है%%javascript IPython.notebook.kernel.execute('notebookName = ' + '"' + IPython.notebook.notebook_name + '"')
jfb

9
किसी कारण से यह केवल तभी काम करता है जब मैं जावास्क्रिप्ट सेल "मैन्युअल रूप से" चलाता हूं। यदि मैं पूर्ण नोटबुक चलाता हूं तो दूसरी सेल विफल हो जाती है। कोई विचार क्यों?
पियरे-एंटोनी

मैं किसी कारण से अनुमान लगाता हूं, अगर एक चर को जावास्क्रिप्ट से संशोधित किया जाता है, तो उसी कॉल में शुद्ध अजगर से एक्सेस किया जाता है, अजगर संस्करण अपडेट नहीं देखता है और जावास्क्रिप्ट संस्करण को भी बदल देता है। इसलिए मुझे लगता है कि आप जावास्क्रिप्ट सेल को शीर्ष पर ले जा सकते हैं, इसे चला सकते हैं, फिर "सेल> रन ऑल बोलो" का उपयोग कर सकते हैं।
महमूद इलागरदार

2
हमें वास्तव में जावास्क्रिप्ट की आवश्यकता क्यों है? अधिक मूल कुछ नहीं?
15

1
Jupyter लैब पर विफल रहता है:Javascript Error: IPython is not defined
magicrebirth

27

बृहस्पति 3.0 पर निम्नलिखित कार्य करता है। यहाँ मैं ज्यूपिटर सर्वर पर पूरा रास्ता दिखा रहा हूँ, न कि केवल नोटबुक नाम:

NOTEBOOK_FULL_PATHवर्तमान नोटबुक फ्रंट एंड पर स्टोर करने के लिए :

%%javascript
var nb = IPython.notebook;
var kernel = IPython.notebook.kernel;
var command = "NOTEBOOK_FULL_PATH = '" + nb.base_url + nb.notebook_path + "'";
kernel.execute(command);

फिर इसे प्रदर्शित करने के लिए:

print("NOTEBOOK_FULL_PATH:\n", NOTEBOOK_FULL_PATH)

पहले जावास्क्रिप्ट सेल चलाने से कोई आउटपुट नहीं मिलता है। दूसरा पायथन सेल चलाने से कुछ ऐसा होता है:

NOTEBOOK_FULL_PATH:
 /user/zeph/GetNotebookName.ipynb

4
यह बहुत साफ है। फिर आप एक पायथन फ़ंक्शन से जावास्क्रिप्ट कोड को कैसे कॉल करेंगे?
लुकास

हम्म्म्म ... हो सकता है कि उस मामले में आपको पोर्ट नंबर के बाद एक कोलन के साथ पोर्ट को जोड़ना चाहिए?
जेफान्याह ग्रुन्स्क्लाग

3
यह सापेक्ष पथ नहीं पूर्ण पथ है
इवलिन

इसमें सेटिंग भी शामिल नहीं है c.NotebookApp.notebook_dir
सापज्व

4
मैं हो रही है Javascript Error: IPython is not defined। मैं जावास्क्रिप्ट को कैसे लोड कर सकता हूँ जावास्क्रिप्ट
zozo

25

ऐसा लगता है कि मैं कोई टिप्पणी नहीं कर सकता, इसलिए मुझे इसे उत्तर के रूप में पोस्ट करना होगा।

@Iguananaut द्वारा स्वीकृत समाधान और @mbdevpl द्वारा अपडेट नोटबुक के हाल के संस्करणों के साथ काम नहीं करता प्रतीत होता है। मैंने इसे नीचे दिखाए अनुसार ठीक किया। मैंने इसे Python v3.6.1 + नोटबुक v5.0.0 और Python v3.6.5 और नोटबुक v5.5.0 पर चेक किया।

from notebook import notebookapp
import urllib
import json
import os
import ipykernel

def notebook_path():
    """Returns the absolute path of the Notebook or None if it cannot be determined
    NOTE: works only when the security is token-based or there is also no password
    """
    connection_file = os.path.basename(ipykernel.get_connection_file())
    kernel_id = connection_file.split('-', 1)[1].split('.')[0]

    for srv in notebookapp.list_running_servers():
        try:
            if srv['token']=='' and not srv['password']:  # No token and no password, ahem...
                req = urllib.request.urlopen(srv['url']+'api/sessions')
            else:
                req = urllib.request.urlopen(srv['url']+'api/sessions?token='+srv['token'])
            sessions = json.load(req)
            for sess in sessions:
                if sess['kernel']['id'] == kernel_id:
                    return os.path.join(srv['notebook_dir'],sess['notebook']['path'])
        except:
            pass  # There may be stale entries in the runtime directory 
    return None

जैसा कि डॉक्स्ट्रिंग में कहा गया है, यह तभी काम करता है जब या तो कोई प्रमाणीकरण नहीं होता है या प्रमाणीकरण टोकन आधारित होता है।

ध्यान दें कि, जैसा कि दूसरों द्वारा भी बताया गया है, जावास्क्रिप्ट-आधारित पद्धति "रन ऑल सेल" निष्पादित करते समय काम नहीं करती है (लेकिन कोशिकाओं को "मैन्युअल रूप से निष्पादित करते समय काम करता है"), जो मेरे लिए एक डील-ब्रेकर था।


क्या इसके लिए कोई पुस्तकालय है?
मैट्रनस्टर

जावास्क्रिप्ट विधियों की विफलता मेरे लिए भी एक डील-ब्रेकर थी। इस विकल्प को पोस्ट करने के लिए धन्यवाद!
तर्कशीलता

मुझे jupyter_core.paths आयात jupyter_config_dir से srv ['Notebook_dir'] को बदलना है; traitlets.config से इंपोर्ट कॉन्फ़िगर करें; सी = विन्यास (); file_path = os.path.join (jupyter_config_dir (), 'jupyter_notebook_config.py'); कार्यकारी (खुला (FILE_PATH) .read ()); root_dir = c ['FileContentsManager'] ['root_dir']
डेव

14

Ipyparams पैकेज बहुत आसानी से कर सकते हैं।

import ipyparams
currentNotebook = ipyparams.notebook_name

यह शीर्ष पर स्वीकृत एक से बेहतर उत्तर लगता है।
ऐलेजैंड्रो

1

यदि आपके पास जुपिटर नोटबुक सर्वर का होस्ट, पोर्ट और प्रमाणीकरण टोकन है, तो यह आपके लिए काम करना चाहिए। यह इस उत्तर पर आधारित है ।

import os
import json
import posixpath
import subprocess
import urllib.request
import psutil

def get_notebook_path(host, port, token):
    process_id = os.getpid();
    notebooks = get_running_notebooks(host, port, token)
    for notebook in notebooks:
        if process_id in notebook['process_ids']:
            return notebook['path']

def get_running_notebooks(host, port, token):
    sessions_url = posixpath.join('http://%s:%d' % (host, port), 'api', 'sessions')
    sessions_url += f'?token={token}'
    response = urllib.request.urlopen(sessions_url).read()
    res = json.loads(response)
    notebooks = [{'kernel_id': notebook['kernel']['id'],
                  'path': notebook['notebook']['path'],
                  'process_ids': get_process_ids(notebook['kernel']['id'])} for notebook in res]
    return notebooks

def get_process_ids(name):
    child = subprocess.Popen(['pgrep', '-f', name], stdout=subprocess.PIPE, shell=False)
    response = child.communicate()[0]
    return [int(pid) for pid in response.split()]

उदाहरण का उपयोग:

get_notebook_path('127.0.0.1', 17004, '344eb91bee5742a8501cc8ee84043d0af07d42e7135bed90')

0

फिर भी मेरा नोटबुक सर्वर बदल सकता है। मूल रूप से आप एक यादृच्छिक स्ट्रिंग प्रिंट करते हैं, इसे सहेजते हैं और फिर उस निर्देशिका में एक फ़ाइल की खोज करते हैं जिसमें वर्किंग डायरेक्टरी होती है। समय की आवश्यकता है क्योंकि save_checkpoint अतुल्यकालिक है।

from time import sleep
from IPython.display import display, Javascript
import subprocess
import os
import uuid

def get_notebook_path_and_save():
    magic = str(uuid.uuid1()).replace('-', '')
    print(magic)
    # saves it (ctrl+S)
    display(Javascript('IPython.notebook.save_checkpoint();'))
    nb_name = None
    while nb_name is None:
        try:
            sleep(0.1)
            nb_name = subprocess.check_output(f'grep -l {magic} *.ipynb', shell=True).decode().strip()
        except:
            pass
    return os.path.join(os.getcwd(), nb_name)

0

यदि हम एक बार में एक से अधिक सेल निष्पादित करते हैं, तो सभी Json आधारित समाधान विफल हो जाते हैं, क्योंकि परिणाम निष्पादन के अंत तक तैयार नहीं होगा (इसके लिए नींद का उपयोग करने या किसी भी समय इंतजार करने की बात नहीं है, इसे स्वयं जांचें लेकिन कर्नेल को पुनरारंभ करना याद रखें और सभी परीक्षण चलाएं)

पिछले समाधानों के आधार पर, यह %% मैजिक का उपयोग करने से बचता है, जब आपको इसे किसी अन्य कोड के बीच में रखने की आवश्यकता होती है:

from IPython.display import display, Javascript

# can have comments here :)
js_cmd = 'IPython.notebook.kernel.execute(\'nb_name = "\' + IPython.notebook.notebook_name + \'"\')'
display(Javascript(js_cmd))

अजगर 3 के लिए, @ इगुआनाट द्वारा दिए गए उत्तर के आधार पर और नवीनतम अजगर के लिए अपडेट किया गया और संभवतः कई सर्वर काम करेंगे:

import os
import json
try:
    from urllib2 import urlopen
except:
    from urllib.request import urlopen
import ipykernel

connection_file_path = ipykernel.get_connection_file()
connection_file = os.path.basename(connection_file_path)
kernel_id = connection_file.split('-', 1)[1].split('.')[0]    
    
running_servers = !jupyter notebook list
running_servers = [s.split('::')[0].strip() for s in running_servers[1:]]
nb_name = '???'
for serv in running_servers:
    uri_parts = serv.split('?')
    uri_parts[0] += 'api/sessions'
    sessions = json.load(urlopen('?'.join(uri_parts)))
    for sess in sessions:
        if sess['kernel']['id'] == kernel_id:
            nb_name = os.path.basename(sess['notebook']['path'])
            break
    if nb_name != '???':
        break
print (f'[{nb_name}]')
    
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.