如何实现单仓库多子目录发布PyPI包并共享Python导入基路径
实现单仓库多PyPI包共享命名空间的方案
你要实现的是Python命名空间包机制,和GitHub关系不大,核心是通过Python的包结构设计,让多个独立发布到PyPI的包共享同一个顶级导入路径,完全匹配Azure的包管理模式。
核心实现思路
通过PEP 420定义的隐式命名空间包,让多个独立PyPI包的子目录合并到同一个顶级命名空间下(比如azure),实现独立安装、共享导入的效果。
1. 仓库目录结构设计
在你的单仓库下,为每个要独立发布的PyPI包创建子目录,每个子目录内包含共享顶级命名空间的包结构:
my-monorepo/ ├── azure-keyvault-secrets/ │ ├── pyproject.toml │ └── azure/ │ └── keyvault/ │ ├── __init__.py │ └── secrets/ │ ├── __init__.py │ └── client.py └── azure-mgmt-resource/ ├── pyproject.toml └── azure/ └── mgmt/ ├── __init__.py └── resource/ ├── __init__.py └── client.py
- 重点:所有子包内的
azure目录不要添加__init__.py,这是PEP 420隐式命名空间的关键,Python会自动合并不同包中的azure命名空间。 - 每个子目录对应一个独立的PyPI包,比如
azure-keyvault-secrets对应PyPI上的同名包。
2. 单个子包的打包配置
每个子目录下需要单独的pyproject.toml(或setup.py),配置独立的包信息:
以azure-keyvault-secrets/pyproject.toml为例:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "azure-keyvault-secrets" version = "1.0.0" packages = ["azure.keyvault.secrets"] dependencies = ["azure-core>=1.24.0"] # 可补充作者、描述、许可证等其他配置
packages指定当前包要打包的子模块,setuptools会自动识别并处理命名空间。
3. 独立发布到PyPI
每个子包单独构建和发布,进入对应子目录执行命令:
# 构建包 python -m build # 发布到PyPI(需提前配置twine的PyPI账号) python -m twine upload dist/*
执行完成后,用户就能通过pip install azure-keyvault-secrets或pip install azure-mgmt-resource单独安装每个包。
4. 导入验证
安装任意一个或多个包后,即可在Python代码中共享顶级命名空间导入:
from azure.keyvault.secrets import SecretClient from azure.mgmt.resource import ResourceManagementClient
和Git Submodules的区别
Git Submodules是仓库层面的拆分,用于将多个独立仓库嵌入到主仓库中;而你的需求是在同一个仓库内管理多个独立PyPI包,核心依赖Python的命名空间机制实现导入路径共享,和Git的子模块功能无关。
注意事项
- 若需要兼容Python 3.3以下版本,需使用
pkgutil显式命名空间:在每个子包的azure/__init__.py中添加__path__ = __import__('pkgutil').extend_path(__path__, __name__)。 - 可以编写自动化脚本(比如Makefile或Python脚本),批量遍历所有子包目录,自动完成构建和发布流程。
内容的提问来源于stack exchange,提问作者Bigya Pradhan
相关产品推荐
相关产品推荐

