Создание проекта типа package на Python

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Я хочу рассказать о том, как настраивать проект типа package на Python. Обычно это то, с чем встречаются в самом начале процесса разработки и после всех настроек благополучно забывают. Но я решил весь этот процесс описать, дабы не повторять все эти действия, каждый раз, когда нужно создать новый проект. Может, кто-то скажет, что прежде, чем понять Python, нужно пройти путь самурая и понять все тонкости его настройки самому, опираясь лишь на документацию. Возможно, они правы, но я считаю, что лучше один раз написать, чем тысячу раз вспоминать.

В целом принцип построения проекта такой:

  1. Устанавливаем Python (https://www.tutorialsteacher.com/python/python-package)

  2. Создаем папку на диске и создаем в ней файл __init__.py. Благодаря этому файлу Python понимает, что в ней лежат файлы с исходным кодом. __init__.py может быть пустым, но также в нем можно прописать ссылки на все функции, которые содержаться в файлах типа *.py, которые лежат внутри этой папки.

  3. Для того чтобы можно было удобно проверять, как работают функции в этих файлах можно создать __main__.py в этой же папке. И далее, набирая команду “python -m Имя_Папки” в командной строке, будет выполняться код из файла __main__.py

  4. Далее можно добавить тесты для созданного проекта и также необходимо настроить setup для того, чтобы собирать из проекта пакет на Python, который можно будет где угодно устанавливать и запускать.

  5. Чтобы наш пакет автоматически сохранялся на каком-нибудь локальном сервере, надо будет прописать этот сервер в файле c:\\Users\{CurrentUser}\pip\pip.ini . Если этого не сделать, то пакет будет сохраняться на диске, откуда его можно будет скопировать куда-то руками.

На первый взгляд всё довольно просто, но есть нюансы. Самый простой из них это __init__.py. В папках с кодом на Python надо не забывать его добавлять. Далее – это файл setup.py. От его корректной настройки зависит, то, как будет собираться пакет и будет ли он вообще собираться. Также стоит знать о таком файле как MANIFEST.in. Говорят, что сейчас он не нужен, но без него у меня всё работало через раз. Ну и как вишенка на торте – это дополнительный аргумент для pytests “–no-cov”. С помощью которого можно запускать тесты в режиме отладки, если у нас помимо тестов прикручен анализ покрытия кода этими тестами. Есть ещё одна важная деталь для понимания – все библиотеки необходимые для работы разрабатываемого продукта рекомендуется устанавливать в локально окружение – venv, чтобы они были видны только этому продукту и существовали только внутри него, точнее, его локального виртуального окружения venv (Virtual Environment).

Вооружившись этими знаниями, я решил создать простой проект на Python и потратил на это уйму времени, так как в теории всё быстро и понятно, а на практике всё немного сложнее. Для начала пришлось повозиться с настройками setup.py. Я хотел, чтобы сторонние библиотеки хранились в отдельном файле и оказалось, что это не так просто сделать, так как в документации такой подход не рассматривается. Потом были танцы с бубном вокруг локального хранилища разработанных пакетов. Хранить свои пакеты глобально (https://pypi.org/) у меня не было желания, несмотря на рекомендации делать именно так в документации к питону (https://packaging.python.org/tutorials/packaging-projects/). Если не вдаваться в детали, то для того, чтобы это сделать, надо развернуть локально простенький веб сервер и прописать к нему путь в pip.ini. Ещё были сюрпризы от IntelliJ IDEA, в ней нужно в паре мест что-то подкрутить и подправить, чтобы проект начал нормально работать. Возможно, я немного сгустил краски и в целом создавать свой проект на Python легко и просто, но на всякий случай, я всё же решил написать подробную инструкцию с приложенным к ним видео, в которой описал свои шаги для создания проекта типа package на Python. У меня получилось 86 шагов, которые я разделил на 3 части. Причем в это описание не вошла история о том, как создавать свой локальный сервер для хранения пакетов. Я решил, что это больше относится к DevOps и шаги могут немного отличаться, в зависимости от того куда и как выкладывать эти пакеты. Скачать уже созданный мной тестовый проект можно тут - https://github.com/AlexKorole/mypython

Итак, сами шаги:

1. Создание python проекта типа package (видео тут: https://youtu.be/enahePzYT6E)

1.1. https://www.python.org/downloads/

1.2. create directory "mypython"

1.3. create directory "src" in "mypython"

1.4. create directory "myPyLib" in "src"

1.5. create file "hello.py" in directory "myPyLib"

1.6. add code in "hello.py":

def SayHello(name):

    print("Hello ", name)

1.7. create file "__init__.py" in directory "myPyLib"

1.8. add code in "__init__.py":

from .hello import SayHello

1.9. create file "__main__.py" in directory "myPyLib"

1.10. add code in "__main__.py"

from .hello import SayHello

SayHello("dfg")

1.11. cmd

1.12. cd C:\work\Python\mypython\src

1.13. python -m myPyLib

1.14. cd..

1.15. py -m pip install --upgrade pip

1.16. py -m pip install --user virtualenv

1.17. py -m venv myvenv

1.18. .\myvenv\Scripts\activate

1.19. create file "setup.py" in directory "C:\work\Python\mypython"

1.20. add code in "setup.py":

from setuptools import setup, find_packages
with open("requirements/req.txt") as f:
 required = f.read().splitlines()

setup(
    version = "0.0.1",
    packages=find_packages(where='src', exclude=["tests*"]),
    install_requires=required,
    name="myPkg",
    author="I am",
    author_email="",
    description="library for static functions",
    classifiers=["Programming Language :: Python :: 3"],
    python_requires=">=3.7",
    package_dir={"": "src"},
    include_package_data = True
)

1.21. create file "pyproject.toml" in directory "C:\work\Python\mypython"

1.22. add in "pyproject.toml":

[build-system]
requires = [
    "setuptools>=42",
    "wheel"
]
build-backend = "setuptools.build_meta"

1.23. create directory "requirements" in "C:\work\Python\mypython"

1.24. create file "req.txt" in directory "requirements"

1.25. add in "req.txt":

pandas==1.1.4

1.26. create file "MANIFEST.in" in directory "C:\work\Python\mypython"

1.27. add in "MANIFEST.in"

include requirements/req.txt

1.28. in cmd: "pip install pandas"

1.29. modify "hello.py"

import numpy as np
import pandas as pd

def SayHello(name):
    print("Hello ", name)

def CheckPandas():
    s = pd.Series([1, 3, 5, np.nan, 6, 8])
    print(s)

1.30. modify "__init__.py":

from .hello import SayHello, CheckPandas

1.31. modify "__main__.py"

from .hello import SayHello, CheckPandas
SayHello("dfg")
CheckPandas()

1.32. in cmd: "cd src"

1.33. "python -m myPyLib"

1.34. cd..

1.35. .\myvenv\Scripts\deactivate

1.36. py -m pip install --upgrade build

1.37. py -m build

1.38. cd C:\work\Python\mypython\dist

1.39. py -m venv mytestvenv

1.40. .\mytestvenv\Scripts\activate

1.41. pip install myPkg-0.0.1-py3-none-any.whl

1.42. py

1.43. from myPyLib import SayHello, CheckPandas

1.44. SayHello("aa")

1.45. CheckPandas()

1.46. Ctrl+Z

2. Добавляем к python проекту тесты, покрытие и проверку чистоты кода (видео тут: https://youtu.be/fhNIcTTKA6E)

2.1. .\mytestvenv\Scripts\deactivate

2.2. cd C:\work\Python\mypython

2.3. .\myvenv\Scripts\activate

2.4. in cmd "pip install tox"

2.5. create file "tox.ini" in "C:\work\Python\mypython"

2.6. add text in "tox.ini" file

[tox]
envlist = py38
skipsdist=true

[testenv]
commands = pytest
whitelist_externals = *

2.7. create folder "tests" in "C:\work\Python\mypython"

2.8. add file empty filr "__init__.py" in "C:\work\Python\mypython"

2.9. add file "test_hello.py" in "C:\work\Python\mypython\tests"

2.10. add code in "test_hello.py"

from src.myPyLib import SayHello

def test_SayHello():
    assert SayHello("bb") == None

2.11. in cmd "tox"

2.12. pip install flake8

2.13. add to "tox.ini"

[flake8]
application_import_names = myPyLib, tests
max-line-length = 120
extend-ignore = E203,W503,E231,I201
exclude = myvenv, .tox, build, dist

2.14. in cmd "flake8"

2.15. pip install pytest-cov

2.16. pip install pytest-xdist

2.17. add to "tox.ini"

[pytest]
addopts = --cov=src.myPyLib --cov-append --cov-report term-missing

2.18. in cmd "tox"

3. Открываем python проект в Intellij IDEA (видео тут: https://youtu.be/lQXzBsGWiIo)

3.1. in IntellijIdea - File - Settings - Plugins - Python (install)

3.2. in IntellijIdea - File - Open - directory "C:\work\Python\mypython"

3.3. Event Log - Python framework is detected - Configure

3.4. File - Project Structure - Project - Project SDK - Python 3.8

3.5. File - Project Structure - Modules

3.6. for Test set "tests" directory

3.7. for Source set "src\myPyLib" directory

3.8. Add Configuration -> Python

3.9. Name "run"

3.10. Script path: "C:\work\Python\mypython\src\myPyLib"

3.11. Use SDK of module

3.12. in "C:\work\Python\mypython\src\myPyLib\__main__.py" change:

from src.myPyLib import SayHello, CheckPandas

SayHello("dfg")
CheckPandas()

3.13. In IntellijIdea click Run "run"

3.14. Add Configuration -> PythonTests

3.15. select pytests

3.16. Additional Arguments: --no-cov // for debug

3.17. set "C:\work\Python\mypython\tests"

3.18. Use SDK of module

3.19. Run PythonTests

3.20. File - Settings - Tools - Python Integrated Tools - Testing - Default test runner: pytest

3.21. Run by click

3.22. Edit Configuration - Templates - Python tests - pytest - Additional Arguments: --no-cov

3.23. Run by click

3.24. tox.ini comment "addopts = --cov=src.myPyLib --cov-append --cov-report term-missing"

3.25. pip.ini https://mothergeo-py.readthedocs.io/en/latest/development/how-to/alternate-pypi.html

Источник: https://habr.com/ru/post/575558/


Интересные статьи

Интересные статьи

Предпосылки / проблемаПри работе над своим проектом вручную создавал стилизованную галерею проектов и понял, что бесконечно плодить громоздкие однотипные HTML-контейнеры ...
Всем привет! Сегодня мы будем пытаться собрать Python 1.0.1 (1994 год) на современном железе при помощи современного компилятора. Даже если Вы, как Python разработчик, никогда не компилир...
В процессе миграции на Python 3 разработчики утилиты rdiff-backup усовершенствовали её, добавив много новых фич. В марте 2020 года вышел второй крупный релиз утилиты rdiff-back...
У некоторых бизнес-тренеров в области е-коммерса и консультантов по увеличению интернет-продаж на многие вопросы часто можно слышать универсальную отмазку — «надо тестировать» или другую (чтобы не...
Частенько в дискуссиях на тему работы я встречаю тезисы о том, как плохо работать в том или ином проекте/компании/отрасли и т.д. И несмотря на то, что в отечественном IT в целом очень распростран...