blob: 9b456c14351e44b57912f57b00f2d51098b30fc5 [file] [log] [blame]
Victor Stinner24f8ebf2014-01-23 11:05:01 +01001.. currentmodule:: asyncio
2
Victor Stinner9592edb2014-02-02 15:03:02 +01003.. _asyncio-streams:
Victor Stinner4b4f9eb2014-01-24 17:33:20 +01004
Yury Selivanov7c7605f2018-09-11 09:54:40 -07005=======
6Streams
7=======
Victor Stinner24f8ebf2014-01-23 11:05:01 +01008
Kyle Stanleyf9000642019-10-10 19:18:46 -04009**Source code:** :source:`Lib/asyncio/streams.py`
10
11-------------------------------------------------
12
Yury Selivanov7c7605f2018-09-11 09:54:40 -070013Streams are high-level async/await-ready primitives to work with
Yury Selivanov8be876e2018-09-11 17:10:37 -070014network connections. Streams allow sending and receiving data without
Yury Selivanov7c7605f2018-09-11 09:54:40 -070015using callbacks or low-level protocols and transports.
lf627d2c82017-07-25 17:03:51 -060016
Yury Selivanov7372c3b2018-09-14 15:11:24 -070017.. _asyncio_example_stream:
18
Yury Selivanov8be876e2018-09-11 17:10:37 -070019Here is an example of a TCP echo client written using asyncio
Yury Selivanov7c7605f2018-09-11 09:54:40 -070020streams::
Victor Stinner24f8ebf2014-01-23 11:05:01 +010021
Yury Selivanov7c7605f2018-09-11 09:54:40 -070022 import asyncio
Guido van Rossum19ff6972015-10-19 13:18:04 -070023
Yury Selivanov7c7605f2018-09-11 09:54:40 -070024 async def tcp_echo_client(message):
Yury Selivanov6758e6e2019-09-29 21:59:55 -070025 reader, writer = await asyncio.open_connection(
26 '127.0.0.1', 8888)
Yury Selivanov7c7605f2018-09-11 09:54:40 -070027
Yury Selivanov6758e6e2019-09-29 21:59:55 -070028 print(f'Send: {message!r}')
29 writer.write(message.encode())
30 await writer.drain()
31
32 data = await reader.read(100)
33 print(f'Received: {data.decode()!r}')
34
35 print('Close the connection')
36 writer.close()
37 await writer.wait_closed()
Yury Selivanov7c7605f2018-09-11 09:54:40 -070038
39 asyncio.run(tcp_echo_client('Hello World!'))
Guido van Rossum19ff6972015-10-19 13:18:04 -070040
41
Yury Selivanov8be876e2018-09-11 17:10:37 -070042See also the `Examples`_ section below.
43
44
Yury Selivanov7c7605f2018-09-11 09:54:40 -070045.. rubric:: Stream Functions
Victor Stinner24f8ebf2014-01-23 11:05:01 +010046
Yury Selivanov7c7605f2018-09-11 09:54:40 -070047The following top-level asyncio functions can be used to create
48and work with streams:
Victor Stinner24f8ebf2014-01-23 11:05:01 +010049
Victor Stinner24f8ebf2014-01-23 11:05:01 +010050
Andre Delfinodcc997c2020-12-16 22:37:28 -030051.. coroutinefunction:: open_connection(host=None, port=None, *, \
Yurii Karabas86150d32020-11-29 14:50:57 +020052 limit=None, ssl=None, family=0, proto=0, \
53 flags=0, sock=None, local_addr=None, \
Yury Selivanov7c7605f2018-09-11 09:54:40 -070054 server_hostname=None, ssl_handshake_timeout=None)
55
56 Establish a network connection and return a pair of
Yury Selivanov8be876e2018-09-11 17:10:37 -070057 ``(reader, writer)`` objects.
Yury Selivanov7c7605f2018-09-11 09:54:40 -070058
59 The returned *reader* and *writer* objects are instances of
60 :class:`StreamReader` and :class:`StreamWriter` classes.
61
Yury Selivanov7c7605f2018-09-11 09:54:40 -070062 *limit* determines the buffer size limit used by the
Yury Selivanov8be876e2018-09-11 17:10:37 -070063 returned :class:`StreamReader` instance. By default the *limit*
64 is set to 64 KiB.
Victor Stinner24f8ebf2014-01-23 11:05:01 +010065
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -040066 The rest of the arguments are passed directly to
Yury Selivanov7c7605f2018-09-11 09:54:40 -070067 :meth:`loop.create_connection`.
Victor Stinner24f8ebf2014-01-23 11:05:01 +010068
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -040069 .. versionadded:: 3.7
70
71 The *ssl_handshake_timeout* parameter.
72
Yury Selivanov7c7605f2018-09-11 09:54:40 -070073.. coroutinefunction:: start_server(client_connected_cb, host=None, \
Andre Delfinodcc997c2020-12-16 22:37:28 -030074 port=None, *, limit=None, \
Yury Selivanov7c7605f2018-09-11 09:54:40 -070075 family=socket.AF_UNSPEC, \
76 flags=socket.AI_PASSIVE, sock=None, \
77 backlog=100, ssl=None, reuse_address=None, \
78 reuse_port=None, ssl_handshake_timeout=None, \
79 start_serving=True)
Victor Stinner24f8ebf2014-01-23 11:05:01 +010080
Yury Selivanov7c7605f2018-09-11 09:54:40 -070081 Start a socket server.
Victor Stinner24f8ebf2014-01-23 11:05:01 +010082
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -040083 The *client_connected_cb* callback is called whenever a new client
Yury Selivanov7c7605f2018-09-11 09:54:40 -070084 connection is established. It receives a ``(reader, writer)`` pair
85 as two arguments, instances of the :class:`StreamReader` and
86 :class:`StreamWriter` classes.
Victor Stinner24f8ebf2014-01-23 11:05:01 +010087
Yury Selivanov7c7605f2018-09-11 09:54:40 -070088 *client_connected_cb* can be a plain callable or a
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -040089 :ref:`coroutine function <coroutine>`; if it is a coroutine function,
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -040090 it will be automatically scheduled as a :class:`Task`.
Victor Stinner24f8ebf2014-01-23 11:05:01 +010091
Yury Selivanov7c7605f2018-09-11 09:54:40 -070092 *limit* determines the buffer size limit used by the
Yury Selivanov8be876e2018-09-11 17:10:37 -070093 returned :class:`StreamReader` instance. By default the *limit*
94 is set to 64 KiB.
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -040095
96 The rest of the arguments are passed directly to
Yury Selivanov7c7605f2018-09-11 09:54:40 -070097 :meth:`loop.create_server`.
Victor Stinner24f8ebf2014-01-23 11:05:01 +010098
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -040099 .. versionadded:: 3.7
100
101 The *ssl_handshake_timeout* and *start_serving* parameters.
102
Yury Selivanov8be876e2018-09-11 17:10:37 -0700103
104.. rubric:: Unix Sockets
105
Andre Delfinodcc997c2020-12-16 22:37:28 -0300106.. coroutinefunction:: open_unix_connection(path=None, *, limit=None, \
Yurii Karabas86150d32020-11-29 14:50:57 +0200107 ssl=None, sock=None, server_hostname=None, \
108 ssl_handshake_timeout=None)
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500109
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400110 Establish a Unix socket connection and return a pair of
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700111 ``(reader, writer)``.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500112
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400113 Similar to :func:`open_connection` but operates on Unix sockets.
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -0400114
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700115 See also the documentation of :meth:`loop.create_unix_connection`.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500116
Cheryl Sabella2d6097d2018-10-12 10:55:20 -0400117 .. availability:: Unix.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500118
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -0400119 .. versionadded:: 3.7
120
121 The *ssl_handshake_timeout* parameter.
122
123 .. versionchanged:: 3.7
124
125 The *path* parameter can now be a :term:`path-like object`
126
Yury Selivanov8be876e2018-09-11 17:10:37 -0700127
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700128.. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \
Andre Delfinodcc997c2020-12-16 22:37:28 -0300129 *, limit=None, sock=None, backlog=100, ssl=None, \
Yurii Karabas86150d32020-11-29 14:50:57 +0200130 ssl_handshake_timeout=None, start_serving=True)
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500131
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400132 Start a Unix socket server.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500133
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400134 Similar to :func:`start_server` but works with Unix sockets.
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -0400135
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700136 See also the documentation of :meth:`loop.create_unix_server`.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500137
Cheryl Sabella2d6097d2018-10-12 10:55:20 -0400138 .. availability:: Unix.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500139
Elvis Pranskevichusc0d062f2018-06-08 11:36:00 -0400140 .. versionadded:: 3.7
141
142 The *ssl_handshake_timeout* and *start_serving* parameters.
143
144 .. versionchanged:: 3.7
145
146 The *path* parameter can now be a :term:`path-like object`.
147
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700148
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100149StreamReader
150============
151
Yury Selivanov8be876e2018-09-11 17:10:37 -0700152.. class:: StreamReader
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100153
Yury Selivanov8be876e2018-09-11 17:10:37 -0700154 Represents a reader object that provides APIs to read data
155 from the IO stream.
Victor Stinner83704962015-02-25 14:24:15 +0100156
Yury Selivanov8be876e2018-09-11 17:10:37 -0700157 It is not recommended to instantiate *StreamReader* objects
158 directly; use :func:`open_connection` and :func:`start_server`
159 instead.
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100160
Victor Stinnerbdd574d2015-02-12 22:49:18 +0100161 .. coroutinemethod:: read(n=-1)
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100162
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500163 Read up to *n* bytes. If *n* is not provided, or set to ``-1``,
164 read until EOF and return all read bytes.
165
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400166 If EOF was received and the internal buffer is empty,
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500167 return an empty ``bytes`` object.
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100168
Victor Stinnerbdd574d2015-02-12 22:49:18 +0100169 .. coroutinemethod:: readline()
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100170
Yury Selivanov8be876e2018-09-11 17:10:37 -0700171 Read one line, where "line" is a sequence of bytes
172 ending with ``\n``.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500173
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400174 If EOF is received and ``\n`` was not found, the method
Yury Selivanov8be876e2018-09-11 17:10:37 -0700175 returns partially read data.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500176
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400177 If EOF is received and the internal buffer is empty,
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500178 return an empty ``bytes`` object.
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100179
Victor Stinnerbdd574d2015-02-12 22:49:18 +0100180 .. coroutinemethod:: readexactly(n)
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100181
Yury Selivanov8be876e2018-09-11 17:10:37 -0700182 Read exactly *n* bytes.
183
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400184 Raise an :exc:`IncompleteReadError` if EOF is reached before *n*
Yury Selivanov8be876e2018-09-11 17:10:37 -0700185 can be read. Use the :attr:`IncompleteReadError.partial`
186 attribute to get the partially read data.
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100187
Andre Delfinodcc997c2020-12-16 22:37:28 -0300188 .. coroutinemethod:: readuntil(separator=b'\n')
Yury Selivanov950204d2016-05-16 16:23:00 -0400189
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400190 Read data from the stream until *separator* is found.
Yury Selivanov950204d2016-05-16 16:23:00 -0400191
192 On success, the data and separator will be removed from the
193 internal buffer (consumed). Returned data will include the
194 separator at the end.
195
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400196 If the amount of data read exceeds the configured stream limit, a
197 :exc:`LimitOverrunError` exception is raised, and the data
198 is left in the internal buffer and can be read again.
Yury Selivanov950204d2016-05-16 16:23:00 -0400199
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400200 If EOF is reached before the complete separator is found,
201 an :exc:`IncompleteReadError` exception is raised, and the internal
202 buffer is reset. The :attr:`IncompleteReadError.partial` attribute
203 may contain a portion of the separator.
Yury Selivanov950204d2016-05-16 16:23:00 -0400204
205 .. versionadded:: 3.5.2
206
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500207 .. method:: at_eof()
208
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700209 Return ``True`` if the buffer is empty and :meth:`feed_eof`
210 was called.
Yury Selivanovd3f8e302014-02-20 14:10:02 -0500211
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100212
213StreamWriter
214============
215
Yury Selivanov8be876e2018-09-11 17:10:37 -0700216.. class:: StreamWriter
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100217
Yury Selivanov8be876e2018-09-11 17:10:37 -0700218 Represents a writer object that provides APIs to write data
219 to the IO stream.
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100220
Yury Selivanov8be876e2018-09-11 17:10:37 -0700221 It is not recommended to instantiate *StreamWriter* objects
222 directly; use :func:`open_connection` and :func:`start_server`
223 instead.
Victor Stinner24f8ebf2014-01-23 11:05:01 +0100224
Andrew Svetlova076e4f2019-05-09 15:14:58 -0400225 .. method:: write(data)
Andrew Svetlov11194c82018-09-13 16:53:49 -0700226
Andrew Svetlova076e4f2019-05-09 15:14:58 -0400227 The method attempts to write the *data* to the underlying socket immediately.
228 If that fails, the data is queued in an internal write buffer until it can be
229 sent.
Andrew Svetlov11194c82018-09-13 16:53:49 -0700230
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700231 The method should be used along with the ``drain()`` method::
Andrew Svetlov11194c82018-09-13 16:53:49 -0700232
Andrew Svetlova076e4f2019-05-09 15:14:58 -0400233 stream.write(data)
234 await stream.drain()
Andrew Svetlov11194c82018-09-13 16:53:49 -0700235
Andrew Svetlova076e4f2019-05-09 15:14:58 -0400236 .. method:: writelines(data)
237
238 The method writes a list (or any iterable) of bytes to the underlying socket
239 immediately.
240 If that fails, the data is queued in an internal write buffer until it can be
241 sent.
242
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700243 The method should be used along with the ``drain()`` method::
Andrew Svetlova076e4f2019-05-09 15:14:58 -0400244
245 stream.writelines(lines)
246 await stream.drain()
247
Andrew Svetlova076e4f2019-05-09 15:14:58 -0400248 .. method:: close()
249
250 The method closes the stream and the underlying socket.
251
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700252 The method should be used along with the ``wait_closed()`` method::
Andrew Svetlova076e4f2019-05-09 15:14:58 -0400253
254 stream.close()
255 await stream.wait_closed()
256
Andrew Svetlov11194c82018-09-13 16:53:49 -0700257 .. method:: can_write_eof()
258
Serhiy Storchaka138ccbb2019-11-12 16:57:03 +0200259 Return ``True`` if the underlying transport supports
260 the :meth:`write_eof` method, ``False`` otherwise.
Andrew Svetlov11194c82018-09-13 16:53:49 -0700261
262 .. method:: write_eof()
263
264 Close the write end of the stream after the buffered write
265 data is flushed.
266
267 .. attribute:: transport
268
269 Return the underlying asyncio transport.
270
271 .. method:: get_extra_info(name, default=None)
272
273 Access optional transport information; see
274 :meth:`BaseTransport.get_extra_info` for details.
275
Yury Selivanov8be876e2018-09-11 17:10:37 -0700276 .. coroutinemethod:: drain()
277
278 Wait until it is appropriate to resume writing to the stream.
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400279 Example::
Yury Selivanov8be876e2018-09-11 17:10:37 -0700280
281 writer.write(data)
282 await writer.drain()
283
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400284 This is a flow control method that interacts with the underlying
Yury Selivanov8be876e2018-09-11 17:10:37 -0700285 IO write buffer. When the size of the buffer reaches
Elvis Pranskevichus1fa2ec42018-09-17 19:16:44 -0400286 the high watermark, *drain()* blocks until the size of the
287 buffer is drained down to the low watermark and writing can
Yury Selivanov8be876e2018-09-11 17:10:37 -0700288 be resumed. When there is nothing to wait for, the :meth:`drain`
289 returns immediately.
Victor Stinnerffbe3c62014-02-08 22:50:07 +0100290
Andrew Svetlovfe133aa2018-01-25 00:30:30 +0200291 .. method:: is_closing()
292
Yury Selivanov8be876e2018-09-11 17:10:37 -0700293 Return ``True`` if the stream is closed or in the process of
294 being closed.
Andrew Svetlovfe133aa2018-01-25 00:30:30 +0200295
296 .. versionadded:: 3.7
297
298 .. coroutinemethod:: wait_closed()
299
Yury Selivanov8be876e2018-09-11 17:10:37 -0700300 Wait until the stream is closed.
Andrew Svetlovfe133aa2018-01-25 00:30:30 +0200301
Yury Selivanov8be876e2018-09-11 17:10:37 -0700302 Should be called after :meth:`close` to wait until the underlying
303 connection is closed.
Andrew Svetlovfe133aa2018-01-25 00:30:30 +0200304
305 .. versionadded:: 3.7
306
Victor Stinnerc520edc2014-01-23 11:25:48 +0100307
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700308Examples
309========
Victor Stinner5121a9b2014-10-11 15:52:14 +0200310
Victor Stinnered051592014-10-12 20:18:16 +0200311.. _asyncio-tcp-echo-client-streams:
312
313TCP echo client using streams
314-----------------------------
315
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700316TCP echo client using the :func:`asyncio.open_connection` function::
Victor Stinnered051592014-10-12 20:18:16 +0200317
318 import asyncio
319
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700320 async def tcp_echo_client(message):
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700321 reader, writer = await asyncio.open_connection(
322 '127.0.0.1', 8888)
Victor Stinnered051592014-10-12 20:18:16 +0200323
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700324 print(f'Send: {message!r}')
325 writer.write(message.encode())
326
327 data = await reader.read(100)
328 print(f'Received: {data.decode()!r}')
329
330 print('Close the connection')
331 writer.close()
Victor Stinnered051592014-10-12 20:18:16 +0200332
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700333 asyncio.run(tcp_echo_client('Hello World!'))
334
Victor Stinnered051592014-10-12 20:18:16 +0200335
336.. seealso::
337
Yury Selivanov394374e2018-09-17 15:35:24 -0400338 The :ref:`TCP echo client protocol <asyncio_example_tcp_echo_client_protocol>`
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700339 example uses the low-level :meth:`loop.create_connection` method.
Victor Stinnered051592014-10-12 20:18:16 +0200340
341
342.. _asyncio-tcp-echo-server-streams:
343
344TCP echo server using streams
345-----------------------------
346
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700347TCP echo server using the :func:`asyncio.start_server` function::
Victor Stinnered051592014-10-12 20:18:16 +0200348
349 import asyncio
350
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700351 async def handle_echo(reader, writer):
352 data = await reader.read(100)
Victor Stinnered051592014-10-12 20:18:16 +0200353 message = data.decode()
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700354 addr = writer.get_extra_info('peername')
Victor Stinnered051592014-10-12 20:18:16 +0200355
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700356 print(f"Received {message!r} from {addr!r}")
357
358 print(f"Send: {message!r}")
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700359 writer.write(data)
360 await writer.drain()
Victor Stinnered051592014-10-12 20:18:16 +0200361
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700362 print("Close the connection")
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700363 writer.close()
Victor Stinnered051592014-10-12 20:18:16 +0200364
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700365 async def main():
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700366 server = await asyncio.start_server(
367 handle_echo, '127.0.0.1', 8888)
368
369 addr = server.sockets[0].getsockname()
370 print(f'Serving on {addr}')
371
372 async with server:
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700373 await server.serve_forever()
374
375 asyncio.run(main())
376
Victor Stinnered051592014-10-12 20:18:16 +0200377
378.. seealso::
379
Yury Selivanov394374e2018-09-17 15:35:24 -0400380 The :ref:`TCP echo server protocol <asyncio_example_tcp_echo_server_protocol>`
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700381 example uses the :meth:`loop.create_server` method.
Victor Stinnered051592014-10-12 20:18:16 +0200382
383
Victor Stinner5121a9b2014-10-11 15:52:14 +0200384Get HTTP headers
385----------------
Victor Stinnerc520edc2014-01-23 11:25:48 +0100386
387Simple example querying HTTP headers of the URL passed on the command line::
388
389 import asyncio
390 import urllib.parse
391 import sys
392
Mikhail Terekhovd2ac4002018-08-07 16:29:06 -0400393 async def print_http_headers(url):
Victor Stinnerc520edc2014-01-23 11:25:48 +0100394 url = urllib.parse.urlsplit(url)
Victor Stinner5121a9b2014-10-11 15:52:14 +0200395 if url.scheme == 'https':
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700396 reader, writer = await asyncio.open_connection(
397 url.hostname, 443, ssl=True)
Victor Stinner5121a9b2014-10-11 15:52:14 +0200398 else:
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700399 reader, writer = await asyncio.open_connection(
400 url.hostname, 80)
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700401
402 query = (
403 f"HEAD {url.path or '/'} HTTP/1.0\r\n"
404 f"Host: {url.hostname}\r\n"
405 f"\r\n"
406 )
407
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700408 writer.write(query.encode('latin-1'))
409 while True:
410 line = await reader.readline()
411 if not line:
412 break
413
Victor Stinnerc520edc2014-01-23 11:25:48 +0100414 line = line.decode('latin1').rstrip()
415 if line:
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700416 print(f'HTTP header> {line}')
Victor Stinnerc520edc2014-01-23 11:25:48 +0100417
Victor Stinner5121a9b2014-10-11 15:52:14 +0200418 # Ignore the body, close the socket
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700419 writer.close()
Victor Stinner5121a9b2014-10-11 15:52:14 +0200420
Victor Stinnerc520edc2014-01-23 11:25:48 +0100421 url = sys.argv[1]
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700422 asyncio.run(print_http_headers(url))
423
Victor Stinnerc520edc2014-01-23 11:25:48 +0100424
425Usage::
426
427 python example.py http://example.com/path/page.html
428
Victor Stinner04e6df32014-10-11 16:16:27 +0200429or with HTTPS::
430
431 python example.py https://example.com/path/page.html
432
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700433
Yury Selivanov394374e2018-09-17 15:35:24 -0400434.. _asyncio_example_create_connection-streams:
Victor Stinner04e6df32014-10-11 16:16:27 +0200435
436Register an open socket to wait for data using streams
437------------------------------------------------------
438
439Coroutine waiting until a socket receives data using the
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700440:func:`open_connection` function::
Victor Stinner04e6df32014-10-11 16:16:27 +0200441
442 import asyncio
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700443 import socket
Victor Stinner04e6df32014-10-11 16:16:27 +0200444
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700445 async def wait_for_data():
446 # Get a reference to the current event loop because
447 # we want to access low-level APIs.
448 loop = asyncio.get_running_loop()
Victor Stinner04e6df32014-10-11 16:16:27 +0200449
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700450 # Create a pair of connected sockets.
451 rsock, wsock = socket.socketpair()
452
453 # Register the open socket to wait for data.
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700454 reader, writer = await asyncio.open_connection(sock=rsock)
Victor Stinner04e6df32014-10-11 16:16:27 +0200455
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700456 # Simulate the reception of data from the network
457 loop.call_soon(wsock.send, 'abc'.encode())
Victor Stinner04e6df32014-10-11 16:16:27 +0200458
Yury Selivanov6758e6e2019-09-29 21:59:55 -0700459 # Wait for data
460 data = await reader.read(100)
461
462 # Got data, we are done: close the socket
463 print("Received:", data.decode())
464 writer.close()
Victor Stinner04e6df32014-10-11 16:16:27 +0200465
466 # Close the second socket
467 wsock.close()
468
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700469 asyncio.run(wait_for_data())
Victor Stinner04e6df32014-10-11 16:16:27 +0200470
471.. seealso::
472
473 The :ref:`register an open socket to wait for data using a protocol
Yury Selivanov394374e2018-09-17 15:35:24 -0400474 <asyncio_example_create_connection>` example uses a low-level protocol and
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700475 the :meth:`loop.create_connection` method.
Victor Stinner04e6df32014-10-11 16:16:27 +0200476
477 The :ref:`watch a file descriptor for read events
Yury Selivanov394374e2018-09-17 15:35:24 -0400478 <asyncio_example_watch_fd>` example uses the low-level
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700479 :meth:`loop.add_reader` method to watch a file descriptor.