2016-05-29 20 views
1

我想創建一些簡單易用的pip包,用於在Python中加載常見的機器學習數據集。 (是的,有些東西已經存在,但我希望它是更簡單。)使用setuptools時,如何在安裝時下載外部數據?

我想實現的是:

  • 用戶運行pip install dataset
  • PIP下載數據集,說通過wget http://mydata.com/data.tar.gz。請注意,數據不在python包本身中,而是從其他地方下載。
  • pip從該文件中提取數據並將其放入安裝該軟件包的目錄中(這並不理想,但數據集非常小,因此我們假設在這裏存儲數據並不是什麼大問題。)
  • 稍後,當用戶導入我的模塊時,模塊會自動從特定位置加載數據。

這個問題是關於子彈2和3.有沒有辦法用setuptools做到這一點?

回答

1

正如Kevin暗示的那樣,Python軟件包的安裝應該是完全可重複的,並且任何潛在的外部下載問題都應該推送到運行時。因此不應該用setuptools來處理。

相反,爲避免給用戶造成負擔,請考慮在加載時以懶惰的方式下載數據。例如:

def download_data(url='http://...'): 
    # Download; extract data to disk. 
    # Raise an exception if the link is bad, or we can't connect, etc. 

def load_data(): 
    if not os.path.exists(DATA_DIR): 
     download_data() 
    data = read_data_from_disk(DATA_DIR) 
    return data 

然後我們可以描述在文檔download_data,但大多數用戶會永遠不需要管它。這與imageio模塊在運行時下載必要的解碼器的行爲有些類似,而不是讓用戶自己管理外部下載。

0

Python軟件包安裝指出,爲了安裝Python軟件包,它永遠不應該執行Python代碼。這意味着您可能無法在安裝過程中下載內容。

如果您想要下載一些附加數據,請在安裝軟件包後執行此操作,例如,當您導入軟件包時,可以下載此數據並將其緩存到某處,以便在每次新導入時都不要下載它。

+0

進口副作用是邪惡的。最好提供一個明確地做到這一點的函數。例如,如果用戶沒有互聯網,或者在某種邪惡的MitM代理的後面,給你一個「這個頁面被阻止」的HTML文件而不是你期望的數據集? – Kevin

0

請注意,數據並不駐留在python包本身,而是從其他地方下載。

請不要這樣做。

Python包裝的重點在於提供一個完全確定的,可重複的,可重複使用的方法,每次安裝完全一樣的東西。您的建議已至少存在以下問題:

  • 最終用戶可能下載你的包在計算機A上,把它粘拇指驅動器上,然後在不具備上網計算機B上安裝它。
  • Web上的數據可能會更改,這意味着安裝相同確切軟件包的兩個人會得到不同的結果。
  • 提供該數據的網站可能會不存在或unwisely change the URL,這意味着仍有該軟件包的用戶將無法使用該軟件。
  • 用戶可能位於互聯網過濾器的後面,您可能會得到一個無用的「此頁面被阻止」的HTML文件,而不是您期望的數據集。

相反,您應該包括與包(使用package_data or data_files參數setup())數據,或者在你的Python代碼手動下載數據,當用戶準備確實提供了一個單獨的頂級功能所以。

+0

假設由於許可問題而無法分發數據。然後我認爲你所說的是,在運行時出現的問題比安裝時更好。是? (有沒有想過這個..我想我同意。)也許我會做的是在運行時有一個懶惰的自動下載,可以有點失敗。 – rd11

+0

否。顯式優於隱式。用戶不希望導入包來做任何事情。提供手動啓動下載的功能。 – Kevin

+0

我並不是說它會在導入時發生,手動下載在絕大多數情況下不過是不必要的麻煩。 – rd11

相關問題