blob: e4aed647c3382a1dc4e9a4e21d478e7e46cdab0c [file] [log] [blame]
R David Murray6a143812013-12-20 14:37:39 -05001.. currentmodule:: asyncio
Victor Stinnerea3183f2013-12-03 01:08:00 +01002
lf627d2c82017-07-25 17:03:51 -06003
Yury Selivanov3faaa882018-09-14 13:32:07 -07004.. _asyncio-transports-protocols:
5
6
Yury Selivanov7c7605f2018-09-11 09:54:40 -07007========================
8Transports and Protocols
9========================
lf627d2c82017-07-25 17:03:51 -060010
Yury Selivanov7c7605f2018-09-11 09:54:40 -070011.. rubric:: Preface
12
13Transports and Protocols are used by **low-level** event loop
14APIs such as :meth:`loop.create_connection`. They require using
15callback-based programming style and enable high-performance
16implementations of network or IPC protocols (e.g. HTTP).
17
18Essentially, transports and protocols should only be used in
19libraries and frameworks and never in high-level asyncio
20applications.
21
22This documentation page covers both `Transports`_ and `Protocols`_.
23
24.. rubric:: Introduction
25
26At the highest level, the transport is concerned with *how* bytes
27are transmitted, while the protocol determines *which* bytes to
28transmit (and to some extent when).
29
30A different way of saying the same thing: a transport is an
31abstraction for a socket (or similar I/O endpoint) while a protocol
32is an abstraction for an application, from the transport's point
33of view.
34
Carol Willingc9d66f02018-09-14 10:06:55 -070035Yet another view is the transport and protocol interfaces
Yury Selivanov7c7605f2018-09-11 09:54:40 -070036together define an abstract interface for using network I/O and
37interprocess I/O.
38
39There is always a 1:1 relationship between transport and protocol
40objects: the protocol calls transport methods to send data,
41while the transport calls protocol methods to pass it data that
42has been received.
43
44Most of connection oriented event loop methods
45(such as :meth:`loop.create_connection`) usually accept a
46*protocol_factory* argument used to create a *Protocol* object
47for an accepted connection, represented by a *Transport* object.
48Such methods usually return a tuple of ``(transport, protocol)``.
49
50.. rubric:: Contents
51
52This documentation page contains the following sections:
53
54* The `Transports`_ section documents asyncio :class:`BaseTransport`,
55 :class:`ReadTransport`, :class:`WriteTransport`, :class:`Transport`,
56 :class:`DatagramTransport`, and :class:`SubprocessTransport`
57 classes.
58
59* The `Protocols`_ section documents asyncio :class:`BaseProtocol`,
60 :class:`Protocol`, :class:`BufferedProtocol`,
61 :class:`DatagramProtocol`, and :class:`SubprocessProtocol` classes.
62
63* The `Examples`_ section showcases how to work with transports,
64 protocols, and low-level event loop APIs.
65
Victor Stinner1ca5ba62013-12-03 01:49:43 +010066
Victor Stinner9592edb2014-02-02 15:03:02 +010067.. _asyncio-transport:
Victor Stinnerea3183f2013-12-03 01:08:00 +010068
69Transports
70==========
71
Guido van Rossum589872c2014-03-29 21:14:04 -070072Transports are classes provided by :mod:`asyncio` in order to abstract
Yury Selivanov7c7605f2018-09-11 09:54:40 -070073various kinds of communication channels.
Victor Stinnerea3183f2013-12-03 01:08:00 +010074
Yury Selivanov7c7605f2018-09-11 09:54:40 -070075Transport objects are always instantiated by an
76ref:`asyncio event loop <asyncio-event-loop>`.
Victor Stinnerea3183f2013-12-03 01:08:00 +010077
Yury Selivanov7c7605f2018-09-11 09:54:40 -070078asyncio implements transports for TCP, UDP, SSL, and subprocess pipes.
79The methods available on a transport depend on the transport's kind.
Victor Stinnerea3183f2013-12-03 01:08:00 +010080
Victor Stinner83704962015-02-25 14:24:15 +010081The transport classes are :ref:`not thread safe <asyncio-multithreading>`.
82
Yury Selivanov3432f2f2016-12-12 16:44:58 -050083
Yury Selivanov7c7605f2018-09-11 09:54:40 -070084Transports Hierarchy
85--------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +010086
87.. class:: BaseTransport
88
Yury Selivanov7c7605f2018-09-11 09:54:40 -070089 Base class for all transports. Contains methods that all
90 asyncio transports share.
Victor Stinnerea3183f2013-12-03 01:08:00 +010091
Yury Selivanov7c7605f2018-09-11 09:54:40 -070092.. class:: WriteTransport(BaseTransport)
Victor Stinnerea3183f2013-12-03 01:08:00 +010093
Yury Selivanov7c7605f2018-09-11 09:54:40 -070094 A base transport for write-only connections.
Victor Stinnerea3183f2013-12-03 01:08:00 +010095
Yury Selivanov7c7605f2018-09-11 09:54:40 -070096 Instances of the *WriteTransport* class are returned from
97 the :meth:`loop.connect_write_pipe` event loop method and
98 are also used by subprocess-related methods like
99 :meth:`loop.subprocess_exec`.
Yury Selivanov1744d532015-11-16 12:46:41 -0500100
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700101.. class:: ReadTransport(BaseTransport)
Yury Selivanov1744d532015-11-16 12:46:41 -0500102
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700103 A base transport for read-only connections.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100104
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700105 Instances of the *ReadTransport* class are returned from
106 the :meth:`loop.connect_read_pipe` event loop method and
107 are also used by subprocess-related methods like
108 :meth:`loop.subprocess_exec`.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100109
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700110.. class:: Transport(WriteTransport, ReadTransport)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100111
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700112 Interface representing a bidirectional transport, such as a
113 TCP connection.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100114
Carol Willingc9d66f02018-09-14 10:06:55 -0700115 The user does not instantiate a transport directly; they call a
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700116 utility function, passing it a protocol factory and other
117 information necessary to create the transport and protocol.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100118
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700119 Instances of the *Transport* class are returned from or used by
120 event loop methods like :meth:`loop.create_connection`,
121 :meth:`loop.create_unix_connection`,
122 :meth:`loop.create_server`, :meth:`loop.sendfile`, etc.
Victor Stinnerf7dc7fb2015-09-21 18:06:17 +0200123
Victor Stinnerea3183f2013-12-03 01:08:00 +0100124
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700125.. class:: DatagramTransport(BaseTransport)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100126
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700127 A transport for datagram (UDP) connections.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100128
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700129 Instances of the *DatagramTransport* class are returned from
130 the :meth:`loop.create_datagram_endpoint` event loop method.
Yury Selivanovd757aaf2017-12-18 17:03:23 -0500131
Victor Stinnerea3183f2013-12-03 01:08:00 +0100132
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700133.. class:: SubprocessTransport(BaseTransport)
134
135 An abstraction to represent a connection between a parent and its
136 child OS process.
137
138 Instances of the *SubprocessTransport* class are returned from
139 event loop methods :meth:`loop.subprocess_shell` and
140 :meth:`loop.subprocess_exec`.
141
142
143Base Transport
Victor Stinner0c6f1ca2013-12-03 01:46:39 +0100144--------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100145
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700146.. method:: BaseTransport.close()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100147
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700148 Close the transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100149
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700150 If the transport has a buffer for outgoing
151 data, buffered data will be flushed asynchronously. No more data
152 will be received. After all buffered data is flushed, the
153 protocol's :meth:`protocol.connection_lost()
154 <BaseProtocol.connection_lost>` method will be called with
155 :const:`None` as its argument.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100156
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700157.. method:: BaseTransport.is_closing()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100158
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700159 Return ``True`` if the transport is closing or is closed.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100160
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700161.. method:: BaseTransport.get_extra_info(name, default=None)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100162
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700163 Return information about the transport or underlying resources
164 it uses.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100165
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700166 *name* is a string representing the piece of transport-specific
167 information to get.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100168
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700169 *default* is the value to return if the information is not
170 available, or if the transport does not support querying it
171 with the given third-party event loop implementation or on the
172 current platform.
Victor Stinner52bb9492014-08-26 00:22:28 +0200173
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700174 For example, the following code attempts to get the underlying
175 socket object of the transport::
Victor Stinner52bb9492014-08-26 00:22:28 +0200176
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700177 sock = transport.get_extra_info('socket')
178 if sock is not None:
179 print(sock.getsockopt(...))
Victor Stinner52bb9492014-08-26 00:22:28 +0200180
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700181 Categories of information that can be queried on some transports:
Victor Stinner52bb9492014-08-26 00:22:28 +0200182
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700183 * socket:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100184
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700185 - ``'peername'``: the remote address to which the socket is
186 connected, result of :meth:`socket.socket.getpeername`
187 (``None`` on error)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100188
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700189 - ``'socket'``: :class:`socket.socket` instance
Victor Stinnerea3183f2013-12-03 01:08:00 +0100190
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700191 - ``'sockname'``: the socket's own address,
192 result of :meth:`socket.socket.getsockname`
Kojo Idrissa5200a7c2017-06-20 14:32:00 -0500193
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700194 * SSL socket:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100195
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700196 - ``'compression'``: the compression algorithm being used as a
197 string, or ``None`` if the connection isn't compressed; result
198 of :meth:`ssl.SSLSocket.compression`
Victor Stinner52bb9492014-08-26 00:22:28 +0200199
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700200 - ``'cipher'``: a three-value tuple containing the name of the
201 cipher being used, the version of the SSL protocol that defines
202 its use, and the number of secret bits being used; result of
203 :meth:`ssl.SSLSocket.cipher`
Victor Stinnerea3183f2013-12-03 01:08:00 +0100204
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700205 - ``'peercert'``: peer certificate; result of
206 :meth:`ssl.SSLSocket.getpeercert`
Victor Stinnerea3183f2013-12-03 01:08:00 +0100207
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700208 - ``'sslcontext'``: :class:`ssl.SSLContext` instance
Victor Stinnerea3183f2013-12-03 01:08:00 +0100209
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700210 - ``'ssl_object'``: :class:`ssl.SSLObject` or
211 :class:`ssl.SSLSocket` instance
Victor Stinnerea3183f2013-12-03 01:08:00 +0100212
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700213 * pipe:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100214
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700215 - ``'pipe'``: pipe object
Victor Stinnerea3183f2013-12-03 01:08:00 +0100216
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700217 * subprocess:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100218
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700219 - ``'subprocess'``: :class:`subprocess.Popen` instance
220
221.. method:: BaseTransport.set_protocol(protocol)
222
223 Set a new protocol.
224
225 Switching protocol should only be done when both
226 protocols are documented to support the switch.
227
228.. method:: BaseTransport.get_protocol()
229
230 Return the current protocol.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100231
232
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700233Read-only Transports
234--------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100235
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700236.. method:: ReadTransport.is_reading()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100237
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700238 Return ``True`` if the transport is receiving new data.
239
240 .. versionadded:: 3.7
241
242.. method:: ReadTransport.pause_reading()
243
244 Pause the receiving end of the transport. No data will be passed to
245 the protocol's :meth:`protocol.data_received() <Protocol.data_received>`
246 method until :meth:`resume_reading` is called.
247
248 .. versionchanged:: 3.7
249 The method is idempotent, i.e. it can be called when the
250 transport is already paused or closed.
251
252.. method:: ReadTransport.resume_reading()
253
254 Resume the receiving end. The protocol's
255 :meth:`protocol.data_received() <Protocol.data_received>` method
256 will be called once again if some data is available for reading.
257
258 .. versionchanged:: 3.7
259 The method is idempotent, i.e. it can be called when the
260 transport is already reading.
261
262
263Write-only Transports
264---------------------
265
266.. method:: WriteTransport.abort()
267
268 Close the transport immediately, without waiting for pending operations
269 to complete. Buffered data will be lost. No more data will be received.
270 The protocol's :meth:`protocol.connection_lost()
271 <BaseProtocol.connection_lost>` method will eventually be
272 called with :const:`None` as its argument.
273
274.. method:: WriteTransport.can_write_eof()
275
276 Return :const:`True` if the transport supports
277 :meth:`~WriteTransport.write_eof`, :const:`False` if not.
278
279.. method:: WriteTransport.get_write_buffer_size()
280
281 Return the current size of the output buffer used by the transport.
282
283.. method:: WriteTransport.get_write_buffer_limits()
284
285 Get the *high*- and *low*-water limits for write flow control. Return a
286 tuple ``(low, high)`` where *low* and *high* are positive number of
287 bytes.
288
289 Use :meth:`set_write_buffer_limits` to set the limits.
290
291 .. versionadded:: 3.4.2
292
293.. method:: WriteTransport.set_write_buffer_limits(high=None, low=None)
294
295 Set the *high*- and *low*-water limits for write flow control.
296
297 These two values (measured in number of
298 bytes) control when the protocol's
299 :meth:`protocol.pause_writing() <BaseProtocol.pause_writing>`
300 and :meth:`protocol.resume_writing() <BaseProtocol.resume_writing>`
301 methods are called. If specified, the low-water limit must be less
302 than or equal to the high-water limit. Neither *high* nor *low*
303 can be negative.
304
305 :meth:`~BaseProtocol.pause_writing` is called when the buffer size
306 becomes greater than or equal to the *high* value. If writing has
307 been paused, :meth:`~BaseProtocol.resume_writing` is called when
308 the buffer size becomes less than or equal to the *low* value.
309
310 The defaults are implementation-specific. If only the
311 high-water limit is given, the low-water limit defaults to an
312 implementation-specific value less than or equal to the
313 high-water limit. Setting *high* to zero forces *low* to zero as
314 well, and causes :meth:`~BaseProtocol.pause_writing` to be called
315 whenever the buffer becomes non-empty. Setting *low* to zero causes
316 :meth:`~BaseProtocol.resume_writing` to be called only once the
317 buffer is empty. Use of zero for either limit is generally
318 sub-optimal as it reduces opportunities for doing I/O and
319 computation concurrently.
320
321 Use :meth:`~WriteTransport.get_write_buffer_limits`
322 to get the limits.
323
324.. method:: WriteTransport.write(data)
325
326 Write some *data* bytes to the transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100327
328 This method does not block; it buffers the data and arranges for it
329 to be sent out asynchronously.
330
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700331.. method:: WriteTransport.writelines(list_of_data)
332
333 Write a list (or any iterable) of data bytes to the transport.
334 This is functionally equivalent to calling :meth:`write` on each
335 element yielded by the iterable, but may be implemented more
336 efficiently.
337
338.. method:: WriteTransport.write_eof()
339
340 Close the write end of the transport after flushing buffered data.
341 Data may still be received.
342
343 This method can raise :exc:`NotImplementedError` if the transport
344 (e.g. SSL) doesn't support half-closes.
345
346
347Datagram Transports
348-------------------
349
350.. method:: DatagramTransport.sendto(data, addr=None)
351
352 Send the *data* bytes to the remote peer given by *addr* (a
353 transport-dependent target address). If *addr* is :const:`None`,
354 the data is sent to the target address given on transport
355 creation.
356
357 This method does not block; it buffers the data and arranges
358 for it to be sent out asynchronously.
359
Victor Stinnerea3183f2013-12-03 01:08:00 +0100360.. method:: DatagramTransport.abort()
361
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700362 Close the transport immediately, without waiting for pending
363 operations to complete. Buffered data will be lost.
364 No more data will be received. The protocol's
365 :meth:`protocol.connection_lost() <BaseProtocol.connection_lost>`
366 method will eventually be called with :const:`None` as its argument.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100367
368
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700369.. _asyncio-subprocess-transports:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100370
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700371Subprocess Transports
372---------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100373
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700374.. method:: SubprocessTransport.get_pid()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100375
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700376 Return the subprocess process id as an integer.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100377
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700378.. method:: SubprocessTransport.get_pipe_transport(fd)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100379
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700380 Return the transport for the communication pipe corresponding to the
381 integer file descriptor *fd*:
Victor Stinner4270a242014-10-13 23:56:43 +0200382
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700383 * ``0``: readable streaming transport of the standard input (*stdin*),
384 or :const:`None` if the subprocess was not created with ``stdin=PIPE``
385 * ``1``: writable streaming transport of the standard output (*stdout*),
386 or :const:`None` if the subprocess was not created with ``stdout=PIPE``
387 * ``2``: writable streaming transport of the standard error (*stderr*),
388 or :const:`None` if the subprocess was not created with ``stderr=PIPE``
389 * other *fd*: :const:`None`
Victor Stinnerea3183f2013-12-03 01:08:00 +0100390
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700391.. method:: SubprocessTransport.get_returncode()
Victor Stinner933a8c82013-12-03 01:59:38 +0100392
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700393 Return the subprocess return code as an integer or :const:`None`
Carol Willingc9d66f02018-09-14 10:06:55 -0700394 if it hasn't returned, which is similar to the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700395 :attr:`subprocess.Popen.returncode` attribute.
Victor Stinner933a8c82013-12-03 01:59:38 +0100396
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700397.. method:: SubprocessTransport.kill()
Victor Stinner933a8c82013-12-03 01:59:38 +0100398
Yury Selivanov3faaa882018-09-14 13:32:07 -0700399 Kill the subprocess.
Victor Stinner933a8c82013-12-03 01:59:38 +0100400
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700401 On POSIX systems, the function sends SIGKILL to the subprocess.
402 On Windows, this method is an alias for :meth:`terminate`.
Victor Stinner933a8c82013-12-03 01:59:38 +0100403
Yury Selivanov3faaa882018-09-14 13:32:07 -0700404 See also :meth:`subprocess.Popen.kill`.
405
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700406.. method:: SubprocessTransport.send_signal(signal)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100407
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700408 Send the *signal* number to the subprocess, as in
409 :meth:`subprocess.Popen.send_signal`.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100410
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700411.. method:: SubprocessTransport.terminate()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100412
Yury Selivanov3faaa882018-09-14 13:32:07 -0700413 Stop the subprocess.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100414
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700415 On POSIX systems, this method sends SIGTERM to the subprocess.
416 On Windows, the Windows API function TerminateProcess() is called to
417 stop the subprocess.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100418
Yury Selivanov3faaa882018-09-14 13:32:07 -0700419 See also :meth:`subprocess.Popen.terminate`.
420
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700421.. method:: SubprocessTransport.close()
Victor Stinner4270a242014-10-13 23:56:43 +0200422
Yury Selivanov3faaa882018-09-14 13:32:07 -0700423 Kill the subprocess by calling the :meth:`kill` method.
424
425 If the subprocess hasn't returned yet, and close transports of
426 *stdin*, *stdout*, and *stderr* pipes.
Victor Stinner4270a242014-10-13 23:56:43 +0200427
Victor Stinnerea3183f2013-12-03 01:08:00 +0100428
Victor Stinner9592edb2014-02-02 15:03:02 +0100429.. _asyncio-protocol:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100430
431Protocols
432=========
433
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700434asyncio provides a set of abstract base classes that should be used
435to implement network protocols. Those classes are meant to be used
436together with :ref:`transports <asyncio-transport>`.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100437
Carol Willingc9d66f02018-09-14 10:06:55 -0700438Subclasses of abstract base protocol classes may implement some or
439all methods. All these methods are callbacks: they are called by
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700440transports on certain events, for example when some data is received.
Carol Willingc9d66f02018-09-14 10:06:55 -0700441A base protocol method should be called by the corresponding transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100442
443
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700444Base Protocols
445--------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100446
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700447.. class:: BaseProtocol
Victor Stinnerea3183f2013-12-03 01:08:00 +0100448
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700449 Base protocol with methods that all protocols share.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100450
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700451.. class:: Protocol(BaseProtocol)
452
453 The base class for implementing streaming protocols
454 (TCP, Unix sockets, etc).
455
456.. class:: BufferedProtocol(BaseProtocol)
Yury Selivanov631fd382018-01-28 16:30:26 -0500457
458 A base class for implementing streaming protocols with manual
459 control of the receive buffer.
460
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700461.. class:: DatagramProtocol(BaseProtocol)
Yury Selivanov631fd382018-01-28 16:30:26 -0500462
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700463 The base class for implementing datagram (UDP) protocols.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100464
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700465.. class:: SubprocessProtocol(BaseProtocol)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100466
467 The base class for implementing protocols communicating with child
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700468 processes (unidirectional pipes).
Victor Stinnerea3183f2013-12-03 01:08:00 +0100469
470
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700471Base Protocol
472-------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100473
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700474All asyncio protocols can implement Base Protocol callbacks.
475
476.. rubric:: Connection Callbacks
477
478Connection callbacks are called on all protocols, exactly once per
479a successful connection. All other protocol callbacks can only be
480called between those two methods.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100481
482.. method:: BaseProtocol.connection_made(transport)
483
484 Called when a connection is made.
485
486 The *transport* argument is the transport representing the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700487 connection. The protocol is responsible for storing the reference
488 to its transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100489
490.. method:: BaseProtocol.connection_lost(exc)
491
492 Called when the connection is lost or closed.
493
494 The argument is either an exception object or :const:`None`.
495 The latter means a regular EOF is received, or the connection was
496 aborted or closed by this side of the connection.
497
Victor Stinnerea3183f2013-12-03 01:08:00 +0100498
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700499.. rubric:: Flow Control Callbacks
Victor Stinnerea3183f2013-12-03 01:08:00 +0100500
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700501Flow control callbacks can be called by transports to pause or
502resume writing performed by the protocol.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100503
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700504See the documentation of the :meth:`~WriteTransport.set_write_buffer_limits`
505method for more details.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100506
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700507.. method:: BaseProtocol.pause_writing()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100508
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700509 Called when the transport's buffer goes over the high-water mark.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100510
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700511.. method:: BaseProtocol.resume_writing()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100512
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700513 Called when the transport's buffer drains below the low-water mark.
514
515If the buffer size equals the high-water mark,
516:meth:`~BaseProtocol.pause_writing` is not called: the buffer size must
517go strictly over.
518
519Conversely, :meth:`~BaseProtocol.resume_writing` is called when the
520buffer size is equal or lower than the low-water mark. These end
521conditions are important to ensure that things go as expected when
522either mark is zero.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100523
524
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700525Streaming Protocols
Victor Stinner0c6f1ca2013-12-03 01:46:39 +0100526-------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100527
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700528Event methods, such as :meth:`loop.create_server`,
529:meth:`loop.create_unix_server`, :meth:`loop.create_connection`,
530:meth:`loop.create_unix_connection`, :meth:`loop.connect_accepted_socket`,
531:meth:`loop.connect_read_pipe`, and :meth:`loop.connect_write_pipe`
532accept factories that return streaming protocols.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100533
534.. method:: Protocol.data_received(data)
535
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700536 Called when some data is received. *data* is a non-empty bytes
537 object containing the incoming data.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100538
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700539 Whether the data is buffered, chunked or reassembled depends on
540 the transport. In general, you shouldn't rely on specific semantics
Carol Willingc9d66f02018-09-14 10:06:55 -0700541 and instead make your parsing generic and flexible. However,
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700542 data is always received in the correct order.
543
544 The method can be called an arbitrary number of times during
545 a connection.
546
547 However, :meth:`protocol.eof_received() <Protocol.eof_received>`
548 is called at most once and, if called,
549 :meth:`protocol.data_received() <Protocol.data_received>`
550 won't be called after it.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100551
552.. method:: Protocol.eof_received()
553
Barry Warsawdd9a0a12017-04-07 14:18:14 -0400554 Called when the other end signals it won't send any more data
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700555 (for example by calling :meth:`transport.write_eof()
556 <WriteTransport.write_eof>`, if the other end also uses
Victor Stinnerea3183f2013-12-03 01:08:00 +0100557 asyncio).
558
Serhiy Storchakaecf41da2016-10-19 16:29:26 +0300559 This method may return a false value (including ``None``), in which case
Victor Stinnerea3183f2013-12-03 01:08:00 +0100560 the transport will close itself. Conversely, if this method returns a
Carol Willingc9d66f02018-09-14 10:06:55 -0700561 true value, the protocol used determines whether to close the transport.
562 Since the default implementation returns ``None``, it implicitly closes the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700563 connection.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100564
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700565 Some transports such as SSL don't support half-closed connections,
Carol Willingc9d66f02018-09-14 10:06:55 -0700566 in which case returning true from this method will result in closing
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700567 the connection.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100568
Victor Stinnerea3183f2013-12-03 01:08:00 +0100569
Victor Stinner54a231d2015-01-29 13:33:15 +0100570State machine:
571
Yury Selivanov631fd382018-01-28 16:30:26 -0500572.. code-block:: none
573
574 start -> connection_made
575 [-> data_received]*
576 [-> eof_received]?
577 -> connection_lost -> end
578
579
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700580Buffered Streaming Protocols
581----------------------------
Yury Selivanov631fd382018-01-28 16:30:26 -0500582
583.. versionadded:: 3.7
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700584 **Important:** this has been added to asyncio in Python 3.7
585 *on a provisional basis*! This is as an experimental API that
586 might be changed or removed completely in Python 3.8.
Yury Selivanov631fd382018-01-28 16:30:26 -0500587
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700588Buffered Protocols can be used with any event loop method
589that supports `Streaming Protocols`_.
Yury Selivanov631fd382018-01-28 16:30:26 -0500590
Carol Willingc9d66f02018-09-14 10:06:55 -0700591The idea of ``BufferedProtocol`` is that it allows manual allocation
592and control of the receive buffer. Event loops can then use the buffer
Yury Selivanov631fd382018-01-28 16:30:26 -0500593provided by the protocol to avoid unnecessary data copies. This
594can result in noticeable performance improvement for protocols that
Yury Selivanovdbf10222018-05-28 14:31:28 -0400595receive big amounts of data. Sophisticated protocols implementations
596can allocate the buffer only once at creation time.
Yury Selivanov631fd382018-01-28 16:30:26 -0500597
598The following callbacks are called on :class:`BufferedProtocol`
599instances:
600
Yury Selivanovdbf10222018-05-28 14:31:28 -0400601.. method:: BufferedProtocol.get_buffer(sizehint)
Yury Selivanov631fd382018-01-28 16:30:26 -0500602
Yury Selivanovdbf10222018-05-28 14:31:28 -0400603 Called to allocate a new receive buffer.
604
605 *sizehint* is a recommended minimal size for the returned
606 buffer. It is acceptable to return smaller or bigger buffers
607 than what *sizehint* suggests. When set to -1, the buffer size
608 can be arbitrary. It is an error to return a zero-sized buffer.
609
610 Must return an object that implements the
611 :ref:`buffer protocol <bufferobjects>`.
Yury Selivanov631fd382018-01-28 16:30:26 -0500612
613.. method:: BufferedProtocol.buffer_updated(nbytes)
614
615 Called when the buffer was updated with the received data.
616
617 *nbytes* is the total number of bytes that were written to the buffer.
618
619.. method:: BufferedProtocol.eof_received()
620
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700621 See the documentation of the :meth:`protocol.eof_received()
622 <Protocol.eof_received>` method.
Yury Selivanov631fd382018-01-28 16:30:26 -0500623
624
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700625:meth:`~BufferedProtocol.get_buffer` can be called an arbitrary number
626of times during a connection. However, :meth:`protocol.eof_received()
627<Protocol.eof_received>` is called at most once
628and, if called, :meth:`~BufferedProtocol.get_buffer` and
629:meth:`~BufferedProtocol.buffer_updated` won't be called after it.
Yury Selivanov631fd382018-01-28 16:30:26 -0500630
631State machine:
632
633.. code-block:: none
634
635 start -> connection_made
636 [-> get_buffer
637 [-> buffer_updated]?
638 ]*
639 [-> eof_received]?
640 -> connection_lost -> end
Victor Stinner54a231d2015-01-29 13:33:15 +0100641
642
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700643Datagram Protocols
Victor Stinner0c6f1ca2013-12-03 01:46:39 +0100644------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100645
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700646Datagram Protocol instances should be constructed by protocol
647factories passed to the :meth:`loop.create_datagram_endpoint` method.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100648
649.. method:: DatagramProtocol.datagram_received(data, addr)
650
651 Called when a datagram is received. *data* is a bytes object containing
652 the incoming data. *addr* is the address of the peer sending the data;
653 the exact format depends on the transport.
654
655.. method:: DatagramProtocol.error_received(exc)
656
657 Called when a previous send or receive operation raises an
658 :class:`OSError`. *exc* is the :class:`OSError` instance.
659
660 This method is called in rare conditions, when the transport (e.g. UDP)
661 detects that a datagram couldn't be delivered to its recipient.
662 In many conditions though, undeliverable datagrams will be silently
663 dropped.
664
Victor Stinnerea3183f2013-12-03 01:08:00 +0100665.. note::
Victor Stinnerea3183f2013-12-03 01:08:00 +0100666
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700667 On BSD systems (macOS, FreeBSD, etc.) flow control is not supported
Carol Willingc9d66f02018-09-14 10:06:55 -0700668 for datagram protocols, because it is difficult to detect easily send
669 failures caused by writing too many packets.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700670
Carol Willingc9d66f02018-09-14 10:06:55 -0700671 The socket always appears 'ready' and excess packets are dropped. An
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700672 :class:`OSError` with ``errno`` set to :const:`errno.ENOBUFS` may
673 or may not be raised; if it is raised, it will be reported to
Larry Hastings3732ed22014-03-15 21:13:56 -0700674 :meth:`DatagramProtocol.error_received` but otherwise ignored.
675
Victor Stinnerea3183f2013-12-03 01:08:00 +0100676
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700677.. _asyncio-subprocess-protocols:
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100678
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700679Subprocess Protocols
680--------------------
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100681
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700682Datagram Protocol instances should be constructed by protocol
683factories passed to the :meth:`loop.subprocess_exec` and
684:meth:`loop.subprocess_shell` methods.
685
686.. method:: SubprocessProtocol.pipe_data_received(fd, data)
687
688 Called when the child process writes data into its stdout or stderr
689 pipe.
690
691 *fd* is the integer file descriptor of the pipe.
692
693 *data* is a non-empty bytes object containing the received data.
694
695.. method:: SubprocessProtocol.pipe_connection_lost(fd, exc)
696
697 Called when one of the pipes communicating with the child process
698 is closed.
699
700 *fd* is the integer file descriptor that was closed.
701
702.. method:: SubprocessProtocol.process_exited()
703
704 Called when the child process has exited.
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100705
706
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700707Examples
708========
Victor Stinnered051592014-10-12 20:18:16 +0200709
710.. _asyncio-tcp-echo-server-protocol:
711
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700712TCP Echo Server
713---------------
Victor Stinnered051592014-10-12 20:18:16 +0200714
Carol Willingc9d66f02018-09-14 10:06:55 -0700715Create a TCP echo server using the :meth:`loop.create_server` method, send back
716received data, and close the connection::
Victor Stinnera881a7f2013-12-09 13:19:23 +0100717
718 import asyncio
719
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700720
Victor Stinnercfbea3a2014-10-12 11:30:17 +0200721 class EchoServerClientProtocol(asyncio.Protocol):
Victor Stinnera881a7f2013-12-09 13:19:23 +0100722 def connection_made(self, transport):
723 peername = transport.get_extra_info('peername')
Victor Stinnerc2721b42014-10-12 11:13:40 +0200724 print('Connection from {}'.format(peername))
Victor Stinnera881a7f2013-12-09 13:19:23 +0100725 self.transport = transport
726
727 def data_received(self, data):
Victor Stinnerc2721b42014-10-12 11:13:40 +0200728 message = data.decode()
729 print('Data received: {!r}'.format(message))
730
731 print('Send: {!r}'.format(message))
Victor Stinnera881a7f2013-12-09 13:19:23 +0100732 self.transport.write(data)
733
Victor Stinner53664342014-10-12 11:35:09 +0200734 print('Close the client socket')
Victor Stinnera881a7f2013-12-09 13:19:23 +0100735 self.transport.close()
736
Victor Stinnera881a7f2013-12-09 13:19:23 +0100737
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700738 async def main():
739 # Get a reference to the event loop as we plan to use
740 # low-level APIs.
741 loop = asyncio.get_running_loop()
Victor Stinnerc2721b42014-10-12 11:13:40 +0200742
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700743 server = await loop.create_server(
744 lambda: EchoServerClientProtocol(),
745 '127.0.0.1', 8888)
Victor Stinnera881a7f2013-12-09 13:19:23 +0100746
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700747 async with server:
748 await server.serve_forever()
749
750
751 asyncio.run(main())
752
Victor Stinnera881a7f2013-12-09 13:19:23 +0100753
Victor Stinnered051592014-10-12 20:18:16 +0200754.. seealso::
755
756 The :ref:`TCP echo server using streams <asyncio-tcp-echo-server-streams>`
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700757 example uses the high-level :func:`asyncio.start_server` function.
758
759.. _asyncio-tcp-echo-client-protocol:
760
761TCP Echo Client
762---------------
763
Carol Willingc9d66f02018-09-14 10:06:55 -0700764A TCP echo client using the :meth:`loop.create_connection` method, sends
765data, and waits until the connection is closed::
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700766
767 import asyncio
768
769
770 class EchoClientProtocol(asyncio.Protocol):
771 def __init__(self, message, on_con_lost, loop):
772 self.message = message
773 self.loop = loop
774 self.on_con_lost = on_con_lost
775
776 def connection_made(self, transport):
777 transport.write(self.message.encode())
778 print('Data sent: {!r}'.format(self.message))
779
780 def data_received(self, data):
781 print('Data received: {!r}'.format(data.decode()))
782
783 def connection_lost(self, exc):
784 print('The server closed the connection')
785 self.on_con_lost.set_result(True)
786
787
788 async def main():
789 # Get a reference to the event loop as we plan to use
790 # low-level APIs.
791 loop = asyncio.get_running_loop()
792
793 on_con_lost = loop.create_future()
794 message = 'Hello World!'
795
796 transport, protocol = await loop.create_connection(
797 lambda: EchoClientProtocol(message, on_con_lost, loop),
798 '127.0.0.1', 8888)
799
800 # Wait until the protocol signals that the connection
801 # is lost and close the transport.
802 try:
803 await on_con_lost
804 finally:
805 transport.close()
806
807
808 asyncio.run(main())
809
810
811.. seealso::
812
813 The :ref:`TCP echo client using streams <asyncio-tcp-echo-client-streams>`
814 example uses the high-level :func:`asyncio.open_connection` function.
815
816
817.. _asyncio-udp-echo-server-protocol:
818
819UDP Echo Server
820---------------
821
Carol Willingc9d66f02018-09-14 10:06:55 -0700822A UDP echo server, using the :meth:`loop.create_datagram_endpoint`
823method, sends back received data::
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700824
825 import asyncio
826
827
828 class EchoServerProtocol:
829 def connection_made(self, transport):
830 self.transport = transport
831
832 def datagram_received(self, data, addr):
833 message = data.decode()
834 print('Received %r from %s' % (message, addr))
835 print('Send %r to %s' % (message, addr))
836 self.transport.sendto(data, addr)
837
838
839 async def main():
840 print("Starting UDP server")
841
842 # Get a reference to the event loop as we plan to use
843 # low-level APIs.
844 loop = asyncio.get_running_loop()
845
846 # One protocol instance will be created to serve all
847 # client requests.
848 transport, protocol = await loop.create_datagram_endpoint(
849 lambda: EchoServerProtocol(),
850 local_addr=('127.0.0.1', 9999))
851
852 try:
853 await asyncio.sleep(3600) # Serve for 1 hour.
854 finally:
855 transport.close()
856
857
858 asyncio.run(main())
Victor Stinnered051592014-10-12 20:18:16 +0200859
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200860
861.. _asyncio-udp-echo-client-protocol:
862
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700863UDP Echo Client
864---------------
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200865
Carol Willingc9d66f02018-09-14 10:06:55 -0700866A UDP echo client, using the :meth:`loop.create_datagram_endpoint`
867method, sends data and closes the transport when it receives the answer::
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200868
869 import asyncio
870
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700871
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200872 class EchoClientProtocol:
873 def __init__(self, message, loop):
874 self.message = message
875 self.loop = loop
876 self.transport = None
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700877 self.on_con_lost = loop.create_future()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200878
879 def connection_made(self, transport):
880 self.transport = transport
881 print('Send:', self.message)
882 self.transport.sendto(self.message.encode())
883
884 def datagram_received(self, data, addr):
885 print("Received:", data.decode())
886
887 print("Close the socket")
888 self.transport.close()
889
890 def error_received(self, exc):
891 print('Error received:', exc)
892
893 def connection_lost(self, exc):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700894 print("Connection closed")
895 self.on_con_lost.set_result(True)
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200896
897
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700898 async def main():
899 # Get a reference to the event loop as we plan to use
900 # low-level APIs.
901 loop = asyncio.get_running_loop()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200902
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700903 message = "Hello World!"
904 transport, protocol = await loop.create_datagram_endpoint(
905 lambda: EchoClientProtocol(message, loop),
906 remote_addr=('127.0.0.1', 9999))
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200907
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700908 try:
909 await protocol.on_con_lost
910 finally:
911 transport.close()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200912
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200913
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700914 asyncio.run(main())
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200915
916
Victor Stinner04e6df32014-10-11 16:16:27 +0200917.. _asyncio-register-socket:
Victor Stinnera881a7f2013-12-09 13:19:23 +0100918
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700919Connecting Existing Sockets
920---------------------------
Victor Stinner04e6df32014-10-11 16:16:27 +0200921
922Wait until a socket receives data using the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700923:meth:`loop.create_connection` method with a protocol::
Victor Stinner04e6df32014-10-11 16:16:27 +0200924
925 import asyncio
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700926 import socket
Victor Stinner04e6df32014-10-11 16:16:27 +0200927
Victor Stinner04e6df32014-10-11 16:16:27 +0200928
929 class MyProtocol(asyncio.Protocol):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700930
931 def __init__(self, loop):
932 self.transport = None
933 self.on_con_lost = loop.create_future()
Victor Stinner04e6df32014-10-11 16:16:27 +0200934
935 def connection_made(self, transport):
936 self.transport = transport
937
938 def data_received(self, data):
939 print("Received:", data.decode())
940
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700941 # We are done: close the transport;
942 # connection_lost() will be called automatically.
Victor Stinner04e6df32014-10-11 16:16:27 +0200943 self.transport.close()
944
945 def connection_lost(self, exc):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700946 # The socket has been closed
947 self.on_con_lost.set_result(True)
Victor Stinner04e6df32014-10-11 16:16:27 +0200948
Victor Stinner04e6df32014-10-11 16:16:27 +0200949
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700950 async def main():
951 # Get a reference to the event loop as we plan to use
952 # low-level APIs.
953 loop = asyncio.get_running_loop()
Victor Stinner04e6df32014-10-11 16:16:27 +0200954
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700955 # Create a pair of connected sockets
956 rsock, wsock = socket.socketpair()
Victor Stinner04e6df32014-10-11 16:16:27 +0200957
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700958 # Register the socket to wait for data.
959 transport, protocol = await loop.create_connection(
960 lambda: MyProtocol(loop), sock=rsock)
961
962 # Simulate the reception of data from the network.
963 loop.call_soon(wsock.send, 'abc'.encode())
964
965 try:
966 await protocol.on_con_lost
967 finally:
968 transport.close()
969 wsock.close()
970
971 asyncio.run(main())
Victor Stinner04e6df32014-10-11 16:16:27 +0200972
973.. seealso::
974
975 The :ref:`watch a file descriptor for read events
976 <asyncio-watch-read-event>` example uses the low-level
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700977 :meth:`loop.add_reader` method to register an FD.
Victor Stinner04e6df32014-10-11 16:16:27 +0200978
979 The :ref:`register an open socket to wait for data using streams
980 <asyncio-register-socket-streams>` example uses high-level streams
981 created by the :func:`open_connection` function in a coroutine.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700982
983.. _asyncio-subprocess-proto-example:
984
985loop.subprocess_exec() and SubprocessProtocol
986---------------------------------------------
987
Carol Willingc9d66f02018-09-14 10:06:55 -0700988An example of a subprocess protocol used to get the output of a
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700989subprocess and to wait for the subprocess exit.
990
991The subprocess is created by th :meth:`loop.subprocess_exec` method::
992
993 import asyncio
994 import sys
995
996 class DateProtocol(asyncio.SubprocessProtocol):
997 def __init__(self, exit_future):
998 self.exit_future = exit_future
999 self.output = bytearray()
1000
1001 def pipe_data_received(self, fd, data):
1002 self.output.extend(data)
1003
1004 def process_exited(self):
1005 self.exit_future.set_result(True)
1006
1007 async def get_date():
1008 # Get a reference to the event loop as we plan to use
1009 # low-level APIs.
1010 loop = asyncio.get_running_loop()
1011
1012 code = 'import datetime; print(datetime.datetime.now())'
1013 exit_future = asyncio.Future(loop=loop)
1014
1015 # Create the subprocess controlled by DateProtocol;
1016 # redirect the standard output into a pipe.
1017 transport, protocol = await loop.subprocess_exec(
1018 lambda: DateProtocol(exit_future),
1019 sys.executable, '-c', code,
1020 stdin=None, stderr=None)
1021
1022 # Wait for the subprocess exit using the process_exited()
1023 # method of the protocol.
1024 await exit_future
1025
1026 # Close the stdout pipe.
1027 transport.close()
1028
1029 # Read the output which was collected by the
1030 # pipe_data_received() method of the protocol.
1031 data = bytes(protocol.output)
1032 return data.decode('ascii').rstrip()
1033
1034 if sys.platform == "win32":
1035 asyncio.set_event_loop_policy(
1036 asyncio.WindowsProactorEventLoopPolicy())
1037
1038 date = asyncio.run(get_date())
1039 print(f"Current date: {date}")