blob: d7ecb25bcea325a3a6c2577603b3d02c54f469a5 [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
Carol Willingc9d66f02018-09-14 10:06:55 -070032Yet another view is the transport and protocol interfaces
Yury Selivanov7c7605f2018-09-11 09:54:40 -070033together 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
Carol Willingc9d66f02018-09-14 10:06:55 -0700112 The user does not instantiate a transport directly; they call a
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700113 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`
Carol Willingc9d66f02018-09-14 10:06:55 -0700391 if it hasn't returned, which is similar to the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700392 :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
Carol Willingc9d66f02018-09-14 10:06:55 -0700430Subclasses of abstract base protocol classes may implement some or
431all methods. All these methods are callbacks: they are called by
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700432transports on certain events, for example when some data is received.
Carol Willingc9d66f02018-09-14 10:06:55 -0700433A base protocol method should be called by the corresponding transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100434
435
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700436Base Protocols
437--------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100438
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700439.. class:: BaseProtocol
Victor Stinnerea3183f2013-12-03 01:08:00 +0100440
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700441 Base protocol with methods that all protocols share.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100442
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700443.. class:: Protocol(BaseProtocol)
444
445 The base class for implementing streaming protocols
446 (TCP, Unix sockets, etc).
447
448.. class:: BufferedProtocol(BaseProtocol)
Yury Selivanov631fd382018-01-28 16:30:26 -0500449
450 A base class for implementing streaming protocols with manual
451 control of the receive buffer.
452
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700453.. class:: DatagramProtocol(BaseProtocol)
Yury Selivanov631fd382018-01-28 16:30:26 -0500454
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700455 The base class for implementing datagram (UDP) protocols.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100456
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700457.. class:: SubprocessProtocol(BaseProtocol)
Victor Stinnerea3183f2013-12-03 01:08:00 +0100458
459 The base class for implementing protocols communicating with child
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700460 processes (unidirectional pipes).
Victor Stinnerea3183f2013-12-03 01:08:00 +0100461
462
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700463Base Protocol
464-------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100465
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700466All asyncio protocols can implement Base Protocol callbacks.
467
468.. rubric:: Connection Callbacks
469
470Connection callbacks are called on all protocols, exactly once per
471a successful connection. All other protocol callbacks can only be
472called between those two methods.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100473
474.. method:: BaseProtocol.connection_made(transport)
475
476 Called when a connection is made.
477
478 The *transport* argument is the transport representing the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700479 connection. The protocol is responsible for storing the reference
480 to its transport.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100481
482.. method:: BaseProtocol.connection_lost(exc)
483
484 Called when the connection is lost or closed.
485
486 The argument is either an exception object or :const:`None`.
487 The latter means a regular EOF is received, or the connection was
488 aborted or closed by this side of the connection.
489
Victor Stinnerea3183f2013-12-03 01:08:00 +0100490
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700491.. rubric:: Flow Control Callbacks
Victor Stinnerea3183f2013-12-03 01:08:00 +0100492
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700493Flow control callbacks can be called by transports to pause or
494resume writing performed by the protocol.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100495
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700496See the documentation of the :meth:`~WriteTransport.set_write_buffer_limits`
497method for more details.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100498
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700499.. method:: BaseProtocol.pause_writing()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100500
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700501 Called when the transport's buffer goes over the high-water mark.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100502
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700503.. method:: BaseProtocol.resume_writing()
Victor Stinnerea3183f2013-12-03 01:08:00 +0100504
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700505 Called when the transport's buffer drains below the low-water mark.
506
507If the buffer size equals the high-water mark,
508:meth:`~BaseProtocol.pause_writing` is not called: the buffer size must
509go strictly over.
510
511Conversely, :meth:`~BaseProtocol.resume_writing` is called when the
512buffer size is equal or lower than the low-water mark. These end
513conditions are important to ensure that things go as expected when
514either mark is zero.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100515
516
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700517Streaming Protocols
Victor Stinner0c6f1ca2013-12-03 01:46:39 +0100518-------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100519
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700520Event methods, such as :meth:`loop.create_server`,
521:meth:`loop.create_unix_server`, :meth:`loop.create_connection`,
522:meth:`loop.create_unix_connection`, :meth:`loop.connect_accepted_socket`,
523:meth:`loop.connect_read_pipe`, and :meth:`loop.connect_write_pipe`
524accept factories that return streaming protocols.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100525
526.. method:: Protocol.data_received(data)
527
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700528 Called when some data is received. *data* is a non-empty bytes
529 object containing the incoming data.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100530
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700531 Whether the data is buffered, chunked or reassembled depends on
532 the transport. In general, you shouldn't rely on specific semantics
Carol Willingc9d66f02018-09-14 10:06:55 -0700533 and instead make your parsing generic and flexible. However,
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700534 data is always received in the correct order.
535
536 The method can be called an arbitrary number of times during
537 a connection.
538
539 However, :meth:`protocol.eof_received() <Protocol.eof_received>`
540 is called at most once and, if called,
541 :meth:`protocol.data_received() <Protocol.data_received>`
542 won't be called after it.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100543
544.. method:: Protocol.eof_received()
545
Barry Warsawdd9a0a12017-04-07 14:18:14 -0400546 Called when the other end signals it won't send any more data
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700547 (for example by calling :meth:`transport.write_eof()
548 <WriteTransport.write_eof>`, if the other end also uses
Victor Stinnerea3183f2013-12-03 01:08:00 +0100549 asyncio).
550
Serhiy Storchakaecf41da2016-10-19 16:29:26 +0300551 This method may return a false value (including ``None``), in which case
Victor Stinnerea3183f2013-12-03 01:08:00 +0100552 the transport will close itself. Conversely, if this method returns a
Carol Willingc9d66f02018-09-14 10:06:55 -0700553 true value, the protocol used determines whether to close the transport.
554 Since the default implementation returns ``None``, it implicitly closes the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700555 connection.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100556
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700557 Some transports such as SSL don't support half-closed connections,
Carol Willingc9d66f02018-09-14 10:06:55 -0700558 in which case returning true from this method will result in closing
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700559 the connection.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100560
Victor Stinnerea3183f2013-12-03 01:08:00 +0100561
Victor Stinner54a231d2015-01-29 13:33:15 +0100562State machine:
563
Yury Selivanov631fd382018-01-28 16:30:26 -0500564.. code-block:: none
565
566 start -> connection_made
567 [-> data_received]*
568 [-> eof_received]?
569 -> connection_lost -> end
570
571
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700572Buffered Streaming Protocols
573----------------------------
Yury Selivanov631fd382018-01-28 16:30:26 -0500574
575.. versionadded:: 3.7
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700576 **Important:** this has been added to asyncio in Python 3.7
577 *on a provisional basis*! This is as an experimental API that
578 might be changed or removed completely in Python 3.8.
Yury Selivanov631fd382018-01-28 16:30:26 -0500579
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700580Buffered Protocols can be used with any event loop method
581that supports `Streaming Protocols`_.
Yury Selivanov631fd382018-01-28 16:30:26 -0500582
Carol Willingc9d66f02018-09-14 10:06:55 -0700583The idea of ``BufferedProtocol`` is that it allows manual allocation
584and control of the receive buffer. Event loops can then use the buffer
Yury Selivanov631fd382018-01-28 16:30:26 -0500585provided by the protocol to avoid unnecessary data copies. This
586can result in noticeable performance improvement for protocols that
Yury Selivanovdbf10222018-05-28 14:31:28 -0400587receive big amounts of data. Sophisticated protocols implementations
588can allocate the buffer only once at creation time.
Yury Selivanov631fd382018-01-28 16:30:26 -0500589
590The following callbacks are called on :class:`BufferedProtocol`
591instances:
592
Yury Selivanovdbf10222018-05-28 14:31:28 -0400593.. method:: BufferedProtocol.get_buffer(sizehint)
Yury Selivanov631fd382018-01-28 16:30:26 -0500594
Yury Selivanovdbf10222018-05-28 14:31:28 -0400595 Called to allocate a new receive buffer.
596
597 *sizehint* is a recommended minimal size for the returned
598 buffer. It is acceptable to return smaller or bigger buffers
599 than what *sizehint* suggests. When set to -1, the buffer size
600 can be arbitrary. It is an error to return a zero-sized buffer.
601
602 Must return an object that implements the
603 :ref:`buffer protocol <bufferobjects>`.
Yury Selivanov631fd382018-01-28 16:30:26 -0500604
605.. method:: BufferedProtocol.buffer_updated(nbytes)
606
607 Called when the buffer was updated with the received data.
608
609 *nbytes* is the total number of bytes that were written to the buffer.
610
611.. method:: BufferedProtocol.eof_received()
612
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700613 See the documentation of the :meth:`protocol.eof_received()
614 <Protocol.eof_received>` method.
Yury Selivanov631fd382018-01-28 16:30:26 -0500615
616
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700617:meth:`~BufferedProtocol.get_buffer` can be called an arbitrary number
618of times during a connection. However, :meth:`protocol.eof_received()
619<Protocol.eof_received>` is called at most once
620and, if called, :meth:`~BufferedProtocol.get_buffer` and
621:meth:`~BufferedProtocol.buffer_updated` won't be called after it.
Yury Selivanov631fd382018-01-28 16:30:26 -0500622
623State machine:
624
625.. code-block:: none
626
627 start -> connection_made
628 [-> get_buffer
629 [-> buffer_updated]?
630 ]*
631 [-> eof_received]?
632 -> connection_lost -> end
Victor Stinner54a231d2015-01-29 13:33:15 +0100633
634
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700635Datagram Protocols
Victor Stinner0c6f1ca2013-12-03 01:46:39 +0100636------------------
Victor Stinnerea3183f2013-12-03 01:08:00 +0100637
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700638Datagram Protocol instances should be constructed by protocol
639factories passed to the :meth:`loop.create_datagram_endpoint` method.
Victor Stinnerea3183f2013-12-03 01:08:00 +0100640
641.. method:: DatagramProtocol.datagram_received(data, addr)
642
643 Called when a datagram is received. *data* is a bytes object containing
644 the incoming data. *addr* is the address of the peer sending the data;
645 the exact format depends on the transport.
646
647.. method:: DatagramProtocol.error_received(exc)
648
649 Called when a previous send or receive operation raises an
650 :class:`OSError`. *exc* is the :class:`OSError` instance.
651
652 This method is called in rare conditions, when the transport (e.g. UDP)
653 detects that a datagram couldn't be delivered to its recipient.
654 In many conditions though, undeliverable datagrams will be silently
655 dropped.
656
Victor Stinnerea3183f2013-12-03 01:08:00 +0100657.. note::
Victor Stinnerea3183f2013-12-03 01:08:00 +0100658
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700659 On BSD systems (macOS, FreeBSD, etc.) flow control is not supported
Carol Willingc9d66f02018-09-14 10:06:55 -0700660 for datagram protocols, because it is difficult to detect easily send
661 failures caused by writing too many packets.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700662
Carol Willingc9d66f02018-09-14 10:06:55 -0700663 The socket always appears 'ready' and excess packets are dropped. An
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700664 :class:`OSError` with ``errno`` set to :const:`errno.ENOBUFS` may
665 or may not be raised; if it is raised, it will be reported to
Larry Hastings3732ed22014-03-15 21:13:56 -0700666 :meth:`DatagramProtocol.error_received` but otherwise ignored.
667
Victor Stinnerea3183f2013-12-03 01:08:00 +0100668
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700669.. _asyncio-subprocess-protocols:
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100670
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700671Subprocess Protocols
672--------------------
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100673
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700674Datagram Protocol instances should be constructed by protocol
675factories passed to the :meth:`loop.subprocess_exec` and
676:meth:`loop.subprocess_shell` methods.
677
678.. method:: SubprocessProtocol.pipe_data_received(fd, data)
679
680 Called when the child process writes data into its stdout or stderr
681 pipe.
682
683 *fd* is the integer file descriptor of the pipe.
684
685 *data* is a non-empty bytes object containing the received data.
686
687.. method:: SubprocessProtocol.pipe_connection_lost(fd, exc)
688
689 Called when one of the pipes communicating with the child process
690 is closed.
691
692 *fd* is the integer file descriptor that was closed.
693
694.. method:: SubprocessProtocol.process_exited()
695
696 Called when the child process has exited.
Victor Stinner4b4f9eb2014-01-24 17:33:20 +0100697
698
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700699Examples
700========
Victor Stinnered051592014-10-12 20:18:16 +0200701
702.. _asyncio-tcp-echo-server-protocol:
703
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700704TCP Echo Server
705---------------
Victor Stinnered051592014-10-12 20:18:16 +0200706
Carol Willingc9d66f02018-09-14 10:06:55 -0700707Create a TCP echo server using the :meth:`loop.create_server` method, send back
708received data, and close the connection::
Victor Stinnera881a7f2013-12-09 13:19:23 +0100709
710 import asyncio
711
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700712
Victor Stinnercfbea3a2014-10-12 11:30:17 +0200713 class EchoServerClientProtocol(asyncio.Protocol):
Victor Stinnera881a7f2013-12-09 13:19:23 +0100714 def connection_made(self, transport):
715 peername = transport.get_extra_info('peername')
Victor Stinnerc2721b42014-10-12 11:13:40 +0200716 print('Connection from {}'.format(peername))
Victor Stinnera881a7f2013-12-09 13:19:23 +0100717 self.transport = transport
718
719 def data_received(self, data):
Victor Stinnerc2721b42014-10-12 11:13:40 +0200720 message = data.decode()
721 print('Data received: {!r}'.format(message))
722
723 print('Send: {!r}'.format(message))
Victor Stinnera881a7f2013-12-09 13:19:23 +0100724 self.transport.write(data)
725
Victor Stinner53664342014-10-12 11:35:09 +0200726 print('Close the client socket')
Victor Stinnera881a7f2013-12-09 13:19:23 +0100727 self.transport.close()
728
Victor Stinnera881a7f2013-12-09 13:19:23 +0100729
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700730 async def main():
731 # Get a reference to the event loop as we plan to use
732 # low-level APIs.
733 loop = asyncio.get_running_loop()
Victor Stinnerc2721b42014-10-12 11:13:40 +0200734
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700735 server = await loop.create_server(
736 lambda: EchoServerClientProtocol(),
737 '127.0.0.1', 8888)
Victor Stinnera881a7f2013-12-09 13:19:23 +0100738
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700739 async with server:
740 await server.serve_forever()
741
742
743 asyncio.run(main())
744
Victor Stinnera881a7f2013-12-09 13:19:23 +0100745
Victor Stinnered051592014-10-12 20:18:16 +0200746.. seealso::
747
748 The :ref:`TCP echo server using streams <asyncio-tcp-echo-server-streams>`
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700749 example uses the high-level :func:`asyncio.start_server` function.
750
751.. _asyncio-tcp-echo-client-protocol:
752
753TCP Echo Client
754---------------
755
Carol Willingc9d66f02018-09-14 10:06:55 -0700756A TCP echo client using the :meth:`loop.create_connection` method, sends
757data, and waits until the connection is closed::
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700758
759 import asyncio
760
761
762 class EchoClientProtocol(asyncio.Protocol):
763 def __init__(self, message, on_con_lost, loop):
764 self.message = message
765 self.loop = loop
766 self.on_con_lost = on_con_lost
767
768 def connection_made(self, transport):
769 transport.write(self.message.encode())
770 print('Data sent: {!r}'.format(self.message))
771
772 def data_received(self, data):
773 print('Data received: {!r}'.format(data.decode()))
774
775 def connection_lost(self, exc):
776 print('The server closed the connection')
777 self.on_con_lost.set_result(True)
778
779
780 async def main():
781 # Get a reference to the event loop as we plan to use
782 # low-level APIs.
783 loop = asyncio.get_running_loop()
784
785 on_con_lost = loop.create_future()
786 message = 'Hello World!'
787
788 transport, protocol = await loop.create_connection(
789 lambda: EchoClientProtocol(message, on_con_lost, loop),
790 '127.0.0.1', 8888)
791
792 # Wait until the protocol signals that the connection
793 # is lost and close the transport.
794 try:
795 await on_con_lost
796 finally:
797 transport.close()
798
799
800 asyncio.run(main())
801
802
803.. seealso::
804
805 The :ref:`TCP echo client using streams <asyncio-tcp-echo-client-streams>`
806 example uses the high-level :func:`asyncio.open_connection` function.
807
808
809.. _asyncio-udp-echo-server-protocol:
810
811UDP Echo Server
812---------------
813
Carol Willingc9d66f02018-09-14 10:06:55 -0700814A UDP echo server, using the :meth:`loop.create_datagram_endpoint`
815method, sends back received data::
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700816
817 import asyncio
818
819
820 class EchoServerProtocol:
821 def connection_made(self, transport):
822 self.transport = transport
823
824 def datagram_received(self, data, addr):
825 message = data.decode()
826 print('Received %r from %s' % (message, addr))
827 print('Send %r to %s' % (message, addr))
828 self.transport.sendto(data, addr)
829
830
831 async def main():
832 print("Starting UDP server")
833
834 # Get a reference to the event loop as we plan to use
835 # low-level APIs.
836 loop = asyncio.get_running_loop()
837
838 # One protocol instance will be created to serve all
839 # client requests.
840 transport, protocol = await loop.create_datagram_endpoint(
841 lambda: EchoServerProtocol(),
842 local_addr=('127.0.0.1', 9999))
843
844 try:
845 await asyncio.sleep(3600) # Serve for 1 hour.
846 finally:
847 transport.close()
848
849
850 asyncio.run(main())
Victor Stinnered051592014-10-12 20:18:16 +0200851
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200852
853.. _asyncio-udp-echo-client-protocol:
854
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700855UDP Echo Client
856---------------
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200857
Carol Willingc9d66f02018-09-14 10:06:55 -0700858A UDP echo client, using the :meth:`loop.create_datagram_endpoint`
859method, sends data and closes the transport when it receives the answer::
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200860
861 import asyncio
862
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700863
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200864 class EchoClientProtocol:
865 def __init__(self, message, loop):
866 self.message = message
867 self.loop = loop
868 self.transport = None
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700869 self.on_con_lost = loop.create_future()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200870
871 def connection_made(self, transport):
872 self.transport = transport
873 print('Send:', self.message)
874 self.transport.sendto(self.message.encode())
875
876 def datagram_received(self, data, addr):
877 print("Received:", data.decode())
878
879 print("Close the socket")
880 self.transport.close()
881
882 def error_received(self, exc):
883 print('Error received:', exc)
884
885 def connection_lost(self, exc):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700886 print("Connection closed")
887 self.on_con_lost.set_result(True)
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200888
889
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700890 async def main():
891 # Get a reference to the event loop as we plan to use
892 # low-level APIs.
893 loop = asyncio.get_running_loop()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200894
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700895 message = "Hello World!"
896 transport, protocol = await loop.create_datagram_endpoint(
897 lambda: EchoClientProtocol(message, loop),
898 remote_addr=('127.0.0.1', 9999))
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200899
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700900 try:
901 await protocol.on_con_lost
902 finally:
903 transport.close()
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200904
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200905
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700906 asyncio.run(main())
Victor Stinnerc7edffd2014-10-12 11:24:26 +0200907
908
Victor Stinner04e6df32014-10-11 16:16:27 +0200909.. _asyncio-register-socket:
Victor Stinnera881a7f2013-12-09 13:19:23 +0100910
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700911Connecting Existing Sockets
912---------------------------
Victor Stinner04e6df32014-10-11 16:16:27 +0200913
914Wait until a socket receives data using the
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700915:meth:`loop.create_connection` method with a protocol::
Victor Stinner04e6df32014-10-11 16:16:27 +0200916
917 import asyncio
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700918 import socket
Victor Stinner04e6df32014-10-11 16:16:27 +0200919
Victor Stinner04e6df32014-10-11 16:16:27 +0200920
921 class MyProtocol(asyncio.Protocol):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700922
923 def __init__(self, loop):
924 self.transport = None
925 self.on_con_lost = loop.create_future()
Victor Stinner04e6df32014-10-11 16:16:27 +0200926
927 def connection_made(self, transport):
928 self.transport = transport
929
930 def data_received(self, data):
931 print("Received:", data.decode())
932
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700933 # We are done: close the transport;
934 # connection_lost() will be called automatically.
Victor Stinner04e6df32014-10-11 16:16:27 +0200935 self.transport.close()
936
937 def connection_lost(self, exc):
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700938 # The socket has been closed
939 self.on_con_lost.set_result(True)
Victor Stinner04e6df32014-10-11 16:16:27 +0200940
Victor Stinner04e6df32014-10-11 16:16:27 +0200941
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700942 async def main():
943 # Get a reference to the event loop as we plan to use
944 # low-level APIs.
945 loop = asyncio.get_running_loop()
Victor Stinner04e6df32014-10-11 16:16:27 +0200946
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700947 # Create a pair of connected sockets
948 rsock, wsock = socket.socketpair()
Victor Stinner04e6df32014-10-11 16:16:27 +0200949
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700950 # Register the socket to wait for data.
951 transport, protocol = await loop.create_connection(
952 lambda: MyProtocol(loop), sock=rsock)
953
954 # Simulate the reception of data from the network.
955 loop.call_soon(wsock.send, 'abc'.encode())
956
957 try:
958 await protocol.on_con_lost
959 finally:
960 transport.close()
961 wsock.close()
962
963 asyncio.run(main())
Victor Stinner04e6df32014-10-11 16:16:27 +0200964
965.. seealso::
966
967 The :ref:`watch a file descriptor for read events
968 <asyncio-watch-read-event>` example uses the low-level
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700969 :meth:`loop.add_reader` method to register an FD.
Victor Stinner04e6df32014-10-11 16:16:27 +0200970
971 The :ref:`register an open socket to wait for data using streams
972 <asyncio-register-socket-streams>` example uses high-level streams
973 created by the :func:`open_connection` function in a coroutine.
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700974
975.. _asyncio-subprocess-proto-example:
976
977loop.subprocess_exec() and SubprocessProtocol
978---------------------------------------------
979
Carol Willingc9d66f02018-09-14 10:06:55 -0700980An example of a subprocess protocol used to get the output of a
Yury Selivanov7c7605f2018-09-11 09:54:40 -0700981subprocess and to wait for the subprocess exit.
982
983The subprocess is created by th :meth:`loop.subprocess_exec` method::
984
985 import asyncio
986 import sys
987
988 class DateProtocol(asyncio.SubprocessProtocol):
989 def __init__(self, exit_future):
990 self.exit_future = exit_future
991 self.output = bytearray()
992
993 def pipe_data_received(self, fd, data):
994 self.output.extend(data)
995
996 def process_exited(self):
997 self.exit_future.set_result(True)
998
999 async def get_date():
1000 # Get a reference to the event loop as we plan to use
1001 # low-level APIs.
1002 loop = asyncio.get_running_loop()
1003
1004 code = 'import datetime; print(datetime.datetime.now())'
1005 exit_future = asyncio.Future(loop=loop)
1006
1007 # Create the subprocess controlled by DateProtocol;
1008 # redirect the standard output into a pipe.
1009 transport, protocol = await loop.subprocess_exec(
1010 lambda: DateProtocol(exit_future),
1011 sys.executable, '-c', code,
1012 stdin=None, stderr=None)
1013
1014 # Wait for the subprocess exit using the process_exited()
1015 # method of the protocol.
1016 await exit_future
1017
1018 # Close the stdout pipe.
1019 transport.close()
1020
1021 # Read the output which was collected by the
1022 # pipe_data_received() method of the protocol.
1023 data = bytes(protocol.output)
1024 return data.decode('ascii').rstrip()
1025
1026 if sys.platform == "win32":
1027 asyncio.set_event_loop_policy(
1028 asyncio.WindowsProactorEventLoopPolicy())
1029
1030 date = asyncio.run(get_date())
1031 print(f"Current date: {date}")