IPython dizüstü bilgisayarı çalıştırırken mevcut NoteBook adını almaya çalışıyorum. Defterin üstünde görebildiğimi biliyorum. Gibi bir şeyin peşindeyim
currentNotebook = IPython.foo.bar.notebookname()
Adı bir değişkende almam gerekiyor.
IPython dizüstü bilgisayarı çalıştırırken mevcut NoteBook adını almaya çalışıyorum. Defterin üstünde görebildiğimi biliyorum. Gibi bir şeyin peşindeyim
currentNotebook = IPython.foo.bar.notebookname()
Adı bir değişkende almam gerekiyor.
pip install ipynbname
Yanıtlar:
Daha önce de belirtildiği gibi muhtemelen bunu yapamayacaksın, ama bir yolunu buldum. Bu alevli bir hack, bu yüzden buna hiç güvenmeyin:
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
Cevabımı IPython 2.0'da en azından basit bir testle "çalışan" bir çözümü içerecek şekilde güncelledim. Aynı çekirdeğe bağlı birden fazla dizüstü bilgisayar varsa, muhtemelen doğru cevabı vermenin garantisi yoktur.
from IPython.lib import kernel
Şu an yerine sadece from IPython import kernel
. Ayrıca sözlüklerde 'isim' anahtarını kullanmak yerine, anahtar '
notebook.notebookapp.list_running_servers()
.
IPython 2.0 ile çalışan aşağıdakilere sahibim. Ben defterin adı özelliğinin değeri olarak saklanır gözlemlenmiştir 'data-notebook-name'
içinde <body>
sayfanın etiketinin. Bu nedenle fikir, ilk olarak Javascript'ten --javascripts %%javascript
sihir sayesinde bir kod çözücüsünden çağrılabilir özelliğini almasını istemektir . Ardından, Python değişkenini ayarlayan bir komutla Python Kernel'e yapılan bir çağrı yoluyla Javascript değişkenine erişmek mümkündür. Bu son değişken çekirdekten bilindiği için diğer hücrelerden de erişilebilir.
%%javascript
var kernel = IPython.notebook.kernel;
var body = document.body,
attribs = body.attributes;
var command = "theNotebook = " + "'"+attribs['data-notebook-name'].value+"'";
kernel.execute(command);
Bir Python kod hücresinden
print(theNotebook)
Çıkış []: HowToGetTheNameOfTheNoteBook.ipynb
Bu çözümdeki bir kusur, bir defterin başlığını (adını) değiştirdiğinde, bu adın hemen güncellenmemesi (muhtemelen bir tür önbellek vardır) ve dizüstü bilgisayara erişmek için not defterini yeniden yüklemenin gerekmesidir. yeni isim.
[Düzenle] Düşünüldüğünde, daha verimli bir çözüm, <body>
etiket yerine not defterinin adı için giriş alanını aramaktır. Kaynağa bakıldığında, bu alanın "not defteri_adı" kimliğine sahip olduğu görülmektedir. Daha sonra bu değeri a ile yakalamak document.getElementById()
ve ardından yukarıdaki ile aynı yaklaşımı izlemek mümkündür . Kod, hala javascript büyüsünü kullanıyor
%%javascript
var kernel = IPython.notebook.kernel;
var thename = window.document.getElementById("notebook_name").innerHTML;
var command = "theNotebook = " + "'"+thename+"'";
kernel.execute(command);
Ardından, bir ipython hücresinden
In [11]: print(theNotebook)
Out [11]: HowToGetTheNameOfTheNoteBookSolBis
İlk çözümün aksine, dizüstü bilgisayarın adında yapılan değişiklikler anında güncellenir ve not defterini yenilemeye gerek yoktur.
def getname(): display(Javascript('IPython.notebook.kernel.execute("theNotebook = " + "\'"+IPython.notebook.notebook_name+"\'");'))
globals()['_dh'][0]
önceki cevaplara eklemek,
not defteri adını almak için bir hücrede aşağıdakileri çalıştırın:
%%javascript
IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')
bu size nb_name'deki dosya adını verir
daha sonra tam yolu elde etmek için aşağıdakileri ayrı bir hücrede kullanabilirsiniz:
import os
nb_full_path = os.path.join(os.getcwd(), nb_name)
IPython.notebook.notebook_name
Bunu kullanmak şu şekilde yapılabilir%%javascript IPython.notebook.kernel.execute('notebookName = ' + '"' + IPython.notebook.notebook_name + '"')
Javascript Error: IPython is not defined
Jupyter 3.0'da aşağıdaki çalışır. Burada sadece not defteri adını değil, Jupyter sunucusundaki tüm yolu gösteriyorum:
NOTEBOOK_FULL_PATH
Mevcut dizüstü bilgisayar ön ucunda saklamak için :
%%javascript
var nb = IPython.notebook;
var kernel = IPython.notebook.kernel;
var command = "NOTEBOOK_FULL_PATH = '" + nb.base_url + nb.notebook_path + "'";
kernel.execute(command);
Daha sonra görüntülemek için:
print("NOTEBOOK_FULL_PATH:\n", NOTEBOOK_FULL_PATH)
İlk Javascript hücresini çalıştırmak çıktı üretmez. İkinci Python hücresini çalıştırmak aşağıdaki gibi bir şey üretir:
NOTEBOOK_FULL_PATH:
/user/zeph/GetNotebookName.ipynb
c.NotebookApp.notebook_dir
.
Javascript Error: IPython is not defined
. IPython'u javascript için nasıl yükleyebilirim
Görünüşe göre yorum yapamam, bu yüzden bunu bir cevap olarak göndermem gerekiyor.
@İguananaut tarafından kabul edilen çözüm ve @mbdevpl tarafından yapılan güncelleme, Notebook'un son sürümlerinde çalışmıyor gibi görünüyor. Aşağıda gösterildiği gibi düzelttim. Python v3.6.1 + Notebook v5.0.0 ve Python v3.6.5 ve Notebook v5.5.0'da kontrol ettim.
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
Doküman dizesinde belirtildiği gibi, bu yalnızca kimlik doğrulama olmadığında veya kimlik doğrulaması belirteç tabanlı olduğunda çalışır.
Başkaları tarafından da bildirildiği gibi, Javascript tabanlı yöntemin, benim için bir anlaşma bozan bir "Tüm hücreleri çalıştır" (ancak hücreleri "manuel olarak" yürütürken çalışır) yürütürken çalışmadığını unutmayın.
Jupyter Notebook sunucusunun ana bilgisayarına, bağlantı noktasına ve kimlik doğrulama jetonuna sahip olduğunuzu varsayarsak, bu sizin için çalışmalıdır. Bu cevaba dayanmaktadır .
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()]
Örnek kullanım:
get_notebook_path('127.0.0.1', 17004, '344eb91bee5742a8501cc8ee84043d0af07d42e7135bed90')
Dizüstü bilgisayar sunucum değişebileceğinden bir başka hacky çözüm. Temel olarak rastgele bir dize yazdırır, kaydeder ve ardından bu dizeyi içeren bir dosyayı çalışma dizininde ararsınız. Save_checkpoint eşzamansız olduğu için süre gereklidir.
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)
Aynı anda birden fazla hücre çalıştırırsak, tüm Json tabanlı çözümler başarısız olur, çünkü sonuç yürütme bitene kadar hazır olmayacaktır (bu, uyku veya bekleme meselesi değildir, kendiniz kontrol edin, ancak çekirdeği yeniden başlatmayı unutmayın. ve her testi çalıştırın)
Önceki çözümlere dayanarak, bu, başka bir kodun ortasına koymanız gerekebileceği için %% sihrini kullanmaktan kaçınır:
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))
Python 3 için, aşağıdakiler @Iguananaut tarafından verilen cevaba göre ve en son python ve muhtemelen birden çok sunucu için güncellenmiş:
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}]')