2021年发布Python软件包的正确姿势

本文转载自微信公众号「Python中文社区」,作者Anton  。转载本文请联系Python中文社区公众号。  

如果您像我一样,偶尔编写一个有用的python实用小程序,并希望与您的同事共享。做到这一点的最好方法是制作一个Python软件包:它易于安装,并且可以避免进行拷贝操作。

您可能会认为创建软件包很麻烦。其实现在已经不会这样了。我将通过此分步指南进行说明。只需执行三个主要步骤(以及一系列可选步骤),并辅以几个GitHub链接即可。

1.初始化

我们将创建podsearch - 一种在iTunes中搜索播客的实用程序。让我们创建一个目录和一个虚拟环境:

 
 
 
 
  1. $ mkdir podsearch 
  2. $ cd podsearch 
  3. $ python3 -m venv env 
  4. $ . env/bin/activate 

定义一个最小的包结构:

 
 
 
 
  1. ├── .gitignore 
  2. └── podsearch 
  3.     └── __init__.py 
  4. """Let's find some podcasts!""" 
  5.  
  6.  __version__ = "0.1.0" 
  7.  
  8.  
  9.  def search(name, count=5): 
  10.      """Search podcast by name.""" 
  11.      raise NotImplementedError() 

2.测试包

用Python创建一个包曾经是一个麻烦的任务。幸运的是,如今有一个很棒的 flit (https://flit.readthedocs.io/en/latest/)小程序可以简化所有操作。让我们安装它:

 
 
 
 
  1. pip install flit 

并创建软件包描述:

 
 
 
 
  1. $ flit init 
  2. Module name [podsearch]: 
  3. Author [Anton Zhiyanov]: 
  4. Author email [m@antonz.org]: 
  5. Home page [https://github.com/nalgeon/podsearch-py]: 
  6. Choose a license (see http://choosealicense.com/ for more info) 
  7. 1. MIT - simple and permissive 
  8. 2. Apache - explicitly grants patent rights 
  9. 3. GPL - ensures that code based on this is shared with the same terms 
  10. 4. Skip - choose a license later 
  11. Enter 1-4 [1]: 1 
  12.  
  13. Written pyproject.toml; edit that file to add optional extra info. 

pyproject.toml

Flit已创建pyproject.toml - 项目元数据文件。它已经具有将程序包发布到公共存储库-PyPI所需的一切。

注册TestPyPi(测试存储库)和PyPI(主要存储库)。它们是完全独立的,因此您将需要两个帐户。

在~/ .pypirc中设置对存储库的访问权限:

 
 
 
 
  1. [distutils] 
  2. index-servers = 
  3.   pypi 
  4.   pypitest 
  5.  
  6. [pypi] 
  7. username: nalgeon  # replace with your PyPI username 
  8.  
  9. [pypitest] 
  10. repository: https://test.pypi.org/legacy/ 
  11. username: nalgeon  # replace with your TestPyPI username 

并将软件包发布到测试存储库:

 
 
 
 
  1. $ flit publish --repository pypitest 
  2. Found 4 files tracked in git 
  3. ... 
  4. Package is at https://test.pypi.org/project/podsearch/ 

完毕!该软件包可在TestPyPi上获得。

3.公开软件包

让我们改进代码,以便它能够实际搜索播客:

 
 
 
 
  1. # ... 
  2.  
  3. SEARCH_URL = "https://itunes.apple.com/search" 
  4.  
  5. @dataclass 
  6. class Podcast: 
  7.     """Podcast metadata.""" 
  8.  
  9.     id: str 
  10.     name: str 
  11.     author: str 
  12.     url: str 
  13.     feed: Optional[str] = None 
  14.     category: Optional[str] = None 
  15.     image: Optional[str] = None 
  16.  
  17.  
  18. def search(name: str, limit: int = 5) -> List[Podcast]: 
  19.     """Search podcast by name.""" 
  20.     params = {"term": name, "limit": limit, "media": "podcast"} 
  21.     response = _get(url=SEARCH_URL, params=params) 
  22.     return _parse(response) 

并发布到主存储库-PyPI。仅在您的程序包中包含有用的代码后,才执行此步骤。不要发布无效的程序包和存根。

 
 
 
 
  1. flit publish 

发布完毕!是时候与同事分享了。为了使软件包易于使用,我建议您再执行以下几个步骤。

A.自述文件Readme和变更日志changelog

没人喜欢写文档。但是,如果没有文档,人们不太可能会想要安装您的软件包,因此我们需要添加README.md和CHANGELOG.md。

  • README.md
  • CHANGELOG.md

将README添加到pyproject.toml,以便PyPI在软件包页面上显示它:

 
 
 
 
  1. description-file = "README.md" 

还要指定受支持的最低Python版本:

 
 
 
 
  1. requires-python = ">=3.7" 

更新__init__.py中的版本,并通过flit publish发布软件包:

B.Linters和tests

我们来考虑一下格式设置(black),测试覆盖率(coverage),代码质量(flake8,pylint,mccabe)和静态分析(mypy)。我们将通过tox处理一切。

 
 
 
 
  1. $ pip install black coverage flake8 mccabe mypy pylint pytest tox 

在tox.ini中创建tox配置:

 
 
 
 
  1. [tox] 
  2. isolated_build = True 
  3. envlist = py37,py38,py39 
  4.  
  5. [testenv] 
  6. deps = 
  7.     black 
  8.     coverage 
  9.     flake8 
  10.     mccabe 
  11.     mypy 
  12.     pylint 
  13.     pytest 
  14. commands = 
  15.     black podsearch 
  16.     flake8 podsearch 
  17.     pylint podsearch 
  18.     mypy podsearch 
  19.     coverage erase 
  20.     coverage run --include=podsearch/* -m pytest -ra 
  21.     coverage report -m 

tox.ini

并运行所有检查:

 
 
 
 
  1. $ tox -e py39 
  2. ... 
  3. py39 run-test: commands[0] | black podsearch 
  4. All done!  
  5. ... 
  6. py39 run-test: commands[2] | pylint podsearch 
  7. Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00) 
  8. ... 
  9. py39 run-test: commands[6] | coverage report -m 
  10. TOTAL 100% 
  11. ... 
  12. py39: commands succeeded 
  13. congratulations :) 

linters检测通过,测试也通过了,覆盖率是100%。

C.云构建

每个可靠的开源项目在每次提交后都会进行云测试,因此我们也将这样做。一个很好的附加效果是自述文件中有漂亮的徽章。

让我们使用GitHub Actions构建项目,使用Codecov检查测试覆盖率,并使用Code Climate检查代码质量。

您将必须注册Codecov和Code Climate(均支持GitHub登录)并在设置中启用软件包存储库。

之后,将GitHub Actions构建配置添加到.github / workflows / build.yml:

 
 
 
 
  1. # ... 
  2. jobs: 
  3.     build: 
  4.         runs-on: ubuntu-latest 
  5.         strategy: 
  6.             matrix: 
  7.                 python-version: [3.7, 3.8, 3.9] 
  8.  
  9.         env: 
  10.             USING_COVERAGE: "3.9" 
  11.  
  12.         steps: 
  13.             - name: Checkout sources 
  14.               uses: actions/checkout@v2 
  15.  
  16.             - name: Set up Python 
  17.               uses: actions/setup-python@v2 
  18.               with: 
  19.                   python-version: $ 
  20.  
  21.             - name: Install dependencies 
  22.               run: | 
  23.                   python -m pip install --upgrade pip 
  24.                   python -m pip install black coverage flake8 flit mccabe mypy pylint pytest tox tox-gh-actions 
  25.  
  26.             - name: Run tox 
  27.               run: | 
  28.                   python -m tox 
  29.  
  30.             - name: Upload coverage to Codecov 
  31.               uses: codecov/codecov-action@v1 
  32.               if: contains(env.USING_COVERAGE, matrix.python-version) 
  33.               with: 
  34.                   fail_ci_if_error: true 

build.yml

就像我们前面一样,GitHub通过tox进行测试。tox-gh-actions软件包和USING_COVERAGE设置可确保tox使用与strategy.matrix所需的 GitHub Actions 相同的 Python 版本。

最后一步将测试覆盖率发送给Codecov。Code Climate不需要单独的步骤-它会自动发现存储库更改。

现在,一分钟内提交,推送并享受结果。并且让每个人也喜欢向README.md添加徽章:

 
 
 
 
  1. [![PyPI Version][pypi-image]][pypi-url] 
  2. [![Build Status][build-image]][build-url] 
  3. [![Code Coverage][coverage-image]][coverage-url] 
  4. [![Code Quality][quality-image]][quality-url] 
  5.  
  6. ... 
  7.  
  8.  
  9.  
  10. [pypi-image]: https://img.shields.io/pypi/v/podsearch 
  11. [pypi-url]: https://pypi.org/project/podsearch/ 
  12. [build-image]: https://github.com/nalgeon/podsearch-py/actions/workflows/build.yml/badge.svg 
  13. [build-url]: https://github.com/nalgeon/podsearch-py/actions/workflows/build.yml 
  14. [coverage-image]: https://codecov.io/gh/nalgeon/podsearch-py/branch/main/graph/badge.svg 
  15. [coverage-url]: https://codecov.io/gh/nalgeon/podsearch-py 
  16. [quality-image]: https://api.codeclimate.com/v1/badges/3130fa0ba3b7993fbf0a/maintainability 
  17. [quality-url]: https://codeclimate.com/github/nalgeon/podsearch-py 

是不是很酷?

D.任务自动化

tox很好,但对于开发来说不是很方便。运行单个命令(例如pylint,coverage等)的速度更快。但是它们非常冗长,因此我们将一些无意义的操作进行自动化处理。

让我们为Makefile的频繁操作创建简短的别名:

 
 
 
 
  1. .DEFAULT_GOAL := help 
  2. .PHONY: coverage deps help lint push test 
  3.  
  4. coverage:  ## Run tests with coverage 
  5.  coverage erase 
  6.  coverage run --include=podsearch/* -m pytest -ra 
  7.  coverage report -m 
  8.  
  9. deps:  ## Install dependencies 
  10.  pip install black coverage flake8 mccabe mypy pylint pytest tox 
  11.  
  12. lint:  ## Lint and static-check 
  13.  flake8 podsearch 
  14.  pylint podsearch 
  15.  mypy podsearch 
  16.  
  17. push:  ## Push code with tags 
  18.  git push && git push --tags 
  19.  
  20. test:  ## Run tests 
  21.  pytest -ra 

Makefile

这是我们的任务:

 
 
 
 
  1. $ make help 
  2. Usage: make [task] 
  3.  
  4. task                 help 
  5. ------               ---- 
  6. coverage             Run tests with coverage 
  7. deps                 Install dependencies 
  8. lint                 Lint and static-check 
  9. push                 Push code with tags 
  10. test                 Run tests 
  11. help                 Show help message 

为了使代码更简洁,请使用make调用替换原始的build.yml步骤:

 
 
 
 
  1. - name: Install dependencies 
  2.   run: | 
  3.       make deps 
  4.  
  5. - name: Run tox 
  6.   run: | 
  7.       make tox 

E.云发布

GitHub有能力为我们运行flit publish。让我们创建一个单独的工作流程:

 
 
 
 
  1. name: publish 
  2.  
  3. on: 
  4.     release: 
  5.         types: [created] 
  6.  
  7. jobs: 
  8.     publish: 
  9.         runs-on: ubuntu-latest 
  10.         steps: 
  11.             - name: Checkout sources 
  12.               uses: actions/checkout@v2 
  13.  
  14.             - name: Set up Python 
  15.               uses: actions/setup-python@v2 
  16.               with: 
  17.                   python-version: "3.9" 
  18.  
  19.             - name: Install dependencies 
  20.               run: | 
  21.                   make deps 
  22.  
  23.             - name: Publish to PyPi 
  24.               env: 
  25.                   FLIT_USERNAME: ${{ secrets.PYPI_USERNAME }} 
  26.                   FLIT_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 
  27.               run: | 
  28.                   make publish 

publish.yml

在存储库设置(Settings > Secrets > New repository secret)中设置了PYPI_USERNAME和PYPI_PASSWORD。使用您的PyPi用户名和密码,甚至更好的-API令牌。

现在,一旦创建新版本,GitHub将自动发布该软件包。

您的软件包已准备就绪!它具有人们梦寐以求的一切:干净的代码,清晰的文档,测试和云构建。是时候告诉你的同事和朋友了。

这些设置将使您的 Python 软件包变得AWESOME:

  • pyproject.toml
  • tox.ini
  • Makefile
  • build.yml
  • publish.yml 

文章题目:2021年发布Python软件包的正确姿势
网站路径:http://www.shufengxianlan.com/qtweb/news23/378723.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联