Мэтиз. Изучаем 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.
|
387 Список, создаваемый на базе repo_names , переименован в repo_links , чтобы он более точно отражал свойства информации, объединяемой для диаграммы . За- тем мы извлекаем URL-адрес проекта из repo_dict и присваиваем его временной переменной repo_url . В точке генерируется ссылка на проект. Для этого используется якорный тег HTML вида текст ссылки . Затем ссылка присоединяется к списку repo_links В точке этот список используется для получения значений оси x диаграммы. Результат выглядит так же, как прежде, но теперь пользователь может щелкнуть на любом из имен проектов в нижней части диаграммы, чтобы посетить домашнюю страницу этого проекта на GitHub. Нам удалось построить интерактивную, содер- жательную визуализацию данных, полученных через API! Подробнее о Plotly и GitHub API Если вам захочется больше узнать о работе с диаграммами Plotly, в интернете есть пара хороших мест. Руководство пользователя Plotly находится по адресу https:// plot .ly/python/user-guide/ . Этот ресурс поможет лучше понять, как Plotly использует ваши данные для построения визуализации и почему выбран именно такой подход к определению визуализаций данных. На странице https://plot .ly/python/reference/ перечислены все параметры, использу- емые для настройки визуализаций Plotly. Здесь приведены все возможные типы диаграмм, а также все атрибуты, которые могут устанавливаться для всех параме- тров конфигурации. За дополнительной информацией о GitHub API обращайтесь к документации по адресу https://developer .github .com/v3/ . Из документации вы узнаете, как извлекать разнообразную информацию из GitHub. Если у вас уже имеется учетная запись GitHub, вы можете работать как со своими данными, так и с общедоступными данными из репозиториев других пользователей. API Hacker News Чтобы познакомиться с использованием вызовов API для других сайтов, мы об- ратимся к сайту Hacker News ( http://news .ycombinator .com/ ). На этом сайте поль- зователи делятся друг с другом статьями, посвященными программированию и технологиям, а также активно обсуждают эти статьи. API сайта Hacker News предоставляет доступ ко всем статьям и комментариям на сайте, а для его исполь- зования не требуется регистрация с получением ключа. Следующий вызов возвращает информацию о текущей самой популярной статье (на момент написания книги): https://hacker-news.firebaseio.com/v0/item/19155826.json 388 Глава 17 • Работа с API Если ввести этот URL в браузере, вы увидите, что текст на странице заключен в фигурные скобки; это означает, что перед вами словарь. Но в ответе трудно разо- браться без дополнительного форматирования. Обработаем URL методом json. dump() , как было сделано в проекте с землетрясениями из главы 16, чтобы нам было удобнее изучать возвращенную информацию: hn_article.py import requests import json # Вызов API и сохранение ответа. url = 'https://hacker-news.firebaseio.com/v0/item/19155826.json' r = requests.get(url) print(f"Status code: {r.status_code}") # Анализ структуры данных. response_dict = r.json() readable_file = 'data/readable_hn_data.json' with open(readable_file, 'w') as f: json.dump(response_dict, f, indent=4) В этой программе все должно быть вам знакомо, потому что все эти средства ис- пользовались в двух предшествующих главах. Ответ представляет собой словарь с информацией о статье с идентификатором 19155826: readable_hn_data.json { "by": "jimktrains2", ❶ "descendants": 220, "id": 19155826, ❷ "kids": [ 19156572, 19158857, ], "score": 722, "time": 1550085414, ❸ "title": "Nasa's Mars Rover Opportunity Concludes a 15-Year Mission", "type": "story", ❹ "url": "https://www.nytimes.com/.../mars-opportunity-rover-dead.html" } Словарь содержит ряд ключей, которые могут нам пригодиться. Ключ 'descen- dants' содержит количество комментариев, полученных статьей . Ключ 'kids' предоставляет идентификаторы всех комментариев, сделанных непосредственно в ответ на эту статью . У каждого из этих комментариев могут быть свои дочерние комментарии, так что количество потомков у статьи может быть больше количества дочерних комментариев. Также в данных виден заголовок обсуждаемой статьи и ее URL-адрес . Использование API веб-приложений 389 Следующий URL возвращает простой список всех идентификаторов текущих по- пулярных статей на сайте Hacker News: https://hacker-news.firebaseio.com/v0/topstories.json При помощи этого вызова можно узнать, какие статьи находятся на домашней стра- нице, а затем сгенерировать серию вызовов API, аналогичных приведенному выше. Это позволит нам вывести сводку всех статей, находящихся на главной странице Hacker News в данный момент: hn_submissions.py from operator import itemgetter import requests # Создание вызова API и сохранение ответа. ❶ url = 'https://hacker-news.firebaseio.com/v0/topstories.json' r = requests.get(url) print(f"Status code: {r.status_code}") # Обработка информации о каждой статье. ❷ submission_ids = r.json() ❸ submission_dicts = [] for submission_id in submission_ids[:30]: # Создание отдельного вызова API для каждой статьи. ❹ url = f"https://hacker-news.firebaseio.com/v0/item/{submission_id}.json" r = requests.get(url) print(f"id: {submission_id}\tstatus: {r.status_code}") response_dict = r.json() # Построение словаря для каждой статьи. ❺ submission_dict = { 'title': response_dict['title'], 'hn_link': f"http://news.ycombinator.com/item?id={submission_id}", 'comments': response_dict['descendants'], } ❻ submission_dicts.append(submission_dict) ❼ submission_dicts = sorted(submission_dicts, key=itemgetter('comments'), reverse=True) ❽ for submission_dict in submission_dicts: print(f"\nTitle: {submission_dict['title']}") print(f"Discussion link: {submission_dict['hn_link']}") print(f"Comments: {submission_dict['comments']}") Сначала программа создает вызов API и выводит статус ответа . Этот вызов API возвращает список идентификаторов 500 самых популярных статей на Hacker News на момент выдачи вызова. Текст ответа преобразуется в список Python , который сохраняется в переменной submission_ids . Идентификаторы будут использованы для построения набора словарей, каждый из которых содержит информацию об одной из текущих статей. 390 Глава 17 • Работа с API В точке создается пустой список с именем submission_dicts для хранения сло- варей. Далее программа перебирает идентификаторы 30 самых популярных статей и выдает новый вызов API для каждой статьи, генерируя URL с текущим значением submission_id . Также выводится статус каждого запроса, чтобы мы могли про- верить, успешно ли он был обработан. В точке создается словарь для текущей обрабатываемой статьи, в котором со- храняется заголовок статьи, ссылка на страницу с ее обсуждением и количество комментариев к статье. Затем каждый элемент submission_dict присоединяется к списку submission_dicts . Статьи Hacker News ранжируются по общей системе, основанной на нескольких факторах: сколько раз за статью голосовали, сколько комментариев она получила и давно ли была опубликована. Требуется отсортировать список словарей по ко- личеству комментариев. Для этого мы используем функцию itemgetter() из модуля operator . Мы передаем этой функции ключ 'comments' , а она извлекает значение, связанное с данным ключом, из каждого словаря в списке. Функция sorted() затем использует это значение для сортировки списка. Мы сортируем список в обратном порядке, чтобы публикации с наибольшим количеством ком- ментариев оказались на первом месте. После того как список будет отсортирован, мы перебираем элементы и выво- дим для каждой из самых популярных статей три атрибута: заголовок, ссылку на страницу обсуждения и текущее количество комментариев: Status code: 200 id: 19155826 status: 200 id: 19180181 status: 200 id: 19181473 status: 200 Title: Nasa's Mars Rover Opportunity Concludes a 15-Year Mission Discussion link: http://news.ycombinator.com/item?id=19155826 Comments: 220 Title: Ask HN: Is it practical to create a software-controlled model rocket? Discussion link: http://news.ycombinator.com/item?id=19180181 Comments: 72 Title: Making My Own USB Keyboard from Scratch Discussion link: http://news.ycombinator.com/item?id=19181473 Comments: 62 Аналогичный процесс применяется для обращения и анализа информации из лю- бого API. С такими данными вы сможете построить визуализацию, показывающую, какие публикации вызывали наиболее активные обсуждения за последнее время. Этот метод также лежит в основе приложений, предоставляющих специализиро- ванные средства чтения таких сайтов, как Hacker News. Чтобы больше узнать об информации, доступной через Hacker News API, посетите страницу документации по адресу https://github .com/HackerNews/API/ Итоги 391 УПРАЖНЕНИЯ 17.1. Другие языки: измените вызов API в программе python_repos .py так, чтобы на диа- грамме отображались самые популярные проекты на других языках. Попробуйте такие языки, как JavaScript, Ruby, C, Java, Perl, Haskell и Go. 17.2. Активные обсуждения: на основании данных из hn_submissions .py постройте столбцо- вую диаграмму самых активных обсуждений, проходящих на Hacker News. Высота каждого столбца должна соответствовать количеству комментариев к каждой статье. Метка столбца должна включать заголовок статьи, а сам столбец должен служить ссылкой на страницу обсуждения этой публикации. 17.3. Тестирование python_repos.py: в python_repos.py для проверки успешности вызова API выводится значение status_code . Напишите программу test_python_repos .py , которая использует модуль unittest для проверки того, что значение status_code равно 200. При- думайте другие условия, которые могут проверяться при тестировании, — например, что количество возвращаемых элементов совпадает с ожидаемым, а общее количество репози- ториев превышает некоторый порог. 17.4. Дальнейшие исследования: ознакомьтесь с документацией Plotly и GitHub API (или Hacker News API). Используйте полученную информацию для настройки стилево- го оформления уже построенных диаграмм или загрузите другие данные и постройте соб- ственные визуализации. Итоги В этой главе вы узнали, как использовать API для написания программ, автома- тически собирающих необходимые данные и использующих полученную инфор- мацию для создания визуализации. Мы использовали GitHub API для получения информации о самых популярных проектах Python на GitHub, а также в общих чертах рассмотрели API Hacker News. Вы узнали, как с помощью пакета Requests автоматически выдать вызов API к GitHub и как обработать результаты этого вы- зова. Также были описаны некоторые средства конфигурации Plotly, позволяющие выполнить дополнительную настройку внешнего вида создаваемых диаграмм. В последнем проекте мы используем Django для построения веб-приложения, которое станет нашим последним проектом в этой книге. Проект 3 Веб-приложения 18 Знакомство с Django Современные веб-сайты в действительности представляют собой многофункцио- нальные приложения, достаточно близкие к полноценным приложениям для настольных систем. Python содержит мощный инструментарий для построения веб-приложений, который называется Django. Django представляет собой веб- фреймворк — набор средств, упрощающих построение интерактивных веб-сайтов. В этой главе вы научитесь использовать Django ( http://djangoproject .com/ ) для по- строения проекта Learning Log — сетевой журнальной системы для отслеживания информации, полученной вами по определенной теме. Мы напишем спецификацию для этого проекта, а затем определим модели для данных, с которыми будет работать приложение. Мы воспользуемся администра- тивной системой Django для ввода некоторых начальных данных, а затем научимся писать представления и шаблоны, на базе которых Django будет строить страницы нашего сайта. Django может реагировать на запросы страниц, упрощает чтение и запись информа- ции в базы данных, управление пользователями и многие другие операции. В гла- вах 19 и 20 мы доработаем проект Learning Log, а затем развернем его на сервере, чтобы вы (и ваши друзья) могли использовать его. Подготовка к созданию проекта В начале работы над проектом необходимо описать проект в спецификации. Затем вы создадите виртуальную среду для построения проекта. Написание спецификации В полной спецификации описываются цели проекта, его функциональность, а также внешний вид и интерфейс пользователя. Как и любой хороший проект или бизнес-план, спецификация должна сосредоточиться на самых важных аспек- тах и обеспечивать планомерную разработку проекта. Здесь мы не будем писать полную спецификацию, а сформулируем несколько четких целей, которые будут задавать направление процесса разработки. Вот как выглядит спецификация: 394 Глава 18 • Знакомство с Django Мы напишем веб-приложение с именем Learning Log, при помощи которого пользователь сможет вести журнал интересующих его тем и создавать записи в журнале во время изучения каждой темы. Домашняя страница Learning Log содержит описание сайта и приглашает пользователя зарегистрироваться либо ввести свои учетные данные. После успешного входа пользователь по- лучает возможность создавать новые темы, добавлять новые записи, читать и редактировать существующие записи. Во время изучения нового материала бывает полезно вести журнал того, что вы узнали, — записи пригодятся для контроля и возвращения к необходимой инфор- мации. Хорошее приложение повышает эффективность этого процесса. Создание виртуальной среды Для работы с Django необходимо сначала создать виртуальную среду для работы. Виртуальная среда представляет собой подраздел системы, в котором вы можете устанавливать пакеты в изоляции от всех остальных пакетов Python. Отделение библиотек одного проекта от других проектов принесет пользу при развертывании Learning Log на сервере в главе 20. Создайте для проекта новый каталог с именем learning_log , перейдите в этот каталог в терминальном режиме и создайте виртуальную среду следующими командами: learning_log$ python -m venv ll_env learning_log$ Команда запускает модуль виртуальной среды venv и использует его для создания виртуальной среды с именем ll_env (обратите внимание: в имени ll_env две бук- вы l , а не одна). Если для запуска программ или установки пакетов используется другая команда (например, python3 ), подставьте ее на место python Активизация виртуальной среды После того как виртуальная среда будет создана, ее необходимо активизировать следующей командой: learning_log$ source ll_env/bin/activate ❶ (ll_env)learning_log$ Команда запускает сценарий activate из каталога ll_env/bin . Когда среда активизирует- ся, ее имя выводится в круглых скобках ; теперь вы можете устанавливать пакеты в среде и использовать те пакеты, что были установлены ранее. Пакеты, установлен- ные в ll_env , будут доступны только в то время, пока среда остается активной. ПРИМЕЧАНИЕ Если вы работаете в системе Windows, используйте команду ll_env\ Scripts\activate (без слова source) для активизации виртуальной среды . Если вы используете PowerShell, слово Activate должно начинаться с буквы верхнего регистра . Подготовка к созданию проекта 395 Чтобы завершить использование виртуальной среды, введите команду deactivate : (ll_env)learning_log$ deactivate learning_log$ Среда также становится неактивной при закрытии терминального окна, в котором она работает. Установка Django После того как вы создали свою виртуальную среду и активизировали ее, устано- вите Django: (ll_env)learning_log$ pip install django Collecting django Installing collected packages: pytz, django Successfully installed django-2.2.0 pytz-2018.9 sqlparse-0.2.4 (ll_env)learning_log$ Так как вы работаете в виртуальной среде, эта команда выглядит одинаково во всех системах. Использовать флаг --user не нужно, как и использовать более длинные команды вида python -m pip install имя_пакета. Помните, что с Django можно работать только в то время, пока среда остается активной. ПРИМЕЧАНИЕ Новая версия Django выходит приблизительно раз в восемь месяцев; возможно, при установке Django будет выведен новый номер версии . Скорее всего, про- ект будет работать в том виде, в каком он здесь приведен, даже в новых версиях Django . Если вы хотите использовать ту же версию Django, которая используется здесь, введите команду pip install django==2.2.* . Команда установит последний выпуск Django 2 .2 . Если у вас возникнут проблемы, связанные с версией, обращайтесь к электронным ре- сурсам книги по адресу https://nostarch .com/pythoncrashcourse2e/ Создание проекта в Django Не выходя из активной виртуальной среды (пока ll_env выводится в круглых скобках), введите следующие команды для создания нового проекта: ❶ (ll_env)learning_log$ django-admin.py startproject learning_log . ❷ (ll_env)learning_log$ ls learning_log ll_env manage.py ❸ (ll_env)learning_log$ ls learning_log __init__.py settings.py urls.py wsgi.py Команда приказывает Django создать новый проект с именем learning_log Точка в конце команды создает новый проект со структурой каталогов, которая упрощает развертывание приложения на сервере после завершения разработки. 396 Глава 18 • Знакомство с Django ПРИМЕЧАНИЕ Не забывайте про точку, иначе у вас могут возникнуть проблемы с конфигурацией при развертывании приложения . А если вы все же забыли, удалите созданные файлы и папки (кроме ll_env) и снова выполните команду . Команда ls ( dir в Windows) показывает, что Django создает новый каталог с име- нем learning_log . Также создается файл manage .py — короткая программа, которая получает команды и передает их соответствующей части Django для выполнения. Мы используем эти команды для управления такими задачами, как работа с базами данных и запуск серверов. В каталоге learning_log находятся четыре файла , важнейшими из которых явля- ются файлы settings .py , urls .py и wsgi .py . Файл settings .py определяет то, как Django взаимодействует с вашей системой и управляет вашим проектом. Мы изменим некоторые из существующих настроек и добавим несколько новых настроек в ходе разработки проекта. Файл urls .py сообщает Django, какие страницы следует строить в ответ на запросы браузера. Файл wsgi .py помогает Django предоставлять созданные файлы (имя файла является сокращением от «Web Server Gateway Interface»). Создание базы данных Так как Django хранит большую часть информации в базе данных, относящейся к проекту, на следующем этапе необходимо создать базу данных, с которой Django сможет работать. Введите следующую команду (все еще не покидая активную среду): (ll_env)learning_log$ |