开源 Python 项目详细指南

开发 后端
作者以 SciTime 项目(一个对算法训练时间进行估计的包)的发布为例,详细解释了发布的每个步骤。

[[434539]]

 作者以 SciTime 项目(一个对算法训练时间进行估计的包)的发布为例,详细解释了发布的每个步骤。

注意:本文假设你在 GitHub 上已经有一个想要打包和发布的项目。

第 0 步:获取项目许可证

在做其他事之前,由于你的项目要开源,因此应该有一个许可证。获取哪种许可证取决于项目包的使用方式。开源项目中一些常见许可证有 MIT 或 BSD。

要在项目中添加许可证,只需参照以下链接中的步骤,将 LICENSE 文件添加到项目库中的根目录即可:https://help.github.com/en/articles/adding-a-license-to-a-repository

第 1 步:让你的代码准备就绪

要将项目进行打包,你需要做一些预备工作:

  • 让你的项目结构正确就位。通常情况下,项目库的根目录包含一个以项目名称命名的文件夹,项目的核心代码应该位于此文件夹中。在这个文件夹之外是运行和构建包(测试、文档等)所需的其他代码。
  •  核心文件夹应包括一个(或多个)模块和一个 __init__.py 文件,该文件包含你希望让终端用户访问的类/函数。此文件还可以包含包的版本,以便于终端用户访问。
  •  理想情况下,应使用 logging 包来设置合理的日志记录系统(而不是用 prints 输出)。
  •  理想情况下,应将你的核心代码分配到一个或多个类中。 
  1. from .estimate import Estimator 

以__init__.py 为例,如果 Estimator 是终端用户将会访问的类(该类在 estimate.py 文件中定义) 

  1. import logging  
  2. class LogMixin(object):  
  3.     @property  
  4.     def logger(self):  
  5.         name =  . .join([self.__module__, self.__class__.__name__])  
  6.         FORMAT =  %(name)s:%(levelname)s:%(message)s   
  7.         logging.basicConfig(format=FORMATlevel=logging.DEBUG)  
  8.         logger = logging.getLogger(name)  
  9.         return logger 

以日志系统为例:LogMixin 类可以在其他任何类中使用

第 2 步:使用打包工具创建 setup.py

在你的项目有了一套结构之后,你应该在项目库的根目录下添加 setup.py 文件。这有助于所有发布和版本维护过程的自动化。以下是 setup.py 的例子(源代码:https://github.com/nathan-toubiana/scitime/blob/master/setup.py)。 

  1. from setuptools import setup  
  2. from os import path  
  3. DIR = path.dirname(path.abspath(__file__))  
  4. INSTALL_PACKAGES = open(path.join(DIR,  requirements.txt )).read().splitlines()  
  5. with open(path.join(DIR,  README.md )) as f:  
  6.     README = f.read()  
  7. setup(  
  8.     namescitime ,  
  9.     packages=[ scitime ],  
  10.     description="Training time estimator for scikit-learn algorithms" 
  11.     long_description=README 
  12.     long_description_content_typetext/markdown ,  
  13.     install_requires=INSTALL_PACKAGES 
  14.     version0.0.2 ,  
  15.     urlhttp://github.com/nathan-toubiana/scitime ,  
  16.     authorGabriel Lerner & Nathan Toubiana ,  
  17.     author_emailtoubiana.nathan@gmail.com ,  
  18.     keywords=[ machine-learning ,  scikit-learn ,  training-time ],  
  19.     tests_require=[  
  20.          pytest ,  
  21.          pytest-cov ,  
  22.          pytest-sugar   
  23.     ],  
  24.     package_data={  
  25.         # include json and pkl files  
  26.           : [ *.json ,  models/*.pkl ,  models/*.json ],  
  27.     },  
  28.     include_package_data=True 
  29.     python_requires>=3   

setup.py 文件的示例

几点注意事项:

  •  如果你的包有依赖项,处理这些依赖项的简单方法是在配置文件中通过 install_requires 参数来添加依赖项(如果列表很长,你可以像之前那样指向一个 requirement.txt 文件)。
  •  如果你希望在任何人安装包时(从项目库中)下载元数据,则应通过 package_data 参数来添加这些元数据。
  •  有关 setup() 函数的更多信息,请参见:https://setuptools.readthedocs.io/en/latest/setuptools.html

注意:第 3 步到第 6 步是可选的(但强烈推荐),但是如果你现在马上想发布你的包,可以直接跳到第 7 步。

第 3 步:设置本地测试和检查测试覆盖率

此时还没有完成,你的项目还应该有单元测试。尽管有许多框架能帮助你做到,但一种简单的方法是使用 pytest。所有测试都应该放在一个专用的文件夹中(例如名为 tests/或 testing 的文件夹)。在这个文件夹中放置你需要的所有测试文件,以便尽可能多地包含你的核心代码。下面是一个如何编写单元测试的示例。这里还有一个 SciTime 的测试文件。

一旦就位,你就可以通过在项目库的根目录运行 python -m pytest 在本地进行测试。

创建测试后,你还应该能估算覆盖率。这一点很重要,因为你希望尽可能多地测试项目中的代码量(以减少意外的 bug)。

很多框架也可以用于计算覆盖率,对于 SciTime,我们使用了 codecov。你可以通过创建.codecov.yml 文件来决定允许的最小覆盖率阈值,还可以通过创建.coveragerc 文件来决定要在覆盖率分析中包含哪些文件。 

  1. comment: false  
  2. coverage:  
  3.   status:  
  4.     project:  
  5.       default:  
  6.         target: auto  
  7.         threshold: 10%  
  8.     patch:  
  9.       default:  
  10.         target: auto  
  11.         threshold: 10% 

.codecov.yml 文件示例 

  1. [run]  
  2. branch = True  
  3. source = scitime  
  4. include = */scitime/*  
  5. omit =  
  6.     */_data.py  
  7.     */setup.py 

.coveragerc 文件示例

第 4 步:标准化语法和代码风格

你还需要确保你的代码遵循 PEP8 准则(即具有标准样式并且语法正确)。同样,有很多工具可以帮助你解决。这里我们用了 flake8。

第 5 步:创建一个合理的文档

现在你的项目已经测试过了,结构也很好了,是时候添加一个合理的文档。首先是要有一个好的 readme 文件,它会在你的 Github 项目库的根目录上显示。完成后,加上以下几点会更好:

由于 readme 文件应该相当综合,因此通常会有一个更详细的文档。你可以用 sphinx 来完成,然后在 readthedocs 上管理文档。与文档相关的文件通常放在 docs/文件夹中。sphinx 和 readthedocs 相关教程:https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html

包含标签和说明的项目库示例

第 6 步:创建持续集成

此时,你的项目离发布就绪不远了。但是,在每次提交之后,必须更新文档、运行测试以及检查样式和覆盖率似乎有点难以应付。幸运的是,持续集成(CI)可以帮助你完成。你可以在每次提交之后使用 GitHub 的 webhook 来自动执行所有的这些操作。以下是我们在 SciTime 中使用的一套 CI 工具:

  •  对于运行测试,我们使用了 travis ci 和 appveyor(用于 Windows 平台上的测试)。对于 Travis CI,除了在项目库上设置 webhook 之外,你还必须创建一个.travis.yml 文件,在该文件中,你不仅可以运行测试,还可以上传更新的覆盖率输出以及检查样式和格式。通过创建 appveyor.yml 文件,appveyor 也可以这样做。
  •  codecov 和 readthdocs 也有专用的 webhook 
  1. language: python  
  2. python:  
  3.   - "3.6"  
  4. # command to install dependencies  
  5. install:  
  6.   - pip install -r requirements.txt  
  7.   - pip install flake8  
  8.   - pip install pytest-cov  
  9.   - pip install codecov  
  10. # command to run tests  
  11. script:  
  12.   - python -m pytest --cov=scitime  
  13.   - ./build_tools/flake_diff.sh  
  14. after_success: 
  15.   - codecov 

.travis.yml 文件的示例:请注意,每次提交,测试都需要与检查测试覆盖率一起进行。但还有一个 flake8 检查(逻辑则在 flake_diff.sh 文件中定义:https://github.com/nathan-toubiana/scitime/blob/master/build_tools/flake_diff.sh) 

  1. environment:  
  2.   matrix:  
  3.     - PYTHON: "C:\Python36-x64"  
  4. install:  
  5.   # We need wheel installed to build wheels  
  6.   - "%PYTHON%\python.exe -m pip install -r requirements.txt"  
  7.   - "%PYTHON%\python.exe -m pip install pytest==3.2.1"  
  8. build: off  
  9. test_script:  
  10.   - "%PYTHON%\python.exe -m pytest" 

appveyor.yml 文件示例:这里我们只运行测试。

这将使更新项目库的整个过程更加容易。

集成 webhook 的提交历史记录示例

第 7 步:创建你的第一个 release 和 publication

此时,你即将发布的包应与以下类似: 

  1. your_package/  
  2.    __init__.py  
  3.    your_module.py  
  4. docs/  
  5. tests/  
  6. setup.py  
  7. travis.yml  
  8. appveyor.yml 
  9. .coveragerc  
  10. .codecov.yml  
  11. README.md  
  12. LICENSE  
  13. .github/  
  14.    CODE_OF_CONDUCT.md  
  15.    CONTRIBUTING.md  
  16.    PULL_REQUEST_TEMPLATE.md  
  17.    ISSUE_TEMPLATE/ 

现在可以发布了!首先要做的是在 GitHub 上创建你的第一个 release——这是为了在给定的时间点跟踪项目的状态,每次版本更改时都需要创建新的 release。创建步骤:https://help.github.com/en/articles/creating-releases

完成后,唯一要做的就是发布包。发布 python 包最常见的平台是 PyPI 和 Conda。以下我们将描述如何用两者发布:

  •  对于 PyPI,首先需要创建一个帐户,然后用 twine 执行一些步骤:https://realpython.com/pypi-publish-python-package/。这应该相当简单,而且 Pypi 还提供了一个可以在实际部署之前使用的测试环境。PyPI 总体上包括创建源代码(python setup.py sdist)并使用 twine(twine upload dist/*)来上传。完成后,应该有一个与你的包对应的 PyPI 页面,并且任何人都应该能够通过运行 pip 命令来安装你的包。
  • 对于 Conda,我们推荐通过 conda forge 来发布你的包,conda forge 是一个社区,帮助你通过 conda 渠道发布和维护包。你可以按照以下步骤将包添加到社区:https://conda-forge.org/#add_recipe,然后你会被添加到 conda forge Github 组织中,并能够非常轻松地维护你的包,然后任何人都可以通过运行 conda 命令来安装你的包。

完成!

现在,你的包应该已经发出去,并且任何人都可以使用了!虽然大部分工作都完成了,但是你仍然需要维护你的项目,你需要进行一些更新:这大体上意味着每次进行重大更改时都要更改版本,创建新的 release,并再次执行第 7 步。 

 

责任编辑:庞桂玉 来源: 恋习Python
相关推荐

2019-11-13 12:39:26

Python 开发编程语言

2021-02-20 17:36:30

Google开源项目漏洞

2022-05-26 07:42:22

Python编辑器VSCode

2010-02-23 09:22:36

Python项目

2022-05-16 15:37:32

开源软件

2021-07-07 09:00:00

分解式存储架构云服务

2018-06-28 12:47:30

2012-08-16 13:45:12

ERP产品采购

2024-03-01 19:53:37

PyBuilderPython开发

2018-11-14 10:36:47

Python 开发编程语言

2023-09-12 10:07:30

ML人工智能

2022-05-08 09:39:20

LinuxTee 命令

2022-11-30 08:00:00

金丝雀部署IT测试

2017-03-16 09:51:39

开源OdooSSD

2014-06-26 14:53:48

开源开源软件

2024-05-17 17:29:00

CurdlingPython开发

2018-12-17 13:52:47

Python开源项目数据可视化

2018-07-12 14:34:05

2010-02-06 16:30:25

C++内存对齐
点赞
收藏

51CTO技术栈公众号