Rest запросы примеры python

Работа с REST API на Python

Изображение баннера

В этой статье вы узнаете как выполнять запросы к REST API на Python 3 и обрабатывать ответы.

Если ваша цель — создание своего REST API — переходите к статье «Flask»

Прежде чем что-то устанавливать убедитесь, что вы знакомы с работой в виртуальном окружении Python.

Прочитать об этом можно в статье «Виртуальные окружения в Python»

Подготовка

Активируйте ваше виртуальное окружение и установите requests командой

python -m pip install requests

Изучите список установленных модулей

Package Version ———- ——— certifi 2020.6.20 chardet 3.0.4 idna 2.10 pip 20.2.3 requests 2.24.0 setuptools 50.3.1 urllib3 1.25.10 wheel 0.35.1

requests подтягивает за собой requests, certifi , chardet, idna, urllib3

Проверить куда установился requests в этом окружении можно командой

python3 -m pip show requests

Name: requests Version: 2.24.0 Summary: Python HTTP for Humans. Home-page: https://requests.readthedocs.io Author: Kenneth Reitz Author-email: me@kennethreitz.org License: Apache 2.0 Location: /home/andrei/python/virtualenvs/answerit_env/lib/python3.8/site-packages Requires: certifi, chardet, urllib3, idna Required-by:

GET

Чтобы сделать GET запрос достаточно импортировать requests и выполнить requests. get

Создайте файл rdemo.py следующего содержания:

import requests r = requests. get (‘https://xkcd.com/353/’) print (r)

Запустите скрипт командой

Если получили 200 значит всё хорошо. Изменим наш код, чтобы узнать, какие действия мы можем произвести с объектом

dir(r) выдаст список доступных атрибутов и методов

import requests r = requests. get (‘https://topbicycle.ru/b/stels_pilot_950_md_26.php’) print (dir(r))

[‘__attrs__’, ‘__bool__’, ‘__class__’, ‘__delattr__’, ‘__dict__’, ‘__dir__’, ‘__doc__’, ‘__enter__’, ‘__eq__’, ‘__exit__’, ‘__format__’, ‘__ge__’, ‘__getattribute__’, ‘__getstate__’, ‘__gt__’, ‘__hash__’, ‘__init__’, ‘__init_subclass__’, ‘__iter__’, ‘__le__’, ‘__lt__’, ‘__module__’, ‘__ne__’, ‘__new__’, ‘__nonzero__’, ‘__reduce__’, ‘__reduce_ex__’, ‘__repr__’, ‘__setattr__’, ‘__setstate__’, ‘__sizeof__’, ‘__str__’, ‘__subclasshook__’, ‘__weakref__’, ‘_content’, ‘_content_consumed’, ‘_next’, ‘apparent_encoding’, ‘close’, ‘connection’, ‘content’, ‘cookies’, ‘elapsed’, ‘encoding’, ‘headers’, ‘history’, ‘is_permanent_redirect’, ‘is_redirect’, ‘iter_content’, ‘iter_lines’, ‘json’, ‘links’, ‘next’, ‘ok’, ‘raise_for_status’, ‘raw’, ‘reason’, ‘request’, ‘status_code’, ‘text’, ‘url’]

Более подробную информацию можно получить заменив dir(r) на help(r)

Если вам интересно — прочитайте статью requests help

Из этого документа можно узнать http статус содержится в атрибуте status_code

import requests r = requests. get (‘https://topbicycle.ru/b/stels_pilot_950_md_26.php’) print (r.status_code)

Если всё прошло успешно, то получите

ok вернёт True если ответ не 4XX или 5XX

headers возвращает заголовок ответа

Также из этого документа можно узнать что text возвращает содержимое ответа в формате unicode а content содержимое ответа в байтах

import requests r = requests. get (‘https://xkcd.com/353/’) print («content:») print («——«) print (r.content) print («——«) print («text:») print («——«) print (r.text)

Обычно content используют для работы с изображениями

Перейдите на TopBicycle.ru и найдите первое фото велосипеда.

Теперь измените код так, чтобы сохранить изображение в файл

import requests r = requests. get ( «https://topbicycle.ru/b/img/stels_pilot_950_MD_26.jpg» ) with open(«bike.jpg», «wb») as f: f.write(r.content)

Если всё прошло успешно, в вашей папке появится следующее фото

stels pilot 950 md 26 в сложенном виде изображение сайта www.TopBicycle.ru

GET с параметрами

Для проверки ваших навыков работы с REST API можно воспользоваться сайтом httpbin.org

Он будет возвращать вам обратно ваш запрос.

Параметры можно записать сразу после url за знаком вопроса, но надёжнее оформить их в виде отдельного словаря (dictionary).

import requests payload = r = requests. get ( «https://httpbin.org/get» , params= payload) print (f»url: \n\ntext: \n «)

POST

Чтобы отправить и проверить POST запрос внесите небольшие изменения в код.

Очевидно, что GET нужно заменить на POST, также params нужно заменить на data или json

data – (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the Request.

json – (optional) A JSON serializable Python object to send in the body of the Request.

import requests payload = r = requests. post (‘https://httpbin.org/post’, data= payload) print (f»url: \n\ntext: \n «)

Ответы, которые мы получили с httpbin приходили в формате json.

Для работы c json бывает удобно использовать встроенный метод .json()

В этом случае данные записываются в словарь и к ним очень легко обращаться.

Обратите внимание на «form» данные, которые были переданы возвращаются в этом поле.

Изменим код так, чтобы на экран выводились только эти данные

import requests payload = r = requests. post (‘https://httpbin.org/post’, data= payload) r_dict = r. json () print (r_dict[‘form’])

PUT

Всё аналогично POST просто замените post на put

Рассмотрим пример, в котором нужно передать в теле запроса json, а также использовать имеющийся токен для авторизации

import requests import json url = «http://urn.su» new_access_token = «sdlfjsljglkjfd;lkgjdlkhjlkjgdlkhjlkdjglkj» body = «»»[]»»» payload = json.loads(body) json_headers = < "Content-type" : "application/json" , "Authorization" : "Bearer %s" %new_access_token >r = requests.put(url, headers =json_headers, json =payload, verify =False)

Обратите внимание на следующие моменты

  • При передаче JSON нужно обязательно указать заголовок ‘Content-type’: ‘application/json’
  • Токен передаётся с помощью Bearer
  • Можно легко преобразовать данные в JSON с помощью json.loads()

Обработка ответа

Рассмотрим приёмы, которые пригодятся при работе с полученными данными

Простейший ответ сервера, например 200 может вообще не содержать никаких данных

response = requests.delete ( url , headers=headers , verify= False ) print ( f»type(response): < type (response)>» ) print ( f»response.__repr__: < repr (response)>» ) print ( f»response.__str__: < str (response)>» ) print ( f»response.text: » )

Очень часто данные приходят в формате json.

Например, нужно извлечь из них токен, который хранится в access_token

Чтобы его получить, воспользуйтесь методом json() который возвращает словарь ().

И из этого словаря получите токен по ключевому слову access_token

r_dict = response.json() access_token = r_dict[ «access_token» ]

json.dumps

Если вы хотите сразу же изучить полученный json можно воспользоваться методом dumps()

import json print (json.dumps(response.json() , indent = 4 ))

Если вы получили не json а dict, json.dumps нужно использовать так:

import json print (json.dumps(resp.dict , indent = 4 , sort_keys = True ))

sort_keys делать не обязательно. Это я для примера показываю, что можно отсортировтаь ключевые слова.

Вытащить часть ответа

Часто интерес бывает не весь ответ, а только часть. О том как её грамотно выделить из ответа читайте в статье

Аутентификация

Рассмотрим базовую аутентификацию на сайте httpbin

Придумайте любое имя пользоватлея и пароль к нему.

Я придумал andrey с паролем heihei

Перейдите на httpbin.org . Убедитесь, что в адресной строке стоит basic-auth/andrey/heihei либо те логин и пароль, что придумали вы.

Authentication изображение с сайта www.andreyolegovich.ru

Введите ваши логин и пароль

Authentication изображение с сайта www.andreyolegovich.ru

Убедитесь, что аутентификация прошла успешно

Authentication изображение с сайта www.andreyolegovich.ru

Теперь проделаем такую же аутентификацию с помощью Python

Создайте файл auth_demo.py со следующим кодом

import requests r = requests. get ( ‘https://httpbin.org/basic-auth/andrey/heihei’ , auth= ( ‘andrey’ , ‘heihei’ ) ) print (r.text)

Ответ совпадает с тем что мы уже получали в браузере

Выполните такой же запрос, но с неправильным паролем. Убедитесь в том, что text ничего не содержит. Замените print (r.text) на print (r) и убедитесь, что полученный объект это

Задержка

Часто бывает нужно ограничить время ожидания ответа. Это можно сделать с помощью параметра timeout

Перейдите на httpbin.org раздел — / #/ Dynamic_data / delete_delay__delay_ и изучите документацию — если делать запрос на этот url можно выставлять время, через которое будет отправлен ответ.

Создайте файл timeout_demo.py следующего содержания

import requests r = requests. get (‘https://httpbin.org/delay/1’, timeout= 3) print (r)

Задержка равна одной секунде. А ждать ответ можно до трёх секунд.

Измените код так, чтобы ответ приходил заведомо позже чем наш таймаут в три секунды.

import requests r = requests. get (‘https://httpbin.org/delay/7’, timeout= 3) print (r)

Задержка равна семи секундам. А ждать ответ можно по-прежнему только до трёх секунд.

Traceback (most recent call last): File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 421, in _make_request six.raise_from(e, None) File «», line 3, in raise_from File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 416, in _make_request httplib_response = conn.getresponse() File «/usr/lib/python3.8/http/client.py», line 1347, in getresponse response.begin() File «/usr/lib/python3.8/http/client.py», line 307, in begin version, status, reason = self._read_status() File «/usr/lib/python3.8/http/client.py», line 268, in _read_status line = str(self.fp.readline(_MAXLINE + 1), «iso-8859-1») File «/usr/lib/python3.8/socket.py», line 669, in readinto return self._sock.recv_into(b) File «/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py», line 326, in recv_into raise timeout(«The read operation timed out») socket.timeout: The read operation timed out During handling of the above exception, another exception occurred: Traceback (most recent call last): File «/usr/lib/python3/dist-packages/requests/adapters.py», line 439, in send resp = conn.urlopen( File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 719, in urlopen retries = retries.increment( File «/usr/lib/python3/dist-packages/urllib3/util/retry.py», line 400, in increment raise six.reraise(type(error), error, _stacktrace) File «/usr/lib/python3/dist-packages/six.py», line 703, in reraise raise value File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 665, in urlopen httplib_response = self._make_request( File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 423, in _make_request self._raise_timeout(err=e, url=url, timeout_value=read_timeout) File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 330, in _raise_timeout raise ReadTimeoutError( urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host=’httpbin.org’, port=443): Read timed out. (read timeout=3) During handling of the above exception, another exception occurred: Traceback (most recent call last): File «timeout_demo.py», line 4, in r = requests.get(‘https://httpbin.org/delay/7’, timeout=3) File «/usr/lib/python3/dist-packages/requests/api.py», line 75, in get return request(‘get’, url, params=params, **kwargs) File «/usr/lib/python3/dist-packages/requests/api.py», line 60, in request return session.request(method=method, url=url, **kwargs) File «/usr/lib/python3/dist-packages/requests/sessions.py», line 533, in request resp = self.send(prep, **send_kwargs) File «/usr/lib/python3/dist-packages/requests/sessions.py», line 646, in send r = adapter.send(request, **kwargs) File «/usr/lib/python3/dist-packages/requests/adapters.py», line 529, in send raise ReadTimeout(e, request=request) requests.exceptions.ReadTimeout: HTTPSConnectionPool(host=’httpbin.org’, port=443): Read timed out. (read timeout=3)

Если хотите обработать исключение — измените код используя try except

import requests try : r = requests.get( ‘https://httpbin.org/delay/7’ , timeout= 3 ) print (r) except ( requests.exceptions.Timeout, requests.exceptions. ConnectionError ) as err: print ( ‘Response is taking too long.’ , err)

Response is taking too long. HTTPSConnectionPool(host=’httpbin.org’, port=443): Read timed out. (read timeout=3)

Работа с сертификатами

В Python по умолчанию используются не сертификаты системы, а сертификаты из модуля certif

Источник

Читайте также:  Php перенос длинной строки
Оцените статью