Главная страница

Мэтиз. Изучаем Python. Crash course2 n d e d i t i o na h a n d s o n, p r o j e c t b a s e d i n t r o d u c t i o n t o p r o g r a m m i n g


Скачать 6.2 Mb.
НазваниеCrash course2 n d e d i t i o na h a n d s o n, p r o j e c t b a s e d i n t r o d u c t i o n t o p r o g r a m m i n g
Дата28.06.2022
Размер6.2 Mb.
Формат файлаpdf
Имя файлаМэтиз. Изучаем Python.pdf
ТипДокументы
#618322
страница41 из 52
1   ...   37   38   39   40   41   42   43   44   ...   52
ПРИМЕЧАНИЕ Если эта команда не работает в macOS, попробуйте снова выполнить команду без флага --user .
Обработка ответа API
Теперь мы напишем программу, которая выдает вызов API для поиска на Github проектов Python с наибольшим количеством звезд:
python_repos.py

import requests
# Создание вызова API и сохранение ответа.

url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'

headers = {'Accept': 'application/vnd.github.v3+json'}

r = requests.get(url, headers=headers)

print(f"Status code: {r.status_code}")
# Сохранение ответа API в переменной.

response_dict = r.json()
# Обработка результатов.
print(response_dict.keys())
В точке  импортируется модуль requests
. В точке  URL-адрес вызова API со- храняется в переменной url
. В настоящее время GitHub использует третью версию
API, поэтому для вызова API определяются заголовки , которые явно требуют использовать эту версию API. После этого модуль requests используется для вы- зова .

Использование API веб-приложений 377
Мы вызываем метод get()
и передаем ему URL и заголовок, а объект ответа со- храняется в переменной r
. Объект ответа содержит атрибут status_code
, в котором хранится признак успешного выполнения запроса. (Код 200 — признак успешного ответа.) В точке  программа выводит значение status_code
, чтобы вы могли убе- диться в том, что вызов был обработан успешно.
API возвращает информацию в формате JSON, поэтому в программе используется метод json()
 для преобразования информации в словарь Python. Полученный словарь сохраняется в переменной response_dict
Наконец, программа выводит ключи словаря response_dict
, и мы видим следую- щее:
Status code: 200
dict_keys(['total_count', 'incomplete_results', 'items'])
Код статуса 200 означает, что запрос был обработан успешно. Словарь ответа со- держит всего три ключа:
'total_count'
,
'incomplete_results'
и 'items'
. Присмо- тримся повнимательнее к словарю ответа.
ПРИМЕЧАНИЕ Подобные простые вызовы должны возвращать полный набор ре- зультатов, поэтому значение, связанное с 'incomplete_results', можно достаточно безопасно игнорировать . Но если ваша программа выдает более сложные вызовы API, обязательно проверяйте это значение .
Работа со словарем ответа
Итак, полученная при вызове API информация хранится в словаре, и мы можем заняться работой с данными. Для начала построим сводку с обобщенными сведе- ниями — это позволит убедиться в том, что вызов вернул ожидаемую информацию, и перейти к анализу интересующих данных.
python_repos.py
import requests
# Создание вызова API и сохранение ответа.
# Сохранение ответа API в переменной.
response_dict = r.json()

print(f"Total repositories: {response_dict['total_count']}")
# Анализ информации о репозиториях.

repo_dicts = response_dict['items']
print(f"Repositories returned: {len(repo_dicts)}")
# Анализ первого репозитория.

repo_dict = repo_dicts[0]

pprint(f"\nKeys: {len(repo_dict)}")

for key in sorted(repo_dict.keys()):
print(key)

378 Глава 17 • Работа с API
В точке  выводится значение, связанное с 'total_count'
, которое представляет общее количество репозиториев Python в GitHub.
Значение, связанное с 'items'
, представляет собой список со словарями, каждый из которых содержит данные об одном репозитории Python. В точке  этот список словарей сохраняется в repo_dicts
. Затем программа выводит длину repo_dicts
, чтобы пользователь видел, по какому количеству репозиториев имеется инфор- мация.
Чтобы получить первое представление об информации, возвращенной по каждому репозиторию, программа извлекает первый элемент из repo_dicts и сохраняет его в repo_dict
. Затем программа выводит количество ключей в словаре — это зна- чение определяет объем доступной информации . В точке  выводятся все ключи словаря; по ним можно понять, какая информация включена в ответ.
Из сводки начинает вырисовываться более четкая картина полученных данных:
Status code: 200
Total repositories: 3494030
Repositories returned: 30

Keys: 73
archive_url archived assignees_url url watchers watchers_count
API GitHub возвращает подробную информацию о каждом репозитории: в repo_
dict
73 ключа . Просмотр ключей дает представление о том, какую информацию можно извлечь о проекте. (Чтобы узнать, какую информацию можно получить через API, следует либо прочитать документацию, либо проанализировать инфор- мацию в коде, как мы и поступаем.)
Прочитаем значения некоторых ключей repo_dict
:
python_repos.py
# Анализ информации о репозиториях.
repo_dicts = response_dict['items']
print(f"Repositories returned: {len(repo_dicts)}")
# Анализ первого репозитория.
repo_dict = repo_dicts[0]
print("\nSelected information about first repository:")

print(f"Name: {repo_dict['name']}")

print(f"Owner: {repo_dict['owner']['login']}")

print(f"Stars: {repo_dict['stargazers_count']}")
print(f"Repository: {repo_dict['html_url']}")

Использование API веб-приложений 379

print(f"Created: {repo_dict['created_at']}")

print(f"Updated: {repo_dict['updated_at']}")
print(f"Description: {repo_dict['description']}")
В программе выводятся значения, связанные с некоторыми ключами словаря пер- вого репозитория. В точке  выводится имя проекта. Владельца проекта представ- ляет целый словарь, поэтому в точке  ключ owner используется для обращения к словарю, представляющему владельца, после чего ключ login используется для получения регистрационного имени владельца. В точке  выводится количество звезд, заработанных проектом, и URL репозитория GitHub проекта. Далее выво- дится дата создания  и последнего обновления репозитория . В завершение выводится описание репозитория; вывод должен выглядеть примерно так:
Status code: 200
Total repositories: 3494032
Repositories returned: 30
Selected information about first repository:
Name: awesome-python
Owner: vinta
Stars: 61549
Repository: https://github.com/vinta/awesome-python
Created: 2014-06-27T21:00:06Z
Updated: 2019-02-17T04:30:00Z
Description: A curated list of awesome Python frameworks, libraries, software and resources
Из вывода видно, что на момент написания книги самым «звездным» проектом
Python на GitHub был проект awesome-python, владельцем которого является пользователь vinta, и звезды этот проект получил более чем от 60 000 пользователей
GitHub. Мы видим URL репозитория проекта, дату создания (июнь 2014 г.) и то, что проект недавно обновлялся. Наконец, из описания следует, что awesome-python содержит список самых популярных ресурсов Python.
Сводка самых популярных репозиториев
При построении визуализации этих данных на диаграмму необходимо нанести более одного репозитория. Напишем цикл для вывода информации о каждом ре- позитории, возвращаемом вызовом API, чтобы все эти репозитории можно было включить в визуализацию:
python_repos.py
# Анализ информации о репозиториях.
repo_dicts = response_dict['items']
print(f"Repositories returned: {len(repo_dicts)}")

print("\nSelected information about each repository:")

for repo_dict in repo_dicts:

380 Глава 17 • Работа с API
print(f"\nName: {repo_dict['name']}")
print(f"Owner: {repo_dict['owner']['login']}")
print(f"Stars: {repo_dict['stargazers_count']}")
print(f"Repository: {repo_dict['html_url']}")
print(f"Description: {repo_dict['description']}")
В точке  выводится приветственное сообщение. В точке  перебираются все словари в repo_dicts
. Внутри цикла выводится имя каждого проекта, его владелец, количество звезд, URL на GitHub и краткое описание проекта:
Status code: 200
Total repositories: 3494040
Repositories returned: 30
Selected information about each repository:
Name: awesome-python
Owner: vinta
Stars: 61549
Repository: https://github.com/vinta/awesome-python
Description: A curated list of awesome Python frameworks, libraries, software and resources
Name: system-design-primer
Owner: donnemartin
Stars: 57256
Repository: https://github.com/donnemartin/system-design-primer
Description: Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.
Name: python-patterns
Owner: faif
Stars: 19058
Repository: https://github.com/faif/python-patterns
Description: A collection of design patterns/idioms in Python
В этих результатах встречаются интересные проекты; возможно, вам стоит при- смотреться к некоторым из них… Но не увлекайтесь, потому что мы собираемся создать визуализацию, которая существенно упростит чтение результатов.
Проверка ограничений частоты обращений API
Многие API ограничивают частоту обращений; иначе говоря, существует предел для количества запросов в определенный промежуток времени. Чтобы узнать, не приближаетесь ли вы к ограничениям GitHub, введите в браузере адрес https://api .
github .com/rate_limit
. Вы получите ответ, который выглядит примерно так:
{
"resources": {
"core": {
"limit": 60,
"remaining": 58,

Использование API веб-приложений 381
"reset": 1550385312
},

"search": {

"limit": 10,

"remaining": 8,

"reset": 1550381772
}
},
В этих данных нас интересует частота обращений для поискового API . В точке  видно, что предельная частота составляет 10 запросов в минуту и что на текущую минуту осталось еще 8 запросов . Значение reset представляет Unix-время, или
эпохальное время (число секунд, прошедших с полуночи 1 января 1970 г.) момента, когда произойдет сброс квоты . При достижении предельного количества обраще- ний вы получите короткий ответ, уведомляющий о достижении предела API. Если это произойдет, просто подождите, пока квота будет сброшена.
ПРИМЕЧАНИЕ Многие API требуют регистрации и получения ключа API для соверше- ния вызовов . На момент написания для GitHub такого требования не было, но если вы получите ключ API, предельная частота обращений для ваших программ значительно увеличится .
Визуализация репозиториев с использованием Plotly
Теперь, с появлением интересных данных, мы построим визуализацию, демонстри- рующую относительную популярность проектов Python в GitHub. Мы построим интерактивную столбцовую диаграмму: высота каждого столбца будет представ- лять количество звезд у проекта. Щелчок на столбце будет открывать домашнюю страницу проекта на GitHub. Сохраните копию программы, над которой вы рабо- таете, под именем python_repos_visual .py
, а затем приведите ее к следующему виду:
python_repos_visual.py
import requests

from plotly.graph_objs import Bar from plotly import offline

# Создание вызова API и сохранение ответа.
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
headers = {'Accept': 'application/vnd.github.v3+json'}
r = requests.get(url, headers=headers)
print(f"Status code: {r.status_code}")
# Обработка результатов.
response_dict = r.json()
repo_dicts = response_dict['items']

repo_names, stars = [], []
for repo_dict in repo_dicts:

382 Глава 17 • Работа с API
repo_names.append(repo_dict['name'])
stars.append(repo_dict['stargazers_count'])
# Построение визуализации.

data = [{
'type': 'bar',
'x': repo_names,
'y': stars,
}]

my_layout = {
'title': 'Most-Starred Python Projects on GitHub',
'xaxis': {'title': 'Repository'},
'yaxis': {'title': 'Stars'},
}
fig = {'data': data, 'layout': my_layout}
offline.plot(fig, filename='python_repos.html')
Мы импортируем класс
Bar и модуль offline из plotly
. Импортировать класс
Layout не нужно, потому что для определения макета будет использоваться сло- варь, как это делалось со списком data в проекте с землетрясениями из главы 16.
Затем выводится статус ответа на вызов API, чтобы мы сразу узнали о возможной проблеме с вызовом API . Часть кода обработки ответа API удалена, потому что фаза исследования данных осталась позади; мы знаем, что получены именно те данные, которые нам нужны.
В точке  создаются два пустых списка для хранения данных, включаемых в диа- грамму. Нам понадобится имя каждого проекта (для пометки столбцов) и количе- ство звезд, определяющее высоту столбцов. В цикле имя каждого проекта и коли- чество звезд присоединяются к соответствующему списку.
Затем определяется список data
. Он содержит словарь вроде того, который использовался в главе 16: он определяет тип диаграммы и содержит значения по осям x
и y
. По оси x
размещаются названия проектов, а по оси y
— количество звезд, назначенное каждому проекту.
В точке  макет диаграммы определяется при помощи словаря. Вместо того чтобы создавать экземпляр класса
Layout
, мы строим словарь с нужными спецификаци- ями макета. Далее назначается заголовок для диаграммы в целом, а также метки каждой оси.
Полученная диаграмма изображена на рис. 17.1. Мы видим, что несколько первых проектов существенно популярнее остальных, но все эти проекты занимают важное место в экосистеме Python.
Доработка диаграмм Plotly
Немного доработаем стилевое оформление диаграммы. Как было показано в главе 16, все директивы стилевого оформления включаются в виде пар «ключ- значение» в словари data и my_layout

Использование API веб-приложений 383
Рис. 17.1. Проекты Python на GitHub с наибольшим количеством звезд
Изменения в объекте data влияют на вид столбцов. Ниже приведена обновленная версия объекта data для диаграммы, которая назначает конкретный цвет и хорошо заметную границу для каждого столбца:
python_repos_visuals.py
data = [{
'type': 'bar',
'x': repo_names,
'y': stars,
'marker': {
'color': 'rgb(60, 100, 150)',
'line': {'width': 1.5, 'color': 'rgb(25, 25, 25)'}
},
'opacity': 0.6,
}]
Настройки marker влияют на внешний вид столбцов. Мы назначаем столбцам синий цвет и указываем, что они должны иметь серую границу толщиной 1,5 пик- села. Также для столбцов устанавливается прозрачность
0.6
, чтобы изображение казалось немного размытым.
Затем мы внесем изменения в my_layout
:
python_repos_visual.py
my_layout = {
'title': 'Most-Starred Python Projects on GitHub',

384 Глава 17 • Работа с API

'titlefont': {'size': 28},

'xaxis': {
'title': 'Repository',
'titlefont': {'size': 24},
'tickfont': {'size': 14},
},

'yaxis': {
'title': 'Stars',
'titlefont': {'size': 24},
'tickfont': {'size': 14},
},
}
Ключ 'titlefont'
добавлен для определения размера шрифта общего заголовка диаграммы . В словарь 'xaxis'
добавляются настройки для управления размером шрифта заголовка оси x
(
'titlefont'
) и меток делений (
'tickfont'
) . Так как речь идет об отдельных вложенных словарях, вы можете включить ключи для цвета и семейства шрифтов заголовков осей и меток делений. В точке  аналогичные настройки определяются для оси y
На рис. 17.2 изображена диаграмма с измененным оформлением.
Рис. 17.2. Диаграмма с улучшенным оформлением
Добавление подсказок
В Plotly при наведении указателя мыши на отдельный столбец отображается информация, которую этот столбец представляет. В текущей версии экранная
подсказка (tooltip) отображает количество звезд проекта. Давайте создадим не- стандартную подсказку, которая также будет выводить описание каждого проекта.

Использование API веб-приложений 385
Чтобы сгенерировать подсказки и изменить объект data
, необходимо извлечь до- полнительные данные:
python_repos_visual.py
# Обработка результатов.
response_dict = r.json()
repo_dicts = response_dict['items']

repo_names, stars, labels = [], [], []
for repo_dict in repo_dicts:
repo_names.append(repo_dict['name'])
stars.append(repo_dict['stargazers_count'])

owner = repo_dict['owner']['login']
description = repo_dict['description']

label = f"{owner}
{description}"
labels.append(label)
# Построение визуализации.
data = [{
'type': 'bar',
'x': repo_names,
'y': stars,

'hovertext': labels,
'marker': {
'color': 'rgb(60, 100, 150)',
'line': {'width': 1.5, 'color': 'rgb(25, 25, 25)'}
},
'opacity': 0.6,
}]
Сначала определяется новый пустой список labels для хранения текста, который должен выводиться для каждого проекта . В цикле, где происходит обработка дан- ных, мы извлекаем владельца и описание для каждого проекта . Plotly позволяет использовать разметку HTML в текстовых элементах, поэтому мы сгенерируем для метки текст с разрывом строки (
/>
) между именем владельца проекта и описа- нием . Затем метка сохраняется в списке labels
В словарь data добавляется запись с ключом 'hovertext'
, которой присваивается только что созданный список . При создании каждого столбца Plotly извлекает метки из списка и выводит их только в тот момент, когда пользователь задерживает указатель мыши над столбцом.
Полученная диаграмма изображена на рис. 17.3.
Добавление активных ссылок на диаграмму
Так как Plotly позволяет использовать HTML в текстовых элементах, диаграмму можно легко дополнить ссылками. Используем метки оси x
для того, чтобы пользо-

386 Глава 17 • Работа с API
Рис. 17.3. При наведении указателя мыши на столбец выводится информация о владельце и описание проекта ватель мог открыть домашнюю страницу проекта на GitHub. Необходимо извлечь
URL-адреса из данных и использовать их при генерировании меток для оси x
:
python_repos_visual.py
# Обработка результатов.
response_dict = r.json()
repo_dicts = response_dict['items']

repo_links, stars, labels = [], [], []
for repo_dict in repo_dicts:
repo_name = repo_dict['name']

repo_url = repo_dict['html_url']

repo_link = f"{repo_name}"
repo_links.append(repo_link)
stars.append(repo_dict['stargazers_count'])
# Построение визуализации.
data = [{
'type': 'bar',

'x': repo_links,
'y': stars,
}]

Использование API веб-приложений
1   ...   37   38   39   40   41   42   43   44   ...   52


написать администратору сайта