在Google Cloud Functions安装自定义Python包时缺失package data
解决Google Cloud Function安装自定义命名空间包时丢失数据文件的问题
核心原因分析
本地开发环境安装(比如pip install -e .)会直接读取本地文件系统内容,但Google Cloud Function(GCF)安装时会从源码分发包(sdist)提取文件,sdist的文件列表由MANIFEST.in控制,仅靠setup.py里的package_data可能无法让数据文件进入sdist包。另外,命名空间包(尤其是PEP 420风格的无__init__.py结构)对资源文件的处理逻辑和普通包略有差异。
分步解决方案
1. 确保MANIFEST.in正确配置
创建或修改项目根目录下的MANIFEST.in,明确包含需要打包的数据文件。比如你的命名空间是my_namespace,子包my_subpackage下有data/目录的txt、csv文件,写法如下:
include my_namespace/my_subpackage/data/*.txt recursive-include my_namespace/my_subpackage/data *.csv *.json
include用于指定单个或匹配模式的文件recursive-include用于递归包含某个目录下的所有匹配文件
2. 调整setup.py的配置
针对命名空间包,推荐结合find_namespace_packages和include_package_data=True,而非仅依赖package_data:
from setuptools import setup, find_namespace_packages setup( name="my-namespace-package", version="0.1.0", packages=find_namespace_packages(include=["my_namespace.*"]), include_package_data=True, # 自动读取MANIFEST.in的配置 # 若需精确指定package_data,可补充如下(可选) package_data={ "my_namespace.my_subpackage": ["data/*"], }, )
find_namespace_packages会自动发现命名空间下的所有子包include_package_data=True让setuptools根据MANIFEST.in包含数据文件,同时兼容package_data的配置
3. 本地验证sdist包的完整性
在本地生成源码包并验证数据文件是否被包含:
python setup.py sdist # 解压生成的tar.gz包(示例:dist/my-namespace-package-0.1.0.tar.gz) tar -xzf dist/my-namespace-package-0.1.0.tar.gz # 检查解压后的目录里是否存在目标数据文件 ls my-namespace-package-0.1.0/my_namespace/my_subpackage/data/
如果解压后的包里没有数据文件,说明MANIFEST.in配置有误,调整后重新生成sdist即可。
4. 确认GCF的安装源
如果你的包托管在PyPI或私有仓库,确保上传的是最新的sdist包;如果是通过requirements.txt指向GitHub等源码仓库,确保仓库已提交正确的MANIFEST.in和setup.py修改。
关键注意事项
- 不要依赖
pip install -e .的行为判断包的完整性,必须通过sdist包验证 - PEP 420风格的命名空间包(无
__init__.py)必须用find_namespace_packages,不能用普通的find_packages - 如果数据文件在命名空间根目录下,
MANIFEST.in要对应写成include my_namespace/*.txt
内容的提问来源于stack exchange,提问作者markrogersjr
相关产品推荐
相关产品推荐

