如何正确设置Python项目
#python #devops #cli #softwareengineering

行业的最佳实践来启动您的Python项目。
How to properly setup your Python project

David Clode的照片在Unsplash上​​

当您开始从事Python项目时,您可能需要进行设置
以一致和协作的方式。在本文中,我将描述
对我的项目非常有用的设置。它包括许多行业最佳实践
旨在解释如何安装python,在gitops中运行自动检查
时尚和构造您的项目。

本文涵盖了很多主题。为了简化阅读,我已经将每个主题分为两个部分:

  • ð表示理论部分
  • ðISTIS实用零件(即您需要运行的命令)。

有时您还会看到一个ðâ部分,指示提示或技巧。

目录

  1. Install a Python version manager
  2. Choose an environment manager (poetry)
  3. Alternatively, use Docker as a Dev Environment instead
  4. Add Some Code
  5. Write Some Tests
  6. Lint your code
  7. Automate checks on local with pre-commit
  8. Automate checks on remote with GitHub Actions
  9. Automate your release with GitHub Actions
  10. Enjoy the benefits of your new code practices

1.安装Python版本管理器

ð您需要做的第一件事是安装Python版本管理器。
Python版本管理器将允许您在
上安装多个版本的Python 您的机器并轻松地在它们之间切换。

为了说明这一点,假设您有一个需要Python 3.6和
的项目 另一个需要Python 3.7的项目。如果您只安装了python 3.7
在计算机上,您必须卸载它并每次安装Python 3.6
您想从事第一个项目...这是Python版本管理器
派上用场。

您可以使用pyenv进行此操作并遵循
installation instructions.

ðsing撰写本文档时,您可以通过运行
来安装Pyenv 以下:

curl https://pyenv.run | bash

如果您想对安装进行更多控制,例如在Mac上运行:

  1. 使用啤酒安装pyenv

    brew install pyenv
    
  2. 根据您使用的外壳,将pyenv添加到路径中。

    ðâ€如果您不确定要使用的外壳,可以运行以下命令:

    echo $SHELL
    

    bash:

    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
    echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
    echo 'eval "$(pyenv init -)"' >> ~/.bashrc
    

    for zsh:

    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
    echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
    echo 'eval "$(pyenv init -)"' >> ~/.zshrc
    

2.选择环境经理(诗歌)

ð现在您有了Python版本管理器,您将需要安装
环境经理。环境经理将允许您创建孤立的
项目环境。当您从事多个
工作时,这很有用 需要不同版本的同一软件包的项目。这是一个很棒的
整体练习以确保任何人都可以运行您的项目。

为了说明这一点,假设您有一个需要pandas
的项目 matplotlib进行一些数据分析和另一个需要的项目
tensorflow进行一些机器学习。这被认为是
的好习惯 为每个项目创建一个单独的环境。这样,您可以安装
只有您每个项目所需的软件包,并避免
之间的任何冲突 包裹。

有很多环境经理(Pipenv,Conda,Virtualenv,Python
内置的VENV等...)。我个人使用poetry

通常,您的环境经理将与您的Python版本一起安装。
例如,如果使用pyenv,则可以通过运行以下命令来安装诗歌:

pyenv install 3.10.6
pyenv global 3.10.6
pip install poetry

在这种情况下,诗歌将生活在您的Python环境中。这意味着
您可以为每个python版本拥有不同版本的诗歌
安装在机器上。

ðispip在您的Python环境中使用PIP安装诗歌是一种方法,但您也可以按照以下步骤操作:

  1. 使用卷曲命令安装诗歌

    curl -sSL https://install.python-poetry.org | python3 -
    
  2. 将诗歌添加到您的道路上。在MacOS上,~/Library/Application
    Support/pypoetry/venv/bin/poetry
    添加了诗歌。因此,您可以通过添加
    将其添加到路径中 以下到您的〜/.bashrc或〜/.zshrc文件:

    export PATH="$HOME/Library/Application Support/pypoetry/venv/bin:$PATH"
    

    如果您使用的是其他外壳,则可以通过运行以下命令来找到诗歌的路径:

    poetry config --list --local | grep virtualenvs.path
    

    然后将其添加到您的路径中。

3.或者,将Docker用作开发环境

如果您不想安装Python版本管理器和环境
经理,或想为您的团队抽象,您可以改用Docker。我
在这里不会详细介绍太多细节,但是如果您有兴趣,Vscode的细节很棒
integration with
Docker

4.添加一些代码

ð现在您拥有Python版本经理和环境经理,您
可以开始从事您的项目。让我们写一些简单的功能以获取
开始。出于插图目的 <name>“当您运行它并给出数量的存储库<name>在github上。

ðâ默认情况下,诗歌希望您创建一个包含一个名为
的文件夹 git存储库(唯一的区别是要下调而不是破折号)。因此,如果您的git
存储库称为python-project-template,诗歌将创建一个文件夹
称为python_project_template

ð§您可以在armand-sauzay/hello-world-cli上找到本节的代码

在这种情况下,让我们称我们的项目hello-world。因此,我们将创建一个文件夹
称为hello_world并在其中添加一个名为__init__.py的文件。

ðshistegh创建一个名为hello-world的新存储库,并将其克隆到您的
机器:

gh repo create <your-github-username>/hello-world-cli --template armand-sauzay/python-template --public

要初始化项目,请运行以下命令(它来自上面的模板):

./script/bootstrap

将请求包添加到您的项目:

poetry add requests

到目前为止,我们运行了以下命令:

pyenv install 3.10.6 # install python 3.10.6
pyenv global 3.10.6 # (optional) set python 3.10.6 as the default python version
pip install poetry # install poetry as a python package in your python 3.10.6 environment
poetry add requests # add the requests package to your project

hello_world_cli文件夹中,一个名为main.py的文件,并在其中添加以下代码:

import argparse
import requests


def main(argv=None) -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--name", help="The name to greet and count repos for", default="world"
    )
    args = parser.parse_args(argv)
    if args.name == "":
        print("Username cannot be empty")
        return 1

    print(f"Hello {args.name}!")

    repos = requests.get(f"https://api.github.com/users/{args.name}/repos")
    if repos.status_code != 200:
        print(f"Failed to fetch repos for {args.name}")
        return 1
    repos = repos.json()
    print(f"You have {len(repos)} repos.")  # type: ignore
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

这里有一些技巧值得一提的:

  • 我们使用argparse来解析传递给我们CLI的论点。这是一个内置的 Python软件包允许您解析传递给CLI的论点。
  • 我们使用argv将参数传递给我们的主要功能。这对 测试目的。我们可以将参数列表传递给我们的主要功能,并且 在不必运行CLI的情况下进行测试。
  • 我们使用SystemExit退出我们的程序。这是一个内置的python例外 这使您可以使用特定的退出代码退出程序(成功为0,失败1)。

5.写一些测试

ð现在您有了一些基本方法,您可以开始编写一些测试。测试确保您的代码的行为符合预期。那里
是否有许多类型的测试(单位测试,集成测试,端到端测试等等)
但是在本文中,我们将重点关注单元测试。单位测试是
的测试 检查代码的最小单元(即功能或方法)。

ðisther创建一个名为test_main.py的文件,并在其中添加以下代码:

from hello_world_cli.cli import main

def test_main(capsys):
    assert main(['--name', 'test']) == 0
    out, err = capsys.readouterr()
    # test is a user which does not have any contributions since 2010. 
    # Hopefully this will not change in the future and the test will not break.
    assert out == 'Hello test!\nYou have 5 repos.\n'
    assert err == ''

def test_main_empty_name(capsys):
    assert main(['--name', '']) == 1
    out, err = capsys.readouterr()
    assert out == 'Username cannot be empty\n'
    assert err == ''
  • 我们使用capsys捕获CLI的输出。这是一个内置的pytest,可让您捕获CLI的输出。

6.皮棉代码

ð现在您有了一些测试,您可以开始覆盖代码。绒毛是
检查代码是否有可能发生错误的过程。有很多衬里
那里(Pylint,Flake8,黑色等...)。我个人使用Flake8,Black,Isort和
mypy。 ruff也变得非常受欢迎,并取代了Flake8和Isort。

ðisthisthisthisth,黑色,iSort和mypy,您可以运行以下命令:

poetry add --dev flake8 black isort mypy

然后,您可以使用Mypy检查您的代码:

poetry run mypy hello_world_cli/cli.py

您可以使用Flake8检查您的代码:

poetry run flake8 hello_world_cli/cli.py

您可以使用黑色格式化代码:

poetry run black hello_world_cli/cli.py

但是您每次您都不会真正想手动运行这些命令 更改您的代码。这是预订派上用场的地方,以确保您
不要犯错格式的代码,也不必运行这些命令
手动。

另外,请注意,其中一些衬里的差异很小。
例如,如果您的行超过88个字符,Black会抱怨,
但是Flake8如果您的行超过79个字符,将抱怨。您需要
将它们配置为正确工作:

  • 您应该创建一个带有以下内容的.flake8文件:
[flake8]
max-line-length = 88
extend-ignore = E203
  • 您应该创建一个带有以下内容的.isort.cfg文件:
[settings]
profile = black

7.自动检查本地检查,并使用预先支票

ð现在您有了一些测试和一些衬里,您可以开始自动化
检查。自动支票的目标是确保您的代码始终
处于良好状态。那里有许多工具可以帮助您自动化
检查(预签名,托克斯等...)。我个人使用预先签名。

ðisthistpre commit,您可以运行以下命令:

brew install pre-commit

然后您可以运行预先承诺

pre-commit run --all-files

pre-commit

  • 您可以在上图上看到预先承诺正在运行我们的检查 在.pre-commit-config.yaml文件中定义。
  • 请注意,此文件来自上面的模板 step 4.

8.使用GitHub操作对遥控器进行自动检查

ð现在您有了一些测试和一些衬里,您可以开始自动化
检查服务器端。在服务器端自动检查您的支票的目的
是为了确保您的代码始终处于良好状态。有很多工具
那里可以帮助您自动进行支票自动化(github操作,travis ci,circle
CI等...)。我个人使用github动作。

为了设置GitHub操作,您可以创建一个名为.github/workflows/ci.yaml的文件,然后在其中添加以下代码:

name: CI

on:
  workflow_dispatch:
  push:
jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: armand-sauzay/actions-python/lint@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: armand-sauzay/actions-python/test@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          test-flags: --version

请注意,如果您使用了上面提到的模板,则应该已经创建此文件(请参见step 4中的GH命令。<​​/p>

说明:

  • 如果您不熟悉GitHub动作的语法,则可以阅读documentation
  • 在这里,我们称之为两个作业:棉绒和测试。每个作业都在Ubuntu-Latest(Linux机器)上运行。
  • 绒毛作业使用armand-sauzay/actions-python/lint操作来运行预先承诺。
  • 测试作业使用armand-sauzay/actions-python/test操作来运行pytest。在这里,我们将标志传到py​​test,以进行虚拟测试。您可以删除此标志以运行实际的测试。

remote-checks

9.使用GitHub动作自动释放您的版本

ð我们简要讨论了用黑色,薄片,iSort和mypy和mypy-以及使用pytest进行测试。发行是一个同样重要的概念,可让您将版本提供给

为了设置GitHub操作,您可以创建一个名为.github/workflows/release.yaml的文件,然后向其添加以下代码:

name: Release

on:
  push:
    branches:
      - main
  workflow_dispatch: # enable manual release

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: armand-sauzay/actions-python/lint@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: armand-sauzay/actions-python/test@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          test-flags: --version

  release:
    name: Release
    needs: [lint, test]
    runs-on: ubuntu-latest
    outputs:
      new-release-published: ${{ steps.release.outputs.new-release-published }}
      new-release-version: ${{ steps.release.outputs.new-release-version }}
    steps:
      - uses: armand-sauzay/actions-python/release@v1
        id: release
        with:
          github-token: ${{ secrets.ADMIN_TOKEN || secrets.GITHUB_TOKEN }}

release

一些值得注意的事情:

  • 此工作流将触发在主要分支和手动触发器(Workflow_dispatch)
  • 上触发
  • 它将运行棉绒和测试作业
  • 然后,它将运行发行作业,该作业将对代码进行语义版本并在GitHub上创建版本。如果您不知道什么是语义版本,则可以阅读documentation
  • 为了遵循语义版本,您可以遵循常规提交(这就是为什么在发行说明中显示为fix: ...feat: ...的提交的原因)。您可以在conventional commits上阅读更多信息。
  • 有时您可能会有一个受保护的分支,默认的github_token将没有足够的权限来创建版本。在这种情况下,您可以创建一个名为ADMIN_TOKEN的个人访问令牌,并给予正确的权限。然后,您可以在工作流程中使用此令牌。

10.享受新代码惯例的好处

现在您知道如何:

  • 使用Pyenv安装不同的Python版本
  • 使用诗歌来管理您的依赖项(诗歌添加/删除)
  • 使用Pytest测试您的Python代码
  • 什么是覆盖物以及如何使用薄片,黑色,伊索和mypy
  • 使用预先承诺在本地计算机上自动化您的支票
  • 使用github操作自动在服务器端自动检查

享受新代码实践的好处! ð

一如既往,如果您有任何疑问,请随时在下面发表评论,或在不同的平台上与我联系:












4214976


4214976