Модуль requests - взаимодействие с веб-сервисами с помощью Python

Введение

API, или Application Programming Interface, - это интерфейс, позволяющий получать и отправлять данные с помощью кода. Чаще всего мы используем API для получения данных, и именно этому будет посвящено данное учебное пособие для начинающих.

Наиболее распространенный пример API:

Представьте себя за столиком ресторана с меню, из которого вам предлагается выбрать один из вариантов. Ваш заказ готовится на кухне, которая является частью "системы". Не хватает только того звена, которое позволит вам передать заказ на кухню и доставить его к вашему столику. Именно здесь и появляется официант. Официант - это посыльный, или API, который получает ваш запрос или заказ и передает его на кухню, или в систему. Затем официант выдает вам ответ, который в данном случае представляет собой еду.

Когда мы хотим получить данные от API, нам необходимо сделать запрос. Запросы используются повсеместно в Интернете. Например, когда вы зашли на эту страницу блога, ваш браузер сделал запрос к веб-серверу iRead, который ответил содержимым этой веб-страницы.

Запросы API работают точно так же - вы делаете запрос к серверу API на получение данных, а он отвечает на ваш запрос.

Различные методы и коды состояния HTTP

Для REST API существуют различные методы HTTP. Эти методы указывают API, какие операции необходимо выполнить с данными. Хотя существует множество методов HTTP, пять методов, перечисленных ниже, наиболее часто используются в REST API:

HTTP METHOD DESCRIPTION
GET Retrieve existing data
POST Add new data
PUT Update existing data
PATCH Partially update existing data
DELETE Delete data

После того как REST API получает и обрабатывает HTTP-запрос, он возвращает ответ с кодом состояния HTTP. Этот код состояния предоставляет информацию об ответе и помогает клиентскому приложению узнать, какого рода этот ответ.

Коды состояния нумеруются в зависимости от категории результата:

CODE RANGE CATEGORY
1xx Informational response
2xx Successful operation
3xx Redirection
4xx Client error
5xx Server error

Подробнее о кодах состояния HTTP можно узнать из MDN Web Docs.

API Endpoints

Конечные точки API - это публичные URL-адреса, открытые сервером, которые клиентское приложение использует для доступа к ресурсам и данным.

В рамках данного учебника мы будем использовать Fake Store REST API. Более конкретно, мы будем использовать следующие конечные точки:

HTTP METHOD API ENDPOINT DESCRIPTION
GET /products Get a list of products.
GET /products?limit=x Get only x products.
GET /products/<product_id> Get a single product.
POST /products Create a new product.
PUT /products/<product_id> Update a product.
PATCH /products/<product_id> Partially update a product.
DELETE /products/<product_id> Delete a product.

Каждая из приведенных выше конечных точек выполняет различные действия в зависимости от метода HTTP. Для каждого URL API базовым URL является: https://fakestoreapi.com. Мы рассмотрим их последовательно.

Но сначала нам необходимо установить внешнюю библиотеку для использования этих API. Большинство разработчиков Python используют для взаимодействия с веб-сервисами библиотеку requests. Установить эту библиотеку можно с помощью команды pip следующим образом:

$ pip install requests

После установки библиотеки все готово!

GET Request

Это один из наиболее распространенных методов HTTP-запроса, с которым вы можете столкнуться. Это операция только для чтения, позволяющая получить данные из API.

Попробуем выполнить GET-запрос к первой конечной точке, о которой мы говорили выше, и получить в ответ список товаров.

import requests

BASE_URL = 'https://fakestoreapi.com'

response = requests.get(f"{BASE_URL}/products")
print(response.json())

Приведенный выше сценарий использует метод requests.get() для отправки GET-запроса на конечную точку API /products. В ответ он получает список всех товаров. Затем мы вызываем .json() для просмотра JSON-ответа, который выглядит следующим образом:

[
  {
    "id": 1,
    "title": "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops",
    "price": 109.95,
    "description": "Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday",
    "category": "men's clothing",
    "image": "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg",
    "rating": {
      "rate": 3.9,
      "count": 120
    }
  },
  {
    "id": 2,
    "title": "Mens Casual Premium Slim Fit T-Shirts ",
    "price": 22.3,
    "description": "Slim-fitting style, contrast raglan long sleeve, three-button henley placket, light weight & soft fabric for breathable and comfortable wearing. And Solid stitched shirts with round neck made for durability and a great fit for casual fashion wear and diehard baseball fans. The Henley style round neckline includes a three-button placket.",
    "category": "men's clothing",
    "image": "https://fakestoreapi.com/img/71-3HjGNDUL._AC_SY879._SX._UX._SY._UY_.jpg",
    "rating": {
      "rate": 4.1,
      "count": 259
    }
  },
  {
    "id": 3,
    "title": "Mens Cotton Jacket",
    "price": 55.99,
    "description": "great outerwear jackets for Spring/Autumn/Winter, suitable for many occasions, such as working, hiking, camping, mountain/rock climbing, cycling, traveling or other outdoors. Good gift choice for you or your family member. A warm hearted love to Father, husband or son in this thanksgiving or Christmas Day.",
    "category": "men's clothing",
    "image": "https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg",
    "rating": {
      "rate": 4.7,
      "count": 500
    }
  },
  {
    "id": 4,
    "title": "Mens Casual Slim Fit",
    "price": 15.99,
    "description": "The color could be slightly different between on the screen and in practice. / Please note that body builds vary by person, therefore, detailed size information should be reviewed below on the product description.",
    "category": "men's clothing",
    "image": "https://fakestoreapi.com/img/71YXzeOuslL._AC_UY879_.jpg",
    "rating": {
      "rate": 2.1,
      "count": 430
    }
  },
  {
    "id": 5,
    "title": "John Hardy Women's Legends Naga Gold & Silver Dragon Station Chain Bracelet",
    "price": 695,
    "description": "From our Legends Collection, the Naga was inspired by the mythical water dragon that protects the ocean's pearl. Wear facing inward to be bestowed with love and abundance, or outward for protection.",
    "category": "jewelery",
    "image": "https://fakestoreapi.com/img/71pWzhdJNwL._AC_UL640_QL65_ML3_.jpg",
    "rating": {
      "rate": 4.6,
      "count": 400
    }
  },
  {
    "id": 6,
    "title": "Solid Gold Petite Micropave ",
    "price": 168,
    "description": "Satisfaction Guaranteed. Return or exchange any order within 30 days.Designed and sold by Hafeez Center in the United States. Satisfaction Guaranteed. Return or exchange any order within 30 days.",
    "category": "jewelery",
    "image": "https://fakestoreapi.com/img/61sbMiUnoGL._AC_UL640_QL65_ML3_.jpg",
    "rating": {
      "rate": 3.9,
      "count": 70
    }
  },
  {
    "id": 7,
    "title": "White Gold Plated Princess",
    "price": 9.99,
    "description": "Classic Created Wedding Engagement Solitaire Diamond Promise Ring for Her. Gifts to spoil your love more for Engagement, Wedding, Anniversary, Valentine's Day...",
    "category": "jewelery",
    "image": "https://fakestoreapi.com/img/71YAIFU48IL._AC_UL640_QL65_ML3_.jpg",
    "rating": {
      "rate": 3,
      "count": 400
    }
  },
  {
    "id": 8,
    "title": "Pierced Owl Rose Gold Plated Stainless Steel Double",
    "price": 10.99,
    "description": "Rose Gold Plated Double Flared Tunnel Plug Earrings. Made of 316L Stainless Steel",
    "category": "jewelery",
    "image": "https://fakestoreapi.com/img/51UDEzMJVpL._AC_UL640_QL65_ML3_.jpg",
    "rating": {
      "rate": 1.9,
      "count": 100
    }
  },
  {
    "id": 9,
    "title": "WD 2TB Elements Portable External Hard Drive - USB 3.0 ",
    "price": 64,
    "description": "USB 3.0 and USB 2.0 Compatibility Fast data transfers Improve PC Performance High Capacity; Compatibility Formatted NTFS for Windows 10, Windows 8.1, Windows 7; Reformatting may be required for other operating systems; Compatibility may vary depending on user’s hardware configuration and operating system",
    "category": "electronics",
    "image": "https://fakestoreapi.com/img/61IBBVJvSDL._AC_SY879_.jpg",
    "rating": {
      "rate": 3.3,
      "count": 203
    }
  },
  {
    "id": 10,
    "title": "SanDisk SSD PLUS 1TB Internal SSD - SATA III 6 Gb/s",
    "price": 109,
    "description": "Easy upgrade for faster boot up, shutdown, application load and response (As compared to 5400 RPM SATA 2.5” hard drive; Based on published specifications and internal benchmarking tests using PCMark vantage scores) Boosts burst write performance, making it ideal for typical PC workloads The perfect balance of performance and reliability Read/write speeds of up to 535MB/s/450MB/s (Based on internal testing; Performance may vary depending upon drive capacity, host device, OS and application.)",
    "category": "electronics",
    "image": "https://fakestoreapi.com/img/61U7T1koQqL._AC_SX679_.jpg",
    "rating": {
      "rate": 2.9,
      "count": 470
    }
  },
  {
    "id": 11,
    "title": "Silicon Power 256GB SSD 3D NAND A55 SLC Cache Performance Boost SATA III 2.5",
    "price": 109,
    "description": "3D NAND flash are applied to deliver high transfer speeds Remarkable transfer speeds that enable faster bootup and improved overall system performance. The advanced SLC Cache Technology allows performance boost and longer lifespan 7mm slim design suitable for Ultrabooks and Ultra-slim notebooks. Supports TRIM command, Garbage Collection technology, RAID, and ECC (Error Checking & Correction) to provide the optimized performance and enhanced reliability.",
    "category": "electronics",
    "image": "https://fakestoreapi.com/img/71kWymZ+c+L._AC_SX679_.jpg",
    "rating": {
      "rate": 4.8,
      "count": 319
    }
  },
  {
    "id": 12,
    "title": "WD 4TB Gaming Drive Works with Playstation 4 Portable External Hard Drive",
    "price": 114,
    "description": "Expand your PS4 gaming experience, Play anywhere Fast and easy, setup Sleek design with high capacity, 3-year manufacturer's limited warranty",
    "category": "electronics",
    "image": "https://fakestoreapi.com/img/61mtL65D4cL._AC_SX679_.jpg",
    "rating": {
      "rate": 4.8,
      "count": 400
    }
  },
  {
    "id": 13,
    "title": "Acer SB220Q bi 21.5 inches Full HD (1920 x 1080) IPS Ultra-Thin",
    "price": 599,
    "description": "21. 5 inches Full HD (1920 x 1080) widescreen IPS display And Radeon free Sync technology. No compatibility for VESA Mount Refresh Rate: 75Hz - Using HDMI port Zero-frame design | ultra-thin | 4ms response time | IPS panel Aspect ratio - 16: 9. Color Supported - 16. 7 million colors. Brightness - 250 nit Tilt angle -5 degree to 15 degree. Horizontal viewing angle-178 degree. Vertical viewing angle-178 degree 75 hertz",
    "category": "electronics",
    "image": "https://fakestoreapi.com/img/81QpkIctqPL._AC_SX679_.jpg",
    "rating": {
      "rate": 2.9,
      "count": 250
    }
  },
  {
    "id": 14,
    "title": "Samsung 49-Inch CHG90 144Hz Curved Gaming Monitor (LC49HG90DMNXZA) – Super Ultrawide Screen QLED ",
    "price": 999.99,
    "description": "49 INCH SUPER ULTRAWIDE 32:9 CURVED GAMING MONITOR with dual 27 inch screen side by side QUANTUM DOT (QLED) TECHNOLOGY, HDR support and factory calibration provides stunningly realistic and accurate color and contrast 144HZ HIGH REFRESH RATE and 1ms ultra fast response time work to eliminate motion blur, ghosting, and reduce input lag",
    "category": "electronics",
    "image": "https://fakestoreapi.com/img/81Zt42ioCgL._AC_SX679_.jpg",
    "rating": {
      "rate": 2.2,
      "count": 140
    }
  },
  {
    "id": 15,
    "title": "BIYLACLESEN Women's 3-in-1 Snowboard Jacket Winter Coats",
    "price": 56.99,
    "description": "Note:The Jackets is US standard size, Please choose size as your usual wear Material: 100% Polyester; Detachable Liner Fabric: Warm Fleece. Detachable Functional Liner: Skin Friendly, Lightweigt and Warm.Stand Collar Liner jacket, keep you warm in cold weather. Zippered Pockets: 2 Zippered Hand Pockets, 2 Zippered Pockets on Chest (enough to keep cards or keys)and 1 Hidden Pocket Inside.Zippered Hand Pockets and Hidden Pocket keep your things secure. Humanized Design: Adjustable and Detachable Hood and Adjustable cuff to prevent the wind and water,for a comfortable fit. 3 in 1 Detachable Design provide more convenience, you can separate the coat and inner as needed, or wear it together. It is suitable for different season and help you adapt to different climates",
    "category": "women's clothing",
    "image": "https://fakestoreapi.com/img/51Y5NI-I5jL._AC_UX679_.jpg",
    "rating": {
      "rate": 2.6,
      "count": 235
    }
  },
  {
    "id": 16,
    "title": "Lock and Love Women's Removable Hooded Faux Leather Moto Biker Jacket",
    "price": 29.95,
    "description": "100% POLYURETHANE(shell) 100% POLYESTER(lining) 75% POLYESTER 25% COTTON (SWEATER), Faux leather material for style and comfort / 2 pockets of front, 2-For-One Hooded denim style faux leather jacket, Button detail on waist / Detail stitching at sides, HAND WASH ONLY / DO NOT BLEACH / LINE DRY / DO NOT IRON",
    "category": "women's clothing",
    "image": "https://fakestoreapi.com/img/81XH0e8fefL._AC_UY879_.jpg",
    "rating": {
      "rate": 2.9,
      "count": 340
    }
  },
  {
    "id": 17,
    "title": "Rain Jacket Women Windbreaker Striped Climbing Raincoats",
    "price": 39.99,
    "description": "Lightweight perfet for trip or casual wear---Long sleeve with hooded, adjustable drawstring waist design. Button and zipper front closure raincoat, fully stripes Lined and The Raincoat has 2 side pockets are a good size to hold all kinds of things, it covers the hips, and the hood is generous but doesn't overdo it.Attached Cotton Lined Hood with Adjustable Drawstrings give it a real styled look.",
    "category": "women's clothing",
    "image": "https://fakestoreapi.com/img/71HblAHs5xL._AC_UY879_-2.jpg",
    "rating": {
      "rate": 3.8,
      "count": 679
    }
  },
  {
    "id": 18,
    "title": "MBJ Women's Solid Short Sleeve Boat Neck V ",
    "price": 9.85,
    "description": "95% RAYON 5% SPANDEX, Made in USA or Imported, Do Not Bleach, Lightweight fabric with great stretch for comfort, Ribbed on sleeves and neckline / Double stitching on bottom hem",
    "category": "women's clothing",
    "image": "https://fakestoreapi.com/img/71z3kpMAYsL._AC_UY879_.jpg",
    "rating": {
      "rate": 4.7,
      "count": 130
    }
  },
  {
    "id": 19,
    "title": "Opna Women's Short Sleeve Moisture",
    "price": 7.95,
    "description": "100% Polyester, Machine wash, 100% cationic polyester interlock, Machine Wash & Pre Shrunk for a Great Fit, Lightweight, roomy and highly breathable with moisture wicking fabric which helps to keep moisture away, Soft Lightweight Fabric with comfortable V-neck collar and a slimmer fit, delivers a sleek, more feminine silhouette and Added Comfort",
    "category": "women's clothing",
    "image": "https://fakestoreapi.com/img/51eg55uWmdL._AC_UX679_.jpg",
    "rating": {
      "rate": 4.5,
      "count": 146
    }
  },
  {
    "id": 20,
    "title": "DANVOUY Womens T Shirt Casual Cotton Short",
    "price": 12.99,
    "description": "95%Cotton,5%Spandex, Features: Casual, Short Sleeve, Letter Print,V-Neck,Fashion Tees, The fabric is soft and has some stretch., Occasion: Casual/Office/Beach/School/Home/Street. Season: Spring,Summer,Autumn,Winter.",
    "category": "women's clothing",
    "image": "https://fakestoreapi.com/img/61pHAEJ4NML._AC_UX679_.jpg",
    "rating": {
      "rate": 3.6,
      "count": 145
    }
  }
]

Если присмотреться, то ответ в формате JSON выглядит как список словарей Python. JSON - очень популярный формат обмена данными для REST API.

Вы также можете вывести другие атрибуты, связанные с ответом, например, код состояния.


print(response.status_code)

## OUTPUT
>>> 200

Как известно, код состояния 200 означает успешный ответ.

Поскольку конечная точка /products возвращает много данных, ограничимся только 3 продуктами.

Для этого у нас есть конечная точка /products?limit=x, где x - целое положительное число. Параметр limit называется параметром запроса. Рассмотрим, как можно добавить этот параметр запроса в запрос.

import requests

BASE_URL = 'https://fakestoreapi.com'

query_params = {
    "limit": 3
}

response = requests.get(f"{BASE_URL}/products", params=query_params)
print(response.json())

Метод requests.get() принимает параметр params, в котором мы можем указать параметры запроса в виде словаря Python. Так, мы создали словарь query_params, передали в него limit в качестве ключа и 3 в качестве значения. Затем мы передали этот query_params в requests.get(). Теперь вывод выглядит следующим образом:

[
  {
    "id": 1,
    "title": "Fjallraven - Foldsack No. 1 Backpack, Fits 15 Laptops",
    "price": 109.95,
    "description": "Your perfect pack for everyday use and walks in the forest. Stash your laptop (up to 15 inches) in the padded sleeve, your everyday",
    "category": "men's clothing",
    "image": "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg",
    "rating": { "rate": 3.9, "count": 120 }
  },
  {
    "id": 2,
    "title": "Mens Casual Premium Slim Fit T-Shirts ",
    "price": 22.3,
    "description": "Slim-fitting style, contrast raglan long sleeve, three-button henley placket, light weight & soft fabric for breathable and comfortable wearing. And Solid stitched shirts with round neck made for durability and a great fit for casual fashion wear and diehard baseball fans. The Henley style round neckline includes a three-button placket.",
    "category": "men's clothing",
    "image": "https://fakestoreapi.com/img/71-3HjGNDUL._AC_SY879._SX._UX._SY._UY_.jpg",
    "rating": { "rate": 4.1, "count": 259 }
  },
  {
    "id": 3,
    "title": "Mens Cotton Jacket",
    "price": 55.99,
    "description": "great outerwear jackets for Spring/Autumn/Winter, suitable for many occasions, such as working, hiking, camping, mountain/rock climbing, cycling, traveling or other outdoors. Good gift choice for you or your family member. A warm hearted love to Father, husband or son in this thanksgiving or Christmas Day.",
    "category": "men's clothing",
    "image": "https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg",
    "rating": { "rate": 4.7, "count": 500 }
  }
]

Теперь мы имеем данные об откликах, ограниченные только 3 продуктами. Попробуем получить только один продукт с параметром id 18.

import requests

BASE_URL = 'https://fakestoreapi.com'

response = requests.get(f"{BASE_URL}/products/18")
print(response)

<<<Поскольку у нас есть конечная точка

, мы можем /products/<product_id> передать id 18 в URL API и сделать GET-запрос на нее. Ответ выглядит следующим образом:

{
  "id": 18,
  "title": "MBJ Women's Solid Short Sleeve Boat Neck V ",
  "price": 9.85,
  "description": "95% RAYON 5% SPANDEX, Made in USA or Imported, Do Not Bleach, Lightweight fabric with great stretch for comfort, Ribbed on sleeves and neckline / Double stitching on bottom hem",
  "category": "women's clothing",
  "image": "https://fakestoreapi.com/img/71z3kpMAYsL._AC_UY879_.jpg",
  "rating": {
    "rate": 4.7,
    "count": 130
  }
}

POST-запрос

Для добавления новых данных в REST API мы используем запрос POST. Данные отправляются на сервер в формате JSON, который выглядит как словарь Python. Согласно документации Fake Store API, товар имеет следующие атрибуты: title, price, description, image и category. Таким образом, новый товар выглядит следующим образом:

new_product = {
    "title": 'test product',
    "price": 13.5,
    "description": 'lorem ipsum set',
    "image": 'https://i.pravatar.cc',
    "category": 'electronic'
}

Мы можем отправить POST-запрос с использованием метода requests.post() следующим образом:

import requests

BASE_URL = 'https://fakestoreapi.com'

new_product = {
    "title": 'test product',
    "price": 13.5,
    "description": 'lorem ipsum set',
    "image": 'https://i.pravatar.cc',
    "category": 'electronic'
}

response = requests.post(f"{BASE_URL}/products", json=new_product)
print(response.json())

В методе requests.post() мы можем передавать JSON-данные с помощью аргумента json. Использование аргумента json автоматически устанавливает значение Content-Type в Application/JSON в заголовке запроса.

После выполнения POST-запроса на конечной точке /products мы получаем в ответе объект продукта с кодом id. Ответ выглядит следующим образом:

{
  "_id": "61b45067e087f30012c45a45",
  "id": 21,
  "title": "test product",
  "price": 13.5,
  "description": "lorem ipsum set",
  "image": "https://i.pravatar.cc",
  "category": "electronic"
}

Если мы не используем аргумент json, то POST-запрос должен быть составлен следующим образом:

import requests
import json

BASE_URL = 'https://fakestoreapi.com'

new_product = {
    "title": 'test product',
    "price": 13.5,
    "description": 'lorem ipsum set',
    "image": 'https://i.pravatar.cc',
    "category": 'electronic'
}

headers = {
    "Content-Type": "application/json"
}

response = requests.post(f"{BASE_URL}/products", data=json.dumps(new_product), headers=headers)
print(response.json())

В данном случае, когда мы используем аргумент data вместо json, нам необходимо в заголовке явно установить Content-Type в application/json. В то время как в случае аргумента json нам не нужно сериализовать данные - но в этом случае нам нужно сериализовать данные с помощью json.dumps().

PUT Request

Часто возникает необходимость обновить существующие данные в API. Используя запрос PUT, мы можем обновить все данные. Это означает, что когда мы выполняем PUT-запрос, он заменяет старые данные новыми.

В POST-запросе мы создали новый товар, id которого был равен 21. Давайте обновим старый товар новым, выполнив PUT-запрос на конечной точке products/<product_id>.

import requests

BASE_URL = 'https://fakestoreapi.com'

updated_product = {
    "title": 'updated_product',
    "category": 'clothing'
}

response = requests.put(f"{BASE_URL}/products/21", json=updated_product)
print(response.json())

Когда мы выполняем PUT-запрос с помощью метода updated_product, используя метод requests.put(), в ответ получаем следующие JSON-данные:

{
  "id": "21",
  "title": "updated_product",
  "category": "clothing"
}

Уведомление о том, что старый продукт был полностью заменен на обновленный.

Запрос PATCH

Иногда нет необходимости полностью заменять старые данные. Скорее, мы хотим изменить только некоторые поля. В этом случае мы используем запрос PATCH.

Давайте обновим категорию товара с clothing на electronic, выполнив запрос PATCH на конечной точке products/<product_id>.

import requests

BASE_URL = 'https://fakestoreapi.com'

updated_product = {
    "category": 'electronic'
}

response = requests.patch(f"{BASE_URL}/products/21", json=updated_product)
print(response.json())

В данном случае мы используем метод requests.patch(), который возвращает ответ следующего вида:

{
  "id": "21",
  "title": "updated_product",
  "category": "electronic"
}

Обратите внимание, что на этот раз все данные не изменились - обновлено только поле категории.

DELETE Request

Как следует из названия, для удаления ресурса из API можно использовать запрос DELETE. Давайте удалим этот товар с помощью запроса id 21.

import requests

BASE_URL = 'https://fakestoreapi.com'

response = requests.delete(f"{BASE_URL}/products/21")
print(response.json())

Метод requests.delete() помогает нам выполнить запрос DELETE на конечной точке /products/<product_id>.

Завершение

В этом уроке мы узнали, как можно взаимодействовать с веб-сервисами с помощью замечательного инструмента под названием requests в Python.

Надеюсь, вам понравилось - и спасибо, что читаете!

Вернуться на верх