Руководство по созданию api-запросов в python
Содержание:
- Python NumPy
- Постоянные соединения
- Parameter Values
- Python Tutorial
- Python Tutorial
- Тайм-ауты
- Отправка файлов cookie и заголовков
- Properties and Methods
- Производительность
- Объекты сеанса
- Python Matplotlib
- Создание запроса GET
- Methods
- Report Error
- Parameter Values
- Редиректы и история
- Задержка
- Parameter Values
- Python Tutorial
- Асинхронность
Python NumPy
NumPy IntroNumPy Getting StartedNumPy Creating ArraysNumPy Array IndexingNumPy Array SlicingNumPy Data TypesNumPy Copy vs ViewNumPy Array ShapeNumPy Array ReshapeNumPy Array IteratingNumPy Array JoinNumPy Array SplitNumPy Array SearchNumPy Array SortNumPy Array FilterNumPy Random
Random Intro
Data Distribution
Random Permutation
Seaborn Module
Normal Distribution
Binomial Distribution
Poisson Distribution
Uniform Distribution
Logistic Distribution
Multinomial Distribution
Exponential Distribution
Chi Square Distribution
Rayleigh Distribution
Pareto Distribution
Zipf Distribution
NumPy ufunc
ufunc Intro
ufunc Create Function
ufunc Simple Arithmetic
ufunc Rounding Decimals
ufunc Logs
ufunc Summations
ufunc Products
ufunc Differences
ufunc Finding LCM
ufunc Finding GCD
ufunc Trigonometric
ufunc Hyperbolic
ufunc Set Operations
Постоянные соединения
Первый способ, который необходимо принять во внимание, — это постоянное подключение к веб-серверу. Постоянные соединения являются стандартом начиная с HTTP 1.1, хотя многие приложения не используют их
Отсутствие оптимизации в нем легко объяснить, если вы знаете, что при использовании запросов в простом режиме (например, с функцией get) соединение закрывается при получение ответа от сервера. Чтобы избежать этого, приложению необходимо использовать объект Session, который позволяет повторно использовать уже открытое соединение.
Использование сеанса (Session) с запросами
import requests session = requests.Session() session.get("http://example.com") # Connection is re-used session.get("http://example.com")
Каждое соединение хранится в пуле соединений (по умолчанию помещает 10 соединений), размер пула также настраивается:
Изменение размера пула
import requests session = requests.Session() adapter = requests.adapters.HTTPAdapter( pool_connections=100, pool_maxsize=100) session.mount('http://', adapter) response = session.get("http://example.org")
Повторное использование TCP-соединения для отправки нескольких HTTP-запросов дает ряд преимуществ в производительности:
- Снижение использования процессора и памяти (меньшее количество одновременно открытых соединений).
- Уменьшенная задержка при последующих запросах (без TCP-handshaking).
- Исключения могут быть подняты без штрафа закрытия TCP-соединения.
Протокол HTTP также обеспечивает конвейеризацию (pipelining), которая позволяет отправлять несколько запросов по одному и тому же соединению, не дожидаясь получения ответов (думаю, пакет). К сожалению, это не поддерживается библиотекой requests. Однако конвейеризация запросов может быть не такой быстрой, как их параллельная отправка. Так как, протокол HTTP 1.1 заставляет отправлять ответы в том же порядке, в котором были отправлены запросы — первым пришел — первым вышел.
Parameter Values
Parameter | Description | |
---|---|---|
url | Try it | Required. The url of the request |
data | Try it | Optional. A dictionary, list of tuples, bytes or a file object to send to the specified url |
json | Try it | Optional. A JSON object to send to the specified url |
files | Try it | Optional. A dictionary of files to send to the specified url |
allow_redirects | Try it | Optional. A Boolean to enable/disable redirection.Default (allowing redirects) |
auth | Try it | Optional. A tuple to enable a certain HTTP authentication.Default |
cert | Try it | Optional. A String or Tuple specifying a cert file or key.Default |
cookies | Try it | Optional. A dictionary of cookies to send to the specified url.Default |
headers | Try it | Optional. A dictionary of HTTP headers to send to the specified url.Default |
proxies | Try it | Optional. A dictionary of the protocol to the proxy url.Default |
stream | Try it | Optional. A Boolean indication if the response should be immediately downloaded (False) or streamed (True).Default |
timeout | Try it | Optional. A number, or a tuple, indicating how many seconds to wait for the client to make a connection and/or send a response.Default which means the request will continue until the connection is closed |
verify |
Try it Try it |
Optional. A Boolean or a String indication to verify the servers TLS certificate or not.Default |
Python Tutorial
Python HOMEPython IntroPython Get StartedPython SyntaxPython CommentsPython Variables
Python Variables
Variable Names
Assign Multiple Values
Output Variables
Global Variables
Variable Exercises
Python Data TypesPython NumbersPython CastingPython Strings
Python Strings
Slicing Strings
Modify Strings
Concatenate Strings
Format Strings
Escape Characters
String Methods
String Exercises
Python BooleansPython OperatorsPython Lists
Python Lists
Access List Items
Change List Items
Add List Items
Remove List Items
Loop Lists
List Comprehension
Sort Lists
Copy Lists
Join Lists
List Methods
List Exercises
Python Tuples
Python Tuples
Access Tuples
Update Tuples
Unpack Tuples
Loop Tuples
Join Tuples
Tuple Methods
Tuple Exercises
Python Sets
Python Sets
Access Set Items
Add Set Items
Remove Set Items
Loop Sets
Join Sets
Set Methods
Set Exercises
Python Dictionaries
Python Dictionaries
Access Items
Change Items
Add Items
Remove Items
Loop Dictionaries
Copy Dictionaries
Nested Dictionaries
Dictionary Methods
Dictionary Exercise
Python If…ElsePython While LoopsPython For LoopsPython FunctionsPython LambdaPython ArraysPython Classes/ObjectsPython InheritancePython IteratorsPython ScopePython ModulesPython DatesPython MathPython JSONPython RegExPython PIPPython Try…ExceptPython User InputPython String Formatting
Python Tutorial
Python HOMEPython IntroPython Get StartedPython SyntaxPython CommentsPython Variables
Python Variables
Variable Names
Assign Multiple Values
Output Variables
Global Variables
Variable Exercises
Python Data TypesPython NumbersPython CastingPython Strings
Python Strings
Slicing Strings
Modify Strings
Concatenate Strings
Format Strings
Escape Characters
String Methods
String Exercises
Python BooleansPython OperatorsPython Lists
Python Lists
Access List Items
Change List Items
Add List Items
Remove List Items
Loop Lists
List Comprehension
Sort Lists
Copy Lists
Join Lists
List Methods
List Exercises
Python Tuples
Python Tuples
Access Tuples
Update Tuples
Unpack Tuples
Loop Tuples
Join Tuples
Tuple Methods
Tuple Exercises
Python Sets
Python Sets
Access Set Items
Add Set Items
Remove Set Items
Loop Sets
Join Sets
Set Methods
Set Exercises
Python Dictionaries
Python Dictionaries
Access Items
Change Items
Add Items
Remove Items
Loop Dictionaries
Copy Dictionaries
Nested Dictionaries
Dictionary Methods
Dictionary Exercise
Python If…ElsePython While LoopsPython For LoopsPython FunctionsPython LambdaPython ArraysPython Classes/ObjectsPython InheritancePython IteratorsPython ScopePython ModulesPython DatesPython MathPython JSONPython RegExPython PIPPython Try…ExceptPython User InputPython String Formatting
Тайм-ауты
Вы можете сказать Requests прекратить ожидание ответа после определенного количества секунд с помощью параметра :
>>> requests.get('http://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) 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)
Примечание: это не ограничение по времени полной загрузки ответа. Исключение возникает, если сервер не дал ответ за секунд (точнее, если ни одного байта не было получено от основного сокета за секунд).
Как уже упоминалось ранее, вы можете получить доступ к файлам cookie и заголовкам, которые сервер отправляет вам обратно с помощью и . Запросы также позволяют отправлять свои собственные cookie-файлы и заголовки с запросом. Это может быть полезно, если вы хотите, скажем, установить пользовательский агента для вашего запроса.
Чтобы добавить HTTP-заголовки в запрос, вы можете просто передать их в для параметра . Аналогично, вы также можете отправлять свои собственные файлы cookie на сервер, используя , переданный в параметр .
Cookies также может быть передано в Cookie Jar. Они предоставляют более полный интерфейс, позволяющий использовать эти файлы cookie на нескольких путях. Вот пример:
Properties and Methods
Property/Method | Description | |
---|---|---|
apparent_encoding | Try it | Returns the apparent encoding |
close() | Try it | Closes the connection to the server |
content | Try it | Returns the content of the response, in bytes |
cookies | Try it | Returns a CookieJar object with the cookies sent back from the server |
elapsed | Try it | Returns a timedelta object with the time elapsed from sending the request to the arrival of the response |
encoding | Try it | Returns the encoding used to decode r.text |
headers | Try it | Returns a dictionary of response headers |
history | Try it | Returns a list of response objects holding the history of request (url) |
is_permanent_redirect | Try it | Returns True if the response is the permanent redirected url, otherwise False |
is_redirect | Try it | Returns True if the response was redirected, otherwise False |
iter_content() | Try it | Iterates over the response |
iter_lines() | Try it | Iterates over the lines of the response |
json() | Try it | Returns a JSON object of the result (if the result was written in JSON format, if not it raises an error) |
links | Try it | Returns the header links |
next | Try it | Returns a PreparedRequest object for the next request in a redirection |
ok | Try it | Returns True if status_code is less than 400, otherwise False |
raise_for_status() | Try it | If an error occur, this method returns a HTTPError object |
reason | Try it | Returns a text corresponding to the status code |
request | Try it | Returns the request object that requested this response |
status_code | Try it | Returns a number that indicates the status (200 is OK, 404 is Not Found) |
text | Try it | Returns the content of the response, in unicode |
url | Try it | Returns the URL of the response |
Производительность
Ниже приведен фрагмент HTTP-клиента, отправляющего запросы на httpbin.org, HTTP-API, который обеспечивает (среди прочего) конечную точку, имитирующую длинный запрос. Этот пример реализует все методы, перечисленные выше.
Программа для сравнения производительности использования различных запросов
import contextlib import time import aiohttp import asyncio import requests from requests_futures import sessions URL = "http://httpbin.org/delay/1" TRIES = 10 @contextlib.contextmanager def report_time(test): t0 = time.time() yield print("Time needed for `%s' called: %.2fs" % (test, time.time() - t0)) with report_time("serialized"): for i in range(TRIES): requests.get(URL) session = requests.Session() with report_time("Session"): for i in range(TRIES): session.get(URL) session = sessions.FuturesSession(max_workers=2) with report_time("FuturesSession w/ 2 workers"): futures = for f in futures: f.result() session = sessions.FuturesSession(max_workers=TRIES) with report_time("FuturesSession w/ max workers"): futures = for f in futures: f.result() async def get(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: await response.read() loop = asyncio.get_event_loop() with report_time("aiohttp"): loop.run_until_complete( asyncio.gather(*))
Запуск этой программы дает следующий вывод:
Time needed for `serialized' called: 12.12s Time needed for `Session' called: 11.22s Time needed for `FuturesSession w/ 2 workers' called: 5.65s Time needed for `FuturesSession w/ max workers' called: 1.25s Time needed for `aiohttp' called: 1.19s
Не удивительно, что более медленный результат приходит с сериализованной версией, поскольку все запросы выполняются один за другим без повторного использования соединения — 12 секунд на 10 запросов.
Использование объекта Session и, следовательно, повторное использование соединения означает экономию 8% времени, что уже является большим и легким выигрышем. Как минимум, вы всегда должны использовать Session.
Если ваша система и программа допускают использование потоков, рекомендуется использовать их для распараллеливания запросов. Однако у потоков есть некоторые накладные расходы, и они не менее весовые. Они должны быть созданы, запущены и затем присоединены.
Если вы не используете старые версии Python, то, без сомнения, использование aiohttp должно быть вашим выбором, если вы хотите написать быстрый и асинхронный HTTP-клиент. Это самое быстрое и масштабируемое решение, поскольку оно может обрабатывать сотни параллельных запросов.
Объекты сеанса
Иногда полезно сохранять определенные параметры для нескольких запросов. Объект Session делает именно это. Например, он будет сохранять данные cookie во всех запросах, сделанных с использованием того же сеанса. Объект Session использует объединение соединений urllib3. Это означает, что базовое TCP-соединение будет повторно использоваться для всех запросов, сделанных на один и тот же хост. Это может значительно повысить производительность. Вы также можете использовать методы объекта Requests с объектом Session.
Ниже приведен пример нескольких запросов, отправленных с использованием и без использования сеансов:
Как вы можете видеть, cookie сеанса имеет другое значение в первом и втором запросах, но имеет такое же значение, когда мы использовали объект Session. При тестировании кода вы получите другое значение, но в вашем случае cookie для запросов, сделанных с использованием объекта сеанса, будет иметь такое же значение.
Сессии также полезны, если вы хотите отправлять одни и те же данные по всем запросам. Например, если вы решили отправить куки-файл или заголовок пользовательского агента со всеми запросами в данный домен, вы можете использовать объекты сеанса. Вот пример:
Как вы можете видеть, cookie сеанса отправляется со всеми тремя запросами. Однако cookie отправляется только во время второго запроса. В третьем запросе также не упоминается . Это подтверждает тот факт, что файлы cookie или другие данные, установленные по отдельным запросам, не будут отправляться с другими запросами сеанса.
Python Matplotlib
Создание запроса GET
Очень просто отправить HTTP-запрос с помощью Requests. Сначала вы импортируете модуль и затем выполните запрос. Вот пример:
Вся информация о нашем запросе теперь хранится в объекте Response, называемом . Например, вы можете получить кодировку веб-страницы, используя свойство . Вы также можете получить код состояния запроса, используя свойство .
Вы можете получить доступ к файлам cookie, отправленным сервером с помощью . Аналогично, вы можете получить заголовки ответов, используя . Свойство возвращает нечувствительный к регистру словарь заголовков ответов. Это означает, что , и вернут значение заголовка ответа .
Вы можете проверить, является ли ответ корректным HTTP-перенаправлением, которое могло быть обработано автоматически с использованием свойства . Он будет возвращать или на основе ответа. Вы также можете получить время, прошедшее между отправкой запроса и возвратом ответа с использованием свойства .
URL, который вы первоначально передали функции , может отличаться от конечного URL-адреса ответа по целому ряду причин, включая перенаправления. Чтобы увидеть окончательный URL-адрес ответа, вы можете использовать свойство .
Получение всей этой информации о веб-странице, к которой вы обращаетесь, приятно, но вы, скорее всего, хотите получить доступ к фактическому контенту. Если контент, к которому вы обращаетесь, является текстом, вы можете использовать свойство для доступа к нему. Затем содержимое анализируется как unicode. Вы можете передать кодировку, с помощью которой можно декодировать текст, используя свойство .
В случае нетекстовых ответов вы можете получить к ним доступ в двоичной форме, используя . Модуль автоматически расшифровывает и кодирование передачи. Это может быть полезно, когда вы имеете дело с медиафайлами. Аналогично, вы можете получить доступ к json-закодированному контенту ответа, если он существует, используя .
Вы также можете получить исходный ответ с сервера, используя . Имейте в виду, что вам придется передать в запросе, чтобы получить исходный ответ.
Некоторые файлы, которые вы загружаете из Интернета с помощью модуля Requests, могут иметь огромный размер. В таких случаях неразумно загружать весь ответ или файл в память сразу. Вы можете загрузить файл на куски или фрагменты, используя метод .
Этот метод выполняет итерацию по данным ответа в количество байтов одновременно. Когда в запросе задан , этот метод не позволит сразу считывать весь файл в память для больших ответов. Параметр может быть integer или . Когда установлено значение integer, определяет количество байтов, которые должны быть прочитаны в памяти.
Если для параметра установлено значение , а для установлено значение , данные будут считаны по мере того, как он достигнет любого размера кусков. Если для параметра установлено значение , а для установлено значение , все данные будут возвращены как один кусок.
Давайте загрузим этот образ леса на Pixabay с помощью модуля Requests. Вот фактическое изображение:
Это код, который вам нужен:
— это фактический URL изображения; вы можете поместить URL-адрес любого другого изображения здесь, чтобы загрузить что-то еще. Данный файл изображения имеет размер 185kb, и вы установили в 50 000 байт. Это означает, что сообщение «Получено сообщение» должно быть напечатано четыре раза в терминале. Размер последнего фрагмента будет всего 39350 байт, потому что часть файла, которая остается полученной после первых трех итераций, составляет 39350 байт.
Запросы также позволяют передавать параметры в URL-адресе. Это может быть полезно при поиске на веб-странице некоторых результатов, таких как конкретный образ или учебник. Вы можете предоставить эти строки запроса как словарь строк, используя ключевое слово в запросе GET. Вот пример:
Methods
Report Error
Parameter Values
Parameter | Description | |
---|---|---|
url | Try it | Required. The url of the request |
allow_redirects | Try itTry it | Optional. A Boolean to enable/disable redirection.Default (not allowing redirects) |
auth | Try it | Optional. A tuple to enable a certain HTTP authentication.Default |
cert | Try it | Optional. A String or Tuple specifying a cert file or key.Default |
cookies | Try it | Optional. A dictionary of cookies to send to the specified url.Default |
headers | Try it | Optional. A dictionary of HTTP headers to send to the specified url.Default |
proxies | Try it | Optional. A dictionary of the protocol to the proxy url.Default |
stream | Try it | Optional. A Boolean indication if the response should be immediately downloaded (False) or streamed (True).Default |
timeout | Try it | Optional. A number, or a tuple, indicating how many seconds to wait for the client to make a connection and/or send a response.Default which means the request will continue until the connection is closed |
verify | Try it | Optional. A Boolean or a String indication to verify the servers TLS certificate or not.Default |
Редиректы и история
По умолчанию будет выполнять редиректы для всех HTTP методов, кроме . Мы можем использовать свойство объекта , чтобы отслеживать редиректы. Список содержит объекты , которые были созданы во время выполнения запроса. Список сортируется от более ранних к более поздним ответам.
Например, GitHub перенаправляет все HTTP запросы на HTTPS:
>>> r = requests.get('http://github.com') >>> r.url 'https://github.com/' >>> r.status_code 200 >>> r.history >]
Если вы используете , , , , или , вы можете отключить обработку редиректов с помощью параметра :
>>> r = requests.get('http://github.com', allow_redirects=False) >>> r.status_code 301 >>> r.history []
Если вы используете , вы можете включить обработку редиректов:
>>> r = requests.head('http://github.com', allow_redirects=True) >>> r.url 'https://github.com/' >>> r.history >]
Задержка
Часто бывает нужно ограничить время ожидания ответа. Это можно сделать
с помощью параметра timeout
Перейдите на
раздел — / #/ Dynamic_data / delete_delay__delay_
и изучите документацию — если делать запрос на этот url можно выставлять время, через которое
будет отправлен ответ.
Создайте файл timeout_demo.py следующего содержания
Задержка равна одной секунде. А ждать ответ можно до трёх секунд.
python3 tiemout_demo.py
<Response >
Измените код так, чтобы ответ приходил заведомо позже чем наш таймаут в три секунды.
Задержка равна семи секундам. А ждать ответ можно по-прежнему только до трёх секунд.
python3 tiemout_demo.py
Traceback (most recent call last):
File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 421, in _make_request
six.raise_from(e, None)
File «<string>», line 3, in raise_from
File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 416, in _make_request
httplib_response = conn.getresponse()
File «/usr/lib/python3.8/http/client.py», line 1347, in getresponse
response.begin()
File «/usr/lib/python3.8/http/client.py», line 307, in begin
version, status, reason = self._read_status()
File «/usr/lib/python3.8/http/client.py», line 268, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), «iso-8859-1»)
File «/usr/lib/python3.8/socket.py», line 669, in readinto
return self._sock.recv_into(b)
File «/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py», line 326, in recv_into
raise timeout(«The read operation timed out»)
socket.timeout: The read operation timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File «/usr/lib/python3/dist-packages/requests/adapters.py», line 439, in send
resp = conn.urlopen(
File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 719, in urlopen
retries = retries.increment(
File «/usr/lib/python3/dist-packages/urllib3/util/retry.py», line 400, in increment
raise six.reraise(type(error), error, _stacktrace)
File «/usr/lib/python3/dist-packages/six.py», line 703, in reraise
raise value
File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 665, in urlopen
httplib_response = self._make_request(
File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 423, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 330, in _raise_timeout
raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host=’httpbin.org’, port=443): Read timed out. (read timeout=3)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File «timeout_demo.py», line 4, in <module>
r = requests.get(‘https://httpbin.org/delay/7’, timeout=3)
File «/usr/lib/python3/dist-packages/requests/api.py», line 75, in get
return request(‘get’, url, params=params, **kwargs)
File «/usr/lib/python3/dist-packages/requests/api.py», line 60, in request
return session.request(method=method, url=url, **kwargs)
File «/usr/lib/python3/dist-packages/requests/sessions.py», line 533, in request
resp = self.send(prep, **send_kwargs)
File «/usr/lib/python3/dist-packages/requests/sessions.py», line 646, in send
r = adapter.send(request, **kwargs)
File «/usr/lib/python3/dist-packages/requests/adapters.py», line 529, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host=’httpbin.org’, port=443): Read timed out. (read timeout=3)
Если такая обработка исключений не вызывает у вас восторга — измените код используя try except
python3 tiemout_demo.py
Response is taking too long.
Parameter Values
Parameter | Description | |
---|---|---|
url | Try it | Required. The url of the request |
params | Try it | Optional. A dictionary, list of tuples or bytes to send as a query string.Default |
allow_redirects | Try it | Optional. A Boolean to enable/disable redirection.Default (allowing redirects) |
auth | Try it | Optional. A tuple to enable a certain HTTP authentication.Default |
cert | Try it | Optional. A String or Tuple specifying a cert file or key.Default |
cookies | Try it | Optional. A dictionary of cookies to send to the specified url.Default |
headers | Try it | Optional. A dictionary of HTTP headers to send to the specified url.Default |
proxies | Try it | Optional. A dictionary of the protocol to the proxy url.Default |
stream | Try it | Optional. A Boolean indication if the response should be immediately downloaded (False) or streamed (True).Default |
timeout | Try it | Optional. A number, or a tuple, indicating how many seconds to wait for the client to make a connection and/or send a response.Default which means the request will continue until the connection is closed |
verify |
Try it Try it |
Optional. A Boolean or a String indication to verify the servers TLS certificate or not.Default |
Python Tutorial
Python HOMEPython IntroPython Get StartedPython SyntaxPython CommentsPython Variables
Python Variables
Variable Names
Assign Multiple Values
Output Variables
Global Variables
Variable Exercises
Python Data TypesPython NumbersPython CastingPython Strings
Python Strings
Slicing Strings
Modify Strings
Concatenate Strings
Format Strings
Escape Characters
String Methods
String Exercises
Python BooleansPython OperatorsPython Lists
Python Lists
Access List Items
Change List Items
Add List Items
Remove List Items
Loop Lists
List Comprehension
Sort Lists
Copy Lists
Join Lists
List Methods
List Exercises
Python Tuples
Python Tuples
Access Tuples
Update Tuples
Unpack Tuples
Loop Tuples
Join Tuples
Tuple Methods
Tuple Exercises
Python Sets
Python Sets
Access Set Items
Add Set Items
Remove Set Items
Loop Sets
Join Sets
Set Methods
Set Exercises
Python Dictionaries
Python Dictionaries
Access Items
Change Items
Add Items
Remove Items
Loop Dictionaries
Copy Dictionaries
Nested Dictionaries
Dictionary Methods
Dictionary Exercise
Python If…ElsePython While LoopsPython For LoopsPython FunctionsPython LambdaPython ArraysPython Classes/ObjectsPython InheritancePython IteratorsPython ScopePython ModulesPython DatesPython MathPython JSONPython RegExPython PIPPython Try…ExceptPython User InputPython String Formatting
Асинхронность
Как объяснялось ранее, requests полностью синхронен. Он блокирует приложение в ожидании ответа сервера, замедляя работу программы. Создание HTTP-запросов в потоках является одним из решений, но потоки имеют свои собственные накладные расходы, и это подразумевает параллелизм, который не всегда каждый рад видеть в программе.
Начиная с версии 3.5, Python предлагает асинхронность внутри своего ядра, используя aiohttp. Библиотека aiohttp предоставляет асинхронный HTTP-клиент, построенный поверх asyncio. Эта библиотека позволяет отправлять запросы последовательно, но не дожидаясь первого ответа, прежде чем отправлять новый. В отличие от конвейерной передачи HTTP, aiohttp отправляет запросы по нескольким соединениям параллельно, избегая проблемы, описанной ранее.
Использование aiohttp
import aiohttp import asyncio async def get(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: return response loop = asyncio.get_event_loop() coroutines = [get("http://example.com") for _ in range(8)] results = loop.run_until_complete(asyncio.gather(*coroutines)) print("Results: %s" % results)
Все эти решения (с использованием Session, thread, futures или asyncio) предлагают разные подходы к ускорению работы HTTP-клиентов. Но какая между ними разница с точки зрения производительности?