使用setuptools,如何在安装时下载外部数据?

时间:2016-05-29 18:12:43

标签: python pip setuptools

我想创建一些非常易于使用的pip包,用于在Python中加载常见的机器学习数据集。 (是的,有些东西已经存在,但我希望它更简单。)

我想要实现的目标是:

  • 用户运行pip install dataset
  • pip下载数据集,例如通过wget http://mydata.com/data.tar.gz。请注意,数据不会驻留在python包本身,而是从其他地方下载。
  • pip从这个文件中提取数据并将其放入安装包的目录中。(这不太理想,但数据集非常小,所以我们假设在这里存储数据并不是什么大问题。)
  • 稍后,当用户导入我的模块时,模块会自动从特定位置加载数据。

这个问题是关于子弹2和3.有没有办法用setuptools做到这一点?

3 个答案:

答案 0 :(得分:1)

正如凯文所提到的,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模块中关于在运行时下载必要的解码器的行为,而不是让用户自己管理外部下载。

答案 1 :(得分:0)

Python包安装声明它永远不应该执行Python代码以安装Python包。这意味着您可能无法在安装过程中下载内容。

如果您想下载一些其他数据,请在安装软件包后执行此操作,例如,在导入软件包时,您可以下载此数据并将其缓存到某个位置,以便在每次新导入时都不下载它。

答案 2 :(得分:0)

  

请注意,数据不会驻留在python包本身,而是从其他地方下载。

请不要这样做。

Python打包的重点是提供一种完全确定的,可重复的,可重复使用的方法,每次完全相同的安装。您的提案至少存在以下问题:

  • 最终用户可能会在计算机A上下载您的软件包,将其粘贴在拇指驱动器上,然后将其安装在没有互联网的计算机B上。
  • 网络上的数据可能会发生变化,这意味着安装相同精确套餐的两个人会得到不同的结果。
  • 提供数据的网站可能不复存在或unwisely change the URL,这意味着仍然拥有该套餐的人无法使用该网站。
  • 用户可能在互联网过滤器后面,你可能会得到一个无用的"这个页面被阻止" HTML文件而不是您期望的数据集。

相反,您应该将数据包含在包中(使用setup()的{​​{3}}参数),或者在Python代码中提供单独的顶级函数来手动下载数据。用户已准备好这样做。