用 papermill 參數化和自動化 Jupyter
Python中文社區(ID:python-china)
你是否曾經創建過 Jupyter notebook 并希望可以使用一組不同的參數生成notebook?這樣做的話你可能至少執行了以下操作之一:
•編輯單元格中的變量并重新運行notebook,根據需要保存副本。•保存了notebook的副本,并且可能修改了代碼以直接在 .ipynb 文件中編輯值并重新運行notebooks•構建了一些自定義代碼以使用從數據庫或配置文件加載的數據設置變量,然后重新運行notebook
這個問題有一個很好的解決方案,可以將交互式筆記本參數化并與自動化作業很好地共存,這就是所謂的papermill。
動機
許多notebook用戶使用在其notebook頂部附近指定一個單元格作為全局變量的標準做法。然后修改單元格中的值并運行整個notebook以獲得不同的結果。為了保持輸出,作者將手動下載另一種格式的notebook或將其另存為不同的notebook文件。但是僅使用notebook服務器和這些手動方法很快就會變得混亂且難以跟蹤,更不用說容易出錯了。你編輯的是哪個notebook? Papermill 有助于解決這個問題。在這篇文章中,我將介紹 papermill 和基本用法,通過一個參數化的例子,最后談談使用 cron 完全調度和自動化 notebook 執行的方法。
對于papermill,notebook中的一個特殊單元格被指定為參數。當 papermill 通過命令行界面 (CLI) 或使用 Python API 執行參數化notebook時,參數會傳入并在后續單元中執行。這允許notebook以不同的參數快速運行多次。然后可以將生成的執行后的notebook保存在各種位置,包括本地或云存儲。
安裝
要安裝 papermill,請使用 pip。我建議使用 virtualenv 或 conda 的虛擬環境。我經常推薦使用 pyenv 來安裝最新的 Python 版本并創建一個 virtualenv虛擬環境。
- pip install papermill
如果您想使用各種輸入和輸出選項,如 Amazon 的 s3 或 Microsoft 的 azure,您可以安裝所有依賴項。我不會在這里詳細介紹,但文檔涵蓋了這些選項,你甚至可以擴展 papermill 為notebooks的輸入/輸出 (I/O) 添加其他處理程序。
- pip install papermill[all]
基本使用
大多數用戶想要用 papermill 做的第一件事就是參數化notebook。一旦您運行了 Jupyter 并打開了一個notebook,您需要做的就是將參數標簽添加到包含參數的單元格中。
保存notebook,現在您可以使用 papermill 執行它了。對于示例notebook,請使用 CLI 運行notebook,并提供您自己的名稱。
- papermill -p name Matt papermill_example1.ipynb papermill_matt.ipynb
此命令告訴 papermill 執行輸入 notebook papermill_example1.ipynb 并將輸出寫入 papermill_matt.ipynb,同時將參數名稱設置為值 Matt。如果您打開生成的notebook,將在帶有注入參數標簽的參數標記之后包含一個新單元格,如下所示。
您現在應該看到如何根據需要添加盡可能多的參數,以便從現有notebook制作新notebook。將主notebook(在我們的例子中是papermill_example1.ipynb)想象成一個模板,您可以使用它通過快速注入參數來制作任意數量的副本。
API 的基本使用
您可能希望使用 Python 代碼獲取或構建您注入的參數,因此還可以使用 Python API 來執行 papermill。我們可以在 Python 腳本中實現與上述完全相同的結果(或在notebook中,它在那里也能很好地工作 - 并且會動態地向您顯示進度)。
- import papermill as pm
- name = "Matt"
- res = pm.execute_notebook(
- 'papermill_example1.ipynb',
- 'papermill_{name}.ipynb',
- parameters = dict(namename=name)
- )
- {"version_major":2,"version_minor":0,"model_id":"cf8280b216094bf6a75a9536b6505051"}
更多參數傳遞
到目前為止,我們只傳遞了一個參數,并使用了 -p 選項來實現這一點。您可以通過幾種方式傳遞參數。
命令行
您可以使用示例notebook運行所有這些內容,然后自己查看結果。首先,您可以從 CLI 指定多個參數。即使notebook中尚不存在參數,也可以傳入和創建參數。在這種情況下,papermill 將創建一個注入參數單元并在notebook頂部執行它。
這是一個例子。
- papermill -p name Matt -p level 5 -p factor 0.33 -p alive True papermill_example1.ipynb papermill_matt.ipynb
或者用長選項代替......
- papermill --parameters name Matt --parameters level 5 --parameters factor 0.33 --parameters alive True papermill_example1.ipynb papermill_matt.ipynb
請注意, -p 或 --parameters 選項將嘗試解析整數和浮點數,因此如果您希望將它們解釋為字符串,請使用 -r 或 --raw 選項以字符串形式獲取所有值。
- papermill -r name Matt -r level 5 -r factor 0.33 -r alive True papermill_example1.ipynb papermill_matt.ipynb
您還可以使用 yaml 來指定參數。這可以通過文件(-f 或 --parameters_file)、字符串(-y 或 --parameters_yaml)或 base64 編碼字符串(-b 或 --parameters_base64)傳入。這允許您傳入更復雜的數據,包括列表和字典。
- papermill papermill_example1.ipynb papermill_matt.ipynb -y "
- name: Matt
- level: 5
- factor: 0.33
- alive: True
- sizes:
- - 1.0
- - 2.5
- - 3.7
- params:
- x: 3
- y: 4"
您可以很容易地對字符串進行 base64 編碼。(在 Mac 或 Linux 或 Windows WSL 上notebook文件所在目錄中的 shell 中運行此命令)。
- echo "
- name: Matt
- level: 5
- factor: 0.33
- alive: True
- sizes:
- - 1.0
- - 2.5
- - 3.7
- params:
- x: 3
- y: 4" > params.yaml
現在您可以運行文件版本。
- papermill papermill_example1.ipynb papermill_matt.ipynb -f params.yaml
或者base64版本
- PARAMS=$(cat params.yaml| base64) # makes the base64 version of the yaml file
- papermill papermill_example1.ipynb papermill_matt.ipynb -b $PARAMS
無論哪種方式,你都應該了解可以從命令行和 API 將復雜數據傳遞到notebook中。這些示例都使用本地文件系統進行notebook的輸入和輸出,但也可以從 Amazon s3、Azure、Google Cloud Storage 或 Web 服務器讀取和寫入notebook。
檢查notebook
可以從 CLI 檢查notebook的可用參數。
- $ papermill --help-notebook papermill_example1.ipynb
- Usage: papermill [OPTIONS] NOTEBOOK_PATH [OUTPUT_PATH]
- Parameters inferred for notebook 'papermill_example1.ipynb':
- name: Unknown type (default "Joe")
或者使用 Python API。
- pm.inspect_notebook('papermill_example1.ipynb')
- {'name': {'name': 'name',
- 'inferred_type_name': 'None',
- 'default': '"Joe"',
- 'help': ''}}
執行完整的工作流程
papermill的典型工作流程是擁有一個參數化notebook,使用多個值運行它,然后將生成的notebook轉換為另一種格式以供審查或報告。讓我們通過一個示例來了解如何設置。
首先,我們有一個使用 Yahoo! 金融 API 來獲取股票價格并繪制股票歷史最高價的數據(或者至少是過去兩年的最高價,因為我此時只獲取那么多數據)。
如果要運行此示例,則需要確保已安裝 yfinance API 和 matplotlib。如果需要,您可以使用 pip 安裝兩者。
我們可以使用papermill CLI 來檢查參數。
- $ papermill --help-notebook papermill_example2.ipynb
- Usage: papermill [OPTIONS] NOTEBOOK_PATH [OUTPUT_PATH]
- Parameters inferred for notebook 'papermill_example2.ipynb':
- symbol: Unknown type (default 'AAPL')
我們將用幾個符號運行這個notebook 。我選擇為此使用 shell 腳本,以便我可以通過計劃的 cron 程序運行它。如果需要,這可以使用簡單的 Python 腳本輕松完成。但是,如果您使用的是虛擬環境,您最終可能需要一個腳本來確保正確加載 virtualenv。在這種情況下,在整個過程中使用 shell 腳本可能會更容易。
我還將使用 jupyter nbconvert(或者您可以將其作為 jupyter-nbconvert 運行)命令將notebook轉換為 html 文件,以便通過 Web 瀏覽器查看。就像 papermill一樣,nbconvert 可通過命令行或使用 Python API 獲得。
自動化腳本
- #!/bin/bash
- set -eux
- # activate our virtualenv (this was created using pyenv-virtualenv, yours will be elsewhere)
- source /Users/mcw/.pyenv/versions/3.8.6/envs/pandas/bin/activate
- # get to the script directory if running via cron
- cd $(dirname "${BASH_SOURCE[0]}")
- for S in AAPL MSFT GOOG FB
- do
- papermill -p symbol $S papermill_example2.ipynb papermill_${S}.ipynb
- jupyter-nbconvert --no-input --to html papermill_${S}.ipynb
- done
您可以從 shell 運行此命令(在調整激活虛擬環境的行之后)。您還可以很容易地安排它在 cron 中定期運行。例如,您可以像下面這樣(使用您自己的路徑)在每個工作日的下午 4 點運行此報告。
- 00 16 * * mon-fri /Users/mcw/projects/python_blogposts/tools/run_papermill.sh
擴展示例
只需多一點創意(和 nbconvert 上的軟件配置),您就可以將notebooks 輸出為 PDF 或其他格式,通過電子郵件發送,或將它們上傳到服務器,以便每天更新報告。
請注意,每個符號的notebooks 都保存到本地磁盤。如果需要調試或進一步工作,它們可以在 Jupyter 服務器中打開并輕松重新執行。請注意,如果您正在運行一個自動化作業,那么每次運行時都會更換notebook。理想情況下,在主模板notebook上工作,然后通過自動化為每個符號生成新版本。
另一個技巧是papermill可以讀寫標準輸入和輸出。這意味著如果您有其他工具將notebook文件作為輸入,則不必將文件寫入磁盤。例如,在上面的 shell 腳本中,我們可以防止為每個符號寫出每個單獨的notebook文件,而是在循環中執行以下操作。
- papermill -p symbol $S papermill_example2.ipynb | jupyter-nbconvert --stdin --no-input --to html --output report_${S}.html
請注意,如果您這樣做,則需要打開主notebook (papermill_example2.ipynb) 并編輯參數以調試問題。但是,如果您需要節省磁盤空間并且不需要單獨調試每個notebook的能力,那么這可能更可取。
總結
Papermill 是一個用于參數化和執行 Jupyter notebook的庫。您可以使用它來自動執行您的notebook,其中包含您可以想到的任何參數集。接著使用 nbconvert 轉換notebook,以提供可讀且有用的notebook版本。
notebook自動化還有很多事情要做,但是從 Papermill 開始作為執行和參數化notebook的工具是一個很好的構建平臺。