- PVSM.RU - https://www.pvsm.ru -

Пишем обертку над API, делаем из нее PIP-пакет, подключаем тестирование от Travis CI и смотрим на лицензии открытого ПО

Пишем обертку над API, делаем из нее PIP-пакет, подключаем тестирование от Travis CI и смотрим на лицензии открытого ПО - 1

Приветствую! Данная статья будет полезна желающим ознакомиться не только с оформлением собственного пакета Python Package Index (PIP), но и с различными вспомогательными инструментами, помогающими сопровождать разработку на всех стадиях — на примере авторской работы.

Необходимые инструменты:

  • среда разработки — написание объектно-ориентированного кода, тесно работающего с интерфейсом приложения (в нашем случае веб-сайта), другими словами — отправка и обработка запросов к API, и дополнительных вспомогательных файлов;
  • загрузка своих наработок в общий каталог пакетов — PyPI [1];
  • Github [2] — создание репозитория с целью контроля качества, улучшения и перманентного обновления библиотеки, общего взаимодействия с областью открытого исходного кода;
  • одна из лицензий свободного программного обеспечения, в нашем случае — MIT License [3];
  • Travis CI [4] — непрерывная сборка и тестирование разрабатываемого проекта в различных окружениях (например, разные версии языка или интерпретатора).

Данный список можно принимать за содержание статьи в соответствующем порядке.

Хочу добавить, что переходить по предложенным материалам, в которых указано много важной и интересной информации, не обязательно — вы все равно получите необходимые данные для завершения подобного проекта и уже тогда решите, стоит ли вам использовать дополнительные ссылки.

Введение

Я — постоянный посетитель различных интернет-ресурсов, в том числе одного известного украинского сообщества программистов, а по совместительству и постоянно практикующий программист, — поэтому за недостатком идей ринулся конструировать реализацию статистики публикаций (на примере Хабрахабра) (см. рисунок ниже) для пользователей площадки. Не важно, в каком виде проект будет реализован, но промежуточной задачей является предмет обсуждения статьи — работа с API этого сайта [5], что в значительной мере облегчается написанием собственной обертки (PIP-пакета), включая несомненные дополнительные плюсы от разработки — например, интересная новая область и приобретенный опыт.

Пишем обертку над API, делаем из нее PIP-пакет, подключаем тестирование от Travis CI и смотрим на лицензии открытого ПО - 2

Конструкция проекта, необходимая для реализации обертки и загрузки ее в общий каталог, отличается от окончательной, в свою очередь надлежащей для качественного поддержания дальнейшей работы.

Пример окончательного варианта — DouAPI [6] (ссылка на github, держите ее открытой параллельно со статьей и обращайтесь для детализации описываемого, не забудьте прочитать описание репозитория). В нем отсутствуют нужные файлы для тестирования и какие-то вспомогательные решения (например, вынести в отдельное место объемный код, выполняющий форматирование строк или обработку дополнительных запросов), но только из-за отсутствия такого требования на данном этапе разработки.

Непосредственно структура самого пакета должна состоять из главного каталога, подкаталога с основным и вспомогательными файлами и файла дистрибуции «setup.py».

Пишем обертку над API, делаем из нее PIP-пакет, подключаем тестирование от Travis CI и смотрим на лицензии открытого ПО - 3

Для большей ясности стоит начать описание реализации с модуля «api.py» (ссылка на github [7]) — импортирование модуля Requests [8], позволяющего обращаться с HTTP-запросами на улучшеном уровне.

import requests

Создание непосредственно отдельного класса для обращения по заданным к API сайта по заданным URL определенным методом. Если ваша разработка будет ограничиваться какими-то факторами и создание дополнительного класса для запросов излишне — создавайте закрытый метод уже в основном классе, но если вы не знаете, как далеко зайдет проект, какие фичи вы захотите добавить и какая сложность вас ждет — лишним не будет, чтобы не тратить время на переписывание кода.

class DouAPI(object):

    def method(self, method, values=None):

        if values is not None: values['limit'] = 10000

        response = requests.get('https://api.dou.ua/{0}/'.format(method), params=values)

        if response.status_code == 200:
            return response.json()['results']
        else:
            message = 'A request to the Dou API was unsuccessful. The server returned HTTP {0} {1}.'
            return message.format(response.status_code, response.reason)

Вызов функции «method», принимающий название метода, которое соответствует необходимому URL и набору ключей-значений (HTTP Headers [9]), возвращает результат в виде формата JSON (такой же набор ключей-значений) в успешном случае, и просто строку с кодом ошибки и причиной ответа в противном случае (так старайтесь не делать, лучше создавать отдельно свои пользовательские исключения, как написано здесь [10] или здесь [11]).
Класс, к которому дальше обращается программист через объект (все остальное, что выходит за рамки требуемых инструментов, заворачивайте в приватные переменные [12] и методы [13]), содержит одну функцию «lenta», возвращающую объект класса с методом запросов, передавая название метода «articles» и набор ключей-значений (например, категорию и автора).

class Dou():
    __slots__ = ('_dou')

    def __init__(self):
        self._dou = DouAPI()

    def lenta(self, category=None, tag=None, author=None, date_from=None, date_to=None):

        values = locals().copy()
        values.pop('self')

        values = {header:value for header, value in values.items() if value != None}

        return self._dou.method('articles', values=values)

Так в итоге выглядит пример использования обертки — импортируем необходимый класс, создаем объект, обращаемся к методу класса, указывая интересующие параметры, получаем в ответ данные в формате JSON.

from dou import Dou

dou = Dou()

news = dou.lenta(category = 'news', date_from='2016-06-01')

print(news)

Если проиллюстрировать процесс, взаимодействие происходит следующим образом:

Пишем обертку над API, делаем из нее PIP-пакет, подключаем тестирование от Travis CI и смотрим на лицензии открытого ПО - 4

Теперь рассмотрим момент с файлом
«__init__.py», позволяющим проинициализировать [14] класс реализации на уровне обращения к каталогу, записываем в него следующее (ссылка на github [15]).

from .api import Dou

Финальный этап — «setup.py» (ссылка на github [16]) описывает ряд данных, которые необходимы для сборки проекта из исходников (подробнее здесь [17]) — понятнее станет на практике, когда повзаимодействуете с архивацией и распределением пакета. Описывать что-либо излишне, все должно быть понятно интуитивно.

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

setup(
    name='DouAPI',
    version='1.0.0',
    author='DmytryiStriletskyi',
    author_email='dmytryi.striletskyi@gmail.com',
    url='https://github.com/DmytryiStriletskyi/DouAPI',
    description='Dou API wrapper',
    download_url='https://github.com/DmytryiStriletskyi/DouAPI/archive/master.zip',
    license='MIT',

    packages=['dou'],
    install_requires=['requests'],

    classifiers=[
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
    ]
)

Python Package Index (PIP)

В сети существует множество инструкций по инсталляции пакетов в общий каталог, поэтому в данной статье я буду описывать один-единственный метод, который оказался наиболее удобным и продуктивным для меня:

  1. Регистрируем профиль в PyPI [18];
  2. устанавливаем утилиту «Twine» для регистрации и загрузки пакетов (подробнее здесь [19]) прямо в корень проекта — «pip install twine»;
  3. комплектуем дистрибутив — «python setup.py sdist»;
  4. следующий этап — «колеса», это современный формат распространения (фактически заархивированные данные) пакетов — «python setup.py bdist_wheel» (подробнее здесь [20] и здесь [21]);
  5. регистрация проекта [22] — необходимо передать указанные метаданные («setup.py»), которые расположены в файле PKG-INFO (находится внутри архивированного проекта);
  6. финальный этап — загрузить пакет — «twine upload dist/*».

Подробное руководство расположено по ссылке [23], есть вариант использования также тестового сервера и авторизации из каталога — здесь [24], в сети доступен материал на русском языке.

Остальные взаимодействия происходят через личный аккаунт в PyPI: удаление, редактирование, журнал историй, релизы, роли и так далее.

Репозиторий пакета

Если проделанная работа в перспективе может стать востребована аудиторией, нужно предпринять следующий ряд мер: собственно создать репозиторий, оформить титульный лист проекта (README.md), подключить тестирование и выбрать лицензию. Если с двумя первыми файлами понятно все, то следующие требуют уточнений.

Лицензия открытого программного обеспечения

Существует разнообразное множество лицензий, но лидирующие позиции занимают MIT License [25], Apache License [26] и GPL [27]. Я использую первую —
она разрешает использование и изменение кода любым образом (при условии наличия копирайта), а также имеет маленький размер. Существуют и минусы — отсутствует патентное право, присущее другим лицензиям, но маленьким проектам данная лицензия подходит хорошо.

Например, вот так выглядит лицензия в моем репозитории — MIT License [28], Github сам поставит наличие лицензии в верхнюю панельку репозитория.

Тестирование проекта

Travis CI [4] — если описать простыми словами, то каждое изменение в вашем проекте тестируется на указанных вами окружениях. Данная площадка достаточно легкая в использовании — помещаем файл (ссылка на github [29]) с названием «.travis.yml» в корневой каталог, в котором указывают: язык программирования, необходимые версии, интерпретаторы языка, какие зависимости установить при интеграции и разворачивании на сервере, плагин тестирования и еще ряд параметров.

Плюсов очень много, помимо самого тестирования — удобный интерфейс с множеством отображений статуса тестирования, ошибок, истории, быстрое подключение, проверка пользовательских коммитов в ваш проект до слияния. Также «Трэвис» сообщает о результатах по почте.

Пишем обертку над API, делаем из нее PIP-пакет, подключаем тестирование от Travis CI и смотрим на лицензии открытого ПО - 5

Первым делом устанавливаем крюк на репозиторий, следом добавляем файл «.travis.yml», затем пушим изменения в проекте и наблюдаем за результатами.

Пишем обертку над API, делаем из нее PIP-пакет, подключаем тестирование от Travis CI и смотрим на лицензии открытого ПО - 6

Буду рад, если данная статья поможет кому-нибудь в освоении нового материала или пробудит интерес к этой области. Присылайте свои вопросы и советы, если они у вас есть, в личные сообщения.

Автор: dmytryistriletskyi

Источник [30]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/236724

Ссылки в тексте:

[1] PyPI: https://pypi.python.org/pypi

[2] Github: https://github.com/

[3] MIT License: https://en.wikipedia.org/wiki/MIT_License

[4] Travis CI: https://travis-ci.org/

[5] API этого сайта: https://api.dou.ua/articles/

[6] DouAPI: https://github.com/DmytryiStriletskyi/DouAPI

[7] ссылка на github: https://github.com/DmytryiStriletskyi/DouAPI/blob/master/dou/api.py

[8] Requests: http://docs.python-requests.org/en/master/

[9] HTTP Headers: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields

[10] как написано здесь: https://www.programiz.com/python-programming/user-defined-exception

[11] здесь: http://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python

[12] переменные: https://docs.python.org/3.5/tutorial/classes.html#private-variables

[13] методы: http://www.diveintopython.net/object_oriented_framework/private_functions.html

[14] проинициализировать: https://docs.python.org/2/tutorial/modules.html#packages

[15] ссылка на github: https://github.com/DmytryiStriletskyi/DouAPI/blob/master/dou/__init__.py

[16] ссылка на github: https://github.com/DmytryiStriletskyi/DouAPI/blob/master/setup.py

[17] здесь: https://docs.python.org/3/install/index.html#the-new-standard-distutils

[18] Регистрируем профиль в PyPI: https://pypi.python.org/pypi?%3Aaction=register_form

[19] здесь: https://pypi.python.org/pypi/twine

[20] здесь: http://pythonwheels.com/

[21] здесь: https://pypi.python.org/pypi/wheel

[22] регистрация проекта: https://pypi.python.org/pypi?%3Aaction=submit_form

[23] по ссылке: https://packaging.python.org/distributing/

[24] здесь: http://peterdowns.com/posts/first-time-with-pypi.html

[25] MIT License: https://choosealicense.com/licenses/mit/

[26] Apache License: https://choosealicense.com/licenses/apache-2.0/

[27] GPL: https://choosealicense.com/licenses/gpl-2.0/

[28] MIT License: https://github.com/DmytryiStriletskyi/DouAPI/blob/master/LICENSE

[29] ссылка на github: https://github.com/DmytryiStriletskyi/DouAPI/blob/master/.travis.yml

[30] Источник: https://habrahabr.ru/post/320264/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best