blob: 84a275e0d0b6443804424d36f826ac8e5604b07b [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 Selivanov7c7605f2018-09-11 09:54:40 -07004========================
5Transports and Protocols
6========================
lf627d2c82017-07-25 17:03:51 -06007
Yury Selivanov7c7605f2018-09-11 09:54:40 -07008.. rubric:: Preface
9
10Transports and Protocols are used by **low-level** event loop
11APIs such as :meth:`loop.create_connection`. They require using
12callback-based programming style and enable high-performance
13implementations of network or IPC protocols (e.g. HTTP).
14
15Essentially, transports and protocols should only be used in
16libraries and frameworks and never in high-level asyncio
17applications.
18
19This documentation page covers both `Transports`_ and `Protocols`_.
20
21.. rubric:: Introduction
22
23At the highest level, the transport is concerned with *how* bytes
24are transmitted, while the protocol determines *which* bytes to
25transmit (and to some extent when).
26
27A different way of saying the same thing: a transport is an
28abstraction for a socket (or similar I/O endpoint) while a protocol
29is an abstraction for an application, from the transport's point
30of view.
31
32Yet another view is simply that the transport and protocol interfaces
33together define an abstract interface for using network I/O and
34interprocess I/O.
35
36There is always a 1:1 relationship between transport and protocol
37objects: the protocol calls transport methods to send data,
38while the transport calls protocol methods to pass it data that
39has been received.
40
41Most of connection oriented event loop methods
42(such as :meth:`loop.create_connection`) usually accept a
43*protocol_factory* argument used to create a *Protocol* object
44for an accepted connection, represented by a *Transport* object.
45Such methods usually return a tuple of ``(transport, protocol)``.
46
47.. rubric:: Contents
48
49This documentation page contains the following sections:
50
51* The `Transports`_ section documents asyncio :class:`BaseTransport`,
52 :class:`ReadTransport`, :class:`WriteTransport`, :class:`Transport`,
53 :class:`DatagramTransport`, and :class:`SubprocessTransport`
54 classes.
55
56* The `Protocols`_ section documents asyncio :class:`BaseProtocol`,
57 :class:`Protocol`, :class:`BufferedProtocol`,
58 :class:`DatagramProtocol`, and :class:`SubprocessProtocol` classes.
59
60* The `Examples`_ section showcases how to work with transports,
61 protocols, and low-level event loop APIs.
62
Victor Stinner1ca5ba62013-12-03 01:49:43 +010063
Victor Stinner9592edb2014-02-02 15:03:02 +010064.. _asyncio-transport:
Victor Stinnerea3183f2013-12-03 01:08:00 +010065
66Transports
67==========
68
Guido van Rossum589872c2014-03-29 21:14:04 -070069Transports are classes provided by :mod:`asyncio` in order to abstract
Yury Selivanov7c7605f2018-09-11 09:54:40 -070070various kinds of communication channels.
Victor Stinnerea3183f2013-12-03 01:08:00 +010071
Yury Selivanov7c7605f2018-09-11 09:54:40 -070072Transport objects are always instantiated by an
73ref:`asyncio event loop <asyncio-event-loop>`.
Victor Stinnerea3183f2013-12-03 01:08:00 +010074
Yury Selivanov7c7605f2018-09-11 09:54:40 -070075asyncio implements transports for TCP, UDP, SSL, and subprocess pipes.
76The methods available on a transport depend on the transport's kind.
Victor Stinnerea3183f2013-12-03 01:08:00 +010077
Victor Stinner83704962015-02-25 14:24:15 +010078The transport classes are :ref:`not thread safe <asyncio-multithreading>`.
79
Yury Selivanov3432f2f2016-12-12 16:44:58 -050080
Yury Selivanov7c7605f2018-09-11 09:54:40 -070081Transports Hierarchy
82--------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +010083
84.. class:: BaseTransport
85
Yury Selivanov7c7605f2018-09-11 09:54:40 -070086 Base class for all transports. Contains methods that all
87 asyncio transports share.
Victor Stinnerea3183f2013-12-03 01:08:00 +010088
Yury Selivanov7c7605f2018-09-11 09:54:40 -070089.. class:: WriteTransport(BaseTransport)
Victor Stinnerea3183f2013-12-03 01:08:00 +010090
Yury Selivanov7c7605f2018-09-11 09:54:40 -070091 A base transport for write-only connections.
Victor Stinnerea3183f2013-12-03 01:08:00 +010092
Yury Selivanov7c7605f2018-09-11 09:54:40 -070093 Instances of the *WriteTransport* class are returned from
94 the :meth:`loop.connect_write_pipe` event loop method and
95 are also used by subprocess-related methods like
96 :meth:`loop.subprocess_exec`.
Yury Selivanov1744d532015-11-16 12:46:41 -050097
Yury Selivanov7c7605f2018-09-11 09:54:40 -070098.. class:: ReadTransport(BaseTransport)
Yury Selivanov1744d532015-11-16 12:46:41 -050099
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700100 A base transport for read-only connections.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100101
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700102 Instances of the *ReadTransport* class are returned from
103 the :meth:`loop.connect_read_pipe` event loop method and
104 are also used by subprocess-related methods like
105 :meth:`loop.subprocess_exec`.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100106
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700107.. class:: Transport(WriteTransport, ReadTransport)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100108
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700109 Interface representing a bidirectional transport, such as a
110 TCP connection.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100111
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700112 The user never instantiates a transport directly; they call a
113 utility function, passing it a protocol factory and other
114 information necessary to create the transport and protocol.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100115
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700116 Instances of the *Transport* class are returned from or used by
117 event loop methods like :meth:`loop.create_connection`,
118 :meth:`loop.create_unix_connection`,
119 :meth:`loop.create_server`, :meth:`loop.sendfile`, etc.
Victor Stinnerf7dc7fb2015-09-21 18:06:17 +0200120
Victor Stinnerea3183f2013-12-03 01:08:00 +0100121
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700122.. class:: DatagramTransport(BaseTransport)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100123
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700124 A transport for datagram (UDP) connections.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100125
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700126 Instances of the *DatagramTransport* class are returned from
127 the :meth:`loop.create_datagram_endpoint` event loop method.
Yury Selivanovd757aaf2017-12-18 17:03:23 -0500128
Victor Stinnerea3183f2013-12-03 01:08:00 +0100129
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700130.. class:: SubprocessTransport(BaseTransport)
131
132 An abstraction to represent a connection between a parent and its
133 child OS process.
134
135 Instances of the *SubprocessTransport* class are returned from
136 event loop methods :meth:`loop.subprocess_shell` and
137 :meth:`loop.subprocess_exec`.
138
139
140Base Transport
Victor Stinner0c6f1ca2013-12-03 01:46:39 +0100141--------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100142
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700143.. method:: BaseTransport.close()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100144
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700145 Close the transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100146
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700147 If the transport has a buffer for outgoing
148 data, buffered data will be flushed asynchronously. No more data
149 will be received. After all buffered data is flushed, the
150 protocol's :meth:`protocol.connection_lost()
151 <BaseProtocol.connection_lost>` method will be called with
152 :const:`None` as its argument.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100153
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700154.. method:: BaseTransport.is_closing()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100155
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700156 Return ``True`` if the transport is closing or is closed.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100157
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700158.. method:: BaseTransport.get_extra_info(name, default=None)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100159
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700160 Return information about the transport or underlying resources
161 it uses.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100162
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700163 *name* is a string representing the piece of transport-specific
164 information to get.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100165
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700166 *default* is the value to return if the information is not
167 available, or if the transport does not support querying it
168 with the given third-party event loop implementation or on the
169 current platform.
Victor Stinner52bb9492014-08-26 00:22:28 +0200170
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700171 For example, the following code attempts to get the underlying
172 socket object of the transport::
Victor Stinner52bb9492014-08-26 00:22:28 +0200173
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700174 sock = transport.get_extra_info('socket')
175 if sock is not None:
176 print(sock.getsockopt(...))
Victor Stinner52bb9492014-08-26 00:22:28 +0200177
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700178 Categories of information that can be queried on some transports:
Victor Stinner52bb9492014-08-26 00:22:28 +0200179
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700180 * socket:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100181
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700182 - ``'peername'``: the remote address to which the socket is
183 connected, result of :meth:`socket.socket.getpeername`
184 (``None`` on error)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100185
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700186 - ``'socket'``: :class:`socket.socket` instance
Victor Stinnerea3183f2013-12-03 01:08:00 +0100187
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700188 - ``'sockname'``: the socket's own address,
189 result of :meth:`socket.socket.getsockname`
Kojo Idrissa5200a7c2017-06-20 14:32:00 -0500190
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700191 * SSL socket:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100192
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700193 - ``'compression'``: the compression algorithm being used as a
194 string, or ``None`` if the connection isn't compressed; result
195 of :meth:`ssl.SSLSocket.compression`
Victor Stinner52bb9492014-08-26 00:22:28 +0200196
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700197 - ``'cipher'``: a three-value tuple containing the name of the
198 cipher being used, the version of the SSL protocol that defines
199 its use, and the number of secret bits being used; result of
200 :meth:`ssl.SSLSocket.cipher`
Victor Stinnerea3183f2013-12-03 01:08:00 +0100201
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700202 - ``'peercert'``: peer certificate; result of
203 :meth:`ssl.SSLSocket.getpeercert`
Victor Stinnerea3183f2013-12-03 01:08:00 +0100204
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700205 - ``'sslcontext'``: :class:`ssl.SSLContext` instance
Victor Stinnerea3183f2013-12-03 01:08:00 +0100206
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700207 - ``'ssl_object'``: :class:`ssl.SSLObject` or
208 :class:`ssl.SSLSocket` instance
Victor Stinnerea3183f2013-12-03 01:08:00 +0100209
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700210 * pipe:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100211
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700212 - ``'pipe'``: pipe object
Victor Stinnerea3183f2013-12-03 01:08:00 +0100213
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700214 * subprocess:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100215
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700216 - ``'subprocess'``: :class:`subprocess.Popen` instance
217
218.. method:: BaseTransport.set_protocol(protocol)
219
220 Set a new protocol.
221
222 Switching protocol should only be done when both
223 protocols are documented to support the switch.
224
225.. method:: BaseTransport.get_protocol()
226
227 Return the current protocol.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100228
229
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700230Read-only Transports
231--------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100232
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700233.. method:: ReadTransport.is_reading()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100234
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700235 Return ``True`` if the transport is receiving new data.
236
237 .. versionadded:: 3.7
238
239.. method:: ReadTransport.pause_reading()
240
241 Pause the receiving end of the transport. No data will be passed to
242 the protocol's :meth:`protocol.data_received() <Protocol.data_received>`
243 method until :meth:`resume_reading` is called.
244
245 .. versionchanged:: 3.7
246 The method is idempotent, i.e. it can be called when the
247 transport is already paused or closed.
248
249.. method:: ReadTransport.resume_reading()
250
251 Resume the receiving end. The protocol's
252 :meth:`protocol.data_received() <Protocol.data_received>` method
253 will be called once again if some data is available for reading.
254
255 .. versionchanged:: 3.7
256 The method is idempotent, i.e. it can be called when the
257 transport is already reading.
258
259
260Write-only Transports
261---------------------
262
263.. method:: WriteTransport.abort()
264
265 Close the transport immediately, without waiting for pending operations
266 to complete. Buffered data will be lost. No more data will be received.
267 The protocol's :meth:`protocol.connection_lost()
268 <BaseProtocol.connection_lost>` method will eventually be
269 called with :const:`None` as its argument.
270
271.. method:: WriteTransport.can_write_eof()
272
273 Return :const:`True` if the transport supports
274 :meth:`~WriteTransport.write_eof`, :const:`False` if not.
275
276.. method:: WriteTransport.get_write_buffer_size()
277
278 Return the current size of the output buffer used by the transport.
279
280.. method:: WriteTransport.get_write_buffer_limits()
281
282 Get the *high*- and *low*-water limits for write flow control. Return a
283 tuple ``(low, high)`` where *low* and *high* are positive number of
284 bytes.
285
286 Use :meth:`set_write_buffer_limits` to set the limits.
287
288 .. versionadded:: 3.4.2
289
290.. method:: WriteTransport.set_write_buffer_limits(high=None, low=None)
291
292 Set the *high*- and *low*-water limits for write flow control.
293
294 These two values (measured in number of
295 bytes) control when the protocol's
296 :meth:`protocol.pause_writing() <BaseProtocol.pause_writing>`
297 and :meth:`protocol.resume_writing() <BaseProtocol.resume_writing>`
298 methods are called. If specified, the low-water limit must be less
299 than or equal to the high-water limit. Neither *high* nor *low*
300 can be negative.
301
302 :meth:`~BaseProtocol.pause_writing` is called when the buffer size
303 becomes greater than or equal to the *high* value. If writing has
304 been paused, :meth:`~BaseProtocol.resume_writing` is called when
305 the buffer size becomes less than or equal to the *low* value.
306
307 The defaults are implementation-specific. If only the
308 high-water limit is given, the low-water limit defaults to an
309 implementation-specific value less than or equal to the
310 high-water limit. Setting *high* to zero forces *low* to zero as
311 well, and causes :meth:`~BaseProtocol.pause_writing` to be called
312 whenever the buffer becomes non-empty. Setting *low* to zero causes
313 :meth:`~BaseProtocol.resume_writing` to be called only once the
314 buffer is empty. Use of zero for either limit is generally
315 sub-optimal as it reduces opportunities for doing I/O and
316 computation concurrently.
317
318 Use :meth:`~WriteTransport.get_write_buffer_limits`
319 to get the limits.
320
321.. method:: WriteTransport.write(data)
322
323 Write some *data* bytes to the transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100324
325 This method does not block; it buffers the data and arranges for it
326 to be sent out asynchronously.
327
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700328.. method:: WriteTransport.writelines(list_of_data)
329
330 Write a list (or any iterable) of data bytes to the transport.
331 This is functionally equivalent to calling :meth:`write` on each
332 element yielded by the iterable, but may be implemented more
333 efficiently.
334
335.. method:: WriteTransport.write_eof()
336
337 Close the write end of the transport after flushing buffered data.
338 Data may still be received.
339
340 This method can raise :exc:`NotImplementedError` if the transport
341 (e.g. SSL) doesn't support half-closes.
342
343
344Datagram Transports
345-------------------
346
347.. method:: DatagramTransport.sendto(data, addr=None)
348
349 Send the *data* bytes to the remote peer given by *addr* (a
350 transport-dependent target address). If *addr* is :const:`None`,
351 the data is sent to the target address given on transport
352 creation.
353
354 This method does not block; it buffers the data and arranges
355 for it to be sent out asynchronously.
356
Victor Stinnerea3183f2013-12-03 01:08:00 +0100357.. method:: DatagramTransport.abort()
358
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700359 Close the transport immediately, without waiting for pending
360 operations to complete. Buffered data will be lost.
361 No more data will be received. The protocol's
362 :meth:`protocol.connection_lost() <BaseProtocol.connection_lost>`
363 method will eventually be called with :const:`None` as its argument.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100364
365
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700366.. _asyncio-subprocess-transports:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100367
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700368Subprocess Transports
369---------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100370
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700371.. method:: SubprocessTransport.get_pid()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100372
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700373 Return the subprocess process id as an integer.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100374
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700375.. method:: SubprocessTransport.get_pipe_transport(fd)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100376
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700377 Return the transport for the communication pipe corresponding to the
378 integer file descriptor *fd*:
Victor Stinner4270a242014-10-13 23:56:43 +0200379
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700380 * ``0``: readable streaming transport of the standard input (*stdin*),
381 or :const:`None` if the subprocess was not created with ``stdin=PIPE``
382 * ``1``: writable streaming transport of the standard output (*stdout*),
383 or :const:`None` if the subprocess was not created with ``stdout=PIPE``
384 * ``2``: writable streaming transport of the standard error (*stderr*),
385 or :const:`None` if the subprocess was not created with ``stderr=PIPE``
386 * other *fd*: :const:`None`
Victor Stinnerea3183f2013-12-03 01:08:00 +0100387
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700388.. method:: SubprocessTransport.get_returncode()
Victor Stinner933a8c82013-12-03 01:59:38 +0100389
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700390 Return the subprocess return code as an integer or :const:`None`
391 if it hasn't returned, similarly to the
392 :attr:`subprocess.Popen.returncode` attribute.
Victor Stinner933a8c82013-12-03 01:59:38 +0100393
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700394.. method:: SubprocessTransport.kill()
Victor Stinner933a8c82013-12-03 01:59:38 +0100395
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700396 Kill the subprocess, as in :meth:`subprocess.Popen.kill`.
Victor Stinner933a8c82013-12-03 01:59:38 +0100397
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700398 On POSIX systems, the function sends SIGKILL to the subprocess.
399 On Windows, this method is an alias for :meth:`terminate`.
Victor Stinner933a8c82013-12-03 01:59:38 +0100400
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700401.. method:: SubprocessTransport.send_signal(signal)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100402
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700403 Send the *signal* number to the subprocess, as in
404 :meth:`subprocess.Popen.send_signal`.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100405
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700406.. method:: SubprocessTransport.terminate()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100407
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700408 Ask the subprocess to stop, as in :meth:`subprocess.Popen.terminate`.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100409
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700410 On POSIX systems, this method sends SIGTERM to the subprocess.
411 On Windows, the Windows API function TerminateProcess() is called to
412 stop the subprocess.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100413
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700414.. method:: SubprocessTransport.close()
Victor Stinner4270a242014-10-13 23:56:43 +0200415
Bumsik Kimaca819f2018-09-12 14:31:56 -0400416 Kill the subprocess by calling the :meth:`kill` method
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700417 if the subprocess hasn't returned yet, and close transports of all
418 pipes (*stdin*, *stdout* and *stderr*).
Victor Stinner4270a242014-10-13 23:56:43 +0200419
Victor Stinnerea3183f2013-12-03 01:08:00 +0100420
Victor Stinner9592edb2014-02-02 15:03:02 +0100421.. _asyncio-protocol:
Victor Stinnerea3183f2013-12-03 01:08:00 +0100422
423Protocols
424=========
425
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700426asyncio provides a set of abstract base classes that should be used
427to implement network protocols. Those classes are meant to be used
428together with :ref:`transports <asyncio-transport>`.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100429
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700430Subclasses of abstract base protocol classes can implement some or
431all methods. All those methods are callbacks: they are called by
432transports on certain events, for example when some data is received.
433Base protocol methods are not supposed to be called by anything but
434the corresponding transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100435
436
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700437Base Protocols
438--------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100439
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700440.. class:: BaseProtocol
Victor Stinnerea3183f2013-12-03 01:08:00 +0100441
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700442 Base protocol with methods that all protocols share.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100443
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700444.. class:: Protocol(BaseProtocol)
445
446 The base class for implementing streaming protocols
447 (TCP, Unix sockets, etc).
448
449.. class:: BufferedProtocol(BaseProtocol)
Yury Selivanov631fd382018-01-28 16:30:26 -0500450
451 A base class for implementing streaming protocols with manual
452 control of the receive buffer.
453
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700454.. class:: DatagramProtocol(BaseProtocol)
Yury Selivanov631fd382018-01-28 16:30:26 -0500455
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700456 The base class for implementing datagram (UDP) protocols.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100457
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700458.. class:: SubprocessProtocol(BaseProtocol)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100459
460 The base class for implementing protocols communicating with child
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700461 processes (unidirectional pipes).
Victor Stinnerea3183f2013-12-03 01:08:00 +0100462
463
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700464Base Protocol
465-------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100466
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700467All asyncio protocols can implement Base Protocol callbacks.
468
469.. rubric:: Connection Callbacks
470
471Connection callbacks are called on all protocols, exactly once per
472a successful connection. All other protocol callbacks can only be
473called between those two methods.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100474
475.. method:: BaseProtocol.connection_made(transport)
476
477 Called when a connection is made.
478
479 The *transport* argument is the transport representing the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700480 connection. The protocol is responsible for storing the reference
481 to its transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100482
483.. method:: BaseProtocol.connection_lost(exc)
484
485 Called when the connection is lost or closed.
486
487 The argument is either an exception object or :const:`None`.
488 The latter means a regular EOF is received, or the connection was
489 aborted or closed by this side of the connection.
490
Victor Stinnerea3183f2013-12-03 01:08:00 +0100491
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700492.. rubric:: Flow Control Callbacks
Victor Stinnerea3183f2013-12-03 01:08:00 +0100493
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700494Flow control callbacks can be called by transports to pause or
495resume writing performed by the protocol.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100496
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700497See the documentation of the :meth:`~WriteTransport.set_write_buffer_limits`
498method for more details.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100499
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700500.. method:: BaseProtocol.pause_writing()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100501
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700502 Called when the transport's buffer goes over the high-water mark.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100503
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700504.. method:: BaseProtocol.resume_writing()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100505
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700506 Called when the transport's buffer drains below the low-water mark.
507
508If the buffer size equals the high-water mark,
509:meth:`~BaseProtocol.pause_writing` is not called: the buffer size must
510go strictly over.
511
512Conversely, :meth:`~BaseProtocol.resume_writing` is called when the
513buffer size is equal or lower than the low-water mark. These end
514conditions are important to ensure that things go as expected when
515either mark is zero.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100516
517
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700518Streaming Protocols
Victor Stinner0c6f1ca2013-12-03 01:46:39 +0100519-------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100520
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700521Event methods, such as :meth:`loop.create_server`,
522:meth:`loop.create_unix_server`, :meth:`loop.create_connection`,
523:meth:`loop.create_unix_connection`, :meth:`loop.connect_accepted_socket`,
524:meth:`loop.connect_read_pipe`, and :meth:`loop.connect_write_pipe`
525accept factories that return streaming protocols.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100526
527.. method:: Protocol.data_received(data)
528
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700529 Called when some data is received. *data* is a non-empty bytes
530 object containing the incoming data.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100531
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700532 Whether the data is buffered, chunked or reassembled depends on
533 the transport. In general, you shouldn't rely on specific semantics
534 and instead make your parsing generic and flexible enough. However,
535 data is always received in the correct order.
536
537 The method can be called an arbitrary number of times during
538 a connection.
539
540 However, :meth:`protocol.eof_received() <Protocol.eof_received>`
541 is called at most once and, if called,
542 :meth:`protocol.data_received() <Protocol.data_received>`
543 won't be called after it.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100544
545.. method:: Protocol.eof_received()
546
Barry Warsawdd9a0a12017-04-07 14:18:14 -0400547 Called when the other end signals it won't send any more data
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700548 (for example by calling :meth:`transport.write_eof()
549 <WriteTransport.write_eof>`, if the other end also uses
Victor Stinnerea3183f2013-12-03 01:08:00 +0100550 asyncio).
551
Serhiy Storchakaecf41da2016-10-19 16:29:26 +0300552 This method may return a false value (including ``None``), in which case
Victor Stinnerea3183f2013-12-03 01:08:00 +0100553 the transport will close itself. Conversely, if this method returns a
554 true value, closing the transport is up to the protocol. Since the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700555 default implementation returns ``None``, it implicitly closes the
556 connection.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100557
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700558 Some transports such as SSL don't support half-closed connections,
559 in which case returning true from this method will not prevent closing
560 the connection.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100561
Victor Stinnerea3183f2013-12-03 01:08:00 +0100562
Victor Stinner54a231d2015-01-29 13:33:15 +0100563State machine:
564
Yury Selivanov631fd382018-01-28 16:30:26 -0500565.. code-block:: none
566
567 start -> connection_made
568 [-> data_received]*
569 [-> eof_received]?
570 -> connection_lost -> end
571
572
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700573Buffered Streaming Protocols
574----------------------------
Yury Selivanov631fd382018-01-28 16:30:26 -0500575
576.. versionadded:: 3.7
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700577 **Important:** this has been added to asyncio in Python 3.7
578 *on a provisional basis*! This is as an experimental API that
579 might be changed or removed completely in Python 3.8.
Yury Selivanov631fd382018-01-28 16:30:26 -0500580
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700581Buffered Protocols can be used with any event loop method
582that supports `Streaming Protocols`_.
Yury Selivanov631fd382018-01-28 16:30:26 -0500583
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700584The idea of ``BufferedProtocol`` is that it allows to manually allocate
Yury Selivanov631fd382018-01-28 16:30:26 -0500585and control the receive buffer. Event loops can then use the buffer
586provided by the protocol to avoid unnecessary data copies. This
587can result in noticeable performance improvement for protocols that
Yury Selivanovdbf10222018-05-28 14:31:28 -0400588receive big amounts of data. Sophisticated protocols implementations
589can allocate the buffer only once at creation time.
Yury Selivanov631fd382018-01-28 16:30:26 -0500590
591The following callbacks are called on :class:`BufferedProtocol`
592instances:
593
Yury Selivanovdbf10222018-05-28 14:31:28 -0400594.. method:: BufferedProtocol.get_buffer(sizehint)
Yury Selivanov631fd382018-01-28 16:30:26 -0500595
Yury Selivanovdbf10222018-05-28 14:31:28 -0400596 Called to allocate a new receive buffer.
597
598 *sizehint* is a recommended minimal size for the returned
599 buffer. It is acceptable to return smaller or bigger buffers
600 than what *sizehint* suggests. When set to -1, the buffer size
601 can be arbitrary. It is an error to return a zero-sized buffer.
602
603 Must return an object that implements the
604 :ref:`buffer protocol <bufferobjects>`.
Yury Selivanov631fd382018-01-28 16:30:26 -0500605
606.. method:: BufferedProtocol.buffer_updated(nbytes)
607
608 Called when the buffer was updated with the received data.
609
610 *nbytes* is the total number of bytes that were written to the buffer.
611
612.. method:: BufferedProtocol.eof_received()
613
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700614 See the documentation of the :meth:`protocol.eof_received()
615 <Protocol.eof_received>` method.
Yury Selivanov631fd382018-01-28 16:30:26 -0500616
617
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700618:meth:`~BufferedProtocol.get_buffer` can be called an arbitrary number
619of times during a connection. However, :meth:`protocol.eof_received()
620<Protocol.eof_received>` is called at most once
621and, if called, :meth:`~BufferedProtocol.get_buffer` and
622:meth:`~BufferedProtocol.buffer_updated` won't be called after it.
Yury Selivanov631fd382018-01-28 16:30:26 -0500623
624State machine:
625
626.. code-block:: none
627
628 start -> connection_made
629 [-> get_buffer
630 [-> buffer_updated]?
631 ]*
632 [-> eof_received]?
633 -> connection_lost -> end
Victor Stinner54a231d2015-01-29 13:33:15 +0100634
635
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700636Datagram Protocols
Victor Stinner0c6f1ca2013-12-03 01:46:39 +0100637------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100638
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700639Datagram Protocol instances should be constructed by protocol
640factories passed to the :meth:`loop.create_datagram_endpoint` method.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100641
642.. method:: DatagramProtocol.datagram_received(data, addr)
643
644 Called when a datagram is received. *data* is a bytes object containing
645 the incoming data. *addr* is the address of the peer sending the data;
646 the exact format depends on the transport.
647
648.. method:: DatagramProtocol.error_received(exc)
649
650 Called when a previous send or receive operation raises an
651 :class:`OSError`. *exc* is the :class:`OSError` instance.
652
653 This method is called in rare conditions, when the transport (e.g. UDP)
654 detects that a datagram couldn't be delivered to its recipient.
655 In many conditions though, undeliverable datagrams will be silently
656 dropped.
657
Victor Stinnerea3183f2013-12-03 01:08:00 +0100658.. note::
Victor Stinnerea3183f2013-12-03 01:08:00 +0100659
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700660 On BSD systems (macOS, FreeBSD, etc.) flow control is not supported
661 for datagram protocols, because send failures caused by
662 writing too many packets cannot be detected easily.
663
664 The socket always appears 'ready' and excess packets are dropped; an
665 :class:`OSError` with ``errno`` set to :const:`errno.ENOBUFS` may
666 or may not be raised; if it is raised, it will be reported to
Larry Hastings3732ed22014-03-15 21:13:56 -0700667 :meth:`DatagramProtocol.error_received` but otherwise ignored.
668
Victor Stinnerea3183f2013-12-03 01:08:00 +0100669
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700670.. _asyncio-subprocess-protocols:
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100671
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700672Subprocess Protocols
673--------------------
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100674
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700675Datagram Protocol instances should be constructed by protocol
676factories passed to the :meth:`loop.subprocess_exec` and
677:meth:`loop.subprocess_shell` methods.
678
679.. method:: SubprocessProtocol.pipe_data_received(fd, data)
680
681 Called when the child process writes data into its stdout or stderr
682 pipe.
683
684 *fd* is the integer file descriptor of the pipe.
685
686 *data* is a non-empty bytes object containing the received data.
687
688.. method:: SubprocessProtocol.pipe_connection_lost(fd, exc)
689
690 Called when one of the pipes communicating with the child process
691 is closed.
692
693 *fd* is the integer file descriptor that was closed.
694
695.. method:: SubprocessProtocol.process_exited()
696
697 Called when the child process has exited.
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100698
699
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700700Examples
701========
Victor Stinnered051592014-10-12 20:18:16 +0200702
703.. _asyncio-tcp-echo-server-protocol:
704
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700705TCP Echo Server
706---------------
Victor Stinnered051592014-10-12 20:18:16 +0200707
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700708TCP echo server using the :meth:`loop.create_server` method, send back
Victor Stinnered051592014-10-12 20:18:16 +0200709received data and close the connection::
Victor Stinnera881a7f2013-12-09 13:19:23 +0100710
711 import asyncio
712
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700713
Victor Stinnercfbea3a2014-10-12 11:30:17 +0200714 class EchoServerClientProtocol(asyncio.Protocol):
Victor Stinnera881a7f2013-12-09 13:19:23 +0100715 def connection_made(self, transport):
716 peername = transport.get_extra_info('peername')
Victor Stinnerc2721b42014-10-12 11:13:40 +0200717 print('Connection from {}'.format(peername))
Victor Stinnera881a7f2013-12-09 13:19:23 +0100718 self.transport = transport
719
720 def data_received(self, data):
Victor Stinnerc2721b42014-10-12 11:13:40 +0200721 message = data.decode()
722 print('Data received: {!r}'.format(message))
723
724 print('Send: {!r}'.format(message))
Victor Stinnera881a7f2013-12-09 13:19:23 +0100725 self.transport.write(data)
726
Victor Stinner53664342014-10-12 11:35:09 +0200727 print('Close the client socket')
Victor Stinnera881a7f2013-12-09 13:19:23 +0100728 self.transport.close()
729
Victor Stinnera881a7f2013-12-09 13:19:23 +0100730
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700731 async def main():
732 # Get a reference to the event loop as we plan to use
733 # low-level APIs.
734 loop = asyncio.get_running_loop()
Victor Stinnerc2721b42014-10-12 11:13:40 +0200735
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700736 server = await loop.create_server(
737 lambda: EchoServerClientProtocol(),
738 '127.0.0.1', 8888)
Victor Stinnera881a7f2013-12-09 13:19:23 +0100739
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700740 async with server:
741 await server.serve_forever()
742
743
744 asyncio.run(main())
745
Victor Stinnera881a7f2013-12-09 13:19:23 +0100746
Victor Stinnered051592014-10-12 20:18:16 +0200747.. seealso::
748
749 The :ref:`TCP echo server using streams <asyncio-tcp-echo-server-streams>`
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700750 example uses the high-level :func:`asyncio.start_server` function.
751
752.. _asyncio-tcp-echo-client-protocol:
753
754TCP Echo Client
755---------------
756
757TCP echo client using the :meth:`loop.create_connection` method, send
758data and wait until the connection is closed::
759
760 import asyncio
761
762
763 class EchoClientProtocol(asyncio.Protocol):
764 def __init__(self, message, on_con_lost, loop):
765 self.message = message
766 self.loop = loop
767 self.on_con_lost = on_con_lost
768
769 def connection_made(self, transport):
770 transport.write(self.message.encode())
771 print('Data sent: {!r}'.format(self.message))
772
773 def data_received(self, data):
774 print('Data received: {!r}'.format(data.decode()))
775
776 def connection_lost(self, exc):
777 print('The server closed the connection')
778 self.on_con_lost.set_result(True)
779
780
781 async def main():
782 # Get a reference to the event loop as we plan to use
783 # low-level APIs.
784 loop = asyncio.get_running_loop()
785
786 on_con_lost = loop.create_future()
787 message = 'Hello World!'
788
789 transport, protocol = await loop.create_connection(
790 lambda: EchoClientProtocol(message, on_con_lost, loop),
791 '127.0.0.1', 8888)
792
793 # Wait until the protocol signals that the connection
794 # is lost and close the transport.
795 try:
796 await on_con_lost
797 finally:
798 transport.close()
799
800
801 asyncio.run(main())
802
803
804.. seealso::
805
806 The :ref:`TCP echo client using streams <asyncio-tcp-echo-client-streams>`
807 example uses the high-level :func:`asyncio.open_connection` function.
808
809
810.. _asyncio-udp-echo-server-protocol:
811
812UDP Echo Server
813---------------
814
815UDP echo server using the :meth:`loop.create_datagram_endpoint`
816method, send back received data::
817
818 import asyncio
819
820
821 class EchoServerProtocol:
822 def connection_made(self, transport):
823 self.transport = transport
824
825 def datagram_received(self, data, addr):
826 message = data.decode()
827 print('Received %r from %s' % (message, addr))
828 print('Send %r to %s' % (message, addr))
829 self.transport.sendto(data, addr)
830
831
832 async def main():
833 print("Starting UDP server")
834
835 # Get a reference to the event loop as we plan to use
836 # low-level APIs.
837 loop = asyncio.get_running_loop()
838
839 # One protocol instance will be created to serve all
840 # client requests.
841 transport, protocol = await loop.create_datagram_endpoint(
842 lambda: EchoServerProtocol(),
843 local_addr=('127.0.0.1', 9999))
844
845 try:
846 await asyncio.sleep(3600) # Serve for 1 hour.
847 finally:
848 transport.close()
849
850
851 asyncio.run(main())
Victor Stinnered051592014-10-12 20:18:16 +0200852
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200853
854.. _asyncio-udp-echo-client-protocol:
855
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700856UDP Echo Client
857---------------
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200858
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700859UDP echo client using the :meth:`loop.create_datagram_endpoint`
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200860method, send data and close the transport when we received the answer::
861
862 import asyncio
863
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700864
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200865 class EchoClientProtocol:
866 def __init__(self, message, loop):
867 self.message = message
868 self.loop = loop
869 self.transport = None
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700870 self.on_con_lost = loop.create_future()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200871
872 def connection_made(self, transport):
873 self.transport = transport
874 print('Send:', self.message)
875 self.transport.sendto(self.message.encode())
876
877 def datagram_received(self, data, addr):
878 print("Received:", data.decode())
879
880 print("Close the socket")
881 self.transport.close()
882
883 def error_received(self, exc):
884 print('Error received:', exc)
885
886 def connection_lost(self, exc):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700887 print("Connection closed")
888 self.on_con_lost.set_result(True)
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200889
890
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700891 async def main():
892 # Get a reference to the event loop as we plan to use
893 # low-level APIs.
894 loop = asyncio.get_running_loop()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200895
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700896 message = "Hello World!"
897 transport, protocol = await loop.create_datagram_endpoint(
898 lambda: EchoClientProtocol(message, loop),
899 remote_addr=('127.0.0.1', 9999))
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200900
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700901 try:
902 await protocol.on_con_lost
903 finally:
904 transport.close()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200905
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200906
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700907 asyncio.run(main())
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200908
909
Victor Stinner04e6df32014-10-11 16:16:27 +0200910.. _asyncio-register-socket:
Victor Stinnera881a7f2013-12-09 13:19:23 +0100911
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700912Connecting Existing Sockets
913---------------------------
Victor Stinner04e6df32014-10-11 16:16:27 +0200914
915Wait until a socket receives data using the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700916:meth:`loop.create_connection` method with a protocol::
Victor Stinner04e6df32014-10-11 16:16:27 +0200917
918 import asyncio
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700919 import socket
Victor Stinner04e6df32014-10-11 16:16:27 +0200920
Victor Stinner04e6df32014-10-11 16:16:27 +0200921
922 class MyProtocol(asyncio.Protocol):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700923
924 def __init__(self, loop):
925 self.transport = None
926 self.on_con_lost = loop.create_future()
Victor Stinner04e6df32014-10-11 16:16:27 +0200927
928 def connection_made(self, transport):
929 self.transport = transport
930
931 def data_received(self, data):
932 print("Received:", data.decode())
933
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700934 # We are done: close the transport;
935 # connection_lost() will be called automatically.
Victor Stinner04e6df32014-10-11 16:16:27 +0200936 self.transport.close()
937
938 def connection_lost(self, exc):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700939 # The socket has been closed
940 self.on_con_lost.set_result(True)
Victor Stinner04e6df32014-10-11 16:16:27 +0200941
Victor Stinner04e6df32014-10-11 16:16:27 +0200942
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700943 async def main():
944 # Get a reference to the event loop as we plan to use
945 # low-level APIs.
946 loop = asyncio.get_running_loop()
Victor Stinner04e6df32014-10-11 16:16:27 +0200947
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700948 # Create a pair of connected sockets
949 rsock, wsock = socket.socketpair()
Victor Stinner04e6df32014-10-11 16:16:27 +0200950
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700951 # Register the socket to wait for data.
952 transport, protocol = await loop.create_connection(
953 lambda: MyProtocol(loop), sock=rsock)
954
955 # Simulate the reception of data from the network.
956 loop.call_soon(wsock.send, 'abc'.encode())
957
958 try:
959 await protocol.on_con_lost
960 finally:
961 transport.close()
962 wsock.close()
963
964 asyncio.run(main())
Victor Stinner04e6df32014-10-11 16:16:27 +0200965
966.. seealso::
967
968 The :ref:`watch a file descriptor for read events
969 <asyncio-watch-read-event>` example uses the low-level
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700970 :meth:`loop.add_reader` method to register an FD.
Victor Stinner04e6df32014-10-11 16:16:27 +0200971
972 The :ref:`register an open socket to wait for data using streams
973 <asyncio-register-socket-streams>` example uses high-level streams
974 created by the :func:`open_connection` function in a coroutine.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700975
976.. _asyncio-subprocess-proto-example:
977
978loop.subprocess_exec() and SubprocessProtocol
979---------------------------------------------
980
981An example of a subprocess protocol using to get the output of a
982subprocess and to wait for the subprocess exit.
983
984The subprocess is created by th :meth:`loop.subprocess_exec` method::
985
986 import asyncio
987 import sys
988
989 class DateProtocol(asyncio.SubprocessProtocol):
990 def __init__(self, exit_future):
991 self.exit_future = exit_future
992 self.output = bytearray()
993
994 def pipe_data_received(self, fd, data):
995 self.output.extend(data)
996
997 def process_exited(self):
998 self.exit_future.set_result(True)
999
1000 async def get_date():
1001 # Get a reference to the event loop as we plan to use
1002 # low-level APIs.
1003 loop = asyncio.get_running_loop()
1004
1005 code = 'import datetime; print(datetime.datetime.now())'
1006 exit_future = asyncio.Future(loop=loop)
1007
1008 # Create the subprocess controlled by DateProtocol;
1009 # redirect the standard output into a pipe.
1010 transport, protocol = await loop.subprocess_exec(
1011 lambda: DateProtocol(exit_future),
1012 sys.executable, '-c', code,
1013 stdin=None, stderr=None)
1014
1015 # Wait for the subprocess exit using the process_exited()
1016 # method of the protocol.
1017 await exit_future
1018
1019 # Close the stdout pipe.
1020 transport.close()
1021
1022 # Read the output which was collected by the
1023 # pipe_data_received() method of the protocol.
1024 data = bytes(protocol.output)
1025 return data.decode('ascii').rstrip()
1026
1027 if sys.platform == "win32":
1028 asyncio.set_event_loop_policy(
1029 asyncio.WindowsProactorEventLoopPolicy())
1030
1031 date = asyncio.run(get_date())
1032 print(f"Current date: {date}")