Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions data/async_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

import time

import platform


#################### la version séquentielle
import requests
Expand All @@ -45,6 +47,9 @@ def sequential(urls):
import asyncio
import aiohttp

if platform.system()=='Windows':
"""Solve RuntimeError: Event loop is closed in Windows"""
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

# la première version, qui imprime simplement la fin de chaque url
async def fetch(url):
Expand All @@ -71,6 +76,16 @@ async def fetch2(url, i):
# par rapport à la première variante mais ce n'est pas important
return url

# runner
async def run_fetch(args, urls):
# sans option on utilise juste fetch
if (not args.details):
print(f"Running simple mode (fetch) on {len(urls)} URLs")
await asyncio.gather(*(fetch(url) for url in urls))

else:
print(f"Running detail mode (fetch2) on {len(urls)} URLs")
await asyncio.gather(*(fetch2(url, i) for i, url in enumerate(urls)))

####################
# pour utiliser ce code directement depuis un terminal
Expand Down Expand Up @@ -99,7 +114,7 @@ def main():
args = parser.parse_args()
urls = args.urls

loop = asyncio.get_event_loop()
#loop = asyncio.get_event_loop()

# mode séquentiel
if args.sequential:
Expand All @@ -111,18 +126,11 @@ def main():
# mode asynchrone
else:

# sans option on utilise juste fetch
if (not args.details):
print(f"Running simple mode (fetch) on {len(urls)} URLs")
jobs = (fetch(url) for url in urls)
else:
print(f"Running detail mode (fetch2) on {len(urls)} URLs")
jobs = (fetch2(url, i) for i, url in enumerate(urls))
# il n'y a plus qu'à
beg = time.time()
loop.run_until_complete(asyncio.gather(*jobs))
beg = time.time()
asyncio.run(run_fetch(args, urls))
print(f"duration = {time.time()-beg}s")


if __name__ == '__main__':
main()
main()
3 changes: 1 addition & 2 deletions data/players.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ def main():
args = parser.parse_args()
players = predefined[args.groupnb]

loop = asyncio.get_event_loop()
try:
loop.run_until_complete(players.run())
asyncio.run((players.run()))
sys.exit(0)
except Exception as e:
print(f"EMERGENCY {type(e)}, {e}")
Expand Down
41 changes: 30 additions & 11 deletions w8/w8-s2-av-code.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,20 @@
font-size: 11px;
}
</style>

<h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background-color: #eee;">
<b><i>bloc-note pour copier/coller le code de la vidéo</i></b>
</h3>
<hr />
<!-- Version Python 3.10 -->
<h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background-color: #eee;">
<b><i>La vidéo a été tournée avec la 3.6, le cours a été mis à jour pour 3.10.
Il est préférable d'utiliser les fonctions asyncio de haut niveau, telles qu'asyncio.run().
Le référencement de l'objet boucle ou l'appel de ses méthodes s'adresse principalement aux auteurs de code,
de bibliothèques et de frameworks de niveau inférieur, qui ont besoin d'un contrôle plus fin du comportement de la boucle d'événement.
</i></b>
</h3>
<hr />
<blockquote>
<p>Prendre l’éditeur IDLE et faire nouveau fichier</p>
</blockquote>
Expand All @@ -23,6 +33,15 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background

print(message, &quot;fin&quot;)
return f'{message} par morceaux'

<!-- add coroutines -->
async def main():
L = await asyncio.gather(
morceaux("run 1"),
morceaux("run 2"),
)
print(L)

</code></pre>
<blockquote>
<p>Faire Save As &quot;w8s2 Vidéo.py&quot; puis F5</p>
Expand All @@ -31,13 +50,9 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background

morceaux(&quot;run&quot;)

loop = asyncio.get_event_loop()

loop.run_until_complete(morceaux(&quot;run&quot;))
asyncio.run(morceaux(&quot;run&quot;))

loop.run_until_complete(
asyncio.gather(morceaux(&quot;run1&quot;),
morceaux(&quot;run2&quot;)))
asyncio.run(main())
</code></pre>
<blockquote>
<p>Reprendre sous IDLE le fichier python et ajouter</p>
Expand All @@ -58,14 +73,18 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background

print(message, &quot;fin&quot;)
return f'{message} par famine'

async def main():
L = await asyncio.gather(
famine("run 1"),
famine("run 2"),
)
print(L)
</code></pre>
<blockquote>
<p>Faire Ctl-s puis F5</p>
</blockquote>
<pre><code>loop = asyncio.get_event_loop()

loop.run_until_complete(
asyncio.gather(famine(&quot;run1&quot;),
famine(&quot;run2&quot;)))
<pre><code>
asyncio.run(main())
</code></pre>
</div>
25 changes: 19 additions & 6 deletions w8/w8-s4-av-code.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background
<b><i>bloc-note pour copier/coller le code de la vidéo</i></b>
</h3>
<hr />
<!-- Version Python 3.10 -->
<h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background-color: #eee;">
<b><i>La vidéo a été tournée avec la 3.6, le cours a été mis à jour pour 3.10.
Il est préférable d'utiliser les fonctions asyncio de haut niveau, telles qu'asyncio.run().
Le référencement de l'objet boucle ou l'appel de ses méthodes s'adresse principalement aux auteurs de code,
de bibliothèques et de frameworks de niveau inférieur, qui ont besoin d'un contrôle plus fin du comportement de la boucle d'événement.
</i></b>
</h3>
<hr />
<blockquote>
<p>Prendre un notebook ou un éditeur python</p>
</blockquote>
Expand Down Expand Up @@ -34,6 +43,11 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background
<pre><code>import asyncio
import aiohttp
import time
import platform

if platform.system()=='Windows':
"""Solve RuntimeError: Event loop is closed in Windows"""
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

urls = [&quot;https://www.irs.gov/pub/irs-pdf/f1040.pdf&quot;,
&quot;https://www.irs.gov/pub/irs-pdf/f1040es.pdf&quot;,
Expand All @@ -57,10 +71,9 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background
<blockquote>
<p>Faire Ctl-s puis F5</p>
</blockquote>
<pre><code>loop = asyncio.get_event_loop()

<pre><code>
beg = time.time()
loop.run_until_complete(fetch_urls())
asyncio.run(fetch_urls())
print(f&quot;duration = {time.time() - beg}s&quot;)
</code></pre>
<blockquote>
Expand All @@ -74,9 +87,9 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background
print(f&quot;{i}&quot;, end=&quot;&quot;)
return url

async def run_fetch2():
await asyncio.gather(*(fetch2(url, i) for i, url in enumerate(urls)))

asyncio.get_event_loop().run_until_complete(
asyncio.gather(*(fetch2(url, i) for i, url in enumerate(urls)))
)
asyncio.run(run_fetch2())
</code></pre>
</div>
35 changes: 25 additions & 10 deletions w8/w8-s6-av-code.html
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,22 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background
await asyncio.sleep(2)
show_timer(&quot;&lt;&lt;&lt; c2&quot;)

asyncio.ensure_future(c1())
async def main():
# Il faut maintenant utiliser get_running_loop à la place de get_event_loop.
loop = asyncio.get_running_loop()
# On crée un objet future
fut = loop.create_future()
asyncio.ensure_future(c1())
await fut

start_timer()

# interrompre après 2s
try:
asyncio.get_event_loop().run_forever()
# run dans un terminal, idle, ipython. dans un notebook remplacer par await main()
# asyncio.run() crée toujours une nouvelle boucle d'événements et la ferme à la fin.
# Elle doit être utilisée comme point d'entrée principal pour les programmes asynchrones, et ne doit idéalement être appelée qu'une seule fois.
asyncio.run(main())
except KeyboardInterrupt:
print(&quot;bye&quot;)
</code></pre>
Expand All @@ -111,36 +120,42 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background
<blockquote>
<p>réinitialisation de la boucle</p>
</blockquote>
<pre><code>asyncio.set_event_loop(asyncio.new_event_loop())
<!-- Plus necessaire asyncio.run() gére.
<pre><code>asyncio.set_event_loop(asyncio.new_event_loop()) -->
</code></pre>
<blockquote>
<p>Reprendre le fichier sous IDLE ou votre éditeur python
et remplacer (après l'utilitaire) par</p>
</blockquote>
<pre><code>async def c1_stop():
<pre><code>async def c1_stop(fut):
show_timer(&quot;&gt;&gt;&gt; c1&quot;)
await asyncio.sleep(1)
show_timer(&quot;forking&quot;)
# fork
asyncio.ensure_future(c2_stop())
asyncio.ensure_future(c2_stop(fut))
await asyncio.sleep(1)
show_timer(&quot;&lt;&lt;&lt; c1&quot;)

# sera forkée par c1_stop() après une seconde
async def c2_stop():
async def c2_stop(fut):
show_timer(&quot;&gt;&gt;&gt; c2&quot;)
await asyncio.sleep(2)
show_timer(&quot;&lt;&lt;&lt; c2&quot;)
# attention c'est une méthode bloquante
asyncio.get_event_loop().stop()
# On set un résultat pour l'objet future afin de pouvoir quitter la boucle.
fut.set_result(&quot;End&quot;)

asyncio.ensure_future(c1_stop())
async def main():
loop = asyncio.get_running_loop()
fut = loop.create_future()
asyncio.ensure_future(c1_stop(fut))

print(await fut)

start_timer()

# s'arrête tout seul
try:
asyncio.get_event_loop().run_forever()
asyncio.run(main())
except KeyboardInterrupt:
print(&quot;bye&quot;)

Expand Down
40 changes: 20 additions & 20 deletions w8/w8-s7-av-code.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,32 @@ <h3 style="border: 1px solid #66b; border-radius: 5px; padding: 10px; background
<blockquote>
<p>Prendre un nouveau fichier sous IDLE ou votre éditeur python</p>
</blockquote>
<pre><code>from asyncio import (
get_event_loop, ensure_future, Task )
<pre><code>import asyncio
#Task.all_tasks() et Task.current_task() remplacées par asyncio.all_tasks() et asyncio.current_task()

async def foo():
pass

task = ensure_future(foo())
async def main():
# On crée une task avec asyncio.create_task() On peut lui donner un nom (option)
task = asyncio.create_task(foo(), name=&quot;Foo&quot;)
print(&quot;La task Foo est en attente&quot;)
print(task)
print(&quot;---------&quot;)
print(f&quot;Task Foo terminée ? : {task.done()}&quot;) #La task est terminée ?
print(&quot;---------&quot;)
print(f&quot;Task en cours :\n{asyncio.current_task()}&quot;) # retourne la task en cours.
print(&quot;---------&quot;)
tasks = asyncio.all_tasks() # retourne un set de tasks non terminées.
print(f&quot;Set des tasks non terminées :\n{tasks}&quot;)
await task
print(&quot;---------&quot;)
print(f&quot;Task Foo terminée ? : {task.done()}&quot;) #La task est terminée ?

asyncio.run(main())

</code></pre>
<blockquote>
<p>Faire Save As &quot;w8s7 Vidéo.py&quot; puis F5</p>
</blockquote>
<pre><code>task
</code></pre>
<blockquote>
<p>Reprendre le fichier sous IDLE ou votre éditeur python</p>
</blockquote>
<pre><code># attention : retourne un set
tasks = Task.all_tasks()
</code></pre>
<blockquote>
<p>Faire Ctl-s puis F5</p>
</blockquote>
<pre><code>tasks
task in tasks

# et comme on n'est pas dans la boucle
print(task.current_task())
</code></pre>
</div>
Loading