【问题标题】:google app engine - how to add lib folder?谷歌应用引擎 - 如何添加 lib 文件夹?
【发布时间】:2016-01-07 18:32:23
【问题描述】:

我不断收到 ImportError: No module named twitter 当它在我的 lib 模块中时

详情:

  1. twitter 模块位于 lib 目录中。
  2. lib 目录有一个空的 init.py
  3. 我在目录外的页面上收到错误
  4. 当我将 twitter 模块从 lib 目录中取出并说 import twitter 时,它可以工作
  5. 当我将 twitter 模块放回 lib 并说 from lib import twitter,或者当我说 import twitter 或 import lib.twitter 时,它说,去 **** 并喜欢它
  6. 我尝试这样做:https://cloud.google.com/appengine/docs/python/tools/libraries27?hl=en,这表明:

要告诉您的应用如何在此目录中查找库,请在项目的根目录中创建(或修改)名为 appengine_config.py 的文件,然后添加以下行:

from google.appengine.ext import vendor

# Add any libraries installed in the "lib" folder.
vendor.add('lib')

然后尝试 import twitter,然后尝试 from lib import twitter,它说,“哈哈,不错的尝试。”

现在呢?

【问题讨论】:

  • 我不认为lib 应该是一个模块/包,它应该只是一个包含其他模块/包的目录(如果这与您的问题有关,请不要这样做)。准确显示您的应用程序的目录结构和导致错误的代码片段可能是一个好主意。也最好显示引用的错误,而不是描述。你的应用是多模块的吗?
  • 你用“vendor.add('lib')”得到了最后一点,但你应该只是“import twitter”,vendor.add 添加到你的python路径,'lib'是不是模块或包。

标签: python google-app-engine twitter


【解决方案1】:

tl;dr - cmets 是对的。 'lib' 不是一个模块,它是一个包含模块的文件夹。它需要位于您的 Python 导入路径之前,使用 vendor.add('lib'),当您部署或使用 dev_appserver.py 时,它应该正确设置您的导入路径。如果你将vendor.add(lib) sn-p 放在appengine_config.py 文件中并运行dev_appserver.py 或部署,并且twitter 模块在lib 中,你应该可以import twitter。如果您在 App Engine/devappserver 之外运行,则需要确保 lib 在 PYTHONPATH 上。

这里是lib 文件夹的详细解释;什么是贩卖;以及它们如何适应管理 App Engine 依赖关系的大局。

使用 App Engine,您可以在 app.yaml 中指定沙盒提供的一些依赖项。您可以查看可用库列表here。对于任何其他依赖项(只能是纯 Python 库),这些库需要直接包含在您的项目中。将这些依赖项的代码直接包含在项目中(而不是仅仅将它们列在 requirements.txt 中并期望它们在部署时安装)通常称为“供应商”。

现在,即使我们直接包含依赖项,我们也宁愿只使用 pip 和 requirements.txt,原因我将在下面提到。但是 pip 通常用于将库安装到系统库或 virtualenv 中,而不是安装到项目本身中。因此,向 pip 添加了一项功能,并向 App Engine 添加了一项功能来解决此问题。

pip 功能将依赖项安装到文件夹而不是系统库或 virtualenv 中。您可以像这样使用 -t 标志:

pip install -r requirements.txt -t lib

其中“lib”是要安装到的文件夹。这样,您仍然可以在 requirements.txt 中指定您的依赖项,并使用 pip 安装它们,它们只是直接安装到指定的目录中。正如 cmets 所指出的,lib 文件夹本身不是一个模块 - 它只是包含它们。所以你的lib文件夹不应该有__init__.py,它应该只包含一个像'twitter'这样的文件夹,它有一个__init__.py。由于lib 不是模块,from lib import twitter 实际上没有意义。另请注意,lib 是一个任意名称,但我们通常按照惯例选择该名称。

使用 pip 供应商有几个很大的优势,而不仅仅是手动下载依赖项并将它们添加到项目中。一个优点是您不需要将依赖项检查到源代码控制中 - 只需添加 requirements.txt,并告诉其他用户也使用 pip -t 命令来提供依赖项。另一个优点是它更有条理,可以将您的代码与第三方模块清晰地分开。供应商功能的重点是保持这些优势,同时仍遵循 App Engine 要求,在部署时将依赖项包含在目录中。

您使用的 App Engine 供应商扩展程序用于识别文件夹包含已“供应”的模块并将其添加到路径中。那是您在 sn-p 中使用的供应商扩展。它确保lib 文件夹位于您的导入路径中,以便您可以将安装的模块导入其中。

运行 vendor.add 命令后,您应该能够将模块导入 lib 文件夹中。正如评论所指出的,您需要确保它在之前 import twitter 运行。一个好的做法是确保这些供应商命令先于其他任何东西运行。您可以通过将该代码放入目录中名为appengine_config.py 的文件中来完成此操作。这是一个在其他任何东西之前运行的特殊文件。看一个这样做的例子here

最后几点可能会有所帮助:

  • appengine_config.py 将在 GAE 环境中运行,或者在您运行模拟 GAE 环境的 dev_appserver 时运行。但是,如果您曾经在 GAE 环境之外运行,请确保您的 PYTHONPATH 包含您要从中导入的 lib 文件夹。
  • 既然您可以使用 pip 供应库,您可能会问为什么要使用 app.yaml 包含依赖项?答案是,由于只能出售纯 Python 库,因此对于任何需要 C 库的库(例如 MySQL),您仍然应该使用 app.yaml 依赖项。
  • 如果您有供应商的库和 app.yaml 库,您不希望供应将在 GAE 沙箱中的库,因为版本可能会发生冲突。在这种情况下,最好有一个单独的 requirements.txt 用于您想要供应商的依赖项,以及您希望仅在本地运行时包含的依赖项,但 GAE 将在沙箱中提供。 Here 是 MySQL 的一个例子。

【讨论】:

  • pip install -r requirements.txt -t lib 和导航到 lib 文件夹并执行 pip install <a third party module> -t . 有什么区别?
  • 两个不同之处。首先是你没有使用 requirements.txt,所以如果一个新的开发者克隆了你的 repo,他们怎么知道要安装什么? requirements.txt 是列出运行项目所需的所有依赖项的标准方式。第二个区别是您要安装到当前目录 (.) 而不是 lib/。这可能会为您简化事情,因为您根本不需要使用供应商扩展来更改导入路径。如果您愿意,那也可以,但 lib 文件夹的目的是明确区分哪些模块是第三方的。
  • 我刚刚注意到您说“导航到 lib 文件夹”。在这种情况下,文件夹结构或需要设置导入路径没有区别。您只是从不同的目录安装到 lib 中。
  • @biil-prin 太棒了,我刚刚读了一些 pip.readthedocs.org/en/1.1/requirements.html 。我很高兴你指出了克隆的情况。谢谢! :)
  • 乐于助人。最后一个技巧你可能会觉得有用。如果您键入“pip freeze”,它将列出您已安装的所有模块。如果你在 virtualenv 中工作(强烈推荐),你只安装你需要的,然后你可以输入 pip freeze > requirements.txt 来自动生成文件。
【解决方案2】:
  1. 创建一个名为“libs”的文件夹(在您的 webapp 的主目录中)
  2. 如果只有一个库,那么只需执行以下操作:pip install -t libs/ your_library_name
  3. 如果有多个库,请执行以下操作: pip freeze > requirements.txt, pip install -r requirements.txt -t libs
  4. 现在,创建一个名为 appengine_config.py 的文件(再次在主目录中)
  5. 在上述文件中,添加: from google.appengine.ext import vendor vendor.add('libs')

这些会上传到您的应用引擎环境中,您就可以运行它了!

【讨论】:

  • 注意,我认为这一切都适用于 appengine python 2.7,而不是 python 3。
猜你喜欢
  • 2015-01-02
  • 2015-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 2011-05-06
  • 1970-01-01
相关资源
最近更新 更多