##// END OF EJS Templates
update docs about autoawait
Matthias Bussonnier -
Show More
@@ -13,8 +13,8 b' ability to run asynchronous code from the REPL. Constructs which are'
13 13 :exc:`SyntaxError` s in the Python REPL can be used seamlessly in IPython.
14 14
15 15 The example given here are for terminal IPython, running async code in a
16 notebook interface or any other frontend using the Jupyter protocol will need to
17 use a newer version of IPykernel. The details of how async code runs in
16 notebook interface or any other frontend using the Jupyter protocol need to
17 IPykernel version 5.0 or above. The details of how async code runs in
18 18 IPykernel will differ between IPython, IPykernel and their versions.
19 19
20 20 When a supported library is used, IPython will automatically allow Futures and
@@ -220,3 +220,97 b' feel free to contribute improvements to this codebase and give us feedback.'
220 220
221 221 We invite you to thoroughly test this feature and report any unexpected behavior
222 222 as well as propose any improvement.
223
224 Using Autoawait in a notebook (IPykernel)
225 =========================================
226
227 Update ipykernel to version 5.0 or greater::
228
229 pip install ipykernel ipython --upgrade
230 # or
231 conda install ipykernel ipython --upgrade
232
233 This should automatically enable ``autoawait`` integration. Unlike terminal
234 IPython all code run on ``asynio`` eventloop, so creating a loop by hand will
235 not work, including with magics like ``%run`` or other framework that create
236 the eventloop themselves. In case like this you can try to use projects like
237 `nest_asyncio <https://github.com/erdewit/nest_asyncio>`_ and see discussion like `this one
238 <https://github.com/jupyter/notebook/issues/3397#issuecomment-419386811>`_
239
240 Difference between terminal IPython and IPykernel
241 =================================================
242
243 The exact asynchronous code running behavior can varies between Terminal
244 IPython and IPykernel. The root cause of this behavior is due to IPykernel
245 having a _persistent_ ``asyncio`` loop running, while Terminal IPython start
246 and stop a loop for each code block. This can lead to surprising behavior in
247 some case if you are used to manipulate asyncio loop yourself, see for example
248 :ghissue:`11303` for a longer discussion but here are some of the astonishing
249 cases.
250
251 This behavior is an implementation detail, and should not be relied upon. It
252 can change without warnings in future versions of IPython.
253
254 In terminal IPython a loop is started for each code blocks only if there is top
255 level async code::
256
257 $ ipython
258 In [1]: import asyncio
259 ...: asyncio.get_event_loop()
260 Out[1]: <_UnixSelectorEventLoop running=False closed=False debug=False>
261
262 In [2]:
263
264 In [2]: import asyncio
265 ...: await asyncio.sleep(0)
266 ...: asyncio.get_event_loop()
267 Out[2]: <_UnixSelectorEventLoop running=True closed=False debug=False>
268
269 See that ``running`` is ``True`` only in the case were we ``await sleep()``
270
271 In a Notebook, with ipykernel the asyncio eventloop is always running::
272
273 $ jupyter notebook
274 In [1]: import asyncio
275 ...: loop1 = asyncio.get_event_loop()
276 ...: loop1
277 Out[1]: <_UnixSelectorEventLoop running=True closed=False debug=False>
278
279 In [2]: loop2 = asyncio.get_event_loop()
280 ...: loop2
281 Out[2]: <_UnixSelectorEventLoop running=True closed=False debug=False>
282
283 In [3]: loop1 is loop2
284 Out[3]: True
285
286 In Terminal IPython background task are only processed while the foreground
287 task is running, and IIF the foreground task is async::
288
289 $ ipython
290 In [1]: import asyncio
291 ...:
292 ...: async def repeat(msg, n):
293 ...: for i in range(n):
294 ...: print(f"{msg} {i}")
295 ...: await asyncio.sleep(1)
296 ...: return f"{msg} done"
297 ...:
298 ...: asyncio.ensure_future(repeat("background", 10))
299 Out[1]: <Task pending coro=<repeat() running at <ipython-input-1-02d0ef250fe7>:3>>
300
301 In [2]: await asyncio.sleep(3)
302 background 0
303 background 1
304 background 2
305 background 3
306
307 In [3]: import time
308 ...: time.sleep(5)
309
310 In [4]: await asyncio.sleep(3)
311 background 4
312 background 5
313 background 6
314
315 In a Notebook, QtConsole, or any other frontend using IPykernel, background
316 task should behave as expected.
General Comments 0
You need to be logged in to leave comments. Login now