В файле requests/api.py нет новой функциональности; она существует для того, чтобы предоставить пользователю простой API. Плюс размещение строковых методов HTTP непосредственно в API в качестве имен функций означает, что любая опечатка в имени метода будет найдена на ранних этапах, например:

>>> requests.foo('http://www.python.org')

Traceback (most recent call last):

····File "", line 1, in

AttributeError: 'module' object has no attribute 'foo'

>>>

>>> requests.request('foo', 'http://www.python.org')

Объекты класса Request и PreparedRequest (мы все — ответственные пользователи)

Файл __init__.py предоставляет классы Request, PreparedRequest и Response из файла models.py как часть основного API. Зачем вообще нужен файл models.Request? В стандартной библиотеке уже существует urllib.requests.Request, и в файле cookies.py находится объект MockRequest, который оборачивает models.Request, чтобы он работал как urllib.requests.Request для http.cookiejar[66]. Это означает, что любые методы, необходимые для взаимодействия объекта типа Request с библиотекой cookies, намеренно исключены из requests.Request. Для чего эти лишние усилия?

Дополнительные методы в MockRequest (нужен для эмуляции urllib.request.Request для библиотеки cookies) используются библиотекой cookies для управления cookies. За исключением функции get_type() (которая обычно возвращает http или https при использовании) и непроверяемого свойства (в нашем случае True), они связаны с URL или заголовками запросов.

Связанные с заголовками:

• add_unredirected_header() — добавить в заголовок новую пару ключ-значение;

• get_header() — получить определенное имя из словаря заголовков;

• get_new_headers() — получить словарь, содержащий новые заголовки (которые добавлены с помощью cookielib);

• has_header() — проверяем, существует ли имя в словаре заголовков.

Связанные с URL:

• get_full_url() — соответствует своему имени;

• host и origin_req_host — свойства, чьи значения устанавливаются путем вызова методов get_host() и get_origin_req_host() соответственно;

• get_host() — извлекает хост из URL (например, www.python.org из https://www.python.org/dev/peps/pep-0008/);

• get_origin_req_host() — вызывает get_host()[67].

Все они являются функциями доступа, за исключением MockRequest.add_unredirected_header().

В строке документации к объекту MockRequest указывается, что «оригинальный объект запроса доступен только для чтения».

В requests.Request вместо этого непосредственно доступны атрибуты данных. Это делает все функции доступа ненужными: для получения или установки заголовков требуется лишь получить доступ к словарю request-instance.headers. Аналогично пользователь может получить или изменить строку URL: request-instance.url.

Объект PreparedRequest инициализируется пустым и заполняется при вызове метода prepared-request-instance.prepare(), что наполняет его релевантными данными (обычно получаемыми путем вызова объекта Request). В этот момент применяются исправления регистра символов, кодировки и пр. Содержимое объекта после подготовки можно будет отправить на сервер, но к каждому атрибуту все еще можно получить доступ непосредственно. Доступен даже PreparedRequest._cookies, однако нижнее подчеркивание, с которого начинается это имя, намекает на то, что атрибут не предназначен для использования за пределами класса, не запрещая при этом доступ (мы все — ответственные пользователи).

Этот выбор позволяет пользователю изменять объекты, но они становятся гораздо читабельнее, а дополнительная работа, выполняемая внутри PreparedRequest, позволяет исправить проблемы с регистром и использовать словарь вместо CookieJar (ищите оператор if isinstance()/else):

#

#… из файла models.py…

#

class PreparedRequest():

····#

····#…пропускаем все остальное…

····#

····def prepare_cookies(self, cookies):

········"""Подготавливает данные заданного HTTP cookie.

········Эта функция в итоге генерирует заголовок ''Cookie'' на основе

········предоставленных cookies с использованием cookielib. Из-за особенностей

········дизайна cookielib заголовок не будет сгенерирован повторно,

········если он уже существует. Это значит, что эта функция может быть

········вызвана всего один раз во время жизни объекта

Перейти на страницу:

Все книги серии Бестселлеры O'Reilly

Похожие книги