使用所有包依赖项部署Python云函数

4
我希望部署一个云函数,不依赖于使用 requirements.txt 安装包。我希望这些包在存储中可用,或者被压缩并作为函数的一部分上传。这种情况是否可能?
编辑 6/14/2019:
基本上,我想发送像 numpy 和 pandas 这样的包与我的代码一起部署云函数。我想在 pypi.org 不可用的情况下这样做。我已经尝试遵循 documentation 的说明。下面是我想要做的示例:
文件夹结构:
-> my_folder
    -> main.py
    -> libs
        -> numpy (the entire package)
        -> pandas (the entire package)
        -> __init__.py

main.py

import libs.numpy as np
import libs.pandas as pd

def function()
    do stuff with numpy and pandas

我尝试使用gcloud命令行和gcp UI部署函数,但均失败。如果可能,请帮忙。

1个回答

7
目前只有两种选项:
  1. 使用 requirements.txt 文件
  2. 将依赖项与您的函数一起打包,链接在此处
它们不能被压缩到存储中,它们将被视为函数源代码的一部分。
如果选择第二个选项,则参数 -t libs 可能会对你有所帮助。您可以使用它来安装所有内容到一个名为 libs 的文件夹中,然后将内容移动到本地目录即可。作为一个单独的命令,它看起来像这样:
pip install -t libs [your library name(s)] && rm -rf libs/*.dist-info && mv -r libs/* . && rm -rf libs

我添加了rm -rf libs/*.dist-info部分是为了避免在源文件夹中污染大量无用的库版本和分发信息,这些信息在冻结和计划更新时由pip使用。 编辑于2019年6月14日 您将库保存在libs文件夹中。这是我上面添加的一行代码mv -r libs/* .之前的位置。
使用libs文件夹可以使一切更有组织性,因此如果您想要将包保留在那里,则需要将该文件夹添加到main.py的所有其他导入之前,作为供应商。
# Vendoring packages from libs folder
import sys
import os
sys.path.insert(1, os.path.join(
    os.path.dirname(os.path.realpath(__file__)),
    "libs"
))
# All other imports go below this line

解释:

__file__是每个模块都有的全局变量,它保存了定义模块的文件路径,也就是使用它的文件路径,对于我们来说,是main.py的路径。

因为我们无法确定在导入main.py时的工作目录,所以我们将其传递给os.path.realpath以确保路径结构。也可以使用os.path.abspath,我看过并使用了这两种方法,没有注意到任何区别。

从文件路径中,我们使用os.path.dirname获取源代码目录的路径,然后使用os.path.join转到其中的libs文件夹。

现在最重要的部分。当您尝试导入包时,Python会在系统/Python路径上查找它们。因此,我们将我们建立的libs全路径添加为系统路径中的第一个查找位置(在您的工作目录之后)。新的导入语句将首先在该文件夹中查找,如果该包不存在,则按照其他查找目录正常进行。
如果您希望仅在系统和Python环境中找不到包时才在libs中查找包,请将libs路径附加到sys.path末尾而不是插入到第一个位置。

之后您无需在导入中添加libs.前缀,只需使用正常的import numpy即可。

对于完全独立的包,这可能有效,但对于具有依赖项的包,则无法正常工作,因为它们期望其依赖项可以直接从sys.path的任何位置进行导入。


我想我可能漏掉了什么。那么我该如何在云函数上部署它呢? - not_a_comp_scientist
它不会改变。使用相同的 gcloud functions deploy 命令和您的部署参数,gcloud 将在构建源代码压缩包并部署时将库包含为源代码的一部分。 - Luiz Ferraz
我尝试了你的建议,但失败了。如果您有兴趣,我已经编辑了原始问题并添加了更多上下文。无论如何,我都非常感谢您的帮助。 - not_a_comp_scientist
这就是为什么需要mv -r libs/* .命令。我会编辑我的答案来解释。 - Luiz Ferraz
谢谢你的帮助。在你进一步解释后,我现在更好地理解了你原来的回复的意思。我尝试了你所做的事情,但是我得到了以下错误 File "/user_code/numpy/core/overrides.py", line 6, in <module> from numpy.core._multiarray_umath import ( ModuleNotFoundError: No module named 'numpy.core._multiarray_umath'。我想numpy模块出了问题,这很奇怪,因为当我在本地运行它时,它可以正常工作。 - not_a_comp_scientist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接