2021 年發(fā)布 Python 軟件包的正確姿勢!
podsearch - 一種在iTunes中搜索播客的實用程序。讓我們創(chuàng)建一個目錄和一個虛擬環(huán)境:$ mkdir podsearch
$ cd podsearch
$ python3 -m venv env
$ . env/bin/activate
.
├── .gitignore
└── podsearch
└── __init__.py
"""Let's find some podcasts!"""
__version__ = "0.1.0"
def search(name, count=5):
"""Search podcast by name."""
raise NotImplementedError()
https://flit.readthedocs.io/en/latest/)小程序可以簡化所有操作。讓我們安裝它:pip install flit
$ flit init
Module name [podsearch]:
Author [Anton Zhiyanov]:
Author email [[email protected]]:
Home page [https://github.com/nalgeon/podsearch-py]:
Choose a license (see http://choosealicense.com/ for more info)
1. MIT - simple and permissive
2. Apache - explicitly grants patent rights
3. GPL - ensures that code based on this is shared with the same terms
4. Skip - choose a license later
Enter 1-4 [1]: 1
Written pyproject.toml; edit that file to add optional extra info.
pyproject.toml
pyproject.toml - 項目元數(shù)據(jù)文件。它已經具有將程序包發(fā)布到公共存儲庫-PyPI所需的一切。TestPyPi(測試存儲庫)和PyPI(主要存儲庫)。它們是完全獨立的,因此您將需要兩個帳戶。~/ .pypirc中設置對存儲庫的訪問權限:[distutils]
index-servers =
pypi
pypitest
[pypi]
username: nalgeon # replace with your PyPI username
[pypitest]
repository: https://test.pypi.org/legacy/
username: nalgeon # replace with your TestPyPI username
$ flit publish --repository pypitest
Found 4 files tracked in git
...
Package is at https://test.pypi.org/project/podsearch/
TestPyPi上獲得。
# ...
SEARCH_URL = "https://itunes.apple.com/search"
@dataclass
class Podcast:
"""Podcast metadata."""
id: str
name: str
author: str
url: str
feed: Optional[str] = None
category: Optional[str] = None
image: Optional[str] = None
def search(name: str, limit: int = 5) -> List[Podcast]:
"""Search podcast by name."""
params = {"term": name, "limit": limit, "media": "podcast"}
response = _get(url=SEARCH_URL, params=params)
return _parse(response)
flit publish
Readme和變更日志changelogREADME.md和CHANGELOG.md。README.mdCHANGELOG.md
pyproject.toml,以便PyPI在軟件包頁面上顯示它:description-file = "README.md"
requires-python = ">=3.7"
__init__.py中的版本,并通過flit publish發(fā)布軟件包:
Linters和testsblack),測試覆蓋率(coverage),代碼質量(flake8,pylint,mccabe)和靜態(tài)分析(mypy)。我們將通過tox處理一切。$ pip install black coverage flake8 mccabe mypy pylint pytest tox
tox.ini中創(chuàng)建tox配置:[tox]
isolated_build = True
envlist = py37,py38,py39
[testenv]
deps =
black
coverage
flake8
mccabe
mypy
pylint
pytest
commands =
black podsearch
flake8 podsearch
pylint podsearch
mypy podsearch
coverage erase
coverage run --include=podsearch/* -m pytest -ra
coverage report -m
tox.ini$ tox -e py39
...
py39 run-test: commands[0] | black podsearch
All done!
...
py39 run-test: commands[2] | pylint podsearch
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
...
py39 run-test: commands[6] | coverage report -m
TOTAL 100%
...
py39: commands succeeded
congratulations :)
GitHub Actions構建項目,使用Codecov檢查測試覆蓋率,并使用Code Climate檢查代碼質量。Codecov和Code Climate(均支持GitHub登錄)并在設置中啟用軟件包存儲庫。.github / workflows / build.yml:# ...
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
env:
USING_COVERAGE: "3.9"
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: $
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install black coverage flake8 flit mccabe mypy pylint pytest tox tox-gh-actions
- name: Run tox
run: |
python -m tox
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
if: contains(env.USING_COVERAGE, matrix.python-version)
with:
fail_ci_if_error: true
build.ymltox進行測試。tox-gh-actions軟件包和USING_COVERAGE設置可確保tox使用與strategy.matrix所需的 GitHub Actions 相同的 Python 版本。Codecov。Code Climate不需要單獨的步驟-它會自動發(fā)現(xiàn)存儲庫更改。README.md添加徽章:[![PyPI Version][pypi-image]][pypi-url]
[![Build Status][build-image]][build-url]
[![Code Coverage][coverage-image]][coverage-url]
[![Code Quality][quality-image]][quality-url]
...
<!-- Badges -->
[pypi-image]: https://img.shields.io/pypi/v/podsearch
[pypi-url]: https://pypi.org/project/podsearch/
[build-image]: https://github.com/nalgeon/podsearch-py/actions/workflows/build.yml/badge.svg
[build-url]: https://github.com/nalgeon/podsearch-py/actions/workflows/build.yml
[coverage-image]: https://codecov.io/gh/nalgeon/podsearch-py/branch/main/graph/badge.svg
[coverage-url]: https://codecov.io/gh/nalgeon/podsearch-py
[quality-image]: https://api.codeclimate.com/v1/badges/3130fa0ba3b7993fbf0a/maintainability
[quality-url]: https://codeclimate.com/github/nalgeon/podsearch-py

tox很好,但對于開發(fā)來說不是很方便。運行單個命令(例如pylint,coverage等)的速度更快。但是它們非常冗長,因此我們將一些無意義的操作進行自動化處理。Makefile的頻繁操作創(chuàng)建簡短的別名:.DEFAULT_GOAL := help
.PHONY: coverage deps help lint push test
coverage: ## Run tests with coverage
coverage erase
coverage run --include=podsearch/* -m pytest -ra
coverage report -m
deps: ## Install dependencies
pip install black coverage flake8 mccabe mypy pylint pytest tox
lint: ## Lint and static-check
flake8 podsearch
pylint podsearch
mypy podsearch
push: ## Push code with tags
git push && git push --tags
test: ## Run tests
pytest -ra
Makefile
$ make help
Usage: make [task]
task help
------ ----
coverage Run tests with coverage
deps Install dependencies
lint Lint and static-check
push Push code with tags
test Run tests
help Show help message
make調用替換原始的build.yml步驟:- name: Install dependencies
run: |
make deps
- name: Run tox
run: |
make tox
flit publish。讓我們創(chuàng)建一個單獨的工作流程:name: publish
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.9"
- name: Install dependencies
run: |
make deps
- name: Publish to PyPi
env:
FLIT_USERNAME: ${{ secrets.PYPI_USERNAME }}
FLIT_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
make publish
publish.ymlSettings > Secrets > New repository secret)中設置了PYPI_USERNAME和PYPI_PASSWORD。使用您的PyPi用戶名和密碼,甚至更好的-API令牌。pyproject.tomltox.iniMakefilebuild.ymlpublish.yml
更多閱讀
特別推薦

點擊下方閱讀原文加入社區(qū)會員
評論
圖片
表情
