Python проеты с Poetry и VSCode
Виртуальная среда — это изолированная установка Python, предназначенная для того, чтобы не заполнять нашу базовую среду библиотеками, которые мы могли бы использовать только для одного проекта. Это также позволяет нам управлять несколькими версиями одного и того же пакета в разных проектах. Например, нам может понадобиться Django 4.1 для одного и 1.9 для другого.
Poetry — это инструмент для установки зависимостей, а также сборки и упаковки пакетов Python. Для всего этого нужен только один файл: новый стандартизированный pyproject.toml
. Другими словами, poetry использует pyproject.toml
для замены setup.py
, requirements.txt
, setup.cfg
, MANIFEST.in
и недавно добавленного Pipfile
.
В этой серии статей мы будем использовать Poetry для управления нашими зависимостями, создания простого проекта и с помощью одной команды опубликуем его на PyPI.
В первой части мы:
- Создадим новый проект.
- Создадим виртуальную среду.
- Настроим зависимостями.
Во второй части мы:
- Добавьте нашу виртуальную среду в VSCode.
- Интегрируем наши зависимости для разработчиков:
- Flake8
- Black
- Pytest
И, наконец, в третьей части мы:
- Напишите пример библиотеки.
- Создайте наш проект с Poetry.
- Опубликуйте его на PyPI.
Установка Poetry
Самый простой способ — использовать pip:
$ pip install poetry
Но мы будем использовать собственный установщик Poetry, чтобы изолировать его от остальной системы, продав его зависимости. Это рекомендуемый способ установки poetry:
$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
Таким образом, позже мы сможем обновить поэзию до последней стабильной версии с помощью команды poetry self update
.
Запуск нового проекта
Теперь мы можем начать новый проект Python, используя команду poetry new [project_name]
. Я назову его how-long и это будет простая библиотека для измерения времени выполнения функции:
$ poetry new how-long
Примечание. Для существующих проектов вы можете использовать команду
poetry init
и в интерактивном режиме создать pyproject.toml.
Создаться каталог, how-long и внутри представляет собой базовую структуру проекта:
how-long
├── README.rst
├── how_long
│ └── __init__.py
├── pyproject.toml
└── tests
├── __init__.py
└── test_how_long.py
Примечание. Чтобы иметь возможность опубликовать свой проект, вам необходимо доступное имя. Используйте поиск PyPI для этого.
Файл pyproject.toml
Файл pyproject.toml будет управлять деталями и зависимостями проекта:
[tool.poetry]
name = "how-long"
version = "0.1.0"
description = "A simple decorator to measure a function execution time."
authors = ["wilfredinni <carlos.w.montecinos@gmail.com>"]
[tool.poetry.dependencies]
python = "^3.7"
[tool.poetry.dev-dependencies]
pytest = "^3.0"
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
[tool.poetry]
Детали. Добавление license и README может быть хорошей идеей:
[tool.poetry]
...
license = "MIT"
readme = "README.rst"
[tool.poetry.dependencies]
Во-первых, это версия Python. По сути, этот проект будет совместим с Python 3.7 и выше. Кроме того, отныне каждый устанавливаемый нами пакет, предназначенный для использования в рабочей среде, будет отображаться здесь.
[tool.poetry.dev-dependencies]
Эти пакеты предназначены только для разработки и не будут включены при публикации нашего проекта. По умолчанию Poetry включает Pytest, поэтому мы будем использовать его для тестирования нашего проекта позже.
Создание виртуальной среды
Чтобы создать виртуальную среду и установить Pytest, мы будем использовать команду poetry install
:
$ poetry install
После этого будет создан новый файл poetry.lock
.
Когда Poetry завершит установку, он запишет все пакеты и их точные версии, которые он загрузил, в файл
poetry.lock
, привязав проект к этим конкретным версиям. Вы должны зафиксировать файл поэзии.lock в репозитории вашего проекта, чтобы все люди, работающие над проектом, были привязаны к одним и тем же версиям зависимостей.
Управление зависимостями
Один из способов добавить или удалить зависимости — напрямую отредактировать файл pyproject.toml, а затем запустить poetry install
, чтобы применить изменения. Вместо этого мы будем использовать команды add
и remove
, чтобы избежать ручных изменений.
Добавление зависимостей
Добавим в проект два пакета, pendulum, и coo:
$ poetry add pendulum coo
Откройте pyproject.toml и poetry.lock и посмотрите, как они обновились.
Добавление зависимостей для разработчиков
Эти зависимости будут доступны только во время разработки, Poetry не будет включать их при сборке и публикации проекта.
Мы уже установили Pytest, но также будем использовать flake8 для линтинга и mypy для статической типизации:
$ poetry add -D flake8 mypy
Теперь, когда я думаю об этом, я забыл добавить форматтер. Мы пойдем с black:
$ poetry add -D black
[ValueError]
Could not find a matching version of package black
add [-D|--dev] [--git GIT] [--path PATH] [-E|--extras EXTRAS] [--optional] [--python PYTHON] [--platform PLATFORM] [--allow-prereleases] [--dry-run] [--] <name> (<name>)...
Эта ошибка возникает из-за того, что black находится в состоянии предварительного выпуска, поэтому Poetry не может найти для нас стабильную версию. Но я очень этого хочу, так что давайте все равно установим его с флагом --allow-prereleases
:
$ poetry add -D black --allow-prereleases
Удаление зависимостей
Знаете что, я передумал, в этом проекте не будут использоваться ни coo, ни mypy. Начните с удаления coo, обычной зависимости нашего проекта:
$ poetry remove coo
Теперь mypy, который является зависимостью от разработчиков:
$ poetry remove -D mypy
Мы начали новый проект, создали виртуальную среду и добавили и удалили зависимости с помощью следующих команд:
Command | Description |
---|---|
poetry new [package-name] | Запустите новый проект Python. |
poetry init | Создайте файл pyproject.toml в интерактивном режиме. |
poetry install | Установите пакеты внутри файла pyproject.toml. |
poetry add [package-name] | Добавьте пакет в виртуальную среду. |
poetry add -D [package-name] | Добавьте пакет разработки в виртуальную среду. |
poetry remove [package-name] | Удалить пакет из виртуальной среды. |
poetry remove -D [package-name] | Удалите пакет разработки из виртуальной среды. |
poetry self:update | Обновите поэзию до последней стабильной версии. |
Далее мы увидим больше команд Poetry, добавим нашу виртуальную среду в VSCode и используем установленные нами пакеты для разработки (Flake8), форматирования (Black) и тестирования (Pytest) нашего кода внутри редактора. Наконец, в третьем мы напишем и опубликуем образец библиотеки в PyPI.
Настройка Poetry на VSCode
Стоит проверить наличие новых версий наших зависимостей. Откройте свой терминал, перейдите в каталог вашего проекта и введите команду poetry update
:
Пока новых версий нет.
Когда вы создаете виртуальную среду с помощью команды venv, VSCode автоматически устанавливает ее в качестве среды Python по умолчанию для этого проекта. При работе с Poetry в первый раз нам нужно будет ввести следующее в терминале и внутри папки проекта:
$ poetry shell
$ code .
Первая команда, poetry shell
, создаст нас внутри нашей виртуальной среды, а code .
откроет текущую папку внутри VSCode.
Откройте папку how-long (или папку с названием вашего проекта) с помощью левой панели и рядом с __init__.py
создайте файл how-long.py
. В левом нижнем углу вы увидите текущую среду Python:
Щелкните ее, и отобразится список доступных сред. Выберите тот, в котором есть название вашего проекта:
Теперь давайте интегрируем наши зависимости разработки, Flake8, Black, и Pytest в Visual Studio Code.
Flake8
Flake8 предоставит нашим проектам возможности линтинга. Другими словами, предупреждение об ошибках синтаксиса и стиля, а благодаря VSCode мы узнаем их по мере ввода.
По умолчанию расширение Python поставляется с включенным Pylint, который является мощным, но сложным в настройке. Чтобы переключиться на Flake8, внесите изменения в любой файл Python и сохраните его. В правом нижнем углу появится всплывающее сообщение:
Нажмите Select Linter и выберите Flake8 из списка. Теперь VSCode сообщит нам о наших проблемах с синтаксисом и стилем, зеленым или красным в зависимости от их серьезности, всегда с хорошим описанием того, что не так:
Похоже, у нас есть две проблемы: мы пропустили пустую строку в конце нашего файла (style) и забыли добавить кавычки к нашему Hello, World! строка (syntax). Исправьте их, и все предупреждения исчезнут.
Black
Black это средство форматирования кода, инструмент, который просматривает наш код и автоматически форматирует его в соответствии с руководством по стилю PEP 8, тем же PEP, который использует Flake8 для проверки наших ошибок стиля.
Удерживайте shift + cmd/ctrl + p
, чтобы открыть палитру команд, введите Format Document и нажмите клавишу ВВОД. Появится новое всплывающее сообщение:
Выберите Use Black. Теперь скопируйте этот плохо отформатированный код в ваш файл Python:
for i in range(5): # this comment has too many spaces
print(i) # this line has 6 space indentation.
Какой уродливый кусок дерьмового кода s***.... Попробуйте отформатировать его еще раз и посмотрите, как Black исправит их все за вас!
Еще мы можем настроить VSCode так, чтобы при каждом сохранении Black автоматически форматировал наш код. Удерживайте cmd/ctrl + ,
чтобы открыть настройки. Убедитесь, что вы находитесь в Workspace Settings, найдите Format On Save и установите флажок:
Наконец, Black по умолчанию использует 88 символов в строке, в отличие от 80, разрешенных Flake8, поэтому, чтобы избежать конфликтов, откройте папку .vscode и добавьте следующее в конец файла settings.json:
{
...
"python.linting.flake8Args": [
"--max-line-length=88"
],
}
Pytest
Если вы серьезно относитесь к программированию, вам крайне важно научиться тестировать свои проекты. Это невероятно полезный навык, который позволяет вам писать и выпускать программы с уверенностью, снижая вероятность появления катастрофических ошибок после выпуска.
Pytest — очень популярный и удобный фреймворк для написания тестов. Мы уже установили его, поэтому мы также будем интегрировать его с VSCode.
Откройте папку с tests и выберите файл test_how_long.py
. Poetry уже дает нам первое испытание:
# test_how_long.py
from how_long import __version__
def test_version():
assert __version__ == '0.1.0'
В этом тесте мы импортируем переменную __version__
из файла __init__.py
, который находится в папке how_long, и утверждаем, что текущая версия — 0.1.0. Откройте встроенный терминал, выбрав Terminal > New Terminal и введите:
$ pytest
Вывод будет выглядеть так:
Хорошо, все в порядке. Откройте палитру команд с помощью shift + cmd/ctrl + p
:
- Напишите unit и выберите Python: Configure Unit Tests.
- Выберите pytest.
- Выберите каталог, в котором вы сохранили тесты, в нашем случае tests.
Произошло три вещи:
- В строке состояния появилась новая кнопка: Run Tests. Это то же самое, что ввести pytest в терминале. Нажмите ее и выберите Run All Unit Tests. Когда закончите, он сообщит вам количество пройденных тестов и тестов, которые не пройдены:
- Новая иконка на левой панели. Если вы нажмете на нее, появится панель, отображающая все тесты. Здесь вы можете запустить каждый из них по отдельности:
- Внутри тестового файла перед каждой тестовой функцией будут отображаться новые параметры: появится значок проверки, если все в порядке, и x в противном случае. Он также позволяет запускать определенные тесты:
Выше мы начали новый проект, создали виртуальную среду и управляли зависимостями. Далее мы добавили нашу виртуальную среду в VSCode и интегрировали наши зависимости от разработчиков.
И, наконец, теперь мы:
- Напишем пример библиотеки.
- Создадим наш проект с Poetry.
- Опубликуем его на PyPI.
Вот таблица с командами, используемыми в этой серии, а также их описания. Полный список см. в Документации по поэзии.
Poetry команды
Вот таблица с командами, которые мы еще не использовали, а также их описания. Полный список см. в Poetry документации.
Command | Description |
---|---|
poetry update | Получить последние версии зависимостей |
poetry shell | Создает оболочку в виртуальной среде. |
poetry build | создает архивы исходников . |
poetry publish | Опубликовать пакет в Pypi. |
poetry publish --build | Создайте и опубликуйте пакет. |
Проект
Это будет простой декоратор, который выведет на консоль время, необходимое для запуска функции.
Это будет работать следующим образом:
from how_long import timer
@timer
def test_function():
[i for i in range(10000)]
test_function()
# Execution Time: 955 ms.
Это будет работать следующим образом:
how-long
├── how_long
│ ├── how_long.py
│ └── __init__.py
├── how_long.egg-info
│ ├── dependency_links.txt
│ ├── PKG-INFO
│ ├── requires.txt
│ ├── SOURCES.txt
│ └── top_level.txt
├── LICENSE
├── poetry.lock
├── pyproject.toml
├── README.rst
└── tests
├── __init__.py
└── test_how_long.py
Перед тем, как мы начнем, проверьте наличие обновлений пакетов с помощью команды poetry update
:
Добавьте краткое описание проекта в файл README.rst
:
how_long
========
Simple Decorator to measure a function execution time.
Example
_______
.. code-block:: python
from how_long import timer
@timer
def some_function():
return [x for x in range(10_000_000)]
Перейдите к файлу how_long/how_long.py
:
# how_long.py
from functools import wraps
import pendulum
def timer(function):
"""
Simple Decorator to measure a function execution time.
"""
@wraps(function)
def function_wrapper():
start = pendulum.now()
function()
elapsed_time = pendulum.now() - start
print(f"Execution Time: {elapsed_time.microseconds} ms.")
return function_wrapper
В how_long/__init__.py
:
from .how_long import timer
__version__ = "0.1.1"
И, наконец, в файл tests/test_how_long.py
:
from how_long import __version__
from how_long import timer
def test_version():
assert __version__ == "0.1.1"
def test_wrap():
@timer
def wrapped_function():
return
assert wrapped_function.__name__ == "wrapped_function"
Теперь вы можете использовать poetry install
на своем терминале, чтобы установить и проверить свой пакет локально. Активируйте вашу виртуальную среду, если вы еще этого не сделали, и в интерактивной оболочке Python:
>>> from how_long import timer
>>>
>>> @timer
... def test_function():
... [i for i in range(10000)]
...
>>> test_function()
Execution Time: 705 ms.
Запустите тесты и, если все в порядке, двигайтесь дальше.
Создание и публикация
Наконец-то пришло время сделать этот проект доступным для всего мира! Убедитесь, что у вас есть учетная запись на PyPI. Помните, что имя пакета должно быть уникальным, если вы не уверены, воспользуйтесь поиском, чтобы проверить его.
Сборка
Команда poetry build
создает архивы исходного кода и wheels, которые позже будут загружены в качестве исходного кода проекта:
Будет создан каталог how_long.egg-info.
Публикация
Эта команда публикует пакет в PyPI и автоматически регистрирует его перед загрузкой, если он отправляется впервые:
Вы также можете создать и опубликовать свой проект с помощью
$ poetry publish --build
.
Введите свои учетные данные и, если все в порядке, просмотрите свой проект, и вы увидите что-то вроде этого:
Теперь мы можем сообщить другим, что они могут установить pip install how-long
и с любой машины и из любого места!