Разработка собственной Python-библиотеки: от идеи до публикации
Создание библиотеки на Python с помощью pyproject.toml и setuptools
Современный подход к созданию библиотек предполагает использование файла pyproject.toml, который заменил устаревший setup.py. Это решение обеспечивает единообразие настройки, поддержку стандарта PEP 517/518 и удобство публикации на PyPI.
Структура проекта
Минимальная библиотека состоит из папки с именем пакета, внутри которой лежит __init__.py, и файла pyproject.toml в корне.
my_library/
├── pyproject.toml
└── my_library/
└── __init__.pyсоздание библиотеки python (создание библиотеки python)
Файл __init__.py может быть пустым или содержать импорты. Например:
# my_library/__init__.py
from .core import my_function
__version__ = "0.1.0"Python написание библиотеки (создание собственной библиотеки python)
pyproject.toml содержит метаданные и инструкции для сборки:
[build-system]
requires = ["setuptools","wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-library"
version = "0.1.0"
description = "Пример библиотеки на Python"
readme = "README.md"
authors = [{name = "Иван Иванов", email = "ivan@example.com"}]
license = {text = "MIT"}
python = "^3.8"
dependencies = ["requests>=2.25"]
написать библиотеку на python (создание библиотеки на python)
Основные шаги:
- Определить build-system с необходимыми инструментами (обычно setuptools + wheel).
- В секции project указать имя, версию, описание, авторов, лицензию и зависимости.
- Установить библиотеку в режиме разработки: pip install -e .
Типичная ошибка: импорт модуля внутри пакета не работает, если корневая папка не в sys.path. Решение: установить пакет в режиме редактирования или добавить путь вручную.
Если библиотека требует системных зависимостей (например, компилятор C), укажите их в pyproject.toml в секции [tool.setuptools.external-build] или используйте setup.cfg.
Публикация на PyPI
Соберите исходный и wheel-дистрибутивы:
pip install build
python -m buildЗагрузите с помощью twine:
pip install twine
twine upload dist/*Перед публикацией рекомендуется проверить на TestPyPI:
twine upload --repository-url https://test.pypi.org/legacy/ dist/*Как создать библиотеку с помощью Poetry?
Использование Poetry
Poetry автоматизирует управление зависимостями, сборку и публикацию. Инициализация:
poetry new my_libraryЭта команда создаёт структуру с pyproject.toml, уже настроенным под Poetry. Добавление зависимостей:
poetry add requestsУстановка в редакторе:
poetry installСборка и публикация:
poetry build
poetry publishЦель: упрощение рабочего процесса, автоматическое разрешение версий, встроенная виртуальная среда.
Проблема: Poetry использует собственный формат блокировки (poetry.lock), что может конфликтовать с другими инструментами. Решение: либо придерживаться одного инструмента, либо преобразовывать зависимости в requirements.txt с помощью poetry export.
Как сделать минимальную библиотеку без внешних инструментов (только setup.py)?
Классический способ с setup.py
Хотя этот метод считается устаревшим, он всё ещё используется в старых проектах. Создайте файл setup.py в корне:
from setuptools import setup, find_packages
setup(
name='my_library',
version='0.1.0',
packages=find_packages(),
install_requires=['requests'],
author='Иван Иванов',
description='Простая библиотека'
)Установка: pip install -e .
Ошибка: если не указать find_packages(), пакет не будет найден. Решение: всегда использовать find_packages() или явно указывать список пакетов.
Также сложнее управлять версиями и зависимостями по сравнению с pyproject.toml.
Как добавить тестирование в библиотеку?
Интеграция тестов (pytest)
Создайте папку tests и файл test_core.py:
# tests/test_core.py
from my_library import my_function
def test_my_function():
assert my_function(2, 3) == 5В pyproject.toml добавьте:
[tool.pytest.ini_options]
testpaths = ["tests"]Запуск: pytest
Цель: автоматическая проверка корректности кода.
Частая проблема: тесты не находят модули библиотеки. Решение: установить библиотеку в режиме разработки (pip install -e .) или настроить PYTHONPATH.
Как документировать библиотеку с помощью Sphinx?
Генерация документации
Установите Sphinx и запустите инициализацию:
pip install sphinx
sphinx-quickstart docsНастройте conf.py для автоматического извлечения докстрингов:
import os
import sys
sys.path.insert(0, os.path.abspath('../my_library'))
extensions = ['sphinx.ext.autodoc']Создайте index.rst с ссылкой на модуль:
.. automodule:: my_library
:members:Сборка: make html (в папке docs)
Ошибка: autodoc не находит модуль. Решение: правильно прописать путь в sys.path и установить пакет.
Подробные примеры создания библиотеки на Python
Рассмотрим расширенные варианты с нестандартными возможностями.
Пример 1: Библиотека с модулями на Cython
Используйте Cython для ускорения критических участков. Структура:
my_cython_lib/
├── pyproject.toml
├── my_cython_lib/
│ ├── __init__.py
│ └── fast_calc.pyx
└── build_cython.pyfast_calc.pyx:
def fast_sum(int a, int b):
return a + bbuild_cython.py (сборка вручную):
from Cython.Build import cythonize
from setuptools import Extension, setup
ext_modules = cythonize([Extension("my_cython_lib.fast_calc",
["my_cython_lib/fast_calc.pyx"])])
setup(ext_modules=ext_modules)В pyproject.toml укажите build-backend = 'setuptools.build_meta' и зависимость Cython в [build-system] requires. Сборка:
python build_cython.py build_ext --inplaceРезультат: скомпилированный файл fast_calc.cpython-*.so.
Импорт: from my_cython_lib import fast_calc; print(fast_calc.fast_sum(10,20)) -> 30
Проблема: на Windows требуется установленный компилятор C. Решение: использовать MinGW или Visual Studio Build Tools.
Пример 2: Библиотека с данными (включение статических файлов)
Иногда библиотека содержит ресурсы: иконки, JSON-шаблоны. Используйте package_data в pyproject.toml:
[tool.setuptools.package-data]
my_library = ["data/*.json", "templates/*.html"]Структура:
my_library/
├── pyproject.toml
└── my_library/
├── __init__.py
├── data/
│ └── config.json
└── templates/
└── greeting.htmlКод для доступа:
import importlib.resources
def load_config():
ref = importlib.resources.files('my_library').joinpath('data/config.json')
with ref.open('r') as f:
return f.read()Результат при вызове load_config() вернёт содержимое JSON.
Пример 3: Многоуровневый пакет с подпакетами
Структура:
mypackage/
├── __init__.py
├── core/
│ ├── __init__.py
│ └── utils.py
└── extra/
├── __init__.py
└── helpers.pyВ __init__.py корневого пакета импортируйте подпакеты:
from .core import utils
from .extra import helperspyproject.toml:
[tool.setuptools.packages.find]
where = ["."]
include = ["mypackage*"]
exclude = ["tests*"]Установка: pip install -e .. Проверка:
import mypackage
mypackage.utils.some_function()Пример 4: Использование Flit для быстрой публикации
Flit ориентирован на публикацию пакетов с git-репозиторием. Создайте pyproject.toml:
[build-system]
requires = ["flit_core"]
build-backend = "flit_core.buildapi"
[project]
name = "myquicklib"
version = "0.1.0"
description = "Быстрая публикация с Flit"
authors = [{name = "Петр Петров"}]Укажите точку входа в [project.scripts] (опционально). Публикация:
pip install flit
flit publishFlit автоматически создаёт wheel и загружает на PyPI, если указаны токен или логин.
Ошибка: при отсутствии файла LICENSE или README.md Flit выдаёт предупреждение. Решение: добавить эти файлы.
Пример 5: Динамическая версия из git-тега
Используйте setuptools_scm для автоматического определения версии по git:
[build-system]
requires = ["setuptools", "setuptools_scm"]
build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
version_scheme = "post-release"Версия будет браться из тега git (git tag v0.1.0). При установке без git версия ставится 0.0.1 (настраивается). Результат:
import my_library; print(my_library.__version__) -> '0.1.0'