Как составить post запрос python


Eager to get started? This page gives a good introduction in how to get started
with Requests.

First, make sure that:

  • Requests is installed

  • Requests is up-to-date

Let’s get started with some simple examples.

Make a Request¶

Making a request with Requests is very simple.

Begin by importing the Requests module:

Now, let’s try to get a webpage. For this example, let’s get GitHub’s public
timeline:

>>> r = requests.get('https://api.github.com/events')

Now, we have a Response object called r. We can
get all the information we need from this object.

Requests’ simple API means that all forms of HTTP request are as obvious. For
example, this is how you make an HTTP POST request:

>>> r = requests.post('https://httpbin.org/post', data={'key': 'value'})

Nice, right? What about the other HTTP request types: PUT, DELETE, HEAD and
OPTIONS? These are all just as simple:

>>> r = requests.put('https://httpbin.org/put', data={'key': 'value'})
>>> r = requests.delete('https://httpbin.org/delete')
>>> r = requests.head('https://httpbin.org/get')
>>> r = requests.options('https://httpbin.org/get')

That’s all well and good, but it’s also only the start of what Requests can
do.

Passing Parameters In URLs¶

You often want to send some sort of data in the URL’s query string. If
you were constructing the URL by hand, this data would be given as key/value
pairs in the URL after a question mark, e.g. httpbin.org/get?key=val.
Requests allows you to provide these arguments as a dictionary of strings,
using the params keyword argument. As an example, if you wanted to pass
key1=value1 and key2=value2 to httpbin.org/get, you would use the
following code:

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.get('https://httpbin.org/get', params=payload)

You can see that the URL has been correctly encoded by printing the URL:

>>> print(r.url)
https://httpbin.org/get?key2=value2&key1=value1

Note that any dictionary key whose value is None will not be added to the
URL’s query string.

You can also pass a list of items as a value:

>>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}

>>> r = requests.get('https://httpbin.org/get', params=payload)
>>> print(r.url)
https://httpbin.org/get?key1=value1&key2=value2&key2=value3

Response Content¶

We can read the content of the server’s response. Consider the GitHub timeline
again:

>>> import requests

>>> r = requests.get('https://api.github.com/events')
>>> r.text
'[{"repository":{"open_issues":0,"url":"https://github.com/...

Requests will automatically decode content from the server. Most unicode
charsets are seamlessly decoded.

When you make a request, Requests makes educated guesses about the encoding of
the response based on the HTTP headers. The text encoding guessed by Requests
is used when you access r.text. You can find out what encoding Requests is
using, and change it, using the r.encoding property:

>>> r.encoding
'utf-8'
>>> r.encoding = 'ISO-8859-1'

If you change the encoding, Requests will use the new value of r.encoding
whenever you call r.text. You might want to do this in any situation where
you can apply special logic to work out what the encoding of the content will
be. For example, HTML and XML have the ability to specify their encoding in
their body. In situations like this, you should use r.content to find the
encoding, and then set r.encoding. This will let you use r.text with
the correct encoding.

Requests will also use custom encodings in the event that you need them. If
you have created your own encoding and registered it with the codecs
module, you can simply use the codec name as the value of r.encoding and
Requests will handle the decoding for you.

Binary Response Content¶

You can also access the response body as bytes, for non-text requests:

>>> r.content
b'[{"repository":{"open_issues":0,"url":"https://github.com/...

The gzip and deflate transfer-encodings are automatically decoded for you.

The br transfer-encoding is automatically decoded for you if a Brotli library
like brotli or brotlicffi is installed.

For example, to create an image from binary data returned by a request, you can
use the following code:

>>> from PIL import Image
>>> from io import BytesIO

>>> i = Image.open(BytesIO(r.content))

JSON Response Content¶

There’s also a builtin JSON decoder, in case you’re dealing with JSON data:

>>> import requests

>>> r = requests.get('https://api.github.com/events')
>>> r.json()
[{'repository': {'open_issues': 0, 'url': 'https://github.com/...

In case the JSON decoding fails, r.json() raises an exception. For example, if
the response gets a 204 (No Content), or if the response contains invalid JSON,
attempting r.json() raises requests.exceptions.JSONDecodeError. This wrapper exception
provides interoperability for multiple exceptions that may be thrown by different
python versions and json serialization libraries.

It should be noted that the success of the call to r.json() does not
indicate the success of the response. Some servers may return a JSON object in a
failed response (e.g. error details with HTTP 500). Such JSON will be decoded
and returned. To check that a request is successful, use
r.raise_for_status() or check r.status_code is what you expect.

Raw Response Content¶

In the rare case that you’d like to get the raw socket response from the
server, you can access r.raw. If you want to do this, make sure you set
stream=True in your initial request. Once you do, you can do this:

>>> r = requests.get('https://api.github.com/events', stream=True)

>>> r.raw
<urllib3.response.HTTPResponse object at 0x101194810>

>>> r.raw.read(10)
b'x1fx8bx08x00x00x00x00x00x00x03'

In general, however, you should use a pattern like this to save what is being
streamed to a file:

with open(filename, 'wb') as fd:
    for chunk in r.iter_content(chunk_size=128):
        fd.write(chunk)

Using Response.iter_content will handle a lot of what you would otherwise
have to handle when using Response.raw directly. When streaming a
download, the above is the preferred and recommended way to retrieve the
content. Note that chunk_size can be freely adjusted to a number that
may better fit your use cases.

Note

An important note about using Response.iter_content versus Response.raw.
Response.iter_content will automatically decode the gzip and deflate
transfer-encodings. Response.raw is a raw stream of bytes – it does not
transform the response content. If you really need access to the bytes as they
were returned, use Response.raw.

More complicated POST requests¶

Typically, you want to send some form-encoded data — much like an HTML form.
To do this, simply pass a dictionary to the data argument. Your
dictionary of data will automatically be form-encoded when the request is made:

>>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.post('https://httpbin.org/post', data=payload)
>>> print(r.text)
{
  ...
  "form": {
    "key2": "value2",
    "key1": "value1"
  },
  ...
}

The data argument can also have multiple values for each key. This can be
done by making data either a list of tuples or a dictionary with lists
as values. This is particularly useful when the form has multiple elements that
use the same key:

>>> payload_tuples = [('key1', 'value1'), ('key1', 'value2')]
>>> r1 = requests.post('https://httpbin.org/post', data=payload_tuples)
>>> payload_dict = {'key1': ['value1', 'value2']}
>>> r2 = requests.post('https://httpbin.org/post', data=payload_dict)
>>> print(r1.text)
{
  ...
  "form": {
    "key1": [
      "value1",
      "value2"
    ]
  },
  ...
}
>>> r1.text == r2.text
True

There are times that you may want to send data that is not form-encoded. If
you pass in a string instead of a dict, that data will be posted directly.

For example, the GitHub API v3 accepts JSON-Encoded POST/PATCH data:

>>> import json

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, data=json.dumps(payload))

Please note that the above code will NOT add the Content-Type header
(so in particular it will NOT set it to application/json).

If you need that header set and you don’t want to encode the dict yourself,
you can also pass it directly using the json parameter (added in version 2.4.2)
and it will be encoded automatically:

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)

Note, the json parameter is ignored if either data or files is passed.

POST a Multipart-Encoded File¶

Requests makes it simple to upload Multipart-encoded files:

>>> url = 'https://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}

>>> r = requests.post(url, files=files)
>>> r.text
{
  ...
  "files": {
    "file": "<censored...binary...data>"
  },
  ...
}

You can set the filename, content_type and headers explicitly:

>>> url = 'https://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}

>>> r = requests.post(url, files=files)
>>> r.text
{
  ...
  "files": {
    "file": "<censored...binary...data>"
  },
  ...
}

If you want, you can send strings to be received as files:

>>> url = 'https://httpbin.org/post'
>>> files = {'file': ('report.csv', 'some,data,to,sendnanother,row,to,sendn')}

>>> r = requests.post(url, files=files)
>>> r.text
{
  ...
  "files": {
    "file": "some,data,to,send\nanother,row,to,send\n"
  },
  ...
}

In the event you are posting a very large file as a multipart/form-data
request, you may want to stream the request. By default, requests does not
support this, but there is a separate package which does —
requests-toolbelt. You should read the toolbelt’s documentation for more details about how to use it.

For sending multiple files in one request refer to the advanced
section.

Warning

It is strongly recommended that you open files in binary
mode
. This is because Requests may attempt to provide
the Content-Length header for you, and if it does this value
will be set to the number of bytes in the file. Errors may occur
if you open the file in text mode.

Response Status Codes¶

We can check the response status code:

>>> r = requests.get('https://httpbin.org/get')
>>> r.status_code
200

Requests also comes with a built-in status code lookup object for easy
reference:

>>> r.status_code == requests.codes.ok
True

If we made a bad request (a 4XX client error or 5XX server error response), we
can raise it with
Response.raise_for_status():

>>> bad_r = requests.get('https://httpbin.org/status/404')
>>> bad_r.status_code
404

>>> bad_r.raise_for_status()
Traceback (most recent call last):
  File "requests/models.py", line 832, in raise_for_status
    raise http_error
requests.exceptions.HTTPError: 404 Client Error

But, since our status_code for r was 200, when we call
raise_for_status() we get:

>>> r.raise_for_status()
None

All is well.

Cookies¶

If a response contains some Cookies, you can quickly access them:

>>> url = 'http://example.com/some/cookie/setting/url'
>>> r = requests.get(url)

>>> r.cookies['example_cookie_name']
'example_cookie_value'

To send your own cookies to the server, you can use the cookies
parameter:

>>> url = 'https://httpbin.org/cookies'
>>> cookies = dict(cookies_are='working')

>>> r = requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'

Cookies are returned in a RequestsCookieJar,
which acts like a dict but also offers a more complete interface,
suitable for use over multiple domains or paths. Cookie jars can
also be passed in to requests:

>>> jar = requests.cookies.RequestsCookieJar()
>>> jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
>>> jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
>>> url = 'https://httpbin.org/cookies'
>>> r = requests.get(url, cookies=jar)
>>> r.text
'{"cookies": {"tasty_cookie": "yum"}}'

Redirection and History¶

By default Requests will perform location redirection for all verbs except
HEAD.

We can use the history property of the Response object to track redirection.

The Response.history list contains the
Response objects that were created in order to
complete the request. The list is sorted from the oldest to the most recent
response.

For example, GitHub redirects all HTTP requests to HTTPS:

>>> r = requests.get('http://github.com/')

>>> r.url
'https://github.com/'

>>> r.status_code
200

>>> r.history
[<Response [301]>]

If you’re using GET, OPTIONS, POST, PUT, PATCH or DELETE, you can disable
redirection handling with the allow_redirects parameter:

>>> r = requests.get('http://github.com/', allow_redirects=False)

>>> r.status_code
301

>>> r.history
[]

If you’re using HEAD, you can enable redirection as well:

>>> r = requests.head('http://github.com/', allow_redirects=True)

>>> r.url
'https://github.com/'

>>> r.history
[<Response [301]>]

Timeouts¶

You can tell Requests to stop waiting for a response after a given number of
seconds with the timeout parameter. Nearly all production code should use
this parameter in nearly all requests. Failure to do so can cause your program
to hang indefinitely:

>>> requests.get('https://github.com/', timeout=0.001)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)

Note

timeout is not a time limit on the entire response download;
rather, an exception is raised if the server has not issued a
response for timeout seconds (more precisely, if no bytes have been
received on the underlying socket for timeout seconds). If no timeout is specified explicitly, requests do
not time out.

Errors and Exceptions¶

In the event of a network problem (e.g. DNS failure, refused connection, etc),
Requests will raise a ConnectionError exception.

Response.raise_for_status() will
raise an HTTPError if the HTTP request
returned an unsuccessful status code.

If a request times out, a Timeout exception is
raised.

If a request exceeds the configured number of maximum redirections, a
TooManyRedirects exception is raised.

All exceptions that Requests explicitly raises inherit from
requests.exceptions.RequestException.


Ready for more? Check out the advanced section.

If you’re on the job market, consider taking this programming quiz. A substantial donation will be made to this project, if you find a job through this platform.

API (Application Programming Interface – интерфейс прикладного программирования) – это сервер, который позволяет извлекать и отправлять данные с помощью кода. В основном мы используем API для получения данных. Именно эта тема и будет в фокусе нашего руководства для начинающих. Итак, приступим!

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

Схема работы API

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

Например, когда возвращается HTML-код страницы, для пользователя она преображается именно в страницу с различными надписями, картинками и т.д., а не остается просто в виде кода. Конечно, всегда может что-то пойти не по плану ?, но в остальных случаях это должно работать именно так.

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

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

HTTP-метод Описание
GET Получить существующие данные
POST Добавить новые данные
PUT Обновить существующие данные
PATCH Частично обновить существующие данные
DELETE Удалить данные

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

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

Код Категория результата
1хх Информационный ответ
2хх Успешная операция
3хх Перенаправление
4хх Ошибка на стороне клиента
5хх Ошибка на стороне сервера

Вы можете узнать больше о кодах состояния HTTP в веб-документации MDN.

[python_ad_block]

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

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

HTTP-мето Конечная точка API Описание
GET /products Получить список продуктов
GET /products?limit=x Получить только х товаров (к примеру, только 5 товаров)
GET /products/<product_id>          Получить один конкретный продукт
POST /products Создать новый продукт
PUT /products/<product_id>          Обновить товар
PATCH /products/<product_id>          Частично обновить товар
DELETE /products/<product_id>          Удалить товар

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

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

$ pip install requests

Как только библиотека установлена, все готово и можно приступать!

Как сделать запрос GET

Это один из наиболее распространенных методов 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 возвращает много данных, давайте ограничим эти данные только тремя продуктами.

Для этого у нас есть конечная точка /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 в request.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 }
  }
]

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

import requests

BASE_URL = 'https://fakestoreapi.com'

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

Поскольку у нас есть конечная точка /products/<product_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-запрос

Мы используем запрос POST для добавления новых данных в REST API. Данные отправляются на сервер в формате 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())

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

Как только мы сделаем запрос POST в конечной точке /products, мы получим объект продукта с идентификатором в ответе. Этот ответ выглядит так:

{
  "_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

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

В запросе POST мы создали новый продукт с идентификатором 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.

Давайте обновим категорию (category) продукта обратно с 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"
}

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

Как сделать запрос DELETE

Как следует из названия, если вы хотите удалить ресурс из API, вы можете использовать запрос DELETE. Удалим товар с идентификатором, равным 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>.

Заключение

В этом руководстве мы рассмотрели, как взаимодействовать с веб-сервисами с помощью Python. Мы рассказали о пяти разных запросах: GET, POST, PUT, PATCH и DELETE. Более того, мы разобрали на примерах их синтаксис и принцип работы. Также мы обсудили, какие есть коды ответов или коды состояния и что они значат.

Надеемся, вам понравилось данное руководство – спасибо, что прочитали! Успехов в написании кода!

Перевод статьи Python Requests – «How to Interact with Web Services using Python».

Библиотека requests является стандартным инструментом для составления HTTP-запросов в Python. Простой и аккуратный API значительно облегчает трудоемкий процесс создания запросов. Таким образом, можно сосредоточиться на взаимодействии со службами и использовании данных в приложении.

Содержание статьи

  • Python установка библиотеки requests
  • Python библиотека Requests метод GET
  • Объект Response получение ответа на запрос в Python
  • HTTP коды состояний
  • Получить содержимое страницы в Requests
  • HTTP заголовки в Requests
  • Python Requests параметры запроса
  • Настройка HTTP заголовка запроса (headers)
  • Примеры HTTP методов в Requests
  • Python Requests тело сообщения
  • Python Requests анализ запроса
  • Python Requests аутентификация HTTP AUTH
  • Python Requests проверка SSL сертификата
  • Python Requests производительность приложений
  • Объект Session в Requests
  • HTTPAdapter — Максимальное количество повторов запроса в Requests

В данной статье представлены наиболее полезные особенности requests. Показано, как изменить и приспособить requests к различным ситуациям, с которыми программисты сталкиваются чаще всего. Здесь также даются советы по эффективному использованию requests и предотвращению влияния сторонних служб, которые могут сильно замедлить работу используемого приложения. Мы использовали библиотек requests в уроке по парсингу html через библиотеку BeautifulSoup.

Ключевые аспекты инструкции:

  • Создание запросов при помощи самых популярных HTTP методов;
  • Редактирование заголовков запросов и данных при помощи строки запроса и содержимого сообщения;
  • Анализ данных запросов и откликов;
  • Создание авторизированных запросов;
  • Настройка запросов для предотвращения сбоев и замедления работы приложения.

В статье собран оптимальный набор информации, необходимый для понимания данных примеров и особенностей их использования. Информация представлена в доступной в форме. Тем не менее, стоит иметь в виду, что для оптимального разбора инструкции потребуются хотя бы базовые знания HTTP.

Далее будут показаны наиболее эффективные методы использования requests в разрабатываемом приложении.

Python установка библиотеки requests

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

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Тем, кто для работы с пакетами Python, использует виртуальную среду Pipenv, необходимо использовать немного другую команду.

$ pipenv install requests

Сразу после установки requests можно полноценно использовать в приложении. Импорт requests производится следующим образом.

Таким образом, все подготовительные этапы для последующего использования requests завершены. Начинать изучение requests лучше всего с того, как сделать запрос GET.

Python библиотека Requests метод GET

Такие HTTP методы, как GET и POST, определяют, какие действия будут выполнены при создании HTTP запроса. Помимо GET и POST для этой задачи могут быть использованы некоторые другие методы. Далее они также будут описаны в руководстве.

GET является одним из самых популярных HTTP методов. Метод GET указывает на то, что происходит попытка извлечь данные из определенного ресурса. Для того, чтобы выполнить запрос GET, используется requests.get().

Для проверки работы команды будет выполнен запрос GET в отношении Root REST API на GitHub. Для указанного ниже URL вызывается метод get().

requests.get(‘https://api.github.com’)

<Response [200]>

Если никакие python ошибки не возникло, вас можно поздравить – первый запрос успешно выполнен. Далее будет рассмотрен ответ на данный запрос, который можно получить при помощи объекта Response.

Объект Response получение ответа на запрос в Python

Response представляет собой довольно мощный объект для анализа результатов запроса. В качестве примера будет использован предыдущий запрос, только на этот раз результат будет представлен в виде переменной. Таким образом, получится лучше изучить его атрибуты и особенности использования.

response = requests.get(‘https://api.github.com’)

В данном примере при помощи get() захватывается определенное значение, что является частью объекта Response, и помещается в переменную под названием response. Теперь можно использовать переменную response для того, чтобы изучить данные, которые были получены в результате запроса GET.

HTTP коды состояний

Самыми первыми данными, которые будут получены через Response, будут коды состояния. Коды состояния сообщают о статусе запроса.

Например, статус 200 OK значит, что запрос успешно выполнен. А вот статус 404 NOT FOUND говорит о том, что запрашиваемый ресурс не был найден. Существует множество других статусных кодов, которые могут сообщить важную информацию, связанную с запросом.

Используя .status_code, можно увидеть код состояния, который возвращается с сервера.

>>> response.status_code

200

.status_code вернул значение 200. Это значит, что запрос был выполнен успешно, а сервер ответил, отобразив запрашиваемую информацию.

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

if response.status_code == 200:

    print(‘Success!’)

elif response.status_code == 404:

    print(‘Not Found.’)

В таком случае, если с сервера будет получен код состояния 200, тогда программа выведет значение Success!. Однако, если от сервера поступит код 404, тогда программа выведет значение Not Found.
requests может значительно упростить весь процесс. Если использовать Response в условных конструкциях, то при получении кода состояния в промежутке от 200 до 400, будет выведено значение True. В противном случае отобразится значение False.

Последний пример можно упростить при помощи использования оператора if.

if response:

    print(‘Success!’)

else:

    print(‘An error has occurred.’)

Стоит иметь в виду, что данный способ не проверяет, имеет ли статусный код точное значение 200. Причина заключается в том, что другие коды в промежутке от 200 до 400, например, 204 NO CONTENT и 304 NOT MODIFIED, также считаются успешными в случае, если они могут предоставить действительный ответ.

К примеру, код состояния 204 говорит о том, что ответ успешно получен, однако в полученном объекте нет содержимого. Можно сказать, что для оптимально эффективного использования способа необходимо убедиться, что начальный запрос был успешно выполнен. Требуется изучить код состояния и в случае необходимости произвести необходимые поправки, которые будут зависеть от значения полученного кода.

Допустим, если при использовании оператора if вы не хотите проверять код состояния, можно расширить диапазон исключений для неудачных результатов запроса. Это можно сделать при помощи использования .raise_for_status().

import requests

from requests.exceptions import HTTPError

for url in [‘https://api.github.com’, ‘https://api.github.com/invalid’]:

    try:

        response = requests.get(url)

        # если ответ успешен, исключения задействованы не будут

        response.raise_for_status()

    except HTTPError as http_err:

        print(f‘HTTP error occurred: {http_err}’)  # Python 3.6

    except Exception as err:

        print(f‘Other error occurred: {err}’)  # Python 3.6

    else:

        print(‘Success!’)

В случае вызова исключений через .raise_for_status() к некоторым кодам состояния применяется HTTPError. Когда код состояния показывает, что запрос успешно выполнен, программа продолжает работу без применения политики исключений.

На заметку. Для более продуктивной работы в Python 3.6 будет не лишним изучить f-строки. Не стоит пренебрегать ими, так как это отличный способ упростить форматирование строк.

Анализ способов использования кодов состояния, полученных с сервера, является неплохим стартом для изучения requests. Тем не менее, при создании запроса GET, значение кода состояния является не самой важной информацией, которую хочет получить программист. Обычно запрос производится для извлечения более содержательной информации. В дальнейшем будет показано, как добраться до актуальных данных, которые сервер высылает отправителю в ответ на запрос.

Зачастую ответ на запрос GET содержит весьма ценную информацию. Она находится в теле сообщения и называется пейлоад (payload). Используя атрибуты и методы библиотеки Response, можно получить пейлоад в различных форматах.

Для того, чтобы получить содержимое запроса в байтах, необходимо использовать .content.

>>> response = requests.get(‘https://api.github.com’)

>>> response.content

b‘{«current_user_url»:»https://api.github.com/user»,»current_user_authorizations_html_url»:»https://github.com/settings/connections/applications{/client_id}»,»authorizations_url»:»https://api.github.com/authorizations»,»code_search_url»:»https://api.github.com/search/code?q={query}{&page,per_page,sort,order}»,»commit_search_url»:»https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}»,»emails_url»:»https://api.github.com/user/emails»,»emojis_url»:»https://api.github.com/emojis»,»events_url»:»https://api.github.com/events»,»feeds_url»:»https://api.github.com/feeds»,»followers_url»:»https://api.github.com/user/followers»,»following_url»:»https://api.github.com/user/following{/target}»,»gists_url»:»https://api.github.com/gists{/gist_id}»,»hub_url»:»https://api.github.com/hub»,»issue_search_url»:»https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}»,»issues_url»:»https://api.github.com/issues»,»keys_url»:»https://api.github.com/user/keys»,»notifications_url»:»https://api.github.com/notifications»,»organization_repositories_url»:»https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}»,»organization_url»:»https://api.github.com/orgs/{org}»,»public_gists_url»:»https://api.github.com/gists/public»,»rate_limit_url»:»https://api.github.com/rate_limit»,»repository_url»:»https://api.github.com/repos/{owner}/{repo}»,»repository_search_url»:»https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}»,»current_user_repositories_url»:»https://api.github.com/user/repos{?type,page,per_page,sort}»,»starred_url»:»https://api.github.com/user/starred{/owner}{/repo}»,»starred_gists_url»:»https://api.github.com/gists/starred»,»team_url»:»https://api.github.com/teams»,»user_url»:»https://api.github.com/users/{user}»,»user_organizations_url»:»https://api.github.com/user/orgs»,»user_repositories_url»:»https://api.github.com/users/{user}/repos{?type,page,per_page,sort}»,»user_search_url»:»https://api.github.com/search/users?q={query}{&page,per_page,sort,order}»}’

Использование .content обеспечивает доступ к чистым байтам ответного пейлоада, то есть к любым данным в теле запроса. Однако, зачастую требуется конвертировать полученную информацию в строку в кодировке UTF-8. response делает это при помощи .text.

>>> response.text

‘{«current_user_url»:»https://api.github.com/user»,»current_user_authorizations_html_url»:»https://github.com/settings/connections/applications{/client_id}»,»authorizations_url»:»https://api.github.com/authorizations»,»code_search_url»:»https://api.github.com/search/code?q={query}{&page,per_page,sort,order}»,»commit_search_url»:»https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}»,»emails_url»:»https://api.github.com/user/emails»,»emojis_url»:»https://api.github.com/emojis»,»events_url»:»https://api.github.com/events»,»feeds_url»:»https://api.github.com/feeds»,»followers_url»:»https://api.github.com/user/followers»,»following_url»:»https://api.github.com/user/following{/target}»,»gists_url»:»https://api.github.com/gists{/gist_id}»,»hub_url»:»https://api.github.com/hub»,»issue_search_url»:»https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}»,»issues_url»:»https://api.github.com/issues»,»keys_url»:»https://api.github.com/user/keys»,»notifications_url»:»https://api.github.com/notifications»,»organization_repositories_url»:»https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}»,»organization_url»:»https://api.github.com/orgs/{org}»,»public_gists_url»:»https://api.github.com/gists/public»,»rate_limit_url»:»https://api.github.com/rate_limit»,»repository_url»:»https://api.github.com/repos/{owner}/{repo}»,»repository_search_url»:»https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}»,»current_user_repositories_url»:»https://api.github.com/user/repos{?type,page,per_page,sort}»,»starred_url»:»https://api.github.com/user/starred{/owner}{/repo}»,»starred_gists_url»:»https://api.github.com/gists/starred»,»team_url»:»https://api.github.com/teams»,»user_url»:»https://api.github.com/users/{user}»,»user_organizations_url»:»https://api.github.com/user/orgs»,»user_repositories_url»:»https://api.github.com/users/{user}/repos{?type,page,per_page,sort}»,»user_search_url»:»https://api.github.com/search/users?q={query}{&page,per_page,sort,order}»}’

Декодирование байтов в строку требует наличия определенной модели кодировки. По умолчанию requests попытается узнать текущую кодировку, ориентируясь по заголовкам HTTP. Указать необходимую кодировку можно при помощи добавления .encoding перед .text.

>>> response.encoding = ‘utf-8’ # Optional: requests infers this internally

>>> response.text

‘{«current_user_url»:»https://api.github.com/user»,»current_user_authorizations_html_url»:»https://github.com/settings/connections/applications{/client_id}»,»authorizations_url»:»https://api.github.com/authorizations»,»code_search_url»:»https://api.github.com/search/code?q={query}{&page,per_page,sort,order}»,»commit_search_url»:»https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}»,»emails_url»:»https://api.github.com/user/emails»,»emojis_url»:»https://api.github.com/emojis»,»events_url»:»https://api.github.com/events»,»feeds_url»:»https://api.github.com/feeds»,»followers_url»:»https://api.github.com/user/followers»,»following_url»:»https://api.github.com/user/following{/target}»,»gists_url»:»https://api.github.com/gists{/gist_id}»,»hub_url»:»https://api.github.com/hub»,»issue_search_url»:»https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}»,»issues_url»:»https://api.github.com/issues»,»keys_url»:»https://api.github.com/user/keys»,»notifications_url»:»https://api.github.com/notifications»,»organization_repositories_url»:»https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}»,»organization_url»:»https://api.github.com/orgs/{org}»,»public_gists_url»:»https://api.github.com/gists/public»,»rate_limit_url»:»https://api.github.com/rate_limit»,»repository_url»:»https://api.github.com/repos/{owner}/{repo}»,»repository_search_url»:»https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}»,»current_user_repositories_url»:»https://api.github.com/user/repos{?type,page,per_page,sort}»,»starred_url»:»https://api.github.com/user/starred{/owner}{/repo}»,»starred_gists_url»:»https://api.github.com/gists/starred»,»team_url»:»https://api.github.com/teams»,»user_url»:»https://api.github.com/users/{user}»,»user_organizations_url»:»https://api.github.com/user/orgs»,»user_repositories_url»:»https://api.github.com/users/{user}/repos{?type,page,per_page,sort}»,»user_search_url»:»https://api.github.com/search/users?q={query}{&page,per_page,sort,order}»}’

Если присмотреться к ответу, можно заметить, что его содержимое является сериализированным JSON контентом. Воспользовавшись словарем, можно взять полученные из .text строки str и провести с ними обратную сериализацию при помощи использования json.loads(). Есть и более простой способ, который требует применения .json().

>>> response.json()

{‘current_user_url’: ‘https://api.github.com/user’, ‘current_user_authorizations_html_url’: ‘https://github.com/settings/connections/applications{/client_id}’, ‘authorizations_url’: ‘https://api.github.com/authorizations’, ‘code_search_url’: ‘https://api.github.com/search/code?q={query}{&page,per_page,sort,order}’, ‘commit_search_url’: ‘https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}’, ’emails_url’: ‘https://api.github.com/user/emails’, ’emojis_url’: ‘https://api.github.com/emojis’, ‘events_url’: ‘https://api.github.com/events’, ‘feeds_url’: ‘https://api.github.com/feeds’, ‘followers_url’: ‘https://api.github.com/user/followers’, ‘following_url’: ‘https://api.github.com/user/following{/target}’, ‘gists_url’: ‘https://api.github.com/gists{/gist_id}’, ‘hub_url’: ‘https://api.github.com/hub’, ‘issue_search_url’: ‘https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}’, ‘issues_url’: ‘https://api.github.com/issues’, ‘keys_url’: ‘https://api.github.com/user/keys’, ‘notifications_url’: ‘https://api.github.com/notifications’, ‘organization_repositories_url’: ‘https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}’, ‘organization_url’: ‘https://api.github.com/orgs/{org}’, ‘public_gists_url’: ‘https://api.github.com/gists/public’, ‘rate_limit_url’: ‘https://api.github.com/rate_limit’, ‘repository_url’: ‘https://api.github.com/repos/{owner}/{repo}’, ‘repository_search_url’: ‘https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}’, ‘current_user_repositories_url’: ‘https://api.github.com/user/repos{?type,page,per_page,sort}’, ‘starred_url’: ‘https://api.github.com/user/starred{/owner}{/repo}’, ‘starred_gists_url’: ‘https://api.github.com/gists/starred’, ‘team_url’: ‘https://api.github.com/teams’, ‘user_url’: ‘https://api.github.com/users/{user}’, ‘user_organizations_url’: ‘https://api.github.com/user/orgs’, ‘user_repositories_url’: ‘https://api.github.com/users/{user}/repos{?type,page,per_page,sort}’, ‘user_search_url’: ‘https://api.github.com/search/users?q={query}{&page,per_page,sort,order}’}

Тип полученного значения из .json(), является словарем. Это значит, что доступ к его содержимому можно получить по ключу.

Коды состояния и тело сообщения предоставляют огромный диапазон возможностей. Однако, для их оптимального использования требуется изучить метаданные и заголовки HTTP.

HTTP заголовки ответов на запрос могут предоставить определенную полезную информацию. Это может быть тип содержимого ответного пейлоада, а также ограничение по времени для кеширования ответа. Для просмотра HTTP заголовков загляните в атрибут .headers.

>>> response.headers

{‘Server’: ‘GitHub.com’, ‘Date’: ‘Mon, 10 Dec 2018 17:49:54 GMT’, ‘Content-Type’: ‘application/json; charset=utf-8’, ‘Transfer-Encoding’: ‘chunked’, ‘Status’: ‘200 OK’, ‘X-RateLimit-Limit’: ’60’, ‘X-RateLimit-Remaining’: ’59’, ‘X-RateLimit-Reset’: ‘1544467794’, ‘Cache-Control’: ‘public, max-age=60, s-maxage=60’, ‘Vary’: ‘Accept’, ‘ETag’: ‘W/»7dc470913f1fe9bb6c7355b50a0737bc»‘, ‘X-GitHub-Media-Type’: ‘github.v3; format=json’, ‘Access-Control-Expose-Headers’: ‘ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type’, ‘Access-Control-Allow-Origin’: ‘*’, ‘Strict-Transport-Security’: ‘max-age=31536000; includeSubdomains; preload’, ‘X-Frame-Options’: ‘deny’, ‘X-Content-Type-Options’: ‘nosniff’, ‘X-XSS-Protection’: ‘1; mode=block’, ‘Referrer-Policy’: ‘origin-when-cross-origin, strict-origin-when-cross-origin’, ‘Content-Security-Policy’: «default-src ‘none'», ‘Content-Encoding’: ‘gzip’, ‘X-GitHub-Request-Id’: ‘E439:4581:CF2351:1CA3E06:5C0EA741’}

.headers возвращает словарь, что позволяет получить доступ к значению заголовка HTTP по ключу. Например, для просмотра типа содержимого ответного пейлоада, требуется использовать Content-Type.

>>> response.headers[‘Content-Type’]

‘application/json; charset=utf-8’

У объектов словарей в качестве заголовков есть своим особенности. Специфика HTTP предполагает, что заголовки не чувствительны к регистру. Это значит, что при получении доступа к заголовкам можно не беспокоится о том, использованы строчным или прописные буквы.

>>> response.headers[‘content-type’]

‘application/json; charset=utf-8’

При использовании ключей 'content-type' и 'Content-Type' результат будет получен один и тот же.

Это была основная информация, требуемая для работы с Response. Были задействованы главные атрибуты и методы, а также представлены примеры их использования. В дальнейшем будет показано, как изменится ответ после настройки запроса GET.

Python Requests параметры запроса

Наиболее простым способом настроить запрос GET является передача значений через параметры строки запроса в URL. При использовании метода get(), данные передаются в params. Например, для того, чтобы посмотреть на библиотеку requests можно использовать Search API на GitHub.

import requests

# Поиск местонахождения для запросов на GitHub

response = requests.get(

    ‘https://api.github.com/search/repositories’,

    params={‘q’: ‘requests+language:python’},

)

# Анализ некоторых атрибутов местонахождения запросов

json_response = response.json()

repository = json_response[‘items’][0]

print(f‘Repository name: {repository[«name»]}’)  # Python 3.6+

print(f‘Repository description: {repository[«description»]}’)  # Python 3.6+

Передавая словарь {'q': 'requests+language:python'} в параметр params, который является частью .get(), можно изменить ответ, что был получен при использовании Search API.

Можно передать параметры в get() в форме словаря, как было показано выше. Также можно использовать список кортежей.

>>> requests.get(

...     ‘https://api.github.com/search/repositories’,

...     params=[(‘q’, ‘requests+language:python’)],

... )

<Response [200]>

Также можно передать значение в байтах.

>>> requests.get(

...     ‘https://api.github.com/search/repositories’,

...     params=b‘q=requests+language:python’,

... )

<Response [200]>

Строки запроса полезны для уточнения параметров в запросах GET. Также можно настроить запросы при помощи добавления или изменения заголовков отправленных сообщений.

Для изменения HTTP заголовка требуется передать словарь данного HTTP заголовка в get() при помощи использования параметра headers. Например, можно изменить предыдущий поисковой запрос, подсветив совпадения в результате. Для этого в заголовке Accept медиа тип уточняется при помощи text-match.

import requests

response = requests.get(

    ‘https://api.github.com/search/repositories’,

    params={‘q’: ‘requests+language:python’},

    headers={‘Accept’: ‘application/vnd.github.v3.text-match+json’},

)

# просмотр нового массива `text-matches` с предоставленными данными

# о поиске в пределах результатов

json_response = response.json()

repository = json_response[‘items’][0]

print(f‘Text matches: {repository[«text_matches»]}’)

Заголовок Accept сообщает серверу о типах контента, который можно использовать в рассматриваемом приложении. Здесь подразумевается, что все совпадения будут подсвечены, для чего в заголовке используется значение application/vnd.github.v3.text-match+json. Это уникальный заголовок Accept для GitHub. В данном случае содержимое представлено в специальном JSON формате.

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

Примеры HTTP методов в Requests

Помимо GET, большой популярностью пользуются такие методы, как POST, PUT, DELETE, HEAD, PATCH и OPTIONS. Для каждого из этих методов существует своя сигнатура, которая очень похожа на метод get().

>>> requests.post(‘https://httpbin.org/post’, data={‘key’:‘value’})

>>> requests.put(‘https://httpbin.org/put’, data={‘key’:‘value’})

>>> requests.delete(‘https://httpbin.org/delete’)

>>> requests.head(‘https://httpbin.org/get’)

>>> requests.patch(‘https://httpbin.org/patch’, data={‘key’:‘value’})

>>> requests.options(‘https://httpbin.org/get’)

Каждая функция создает запрос к httpbin сервису, используя при этом ответный HTTP метод. Результат каждого метода можно изучить способом, который был использован в предыдущих примерах.

>>> response = requests.head(‘https://httpbin.org/get’)

>>> response.headers[‘Content-Type’]

‘application/json’

>>> response = requests.delete(‘https://httpbin.org/delete’)

>>> json_response = response.json()

>>> json_response[‘args’]

{}

При использовании каждого из данных методов в Response могут быть возвращены заголовки, тело запроса, коды состояния и многие другие аспекты. Методы POST, PUT и PATCH в дальнейшем будут описаны более подробно.

Python Requests тело сообщения

В соответствии со спецификацией HTTP запросы POST, PUT и PATCH передают информацию через тело сообщения, а не через параметры строки запроса. Используя requests, можно передать данные в параметр data.

В свою очередь data использует словарь, список кортежей, байтов или объект файла. Это особенно важно, так как может возникнуть необходимость адаптации отправляемых с запросом данных в соответствии с определенными параметрами сервера.

К примеру, если тип содержимого запроса application/x-www-form-urlencoded, можно отправить данные формы в виде словаря.

>>> requests.post(‘https://httpbin.org/post’, data={‘key’:‘value’})

<Response [200]>

Ту же самую информацию также можно отправить в виде списка кортежей.

>>> requests.post(‘https://httpbin.org/post’, data=[(‘key’, ‘value’)])

<Response [200]>

В том случае, если требуется отравить данные JSON, можно использовать параметр json. При передачи данных JSON через json, requests произведет сериализацию данных и добавит правильный Content-Type заголовок.

Стоит взять на заметку сайт httpbin.org. Это чрезвычайно полезный ресурс, созданный человеком, который внедрил использование requests – Кеннетом Рейтцом. Данный сервис предназначен для тестовых запросов. Здесь можно составить пробный запрос и получить ответ с требуемой информацией. В качестве примера рассмотрим базовый запрос с использованием POST.

>>> response = requests.post(‘https://httpbin.org/post’, json={‘key’:‘value’})

>>> json_response = response.json()

>>> json_response[‘data’]

‘{«key»: «value»}’

>>> json_response[‘headers’][‘Content-Type’]

‘application/json’

Здесь видно, что сервер получил данные и HTTP заголовки, отправленные вместе с запросом. requests также предоставляет информацию в форме PreparedRequest.

Python Requests анализ запроса

При составлении запроса стоит иметь в виду, что перед его фактической отправкой на целевой сервер библиотека requests выполняет определенную подготовку. Подготовка запроса включает в себя такие вещи, как проверка заголовков и сериализация содержимого JSON.

Если открыть .request, можно просмотреть PreparedRequest.

>>> response = requests.post(‘https://httpbin.org/post’, json={‘key’:‘value’})

>>> response.request.headers[‘Content-Type’]

‘application/json’

>>> response.request.url

‘https://httpbin.org/post’

>>> response.request.body

b‘{«key»: «value»}’

Проверка PreparedRequest открывает доступ ко всей информации о выполняемом запросе. Это может быть пейлоад, URL, заголовки, аутентификация и многое другое.

У всех описанных ранее типов запросов была одна общая черта – они представляли собой неаутентифицированные запросы к публичным API. Однако, подобающее большинство служб, с которыми может столкнуться пользователь, запрашивают аутентификацию.

Python Requests аутентификация HTTP AUTH

Аутентификация помогает сервису понять, кто вы. Как правило, вы предоставляете свои учетные данные на сервер, передавая данные через заголовок Authorization или пользовательский заголовок, определенной службы. Все функции запроса, которые вы видели до этого момента, предоставляют параметр с именем auth, который позволяет вам передавать свои учетные данные.

Одним из примеров API, который требует аутентификации, является Authenticated User API на GitHub. Это конечная точка веб-сервиса, которая предоставляет информацию о профиле аутентифицированного пользователя. Чтобы отправить запрос API-интерфейсу аутентифицированного пользователя, вы можете передать свое имя пользователя и пароль на GitHub через кортеж в get().

>>> from getpass import getpass

>>> requests.get(‘https://api.github.com/user’, auth=(‘username’, getpass()))

<Response [200]>

Запрос выполнен успешно, если учетные данные, которые вы передали в кортеже auth, действительны. Если вы попытаетесь сделать этот запрос без учетных данных, вы увидите, что код состояния 401 Unauthorized.

>>> requests.get(‘https://api.github.com/user’)

<Response [401]>

Когда вы передаете имя пользователя и пароль в кортеже параметру auth, вы используете учетные данные при помощи базовой схемы аутентификации HTTP.

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

>>> from requests.auth import HTTPBasicAuth

>>> from getpass import getpass

>>> requests.get(

...     ‘https://api.github.com/user’,

...     auth=HTTPBasicAuth(‘username’, getpass())

... )

<Response [200]>

Хотя вам не нужно явно указывать обычную аутентификацию, может потребоваться аутентификация с использованием другого метода. requests предоставляет другие методы аутентификации, например, HTTPDigestAuth и HTTPProxyAuth.

Вы даже можете предоставить свой собственный механизм аутентификации. Для этого необходимо сначала создать подкласс AuthBase. Затем происходит имплементация __call__().

import requests

from requests.auth import AuthBase

class TokenAuth(AuthBase):

    «»»Implements a custom authentication scheme.»»»

    def __init__(self, token):

        self.token = token

    def __call__(self, r):

        «»»Attach an API token to a custom auth header.»»»

        r.headers[‘X-TokenAuth’] = f‘{self.token}’  # Python 3.6+

        return r

requests.get(‘https://httpbin.org/get’, auth=TokenAuth(‘12345abcde-token’))

Здесь пользовательский механизм TokenAuth получает специальный токен. Затем этот токен включается заголовок X-TokenAuth запроса.

Плохие механизмы аутентификации могут привести к уязвимостям безопасности, поэтому, если службе по какой-то причине не нужен настраиваемый механизм аутентификации, вы всегда можете использовать проверенную схему аутентификации, такую как Basic или OAuth.

Пока вы думаете о безопасности, давайте рассмотрим использование requests в SSL сертификатах.

Python Requests проверка SSL сертификата

Всякий раз, когда данные, которые вы пытаетесь отправить или получить, являются конфиденциальными, безопасность важна. Вы общаетесь с защищенными сайтами через HTTP, устанавливая зашифрованное соединение с использованием SSL, что означает, что проверка SSL сертификата целевого сервера имеет решающее значение.

Хорошей новостью является то, что requests по умолчанию все делает сам. Однако в некоторых случаях необходимо внести определенные поправки.

Если требуется отключить проверку SSL-сертификата, параметру verify функции запроса можно присвоить значение False.

>>> requests.get(‘https://api.github.com’, verify=False)

InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advancedusage.html#ssl-warnings

  InsecureRequestWarning)

<Response [200]>

В случае небезопасного запроса requests предупреждает о возможности потери информации и просит сохранить данные или отказаться от запроса.

Примечание. Для предоставления сертификатов requests использует пакет, который вызывается certifi. Это дает понять requests, каким ответам можно доверять. Поэтому вам следует часто обновлять certifi, чтобы обеспечить максимальную безопасность ваших соединений.

Python Requests производительность приложений

При использовании requests, особенно в среде приложений, важно учитывать влияние на производительность. Такие функции, как контроль таймаута, сеансы и ограничения повторных попыток, могут помочь обеспечить бесперебойную работу приложения.

Таймауты

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

По умолчанию в requests на ответ время не ограничено, и весь процесс может занять значительный промежуток. По этой причине вы всегда должны указывать время ожидания, чтобы такого не происходило. Чтобы установить время ожидания запроса, используйте параметр timeout. timeout может быть целым числом или числом с плавающей точкой, представляющим количество секунд ожидания ответа до истечения времени ожидания.

>>> requests.get(‘https://api.github.com’, timeout=1)

<Response [200]>

>>> requests.get(‘https://api.github.com’, timeout=3.05)

<Response [200]>

В первом примере запрос истекает через 1 секунду. Во втором примере запрос истекает через 3,05 секунды.

Вы также можете передать кортеж. Это – таймаут соединения (время, за которое клиент может установить соединение с сервером), а второй – таймаут чтения (время ожидания ответа, как только ваш клиент установил соединение):

>>> requests.get(‘https://api.github.com’, timeout=(2, 5))

<Response [200]>

Если запрос устанавливает соединение в течение 2 секунд и получает данные в течение 5 секунд после установления соединения, то ответ будет возвращен, как это было раньше. Если время ожидания истекло, функция вызовет исключение Timeout.

import requests

from requests.exceptions import Timeout

try:

    response = requests.get(‘https://api.github.com’, timeout=1)

except Timeout:

    print(‘The request timed out’)

else:

    print(‘The request did not time out’)

Ваша программа может поймать исключение Timeout и ответить соответственно.

Объект Session в Requests

До сих пор вы имели дело с requests API высокого уровня, такими как get() и post(). Эти функции являются абстракцией того, что происходит, когда вы делаете свои запросы. Они скрывают детали реализации, такие как управление соединениями, так что вам не нужно о них беспокоиться.

Под этими абстракциями находится класс под названием Session. Если вам необходимо настроить контроль над выполнением запросов или повысить производительность ваших запросов, вам может потребоваться использовать Session напрямую.

Сессии используются для сохранения параметров в запросах.

Например, если вы хотите использовать одну и ту же аутентификацию для нескольких запросов, вы можете использовать сеанс:

import requests

from getpass import getpass

# используя менеджер контента, можно убедиться, что ресурсы, применимые

# во время сессии будут свободны после использования

with requests.Session() as session:

    session.auth = (‘username’, getpass())

    # Instead of requests.get(), you’ll use session.get()

    response = session.get(‘https://api.github.com/user’)

# здесь можно изучить ответ

print(response.headers)

print(response.json())

Каждый раз, когда вы делаете запрос session, после того как он был инициализирован с учетными данными аутентификации, учетные данные будут сохраняться.

Первичная оптимизация производительности сеансов происходит в форме постоянных соединений. Когда ваше приложение устанавливает соединение с сервером с помощью Session, оно сохраняет это соединение в пуле соединений. Когда ваше приложение снова хочет подключиться к тому же серверу, оно будет использовать соединение из пула, а не устанавливать новое.

HTTPAdapter — Максимальное количество повторов запроса в Requests

В случае сбоя запроса возникает необходимость сделать повторный запрос. Однако requests не будет делать это самостоятельно. Для применения функции повторного запроса требуется реализовать собственный транспортный адаптер.

Транспортные адаптеры позволяют определить набор конфигураций для каждой службы, с которой вы взаимодействуете. Предположим, вы хотите, чтобы все запросы к https://api.github.com были повторены три раза, прежде чем, наконец, появится ConnectionError. Для этого нужно построить транспортный адаптер, установить его параметр max_retries и подключить его к существующему объекту Session.

import requests

from requests.adapters import HTTPAdapter

from requests.exceptions import ConnectionError

github_adapter = HTTPAdapter(max_retries=3)

session = requests.Session()

# использование `github_adapter` для всех запросов, которые начинаются с указанным URL

session.mount(‘https://api.github.com’, github_adapter)

try:

    session.get(‘https://api.github.com’)

except ConnectionError as ce:

    print(ce)

При установке HTTPAdapter, github_adapter к session, session будет придерживаться своей конфигурации для каждого запроса к https://api.github.com.

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

Заключение

Изучение библиотеки Python requests является очень трудоемким процессом.

После разбора данных в статье примеров можно научиться тому, как:

  • Создавать запросы, используя различные методы HTTPGET, POST и PUT;
  • Настраивать свои запросы, изменив заголовки, аутентификацию, строки запросов и тела сообщений;
  • Проверять данные, которые были отправлены на сервер, а также те данные, которые сервер отправил обратно;
  • Работать с проверкой SSL сертификата;
  • Эффективно использовать requests, max_retries, timeout, Sessions и транспортные адаптеры.

Грамотное использование requests позволит наиболее эффективно настроить разрабатываемые приложения, исследуя широкий спектр веб-сервисов и данных, опубликованных на них.

  • Данная статья является переводом статьи: Python’s Requests Library (Guide)
  • Изображение статьи принадлежит сайту © RealPython

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: vasile.buldumac@ati.utm.md

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»

Время чтения 5 мин.

Метод post() используется, когда мы хотим отправить какие-то данные на сервер. Затем данные сохраняются в базе данных.

Содержание

  1. Что такое HTTP-запрос в Python?
  2. Ключевые моменты POST-запроса
  3. Что такое модуль запросов Python?
  4. Как использовать модуль requests в Python?
  5. Что такое метод requests.post() в Python?
  6. Синтаксис
  7. Параметры
  8. Как использовать requests.post() в Python?
  9. Более сложные POST-запросы
  10. POST-файл с кодировкой из нескольких частей

Что такое HTTP-запрос в Python?

POST отправляет данные на сервер для создания ресурса. Данные, отправленные на сервер с запросом POST, хранятся в теле запроса HTTP.

POST /test/add HTTP/1.1

Host: appdividend.com

name1=value1&name2=value2

  1. Запросы POST не имеют ограничений по длине данных. Это может быть все, что вы хотите.
  2. POST-запросы не сохраняются в истории браузера.
  3. Никогда не кэшируются.
  4. Не могут быть добавлены в закладки.

Что такое модуль запросов Python?

Requests — это HTTP-библиотека под лицензией Apache2, написанная на Python, которая помогает сделать HTTP-запросы более простыми и удобными для человека.

Как использовать модуль requests в Python?

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

python3 m pip install requests

# OR

pip install requests

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

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

Что такое метод requests.post() в Python?

Чтобы создать запрос POST в Python, используйте метод request.post(). Метод запросов post() принимает URL-адреса, данные, json и аргументы в качестве аргументов и отправляет запрос POST на указанный URL-адрес.

Вы можете отправить данные вместе с post-запросом.

Синтаксис

requests.post(url, data={key: value}, json={key: value}, args)

Параметры

Параметр Описание
url обязателен, URL-адрес запроса.
data необязателен. Это может быть словарь, список кортежей, байты или файловый объект для отправки по указанному url.
json необязательно. Это объект JSON для отправки по указанному URL.
files необязательно. Это словарь файлов для отправки по указанному url.
allow_redirects необязательно. Это логическое значение для включения/отключения перенаправления.
Значение по умолчанию True (разрешает перенаправление)
auth необязательно. Это кортеж для включения безопасной аутентификации по протоколу HTTP.
По умолчанию None
cert необязательно. Это строка или кортеж, указывающий файл сертификата или ключ.
По умолчанию None
cookies необязательно. Это словарь файлов cookie для отправки по указанному url-адресу.
По умолчанию None
headers необязательно. Это словарь HTTP-заголовков для отправки по указанному URL.
По умолчанию None
proxies необязательно. Это словарь протокола для URL-адреса прокси-сервера.
По умолчанию None
stream необязательно. Логическое значение показывает, должен ли ответ быть немедленно загружен (False) или передан потоком (True).
Значение по умолчанию False
timeout необязательно. Это кортеж, или число, указывающее, сколько секунд требуется для ожидания, пока клиент установит соединение и отправит ответ. Аргумент по умолчанию равен None, что означает, что запрос будет продолжаться до тех пор, пока соединение не будет закрыто или потеряно.
verify необязательно. Это логическое значение или строковое указание для проверки наличия TLS-сертификата сервера или нет.
Значение по умолчанию True

Как использовать requests.post() в Python?

Чтобы использовать метод request.post(), передайте URL-адрес и данные методу post() и проверьте ответ. Отправьте запрос POST на веб-сайт https://httpbin.org с помощью метода post() и распечатайте ответ.

import requests

res = requests.post(‘https://httpbin.org/post’, data={‘st3’: ‘jim hopper’})

print(res.text)

Выход

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

{

  «args»: {},

  «data»: «»,

  «files»: {},

  «form»: {

    «st3»: «jim hopper»

  },

  «headers»: {

    «Accept»: «*/*»,

    «Accept-Encoding»: «gzip, deflate»,

    «Content-Length»: «14»,

    «Content-Type»: «application/x-www-form-urlencoded»,

    «Host»: «httpbin.org»,

    «User-Agent»: «python-requests/2.23.0»,

    «X-Amzn-Trace-Id»: «Root=1-5ef049b1-f58a70bb84d4803c73f14e21»

  },

  «json»: null,

  «origin»: «43.250.156.99»,

  «url»: «https://httpbin.org/post»

}

В этом примере мы получаем объект ответа, который содержит много информации. Во-первых, объект формы содержит наш ключ и значение, st3 и Jim hopper. Во-вторых, есть объект заголовка, содержащий некоторые свойства, а затем json, источник и URL.

Более сложные POST-запросы

Вы можете отправить некоторые данные, закодированные в форме, так же, как HTML-форма. Для этого вы должны передать словарь аргументу данных.

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

import requests

payload = {

  ‘eleven’: ‘MBB’,

  ‘hopper’: ‘DKH’

}

res = requests.post(‘https://httpbin.org/post’, data=payload)

print(res.text)

Выход

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

{

  «args»: {},

  «data»: «»,

  «files»: {},

  «form»: {

    «eleven»: «MBB»,

    «hopper»: «DKH»

  },

  «headers»: {

    «Accept»: «*/*»,

    «Accept-Encoding»: «gzip, deflate»,

    «Content-Length»: «21»,

    «Content-Type»: «application/x-www-form-urlencoded»,

    «Host»: «httpbin.org»,

    «User-Agent»: «python-requests/2.23.0»,

    «X-Amzn-Trace-Id»: «Root=1-5ef04d9e-3b7860a6206c465070c08258»

  },

  «json»: null,

  «origin»: «43.250.156.99»,

  «url»: «https://httpbin.org/post»

}

Бывают случаи, когда вам нужно отправить данные, которые не закодированы в форме. Например, если вы передадите строку вместо dict, данные будут опубликованы напрямую.

import requests

import json

payload = {

  ‘eleven’: ‘MBB’,

  ‘hopper’: ‘DKH’

}

url = ‘https://httpbin.org/post’

res = requests.post(url, data=json.dumps(payload))

print(res.text)

Выход

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

{

  «args»: {},

  «data»: «{«eleven»: «MBB», «hopper»: «DKH»}»,

  «files»: {},

  «form»: {},

  «headers»: {

    «Accept»: «*/*»,

    «Accept-Encoding»: «gzip, deflate»,

    «Content-Length»: «34»,

    «Host»: «httpbin.org»,

    «User-Agent»: «python-requests/2.23.0»,

    «X-Amzn-Trace-Id»: «Root=1-5ef04e4d-c665add6bae7e8d044ac55aa»

  },

  «json»: {

    «eleven»: «MBB»,

    «hopper»: «DKH»

  },

  «origin»: «43.250.156.99»,

  «url»: «https://httpbin.org/post»

}

Вы можете увидеть свойство данных. Функция Python json.dumps() преобразует словарь в строку, а затем мы печатаем строку и ее тип. Таким образом, в базе данных строка хранится напрямую.

Вместо того, чтобы кодировать dict, вы также можете передать его напрямую, используя параметр json, который будет закодирован автоматически. См. следующий код.

import requests

import json

payload = {

    ‘eleven’: ‘MBB’,

    ‘hopper’: ‘DKH’

}

url = ‘https://httpbin.org/post’

res = requests.post(url, json=payload)

print(res.text)

Это даст нам тот же результат, что и выше. Здесь мы взяли параметр json и передали словарь как значение, которое автоматически кодируется в строку.

POST-файл с кодировкой из нескольких частей

Создайте составной POST-запрос, отправив файл на сервер.

В текущем каталоге проекта у меня есть текстовый файл с именем app.txt, который имеет следующее содержимое: Hello World.

import requests

files = {‘file’: open(‘app.txt’, ‘rb’)}

url = ‘https://httpbin.org/post’

res = requests.post(url, files=files)

print(res.text)

Выход

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

{

  «args»: {},

  «data»: «»,

  «files»: {

    «file»: «Hello world»

  },

  «form»: {},

  «headers»: {

    «Accept»: «*/*»,

    «Accept-Encoding»: «gzip, deflate»,

    «Content-Length»: «154»,

    «Content-Type»: «multipart/form-data; boundary=3fca660e87944d3138832fb6651dad85»,

    «Host»: «httpbin.org»,

    «User-Agent»: «python-requests/2.23.0»,

    «X-Amzn-Trace-Id»: «Root=1-5ef050ce-4d860239803f73dffc9b35a2»

  },

  «json»: null,

  «origin»: «43.250.156.99»,

  «url»: «https://httpbin.org/post»

}

В ответ мы получили пустой объект данных.

Мы также получили файлы для возражения в ответ, атрибут файла, значением которого является содержимое файла. В нашем случае это Hello World.

import requests

files = {

    ‘file’:(‘app.txt’, open(‘app.txt’, ‘rb’), ‘application/txt’, {‘Expires’: ‘0’})

}

url = ‘https://httpbin.org/post’

res = requests.post(url, files=files)

print(res.text)

Если вы публикуете большой файл как запрос multipart/form-data, по умолчанию библиотека запросов не поддерживает этого, но за вас эту работу сделает отдельный пакет, который называется request-toolbelt.

HTTP headers let the client and the server pass additional information with an HTTP request or response. All the headers are case-insensitive, headers fields are separated by colon, key-value pairs in clear-text string format.

Request with headers

Requests do not change its behavior at all based on which headers are specified. The headers are simply passed on into the final request. All header values must be a string, bytestring, or Unicode. While permitted, it’s advised to avoid passing Unicode header values. We can make requests with the headers we specify and by using the headers attribute we can tell the server with additional information about the request.

Headers can be Python Dictionaries like,  { “Name of Header”: “Value of the Header” }

The Authentication Header tells the server who you are.  Typically, we can send the authentication credentials through the Authorization header to make an authenticated request.

Example:

Headers = { “Authorization” : ”our_unique_secret_token” }

response = request.post(“https://example.com/get-my-account-detail”, headers=Headers)

Request Object Structure

Request with body

POST requests pass their data through the message body, The Payload will be set to the data parameter. data parameter takes a dictionary, a list of tuples, bytes, or a file-like object. You’ll want to adapt the data you send in the body of your request to the specified URL.

Syntax:

requests.post(url, data={key: value}, json={key: value}, headers={key:value}, args) *(data, json, headers parameters are optional.)

Given below are few implementations to help understand the concept better.

Example 1: Sending requests with data as a payload

Python3

import requests

data = {

    "id": 1001,

    "name": "geek",

    "passion": "coding",

}

response = requests.post(url, json=data)

print("Status Code", response.status_code)

print("JSON Response ", response.json())

Output:

Example 2: Sending requests with JSON data and headers

Python

import requests

import json

headers = {"Content-Type": "application/json; charset=utf-8"}

data = {

    "id": 1001,

    "name": "geek",

    "passion": "coding",

}

response = requests.post(url, headers=headers, json=data)

print("Status Code", response.status_code)

print("JSON Response ", response.json())

Output:

Last Updated :
23 Nov, 2021

Like Article

Save Article

Понравилась статья? Поделить с друзьями:
  • Как найти парфюмерную воду
  • Почему гаснет монитор во время работы компьютера как исправить
  • Как отключить найти mac на макбуке
  • Как найти на компьютере пароли от wifi
  • Как составить решение для дивидендов