Библиотека запросов в Python

Как программистам, нам приходится иметь дело с API на ежедневной основе. Независимо от вашей должности, наступит момент, когда вам придется использовать API. Если вы работаете с языком Python и хотите узнать, как использовать API в Python, то этот блог для вас.

В этом блоге вы узнаете, как использовать библиотеку Requests для различных операций API. Мы рассмотрим методы GET, POST, PATCH и DELETE API. Для демонстрации всех операций я буду использовать API JSON Placeholder. JSON Placeholder — это бесплатный поддельный API для тестирования и создания прототипов.

Назначение библиотеки Requests в Python

Для получения любого вида данных через Интернет нам необходимо использовать протокол HTTP. Получаете ли вы веб-страницу или вызываете API, любые данные, передаваемые через интернет, должны следовать протоколу HTTP. Библиотека Requests позволяет нам использовать этот протокол HTTP вне браузера.

Зачем использовать Requests, если есть множество других вариантов, спросите вы? 🤔

Если вы посмотрите на статистику этого проекта, вы мне поверите. Не только статистика, но я знаю многих людей, которые предпочитают библиотеку Requests другим модулям HTTP. Согласно официальной странице библиотеки Requests python, «Requests позволяет вам отправлять HTTP/1.1 запросы чрезвычайно легко. Нет необходимости вручную добавлять строки запроса в URL или кодировать данные POST. Keep-alive и HTTP connection pooling на 100% автоматические, благодаря urllib3».


Requests на GitHub

Установка Requests в Python

Прежде чем мы сможем использовать любую стороннюю библиотеку, мы должны ее установить. Чтобы установить Requests, выполните следующую команду в терминале.

pip install requests
Войти в полноэкранный режим Выйти из полноэкранного режима

На Mac и Linux эта команда может выдать ошибку, говорящую о том, что pip недоступен. Если это так, попробуйте

pip3 install requests
Войти в полноэкранный режим Выйти из полноэкранного режима

Если вы все еще получаете ошибку, то, возможно, вам нужно сначала установить pip. Чтобы установить pip на вашу систему, ознакомьтесь с этой документацией.

Для проверки установки вы можете попробовать импортировать запросы в оболочке python.

Различные HTTP-методы в библиотеке Requests

Метод GET в библиотеке Requests

Как следует из названия, запрос get используется для получения данных. Итак, как мы это делаем?
Чтобы использовать метод GET, сначала нужно его импортировать. Вы можете использовать любой из следующих методов для импорта GET из модуля requests.

from requests import get
response = get('https://jsonplaceholder.typicode.com/posts/1')
Войти в полноэкранный режим Выйти из полноэкранного режима

ИЛИ

import requests
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
Войти в полноэкранный режим Выйти из полноэкранного режима

Здесь мы использовали API JSONPLaceholder. В случае успешного вызова API вернет следующие данные.

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipitnsuscipit recusandae consequuntur expedita et cumnreprehenderit molestiae ut ut quas totamnnostrum rerum est autem sunt rem eveniet architecto"
}
Войти в полноэкранный режим Выход из полноэкранного режима

Возникает вопрос, как узнать, что вызов API был успешным и мы получили данные.

Чтобы проверить это, мы можем использовать response.ok, response.status_code или response.raise_for_status(). Позвольте мне показать вам, что все эти три свойства и объекта возвращают в зависимости от успеха вызова API.

from requests import get

response = get('https://jsonplaceholder.typicode.com/posts/1')
print(f"OK: {response.ok}")
print(f"Status Code: {response.status_code}")
print(f"Error: {response.raise_for_status()}")

"""
OUTPUT:
-------
OK: True
Status Code: 200
Error: None
"""
Вход в полноэкранный режим Выход из полноэкранного режима

В приведенном выше коде мы видим, что если вызов API прошел успешно, то response.ok вернет True, а response.status_code вернет код статуса 200 series. Но следует заметить, что response.raise_for_status() ничего не вернет. Почему? Потому что мы не получили никакой ошибки от нашего бэкенда или вызова API.

Чтобы лучше понять все это, давайте посмотрим, что происходит, когда вызов API не является успешным.

from requests import get

response = get('https://jsonplaceholder.typicode.com/garbage')
print(f"OK: {response.ok}")
print(f"Status Code: {response.status_code}")
print(f"Error: {response.raise_for_status()}")

"""
OUTPUT:
-------
OK: False
Status Code: 404
Traceback (most recent call last):
  File "C:UsersSahilDocumentspCloudBlogPythonCodeAPI.py", line 6, in <module>
    print(f"Error: {response.raise_for_status()}")
  File "C:UsersSahilAppDataLocalProgramsPythonPython310libsite-packagesrequestsmodels.py", line 960, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://jsonplaceholder.typicode.com/garbag
"""
Вход в полноэкранный режим Выход из полноэкранного режима

Возможно, вы уже заметили, но позвольте мне пролить на это свет. Неудачный вызов API вернул False для свойства response.ok и 404 для свойства response.status_code. Но, в отличие от успешного вызова, мы получили ошибку от метода response.raise_for_status(). Как следует из названия и официальной документации модуля Requests, метод raise_for_status будет вызывать ошибку HTTPError, если она произошла. В общем, все, кроме серии 200, считается ошибкой.

Поэтому, как и многие другие, я предпочитаю использовать свойство status_code, чтобы я мог обрабатывать ошибки вручную, и в моих руках было то, как поведет себя мой код при возникновении ошибки. Несомненно, вы можете использовать общую обработку ошибок, если предпочитаете использовать raise_for_status().

Наш запрос успешен, что теперь?

Чтобы извлечь данные из ответа, нам нужно преобразовать его в формат JSON. В этом блоге я сосредоточусь на текстовых данных. Если вы хотите, чтобы я написал о других видах данных, свяжитесь со мной в Twitter или LinkedIn.

Чтобы преобразовать ответ в JSON, мы можем использовать метод json().

from requests import get

response = get('https://jsonplaceholder.typicode.com/posts/1')
data = response.json()
print(data)

"""
OUTPUT:
------
{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipitnsuscipit recusandae consequuntur expedita et cumnreprehenderit molestiae ut ut quas totamnnostrum rerum est autem sunt rem eveniet architecto"
}
"""
Вход в полноэкранный режим Выход из полноэкранного режима

По умолчанию Python преобразует любые данные JSON в свой родной формат словаря. Если вы выведете type(data), он вернет <class 'dict'>. Итак, теперь мы можем оперировать данными так же, как мы оперируем словарями в python. Иногда нам нужно передать токен аутентификации вместе с URL на сервер. Позже в этом блоге я покажу вам, как их передавать. Сначала я покажу вам, как использовать метод POST в библиотеке Requests.

Метод POST в библиотеке Requests

Метод POST обычно используется для создания записи. Например, вы создали сайт электронной коммерции и теперь хотите добавить товар на свой сайт из панели администратора. Для этого вы создадите POST-запрос со всеми необходимыми данными и учетными данными. После успешного выполнения POST-запроса API вы сможете получить новые данные, используя метод GET. Для выполнения запроса post вам понадобятся в основном две вещи: подходящая конечная точка и данные. В большинстве запросов вам также потребуется предоставить аутентификационные данные. Но сейчас давайте сосредоточимся на конечной точке и данных.

Итак, если мы хотим добавить новый пост в JSON Placeholder API, мы должны использовать /posts в качестве конечной точки. Мы получим добавленную запись в качестве ответа от JSON Placeholder API. Ответ любого метода зависит от того, как он настроен. Не обязательно отправлять данные повторно, но обычно это стандарт — отправлять назад только что добавленные или обновленные записи.

from requests import post

new_post_data = { 'title': 'foo', 'body': 'bar', 'userId': 1}
response = post('https://jsonplaceholder.typicode.com/posts', data=new_post_data)
data = response.json()
print(data)

"""
OUTPUT:
-------
{
  "userId": 1,
  "id": 101,
  "title": "foo",
  "body": "bar"
}
"""
Вход в полноэкранный режим Выход из полноэкранного режима

Здесь для передачи данных мы использовали словарь Python. Но при желании вы можете использовать и данные JSON. Чтобы использовать данные JSON вместо data в качестве аргумента нужно использовать json.

from requests import post

new_post_data = { 'title': 'foo', 'body': 'bar', 'userId': 1}
response = post('https://jsonplaceholder.typicode.com/posts', json=new_post_data)
data = response.json()
print(data)

"""
OUTPUT:
-------
{
  "userId": 1,
  "id": 101,
  "title": "foo",
  "body": "bar"
}
"""
Вход в полноэкранный режим Выход из полноэкранного режима

Вы можете подумать, что это одно и то же, тогда почему здесь два разных аргумента. Для нашей переменной new_post_data python автоматически преобразует ее в JSON и наоборот. Но иногда мы можем получать JSON-данные из других запросов API и должны передать их в тело POST-запроса. В этом случае нам нужно использовать аргумент json. Python преобразует данные в свои внутренние типы данных, но это происходит не всегда, поэтому чаще всего вместо использования json люди склонны модифицировать или преобразовывать данные во внутренний формат и использовать вместо этого аргумент data.

Методы PATCH & PUT в библиотеке запросов

PATCH и PUT, оба метода используются для обновления данных. В большинстве случаев вы можете использовать их альтернативно. Если вы хотите узнать больше, воспользуйтесь этим объяснением на Stack Overflow. Здесь я покажу вам, как можно использовать метод PATCH с пакетом Requests. Метод PATCH/PUT требует тех же аргументов, что и метод POST. Но главное отличие в том, что вместо вызова общей конечной точки мы используем конечную точку для конкретной записи.
Например, чтобы обновить данные для 2-й записи в JSON Placeholder API, мы будем использовать конечную точку /posts/2.

from requests import get, patch

response = get('https://jsonplaceholder.typicode.com/posts/2')
data = response.json()
print(data)
print('-'*15)

new_post_data = { 'title': 'foo', 'body': 'bar', 'userId': 1}
response = patch('https://jsonplaceholder.typicode.com/posts/2', json=new_post_data)
data = response.json()
print(data)

"""
OUTPUT:
-------
{'userId': 1, 'id': 2, 'title': 'qui est esse', 'body': 'est rerum tempore vitaensequi sint nihil reprehenderit dolor beatae ea dolores nequenfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendisnqui aperiam non debitis possimus qui neque nisi nulla'}
---------------
{'userId': 1, 'id': 2, 'title': 'foo', 'body': 'bar'}
"""
Вход в полноэкранный режим Выход из полноэкранного режима

Как вы могли заметить, мы использовали те же аргументы и процесс, что и в методе POST.

Метод DELETE в библиотеке запросов

Как следует из названия, метод DELETE используется для того, чтобы сделать запись удаленной или неактивной. Мы используем конкретную конечную точку, как и в методе PATCH. Бывают случаи, когда люди создают конечную точку для удаления всех записей, но и в этом случае процесс не отличается. Вам нужно будет изменить только конечную точку.
В нашем случае, чтобы удалить третью запись из JSON Placeholder API. Мы будем использовать следующий код:

from requests import delete

response = delete('https://jsonplaceholder.typicode.com/posts/3')
data = response.json()
print(data)
print(response.status_code)

"""
OUTPUT:
-------
{}
200
"""
Войти в полноэкранный режим Выйти из полноэкранного режима

В случае метода DELETE мы не получили никаких данных, поэтому в выводе мы видим {}.

Прежде чем мы перейдем к следующему разделу, я хотел бы упомянуть, что мы можем использовать response.text также для получения данных. Но он вернется в виде строки. Мы должны сами преобразовать ее в dict/json.

from ast import literal_eval
from json import loads
from requests import get

response = get('https://jsonplaceholder.typicode.com/posts/3')

text_data = response.text
print(text_data)
print(type(text_data))
print('-'*15)

json_data = loads(response.text)
print(json_data)
print(type(json_data))
print('-'*15)

json_data = loads(response.text)
dict_data = literal_eval(text_data)
print(dict_data)
print(type(dict_data))

"""
OUTPUT:
-------
{
  "userId": 1,
  "id": 3,
  "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
  "body": "et iusto sed quo iurenvoluptatem occaecati omnis eligendi aut adnvoluptatem doloribus vel accusantium quis pariaturnmolestiae porro eius odio et labore et velit aut"
}
<class 'str'>
---------------
{'userId': 1, 'id': 3, 'title': 'ea molestias quasi exercitationem repellat qui ipsa sit aut', 'body': 'et iusto sed quo iurenvoluptatem occaecati omnis eligendi aut adnvoluptatem doloribus vel accusantium quis pariaturnmolestiae porro eius odio et labore et velit aut'}
<class 'dict'>
---------------
{'userId': 1, 'id': 3, 'title': 'ea molestias quasi exercitationem repellat qui ipsa sit aut', 'body': 'et iusto sed quo iurenvoluptatem occaecati omnis eligendi aut adnvoluptatem doloribus vel accusantium quis pariaturnmolestiae porro eius odio et labore et velit aut'}
<class 'dict'>
"""
Вход в полноэкранный режим Выход из полноэкранного режима

Если вы хотите отправить данные в теле, вы можете использовать json.dumps() для преобразования dict в строку.

import json
from requests import post

payload_data = {'userId': 1, 'title': 'ea molestias quasi exercitationem repellat qui ipsa sit aut', 'body': 'et iusto sed quo iurenvoluptatem occaecati omnis eligendi aut adnvoluptatem doloribus vel accusantium quis pariaturnmolestiae porro eius odio et labore et velit aut'}
response = post('https://jsonplaceholder.typicode.com/posts', data=json.dumps(payload_data))

print(response.json())
"""
OUTPUT:
-------
{'id': 101}
"""
Войти в полноэкранный режим Выход из полноэкранного режима

Аутентификация и пользовательские заголовки в модуле Requests

Существует множество случаев, когда вам необходимо аутентифицировать/идентифицировать себя. Именно такой сценарий используется в большинстве сторонних библиотек.
Чтобы передать пользовательские заголовки в любом запросе. Мы должны использовать аргумент headers.

import json
from requests import post

payload_data = {'userId': 1, 'title': 'foo', 'body': 'bar'}

headers = {'content-type': 'application/json'}
response = post('https://jsonplaceholder.typicode.com/posts', data=json.dumps(payload_data), headers=headers)
print(response.json())
print('-'*15)

headers = {'content-type': 'application/text'}
response = post('https://jsonplaceholder.typicode.com/posts', data=json.dumps(payload_data), headers=headers)
print(response.json())

"""
OUTPUT:
-------
{'userId': 1, 'title': 'foo', 'body': 'bar', 'id': 101}
---------------
{'id': 101}
"""
Вход в полноэкранный режим Выход из полноэкранного режима

Здесь можно заметить разницу, когда мы используем application/text и application/json. Иногда нам необходимо явно указать, какой тип данных мы отправляем. Это только один случай, существует множество видов заголовков, которые вы можете использовать. Вы можете найти весь список в официальной документации.

Теперь наступает то, чего вы так долго ждали. Как передать данные аутентификации. В приведенном ниже примере я использовал API Twitter для получения данных о твитах. Twitter требует передавать либо токен Bearer, либо другие OAuth-токены при выполнении любых запросов.

import json
from requests import get

URL = "https://api.twitter.com/2/tweets?ids=1505694856240377860&tweet.fields=lang,public_metrics"
headers = {'content-type': 'application/json', 'Authorization': f'Bearer {ACCESS_TOKEN}'}

response = get(URL, headers=headers)
print(response.json()['data'][0])

"""
OUTPUT:
-------
{
  "text": "Inspiration is perishable—act on it immediately.nn— @naval",
  "id": "1505694856240377860",
  "lang": "en",
  "public_metrics": {
    "retweet_count": 29,
    "reply_count": 7,
    "like_count": 351,
    "quote_count": 0
  }
}
"""
Вход в полноэкранный режим Выход из полноэкранного режима

Как видите, вам просто нужно добавить пару ключ-значение Authentication в словарь заголовков. Сейчас я использую токен на предъявителя, но если вы используете другой тип токена, то значение будет отличаться от этого ключа аутентификации.

Что если вы хотите использовать аутентификацию OAuth вместо токена на предъявителя? Чтобы использовать аутентификацию OAuth, вы можете использовать библиотеку requests-oauthlib. Вы можете установить ее с помощью следующей команды терминала:

pip install requests-oauthlib
Войти в полноэкранный режим Выйти из полноэкранного режима

После установки библиотеки requests-oauthlib и ее проверки используйте следующий фрагмент кода для использования аутентификации OAuth1 в модуле Requests.

import json
from requests import get
from requests_oauthlib import OAuth1

URL = "https://api.twitter.com/2/tweets?ids=1505694856240377860&tweet.fields=lang,public_metrics"
auth = OAuth1(CONSUMER_KEY, CONSUMER_SECRET,ACCESS_KEY, ACCESS_SECRET)

response = get(URL,  auth=auth)
print(response.json()["data"][0])

"""
OUTPUT:
-------
{
  "text": "Inspiration is perishable—act on it immediately.nn— @naval",
  "id": "1505694856240377860",
  "lang": "en",
  "public_metrics": {
    "retweet_count": 29,
    "reply_count": 7,
    "like_count": 351,
    "quote_count": 0
  }
}
"""
Вход в полноэкранный режим Выйти из полноэкранного режима

Заключение

уффффф! 13 минут чтения ха😆!

Вот и все, друзья. Надеюсь, вы получили лучшее представление о том, как использовать библиотеку Requests в Python. Помимо вызова API, есть очень много вещей, которые вы можете сделать с помощью библиотеки Requests в сочетании с другими библиотеками.

Обязательно поделитесь любыми мыслями, вопросами или проблемами. Я буду рад их увидеть. Дайте мне знать, если вам нужна помощь или вы хотите что-то обсудить. Свяжитесь со мной в Twitter или LinkedIn.

Оцените статью
devanswers.ru
Добавить комментарий