Tôi đang cố lấy tên NoteBook hiện tại khi chạy sổ ghi chép IPython. Tôi biết tôi có thể nhìn thấy nó ở đầu cuốn sổ. Tôi là gì sau một cái gì đó như thế nào
currentNotebook = IPython.foo.bar.notebookname()
Tôi cần lấy tên trong một biến.
Tôi đang cố lấy tên NoteBook hiện tại khi chạy sổ ghi chép IPython. Tôi biết tôi có thể nhìn thấy nó ở đầu cuốn sổ. Tôi là gì sau một cái gì đó như thế nào
currentNotebook = IPython.foo.bar.notebookname()
Tôi cần lấy tên trong một biến.
pip install ipynbname
Câu trả lời:
Như đã đề cập, có lẽ bạn không thực sự được cho là có thể làm được điều này, nhưng tôi đã tìm ra cách. Tuy nhiên, đó là một vụ hack rực lửa vì vậy đừng dựa vào điều này chút nào:
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
Tôi đã cập nhật câu trả lời của mình để đưa vào giải pháp ít nhất là "hoạt động" trong IPython 2.0 với một bài kiểm tra đơn giản. Có thể không đảm bảo đưa ra câu trả lời chính xác nếu có nhiều sổ ghi chép được kết nối với cùng một hạt nhân, v.v.
from IPython.lib import kernel
bây giờ chỉ là from IPython import kernel
. Ngoài ra thay vì sử dụng chìa khóa 'tên' trong từ điển, sử dụng phím 'path'
notebook.notebookapp.list_running_servers()
.
Tôi có phần sau hoạt động với IPython 2.0. Tôi quan sát thấy rằng tên của sổ ghi chép được lưu trữ dưới dạng giá trị của thuộc tính 'data-notebook-name'
trong <body>
thẻ của trang. Vì vậy, ý tưởng đầu tiên là yêu cầu Javascript truy xuất thuộc tính --javascripts có thể được gọi từ codecell nhờ %%javascript
phép thuật. Sau đó, có thể truy cập vào biến Javascript thông qua lệnh gọi đến Hạt nhân Python, bằng lệnh đặt biến Python. Vì biến cuối cùng này được biết đến từ kernel, nên nó cũng có thể được truy cập trong các ô khác.
%%javascript
var kernel = IPython.notebook.kernel;
var body = document.body,
attribs = body.attributes;
var command = "theNotebook = " + "'"+attribs['data-notebook-name'].value+"'";
kernel.execute(command);
Từ một ô mã Python
print(theNotebook)
Ra []: HowToGetTheNameOfTheNoteBook.ipynb
Một khiếm khuyết trong giải pháp này là khi người ta thay đổi tiêu đề (tên) của sổ ghi chép, thì tên này dường như không được cập nhật ngay lập tức (có thể có một số loại bộ nhớ cache) và cần phải tải lại sổ ghi chép để có quyền truy cập vào tên mới.
[Chỉnh sửa] Khi phản ánh, một giải pháp hiệu quả hơn là tìm kiếm trường nhập cho tên sổ ghi chép thay vì <body>
thẻ. Nhìn vào nguồn, có vẻ như trường này có id "notebook_name". Sau đó có thể bắt giá trị này bằng a document.getElementById()
và sau đó thực hiện theo cách tiếp cận tương tự như trên. Mã trở thành, vẫn sử dụng phép thuật javascript
%%javascript
var kernel = IPython.notebook.kernel;
var thename = window.document.getElementById("notebook_name").innerHTML;
var command = "theNotebook = " + "'"+thename+"'";
kernel.execute(command);
Sau đó, từ một ô ipython,
In [11]: print(theNotebook)
Out [11]: HowToGetTheNameOfTheNoteBookSolBis
Trái với giải pháp đầu tiên, các sửa đổi về tên sổ ghi chép được cập nhật ngay lập tức và không cần phải làm mới sổ ghi chép.
def getname(): display(Javascript('IPython.notebook.kernel.execute("theNotebook = " + "\'"+IPython.notebook.notebook_name+"\'");'))
globals()['_dh'][0]
thêm vào các câu trả lời trước,
để có được tên sổ ghi chép, hãy chạy như sau trong một ô:
%%javascript
IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')
điều này giúp bạn có tên tệp trong nb_name
sau đó để có được đường dẫn đầy đủ, bạn có thể sử dụng như sau trong một ô riêng biệt:
import os
nb_full_path = os.path.join(os.getcwd(), nb_name)
IPython.notebook.notebook_name
điều này có thể được thực hiện bằng cách sử dụng%%javascript IPython.notebook.kernel.execute('notebookName = ' + '"' + IPython.notebook.notebook_name + '"')
Javascript Error: IPython is not defined
Trên Jupyter 3.0, các hoạt động sau đây. Ở đây tôi đang hiển thị toàn bộ đường dẫn trên máy chủ Jupyter, không chỉ tên sổ ghi chép:
Để lưu trữ NOTEBOOK_FULL_PATH
trên giao diện người dùng của sổ ghi chép hiện tại:
%%javascript
var nb = IPython.notebook;
var kernel = IPython.notebook.kernel;
var command = "NOTEBOOK_FULL_PATH = '" + nb.base_url + nb.notebook_path + "'";
kernel.execute(command);
Để sau đó hiển thị nó:
print("NOTEBOOK_FULL_PATH:\n", NOTEBOOK_FULL_PATH)
Chạy ô Javascript đầu tiên không tạo ra kết quả nào. Chạy ô Python thứ hai tạo ra một cái gì đó như:
NOTEBOOK_FULL_PATH:
/user/zeph/GetNotebookName.ipynb
c.NotebookApp.notebook_dir
.
Javascript Error: IPython is not defined
. Làm cách nào để tải IPython cho javascript
Có vẻ như tôi không thể bình luận, vì vậy tôi phải đăng điều này như một câu trả lời.
Giải pháp được chấp nhận bởi @iguananaut và bản cập nhật của @mbdevpl dường như không hoạt động với các phiên bản gần đây của Notebook. Tôi đã sửa nó như hình dưới đây. Tôi đã kiểm tra nó trên Python v3.6.1 + Notebook v5.0.0 và trên Python v3.6.5 và Notebook 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
Như đã nêu trong docstring, điều này chỉ hoạt động khi không có xác thực hoặc xác thực dựa trên mã thông báo.
Lưu ý rằng, như những người khác đã báo cáo, phương pháp dựa trên Javascript dường như không hoạt động khi thực thi "Chạy tất cả các ô" (nhưng hoạt động khi thực thi các ô "theo cách thủ công"), đó là một công cụ phá vỡ thỏa thuận đối với tôi.
Giả sử bạn có máy chủ, cổng và mã xác thực của máy chủ Jupyter Notebook, điều này sẽ phù hợp với bạn. Nó dựa trên câu trả lời này .
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()]
Ví dụ sử dụng:
get_notebook_path('127.0.0.1', 17004, '344eb91bee5742a8501cc8ee84043d0af07d42e7135bed90')
Tuy nhiên, một giải pháp hacky khác vì máy chủ notebook của tôi có thể thay đổi. Về cơ bản, bạn in một chuỗi ngẫu nhiên, lưu nó và sau đó tìm kiếm tệp chứa chuỗi đó trong thư mục làm việc. Trong khi đó là cần thiết vì save_checkpoint là không đồng bộ.
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)
Tất cả các giải pháp dựa trên Json đều thất bại nếu chúng ta thực thi nhiều ô tại một thời điểm vì kết quả sẽ không sẵn sàng cho đến khi kết thúc quá trình thực thi (vấn đề không phải là sử dụng sleep hay chờ bất cứ lúc nào, hãy tự kiểm tra nhưng nhớ khởi động lại kernel và chạy tất cả mọi thử nghiệm)
Dựa trên các giải pháp trước đây, điều này tránh sử dụng phép thuật %% trong trường hợp bạn cần đặt nó ở giữa một số mã khác:
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))
Đối với python 3, phần sau dựa trên câu trả lời của @Iguananaut và được cập nhật cho python mới nhất và có thể nhiều máy chủ sẽ hoạt động:
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}]')