Slide 1

Slide 1 text

ASGI アプリケーション⼊⾨ Junya Fukuda PyConJP 2021 こわくないasyncio基礎と⾮同期IO FastAPIを例に

Slide 2

Slide 2 text

•෱ా ൏໵ʢJunya Fukudaʣʢ@JunyaFffʣ •גࣜձࣾ೔ຊγεςϜٕݚʢJSLʣॴଐ ௕໺ݝͷձࣾ •WebΤϯδχΞ •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ •Effective Python ͷಡॻձ΍ͬͯ·͢ 📚 •ʢ͓͠͝ͱͰʣόϦϡʔϒοΫε •ຊ޷͖ʹѪ͞ΕΔαʔϏεΛ໨ࢦͯ͠ʢݹຊങऔɾൢചʣ ΪʔΫϥϘ௕໺ಡॻձ •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ

Slide 3

Slide 3 text

ΪʔΫϥϘ௕໺OPUF •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ •εϙϯαʔάοζ •γϧΫεΫϦʔϯͰख࡮ΓʂΦϯε૿͠ΊͷϏοΫγϧΤοτ •IT΋ͦΕҎ֎ͷ΋ͷͮ͘Γ΋΍ͬͯΔίϫʔΩϯάεϖʔε •ϒʔεʹ͖ͯ߹ݴ༿Λฉ͍ͯܠ඼Λਃ͠ࠐΜͰͶʂ •എ໘͸Zen of Pythonʂେࣄͳ͜ͱΛϢʔϞΞަ͑ͯഎෛͬͯΈͯ͸ʁ

Slide 4

Slide 4 text

Python実践 •2022೥1݄ൃച༧ఆ •ϖʔδ਺: ະఆ •ֹۚ: ະఆ •PythonΤϯδχΞҭ੒ਪਐڠձ؂म •ʮPythonϥΠϒϥϦݫબϨγϐʯΛେ෯ʹՃචɺվగ!!!

Slide 5

Slide 5 text

みなさんPythonで Webやっていますか?✋

Slide 6

Slide 6 text

JetBrains 2020年の調査 https://www.jetbrains.com/ja-jp/lp/devecosystem-2020/python/

Slide 7

Slide 7 text

JetBrains 2020年の調査 https://www.jetbrains.com/ja-jp/lp/devecosystem-2020/python/

Slide 8

Slide 8 text

JetBrains 2020年の調査 https://www.jetbrains.com/ja-jp/lp/devecosystem-2020/python/

Slide 9

Slide 9 text

JetBrains 2020年の調査 https://www.jetbrains.com/ja-jp/lp/devecosystem-2020/python/ 2019 Django 3 Ͱ ASGIରԠ 2021 Flask 2 Ͱ asyncioରԠ ASGIରԠ

Slide 10

Slide 10 text

JetBrains 2020年の調査 https://www.jetbrains.com/ja-jp/lp/devecosystem-2020/python/ 2019 Django 3 Ͱ ASGIରԠ 2021 Flask 2 Ͱ asyncioରԠ ASGIରԠ

Slide 11

Slide 11 text

JetBrains 2020年の調査 https://www.jetbrains.com/ja-jp/lp/devecosystem-2020/python/

Slide 12

Slide 12 text

JetBrains 2020年の調査 https://www.jetbrains.com/ja-jp/lp/devecosystem-2020/python/

Slide 13

Slide 13 text

って

Slide 14

Slide 14 text

って •PythonͷWeb ϑϨʔϜϫʔΫ

Slide 15

Slide 15 text

って •PythonͷWeb ϑϨʔϜϫʔΫ •tiangolo ࢯʹΑΔOSS

Slide 16

Slide 16 text

って •PythonͷWeb ϑϨʔϜϫʔΫ •ߴύϑΥʔϚϯεɾߴ଎ͳίʔσΟϯάɾগͳ͍όάɾ௚ײతɾ؆୯ɾ୹͍ɾݎ࿚ੑ ✨ •tiangolo ࢯʹΑΔOSS

Slide 17

Slide 17 text

って 2018-12-12 2019-04-19 2019-08-26 2020-01-01 2020-05-08 2020-09-13 2021-01-20 2021-05-28 2021-10-03 Time 0 4700 9300 13900 18500 23200 27800 32400 37000 Stargazers •ελʔ਺ͷભҠ https://starchart.cc/tiangolo/fastapi

Slide 18

Slide 18 text

って •PythonͷWeb ϑϨʔϜϫʔΫ •σʔλ෦ɿPydantic Web෦෼ɿStarlette •tiangolo ࢯʹΑΔOSS •ߴύϑΥʔϚϯεɾߴ଎ͳίʔσΟϯάɾগͳ͍όάɾ௚ײతɾ؆୯ɾ୹͍ɾݎ࿚ੑ ✨

Slide 19

Slide 19 text

って •PythonͷWeb ϑϨʔϜϫʔΫ •tiangolo ࢯʹΑΔOSS •ܕώϯτɾOpenAPIʢSwaggerʣ •ߴύϑΥʔϚϯεɾߴ଎ͳίʔσΟϯάɾগͳ͍όάɾ௚ײతɾ؆୯ɾ୹͍ɾݎ࿚ੑ ✨ •σʔλ෦ɿPydantic Web෦෼ɿStarlette https://fastapi.tiangolo.com/

Slide 20

Slide 20 text

•ߴύϑΥʔϚϯε って •PythonͷWeb ϑϨʔϜϫʔΫ •tiangolo ࢯʹΑΔOSS •ܕώϯτɾOpenAPIʢSwaggerʣ •ߴύϑΥʔϚϯεɾߴ଎ͳίʔσΟϯάɾগͳ͍όάɾ௚ײతɾ؆୯ɾ୹͍ɾݎ࿚ੑ ✨ •σʔλ෦ɿPydantic Web෦෼ɿStarlette

Slide 21

Slide 21 text

って •ߴύϑΥʔϚϯε

Slide 22

Slide 22 text

って •Fast: Very high performance, on par with NodeJS and Go ʢߴ଎: NodeJS ΍ Go ฒΈͷͱͯ΋ߴ͍ύϑΥʔϚϯεʣ https://fastapi.tiangolo.com/ •ߴύϑΥʔϚϯε

Slide 23

Slide 23 text

って •Fast: Very high performance, on par with NodeJS and Go ʢߴ଎: NodeJS ΍ Go ฒΈͷͱͯ΋ߴ͍ύϑΥʔϚϯεʣ https://fastapi.tiangolo.com/ •ߴύϑΥʔϚϯε •͍Ζ͍Ζͳ֯౓͕͋Δ

Slide 24

Slide 24 text

って •Fast: Very high performance, on par with NodeJS and Go ʢߴ଎: NodeJS ΍ Go ฒΈͷͱͯ΋ߴ͍ύϑΥʔϚϯεʣ https://fastapi.tiangolo.com/ •ߴύϑΥʔϚϯε •͍Ζ͍Ζͳ֯౓͕͋Δ - ڞ௨͢Δͷ͸ඇಉظϓϩάϥϛϯά

Slide 25

Slide 25 text

って •Fast: Very high performance, on par with NodeJS and Go ʢߴ଎: NodeJS ΍ Go ฒΈͷͱͯ΋ߴ͍ύϑΥʔϚϯεʣ https://fastapi.tiangolo.com/ •ߴύϑΥʔϚϯε •͍Ζ͍Ζͳ֯౓͕͋Δ - ڞ௨͢Δͷ͸ඇಉظϓϩάϥϛϯά •FastAPIͬͯඇಉظʁ

Slide 26

Slide 26 text

って •Fast: Very high performance, on par with NodeJS and Go ʢߴ଎: NodeJS ΍ Go ฒΈͷͱͯ΋ߴ͍ύϑΥʔϚϯεʣ https://fastapi.tiangolo.com/ •ߴύϑΥʔϚϯε •͍Ζ͍Ζͳ֯౓͕͋Δ - ڞ௨͢Δͷ͸ඇಉظϓϩάϥϛϯά •FastAPIͬͯඇಉظʁ •Webͷ෦෼͸ɺStarlette

Slide 27

Slide 27 text

って •Fast: Very high performance, on par with NodeJS and Go ʢߴ଎: NodeJS ΍ Go ฒΈͷͱͯ΋ߴ͍ύϑΥʔϚϯεʣ https://fastapi.tiangolo.com/ •ߴύϑΥʔϚϯε •͍Ζ͍Ζͳ֯౓͕͋Δ - ڞ௨͢Δͷ͸ඇಉظϓϩάϥϛϯά •FastAPIͬͯඇಉظʁ •Webͷ෦෼͸ɺStarlette = ASGIରԠͷWeb FW ASGIରԠ

Slide 28

Slide 28 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ って? ASGIରԠ

Slide 29

Slide 29 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ って? ASGIରԠ

Slide 30

Slide 30 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ って? ASGIରԠ •WSGI •αʔόɿGunicorn uWSGI ϑϨʔϜϫʔΫɿDjango, Flask, Pyramid

Slide 31

Slide 31 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ って? ASGIରԠ •WSGI •αʔόɿGunicorn uWSGI ⁶ ϑϨʔϜϫʔΫɿDjango, Flask, Pyramid

Slide 32

Slide 32 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ •WSGI って? ASGIରԠ •αʔόɿGunicorn uWSGI ⁶ ϑϨʔϜϫʔΫɿDjango, Flask, Pyramid

Slide 33

Slide 33 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ •WSGI って? ASGIରԠ •αʔόɿGunicorn uWSGI ⁶ ϑϨʔϜϫʔΫɿDjango, Flask, Pyramid •ASGI •αʔόɿUvicorn, Hypercorn ϑϨʔϜϫʔΫɿDjango, FastAPI, Starlette

Slide 34

Slide 34 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ •WSGI って? ASGIରԠ •αʔόɿGunicorn uWSGI ⁶ ϑϨʔϜϫʔΫɿDjango, Flask, Pyramid •ASGI •αʔόɿUvicorn, Hypercorn ⁶ ϑϨʔϜϫʔΫɿDjango, FastAPI, Starlette

Slide 35

Slide 35 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ •WSGI って? ASGIରԠ •αʔόɿGunicorn uWSGI ⁶ ϑϨʔϜϫʔΫɿDjango, Flask, Pyramid •ASGI •αʔόɿUvicorn, Hypercorn ⁶ ϑϨʔϜϫʔΫɿDjango, FastAPI, Starlette

Slide 36

Slide 36 text

•WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ •WSGI って? ASGIରԠ •αʔόɿGunicorn uWSGI ⁶ ϑϨʔϜϫʔΫɿDjango, Flask, Pyramid •ASGI •αʔόɿUvicorn, Hypercorn ⁶ ϑϨʔϜϫʔΫɿDjango, FastAPI, Starlette •WSGIͱASGIɺͳʹ͕ҧ͏ͷ͔

Slide 37

Slide 37 text

WSGI

Slide 38

Slide 38 text

WSGI Web Server Gateway Interface

Slide 39

Slide 39 text

WSGI Web Server Gateway Interface ASGI

Slide 40

Slide 40 text

WSGI Web Server Gateway Interface ASGI Asynchronous Server Gateway Interface

Slide 41

Slide 41 text

WSGI Web Server Gateway Interface ASGI Asynchronous Server Gateway Interface

Slide 42

Slide 42 text

WSGI Web Server Gateway Interface ASGI Asynchronous Server Gateway Interface ⾮同期

Slide 43

Slide 43 text

WSGI Web Server Gateway Interface ASGI Asynchronous Server Gateway Interface ⾮同期 ASGI= asyncio

Slide 44

Slide 44 text

ASGI対応 •WebαʔόͱϑϨʔϜϫʔΫΛͭͳ͙ɺ࢓༷ •WSGIͷਫ਼ਆతޙܧ •Gunicorn ΍ uWSGI ⁶ Django ΍ Flask, Pyramid •Uvicorn ΍ Hypercorn ⁶ Django ΍ FastAPI, Starlette って? asyncioに対応したインターフェース仕様

Slide 45

Slide 45 text

本⽇のおしながき •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ

Slide 46

Slide 46 text

本⽇のおしながき •ASGIΞϓϦέʔγϣϯΛ࢖ͬͨasyncioͷ࢖͍ॴ •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ

Slide 47

Slide 47 text

本⽇のおしながき •ASGIΞϓϦέʔγϣϯΛ࢖ͬͨasyncioͷ࢖͍ॴ •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ •ʢFastAPIˍasyncpgΛྫʹʣ

Slide 48

Slide 48 text

•asyncio͜Θ͍ͳ͋… •ASGIϑϨʔϜϫʔΫͬͯ݁ہͳʹ͕͓͍͍͠ͷ…

Slide 49

Slide 49 text

•asyncio͜Θ͍ͳ͋… •ASGIϑϨʔϜϫʔΫͬͯ݁ہͳʹ͕͓͍͍͠ͷ… •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ΋ 👋

Slide 50

Slide 50 text

•asyncio͜Θ͍ͳ͋… •ASGIϑϨʔϜϫʔΫͬͯ݁ہͳʹ͕͓͍͍͠ͷ… •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ΋ 👋 •ASGIΞϓϦͷಋೖΛݕ౼ͯ͠ΈΑʂ

Slide 51

Slide 51 text

•asyncio͜Θ͍ͳ͋… •ASGIϑϨʔϜϫʔΫͬͯ݁ہͳʹ͕͓͍͍͠ͷ… •asyncio ͪΐͬͱා͘ͳ͘ͳ͔ͬͨ΋ 👋 •ASGIΞϓϦͷಋೖΛݕ౼ͯ͠ΈΑʂ

Slide 52

Slide 52 text

すべてはasync/awaitから始まった

Slide 53

Slide 53 text

> IUUQT fl PSJNPOEEFWCMPHBSUJDMFTJOUSPEVDUJPOUPBTHJBTZODQZUIPOXFC すべてはasync/awaitから始まった

Slide 54

Slide 54 text

asyncioはこわくない

Slide 55

Slide 55 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ asyncioはこわくない

Slide 56

Slide 56 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない

Slide 57

Slide 57 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない

Slide 58

Slide 58 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ

Slide 59

Slide 59 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO

Slide 60

Slide 60 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ࠓ೥RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷॳظͷϦϑΝϨϯεత࣮૷ aioquic

Slide 61

Slide 61 text

asyncio めっちゃこわい

Slide 62

Slide 62 text

•͜Θ͔ͬͨ asyncio めっちゃこわい

Slide 63

Slide 63 text

•͜Θ͔ͬͨ •Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣ asyncio めっちゃこわい •2ͭͷग़ձ͍ https://www.oreilly.com/library/view/using-asyncio-in/9781492075325/

Slide 64

Slide 64 text

•͜Θ͔ͬͨ •Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣ asyncio めっちゃこわい •2ͭͷग़ձ͍ https://www.oreilly.com/library/view/using-asyncio-in/9781492075325/ https://blog.jrfk.dev/posts/using-asyncio-in-python/

Slide 65

Slide 65 text

•͜Θ͔ͬͨ •ίϧʔνϯ͸ා͘ͳ͍ - Minimum Viable Programmer ʢϒϩάʣ •Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣ asyncio めっちゃこわい •2ͭͷग़ձ͍

Slide 66

Slide 66 text

•͜Θ͔ͬͨ •ίϧʔνϯ͸ා͘ͳ͍ - Minimum Viable Programmer ʢϒϩάʣ •Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣ asyncio めっちゃこわい •2ͭͷग़ձ͍ •࣮૷Ͱ஌Δasyncio -Πϕϯτϧʔϓͷਖ਼ମͱ͸ - REI SUYAMA ͞Μ •DAY2 - 10.16(SAT) 16:20 - #pyconjp_2

Slide 67

Slide 67 text

•͜Θ͔ͬͨ •ίϧʔνϯ͸ා͘ͳ͍ - Minimum Viable Programmer ʢϒϩάʣ •Using Asyncio in Python - ΦϥΠϦʔ ʢ🐸ຊʣ asyncio めっちゃこわい •2ͭͷग़ձ͍ •࣮૷Ͱ஌Δasyncio -Πϕϯτϧʔϓͷਖ਼ମͱ͸ - REI SUYAMA ͞Μ •DAY2 - 10.16(SAT) 16:20 - #pyconjp_2

Slide 68

Slide 68 text

•asyncio ͸௒ڊେ 対象はアプリーケーション開発者向けのasyncio

Slide 69

Slide 69 text

•asyncio ͸௒ڊେ •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ 対象はアプリーケーション開発者向けのasyncio

Slide 70

Slide 70 text

•asyncio ͸௒ڊେ •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ 対象はアプリーケーション開発者向けのasyncio

Slide 71

Slide 71 text

•asyncio ͸௒ڊେ •ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ։ൃऀ޲͚ͷػೳ͸ͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏ •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ 対象はアプリーケーション開発者向けのasyncio

Slide 72

Slide 72 text

•asyncio ͸௒ڊେ •ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ։ൃऀ޲͚ͷػೳ͸ͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏ •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ 対象はアプリーケーション開発者向けのasyncio •ΞϓϦέʔγϣϯ։ൃऀ޲͚Λର৅ʹͨ͠asyncio

Slide 73

Slide 73 text

•asyncio ͸௒ڊେ •ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ։ൃऀ޲͚ͷػೳ͸ͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏ •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ •ΞϓϦέʔγϣϯ։ൃऀ޲͚Λର৅ʹͨ͠asyncio •લఏ஌ࣝͱͯ͠ݴ༿ͷઆ໌ͱɺasyncioͰΘͨͨͪ͠ʹͱͬͯඞཁͳ͜ͱ 対象はアプリーケーション開発者向けのasyncio

Slide 74

Slide 74 text

•asyncio ͸௒ڊେ •ϑϨʔϜϫʔΫ΍ϥΠϒϥϦ։ൃऀ޲͚ͷػೳ͸ͪΐͬͱ͓͍͓͖ͯ·͠ΐ͏ •Θͨͨͪ͠͸ΞϓϦέʔγϣϯ։ൃऀ •ެࣜυΩϡϝϯτ΋ߴϨϕϧ APIͱ௿ϨϕϧAPIʹ෼͔ΕͯΔ •ΞϓϦέʔγϣϯ։ൃऀ޲͚Λର৅ʹͨ͠asyncio •લఏ஌ࣝͱͯ͠ݴ༿ͷઆ໌ͱɺasyncioͰΘͨͨͪ͠ʹͱͬͯඞཁͳ͜ͱ 対象はアプリーケーション開発者向けのasyncio

Slide 75

Slide 75 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic

Slide 76

Slide 76 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic

Slide 77

Slide 77 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic

Slide 78

Slide 78 text

⾔葉を完全に理解する

Slide 79

Slide 79 text

IUUQTEPDTQZUIPOPSHKBMJCSBSZBTZODJPIUNM

Slide 80

Slide 80 text

前提知識 並⾏処理

Slide 81

Slide 81 text

前提知識 並⾏処理 並列処理

Slide 82

Slide 82 text

前提知識 並⾏処理 並列処理 逐次処理

Slide 83

Slide 83 text

前提知識 並⾏処理 並列処理 逐次処理 タスクの処理

Slide 84

Slide 84 text

前提知識 並⾏処理 concurrent processing

Slide 85

Slide 85 text

前提知識 並⾏処理 concurrent processing 複数の処理を同時に実⾏するという意味

Slide 86

Slide 86 text

前提知識 並⾏処理 concurrent processing 複数の処理を同時に実⾏するという意味 イメージ重視

Slide 87

Slide 87 text

前提知識 並⾏処理 ฒߦॲཧͱͦͷ۩ମతͳॲཧํࣜͷͭͰ͋Δฒྻॲཧ͸ɺ ιϑτ΢ΣΞ޻ֶͷ෼໺ʹ͓͍ͯ΋ͬͱ΋෯޿͍τϐοΫͷͭͰ͢ɻ ਺े࡭ͷຊΛ΋ͬͯͯ͠΋ɺฒߦॲཧʹ͓͍ͯॏཁͳϙΠϯτ΍ ฒߦॲཧϞσϧʹؔͯ͠े෼ͳٞ࿦͸Ͱ͖ͳ͍Ͱ͠ΐ͏ɻ https://www.kadokawa.co.jp/product/302105001236/ ΤΩεύʔτ1ZUIPOϓϩάϥϛϯάվగ൛ ൃച

Slide 88

Slide 88 text

前提知識 並⾏処理 https://www.oreilly.co.jp/books/9784873119595/ 並⾏コンピューティング技法 ――実践マルチコア/マルチスレッドプログラミング 並⾏プログラミング⼊⾨ ――Rust、C、アセンブリによる実装からのアプローチ https://www.oreilly.co.jp/books/9784873114354/

Slide 89

Slide 89 text

イメージ重視

Slide 90

Slide 90 text

並⾏処理 並列処理 逐次処理

Slide 91

Slide 91 text

並⾏処理 並列処理 逐次処理

Slide 92

Slide 92 text

並⾏処理 並列処理 逐次処理

Slide 93

Slide 93 text

並⾏処理 並列処理 通常の関数を呼び出していく処理 逐次処理

Slide 94

Slide 94 text

並⾏処理 並列処理 通常の関数を呼び出していく処理 multiprocessingモジュール 逐次処理

Slide 95

Slide 95 text

並⾏処理 並列処理 通常の関数を呼び出していく処理 multiprocessingモジュール threadingモジュール asyncioモジュール 逐次処理

Slide 96

Slide 96 text

ちょっとわかりにくいので レストラン🍽に例えます

Slide 97

Slide 97 text

レストラン

Slide 98

Slide 98 text

レストラン どんなタスクが あるでしょうか

Slide 99

Slide 99 text

注⽂をとる

Slide 100

Slide 100 text

料理を作る 注⽂をとる

Slide 101

Slide 101 text

料理を作る 注⽂をとる 料理を運ぶ

Slide 102

Slide 102 text

逐次処理

Slide 103

Slide 103 text

注⽂を取る - 料理を作る - 料理を運ぶ 逐次処理

Slide 104

Slide 104 text

注⽂を取る - 料理を作る - 料理を運ぶ 完了してから次のタスク 逐次処理

Slide 105

Slide 105 text

並列処理

Slide 106

Slide 106 text

並列処理 注⽂を取る 料理を作る 料理を運ぶ

Slide 107

Slide 107 text

並列処理 注⽂を取る 料理を作る 料理を運ぶ 複数のタスクを同時に着⼿する

Slide 108

Slide 108 text

並⾏処理

Slide 109

Slide 109 text

並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ

Slide 110

Slide 110 text

並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ

Slide 111

Slide 111 text

並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド

Slide 112

Slide 112 text

並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ

Slide 113

Slide 113 text

並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ 同じ⼈

Slide 114

Slide 114 text

並⾏処理 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔

Slide 115

Slide 115 text

asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた

Slide 116

Slide 116 text

asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた お客様

Slide 117

Slide 117 text

asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた お客様 ←注⽂

Slide 118

Slide 118 text

asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた 考え中のお客様 ←注⽂待ち

Slide 119

Slide 119 text

asyncio シングルスレッド = ワンオペ どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた 考え中のお客様 ←注⽂待ち あなたから⾒て、 外部のお客様、から 注⽂という ⼊⼒を待つ状態

Slide 120

Slide 120 text

asyncio どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた 考え中のお客様 ←注⽂待ち あなたから⾒て、 外部のお客様、から 注⽂という ⼊⼒を待つ状態

Slide 121

Slide 121 text

a どのタイミングでタスクの切り替えをするのでしょうか 🤔 あなた 考え中のお客様 ←注⽂待ち あなたから⾒て、 外部のお客様、から 注⽂という ⼊⼒を待つ状態 ⾮同期IO syncio

Slide 122

Slide 122 text

a sync io

Slide 123

Slide 123 text

a sync io ⼊⼒

Slide 124

Slide 124 text

a sync io 同期 ⼊⼒

Slide 125

Slide 125 text

a sync io しない 同期 ⼊⼒

Slide 126

Slide 126 text

asyncio ⾮同期IO

Slide 127

Slide 127 text

asyncio ⾮同期IO

Slide 128

Slide 128 text

asyncio ⾮同期IO

Slide 129

Slide 129 text

•Python 3.4 Ͱ ௥Ճ͞Εͨඪ४ϥΠϒϥϦ •Python 3.6 Ͱ ඇಉظδΣωϨʔλʔ / ඇಉظ಺แදه •Python 3.5 Ͱ async/await ߏจ asyncioはこわくない こわい •ฒߦॲཧͷ ίʔυΛॻͨ͘ΊͷϥΠϒϥϦ •γϯάϧεϨουͰΠϕϯτϧʔϓͰඇಉظ IO •ઌ೔RFCͰඪ४Խ͞ΕͨWebن֨ QUIC ͷϦϑΝϨϯεత࣮૷ aioquic γϯάϧεϨου ฒߦॲཧ ඇಉظ IO

Slide 130

Slide 130 text

ฒߦॲཧ asyncioの周辺はちょっとこわくない γϯάϧεϨου ඇಉظ IO

Slide 131

Slide 131 text

ฒߦॲཧ asyncioの周辺はちょっとこわくない γϯάϧεϨου ඇಉظ IO

Slide 132

Slide 132 text

ฒߦॲཧ asyncioの周辺はちょっとこわくない γϯάϧεϨου ඇಉظ IO ϫϯΦϖ

Slide 133

Slide 133 text

ฒߦॲཧ asyncioの周辺はちょっとこわくない γϯάϧεϨου ඇಉظ IO ϫϯΦϖ 外部のお客様、から 注⽂という ⼊⼒を待たないで他のことする

Slide 134

Slide 134 text

asyncio

Slide 135

Slide 135 text

asyncio🌷

Slide 136

Slide 136 text

asyncio で 覚えておくことは3つ asyncio

Slide 137

Slide 137 text

イベントループ

Slide 138

Slide 138 text

コルーチン イベントループ

Slide 139

Slide 139 text

コルーチン イベントループ タスク

Slide 140

Slide 140 text

コルーチン イベントループ タスク → やること

Slide 141

Slide 141 text

コルーチン イベントループ タスク → やること → やること+実⾏状態をもつ

Slide 142

Slide 142 text

コルーチン イベントループ タスク → やること → やることを管理するもの → やること+実⾏状態をもつ

Slide 143

Slide 143 text

コルーチン イベントループ タスク → やること → やることを管理するもの → やること+実⾏状態をもつ

Slide 144

Slide 144 text

レストラン

Slide 145

Slide 145 text

注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio

Slide 146

Slide 146 text

注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ asyncio コルーチンやタスク

Slide 147

Slide 147 text

asyncio 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ 注⽂を取る - 料理を作る - 料理を運ぶ コルーチンやタスク

Slide 148

Slide 148 text

asyncio 注⽂を取 注⽂を取 注⽂を取 コ

Slide 149

Slide 149 text

asyncio イベントループ 注⽂を取 注⽂を取 注⽂を取 コ

Slide 150

Slide 150 text

asyncio イベントループ (あくまでイメージ) 注⽂を取 注⽂を取 注⽂を取 コ

Slide 151

Slide 151 text

コルーチン イベントループ タスク

Slide 152

Slide 152 text

コルーチン イベントループ タスク

Slide 153

Slide 153 text

•ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ コルーチン

Slide 154

Slide 154 text

•ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ コルーチン •Co-routine ͱॻ͘

Slide 155

Slide 155 text

•ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ コルーチン •Co-routine ͱॻ͘ •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ

Slide 156

Slide 156 text

•ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ コルーチン •Co-routine ͱॻ͘ •ؔ਺ͷఆٛʹ async Λ͚ͭΔ ɺதஅͯ͠࠶։͢Δͱ͜Ζʹ await •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ

Slide 157

Slide 157 text

•ίϧʔνϯͱ͸ɺϧʔνϯʢ޿͍ҙຯͰͷؔ਺ʣͷҰछ コルーチン •Co-routine ͱॻ͘ •ؔ਺ͷఆٛʹ async Λ͚ͭΔ ɺதஅͯ͠࠶։͢Δͱ͜Ζʹ await • asyncio Λ࢖͏্Ͱͷجຊͷ͖ •ॲཧΛ్தͰதஅͯ͠࠶։Ͱ͖Δϧʔνϯ

Slide 158

Slide 158 text

考え中のお客様

Slide 159

Slide 159 text

関数を定義 def customers_thinking_order(): ... # ॲཧ

Slide 160

Slide 160 text

def customers_long_thinking_order(): ... # ࣌ؒͷ͔͔Δॲཧ コルーチンを定義 async •async Λ͚ͭΔ͚ͩ •͍ͭ͜͸ίϧʔνϯؔ਺ʹͳΔ •def Ͱఆٛͨؔ͠਺ͱ΄΅มΘΒͳ͍

Slide 161

Slide 161 text

async def customers_long_thinking_order(): asyncio.sleep(10000) return “͟Δͦ͹” 時間のかかる処理にawait await •࣌ؒͷ͔͔ΔॲཧʹawaitΛ͚ͭΔ •͔ͦ͜Βதஅͱ࠶։͢Δ •await Λ͚ͭΔ͜ͱ͕Ͱ͖Δͷ͸ɺίϧʔνϯ΍λεΫʢͳͲʣ

Slide 162

Slide 162 text

関数を実⾏ def customers_long_thinking_order(): time.sleep(10000) return “͟Δͦ͹” >>> print(customers_long_thinking_order()) ͟Δͦ͹ # ௕ߟͷͷͪ

Slide 163

Slide 163 text

def customers_long_thinking_order(): await asyncio.sleep(10000) return “͟Δͦ͹” コルーチンを実⾏ >>> print(customers_long_thinking_order()) async

Slide 164

Slide 164 text

コルーチンを実⾏ >>> print(customers_long_thinking_order()) def customers_long_thinking_order(): await asyncio.sleep(10000) return “͟Δͦ͹” async

Slide 165

Slide 165 text

コルーチンを実⾏ >>> print(customers_long_thinking_order()) ݁ՌΛड͚औΕͳ͍ def customers_long_thinking_order(): await asyncio.sleep(10000) return “͟Δͦ͹” async

Slide 166

Slide 166 text

コルーチン イベントループ タスク

Slide 167

Slide 167 text

asyncio イベントループ 注⽂を取 注⽂を取 注⽂を取 コ (あくまでイメージ)

Slide 168

Slide 168 text

•C10K໰୊΁ͷճ౴ •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ イベントループ

Slide 169

Slide 169 text

•C10K໰୊΁ͷճ౴ •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ •ίϧʔνϯ΍λεΫΛεέδϡʔϦϯά イベントループ

Slide 170

Slide 170 text

•C10K໰୊΁ͷճ౴ •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷ࢓૊Έ •ίϧʔνϯ΍λεΫΛεέδϡʔϦϯά イベントループ

Slide 171

Slide 171 text

•C10K໰୊΁ͷճ౴ •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷ࢓૊Έ •ͦ͜·Ͱҙࣝ͠ͳͯ͘΋ྑ͍ʢͦ͜ʹ͍Δ͜ͱ͸஌ͬͯͯʣ •ίϧʔνϯ΍λεΫΛεέδϡʔϦϯά イベントループ

Slide 172

Slide 172 text

•C10K໰୊΁ͷճ౴ •libuv(nodejs)ͷத֩Λͳ͢࢓૊Έ •ڠௐͯ͠ฒߦʹ࣮ߦ͢ΔͨΊͷ࢓૊Έ •ͦ͜·Ͱҙࣝ͠ͳͯ͘΋ྑ͍ʢͦ͜ʹ͍Δ͜ͱ͸஌ͬͯͯʣ •ίϧʔνϯ΍λεΫΛεέδϡʔϦϯά イベントループ •asyncio ͷத֩Λͳ͢࢓૊Έ

Slide 173

Slide 173 text

•Python 3.7 Ͱ௥Ճ͞Εͨ asyncio.run() イベントループ •ΠϕϯτϧʔϓΛ࡞Δ •λεΫ͕ऴΘͬͨΒ࡟আͯ͘͠ΕΔ •asyncio.run(corutine) Λड͚औΔ͜ͱ͕Ͱ͖Δ

Slide 174

Slide 174 text

async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” イベントループを作る

Slide 175

Slide 175 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹”

Slide 176

Slide 176 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

Slide 177

Slide 177 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ ͝஫จ͸ʁ ͪΐͬͱ଴ͬͯͶ

Slide 178

Slide 178 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ ͝஫จ͸ʁ ͪΐͬͱ଴ͬͯͶ # …௕ߟͷͷͪ 😴

Slide 179

Slide 179 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ ͝஫จ͸ʁ ͪΐͬͱ଴ͬͯͶ ͟Δͦ͹ # ίϧʔνϯͷ໭ΓΛ ड͚औͬͯprint # …௕ߟͷͷͪ 😴

Slide 180

Slide 180 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ ͝஫จ͸ʁ ͪΐͬͱ଴ͬͯͶ ͟Δͦ͹ # ίϧʔνϯͷ໭ΓΛ ड͚औͬͯprint # …௕ߟͷͷͪ 😴

Slide 181

Slide 181 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

Slide 182

Slide 182 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

Slide 183

Slide 183 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

Slide 184

Slide 184 text

イベントループを作る def order(): print(“͝஫จ͸ʁ”) menu = long_thinking() print(menu) def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) sleep(10000) return “͟Δͦ͹” order() # ࣮ߦ͢Δ

Slide 185

Slide 185 text

イベントループを作る async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print(menu) async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

Slide 186

Slide 186 text

考え中のお客様 3⼈とも

Slide 187

Slide 187 text

考え中のお客様 3⼈とも どうせ待つなら同時に 聞いてしまいたい…

Slide 188

Slide 188 text

async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep() return “͟Δͦ͹” await の動作を確認する async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print([menu])

Slide 189

Slide 189 text

async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” await の動作を確認する async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print([menu])

Slide 190

Slide 190 text

await の動作を確認する async def order(): print(“͝஫จ͸ʁ”) menu = await long_thinking() print([menu]) async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

Slide 191

Slide 191 text

async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) menu1 = await long_thinking(1) menu2 = await long_thinking(2) menu3 = await long_thinking(3) print([menu1, memu2, menu3]) await の動作を確認する

Slide 192

Slide 192 text

async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) menu1 = await long_thinking(1) menu2 = await long_thinking(2) menu3 = await long_thinking(3) print([menu1, memu2, menu3]) await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order())

Slide 193

Slide 193 text

async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) menu1 = await long_thinking(1) menu2 = await long_thinking(2) menu3 = await long_thinking(3) print([menu1, memu2, menu3]) await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order()) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ < ͟Δͦ͹ ͟Δͦ͹ ͟Δͦ͹ > UJNF

Slide 194

Slide 194 text

async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) menu1 = await long_thinking(1) print(menu1) menu2 = await long_thinking(2) print(menu2) menu3 = await long_thinking(3) print(menu3) await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order())

Slide 195

Slide 195 text

await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order()) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͟Δͦ͹ ͪΐͬͱ଴ͬͯͶ ͟Δͦ͹ ͪΐͬͱ଴ͬͯͶ b͟Δͦ͹ UJNF async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) menu1 = await long_thinking(1) print(menu1) menu2 = await long_thinking(2) print(menu2) menu3 = await long_thinking(3) print(menu3)

Slide 196

Slide 196 text

await の動作を確認する 並⾏実⾏すると3秒で終わるはず asyncio.run(order()) コルーチンをawaitするだけでは 並⾏にならない 1つのコルーチンが終わってから 次のコルーチン 普通の関数実⾏ と同じ l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͟Δͦ͹ ͪΐͬͱ଴ͬͯͶ ͟Δͦ͹ ͪΐͬͱ଴ͬͯͶ b͟Δͦ͹ UJNF async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) menu1 = await long_thinking(1) print(menu1) menu2 = await long_thinking(2) print(menu2) menu3 = await long_thinking(3) print(menu3)

Slide 197

Slide 197 text

コルーチン イベントループ タスク

Slide 198

Slide 198 text

•TaskΦϒδΣΫτ •ίϧʔνϯΛϥοϓ͠ɺ࣮ߦঢ়ଶΛ΋ͭ •࡞Δํ๏͸େ͖͘2ͭ •Python3.7 Ͱ௥Ճ͞Εͨ asyncio.create_task() •Πϕϯτϧʔϓʹొ࿥͢Δ •ฒྻ࣮ߦΛॿ͚Δ asyncio.gather() タスク

Slide 199

Slide 199 text

初めてのタスク async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) menu1 = await long_thinking(1) menu2 = await long_thinking(2) menu3 = await long_thinking(3) print([menu1, memu2, menu3]) asyncio.run(order())

Slide 200

Slide 200 text

初めてのタスク asyncio.run(order()) async def order(): print(“͝஫จ͸ʁ”) menu1 = await long_thinking(1) menu2 = await long_thinking(2) menu3 = await long_thinking(3) print([menu1, memu2, menu3]) async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

Slide 201

Slide 201 text

初めてのタスク async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(long_thinking(1)) task2 = asyncio.create_task(long_thinking(2)) task3 = asyncio.create_task(long_thinking(3)) menu1 = await task1 menu2 = await task2 menu3 = await task3 print([menu1, memu2, menu3]) asyncio.run(order())

Slide 202

Slide 202 text

初めてのタスク async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(long_thinking(1)) task2 = asyncio.create_task(long_thinking(2)) task3 = asyncio.create_task(long_thinking(3)) menu1 = await task1 menu2 = await task2 menu3 = await task3 print([menu1, memu2, menu3]) asyncio.run(order()) 実⾏してみましょう async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

Slide 203

Slide 203 text

初めてのタスク async def customers_long_thinking_order(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(long_thinking(1)) task2 = asyncio.create_task(long_thinking(2)) task3 = asyncio.create_task(long_thinking(3)) menu1 = await task1 menu2 = await task2 menu3 = await task3 print([menu1, memu2, menu3]) asyncio.run(order()) 実⾏してみましょう ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ < ͟Δͦ͹ ͟Δͦ͹ ͟Δͦ͹ > UJNF

Slide 204

Slide 204 text

初めてのタスク async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(long_thinking(1)) task2 = asyncio.create_task(long_thinking(2)) task3 = asyncio.create_task(long_thinking(3)) menu1 = await task1 print(menu1) menu2 = await task2 print(menu2) menu3 = await task3 print(menu2) asyncio.run(order()) 実⾏してみましょう

Slide 205

Slide 205 text

初めてのタスク async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(long_thinking(1)) task2 = asyncio.create_task(long_thinking(2)) task3 = asyncio.create_task(long_thinking(3)) menu1 = await task1 print(menu1) menu2 = await task2 print(menu2) menu3 = await task3 print(menu2) asyncio.run(order()) 実⾏してみましょう l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͟Δͦ͹ ͟Δͦ͹ ͟Δͦ͹ UJNF async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

Slide 206

Slide 206 text

初めてのタスク async def order(): print(“͝஫จ͸ʁ”) task1 = asyncio.create_task(long_thinking(1)) task2 = asyncio.create_task(long_thinking(2)) task3 = asyncio.create_task(long_thinking(3)) menu1 = await task1 print(menu1) menu2 = await task2 print(menu2) menu3 = await task3 print(menu2) asyncio.run(order()) 実⾏してみましょう l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͟Δͦ͹ ͟Δͦ͹ ͟Δͦ͹ UJNF async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹”

Slide 207

Slide 207 text

gatherを利⽤して結果をまとめて受け取る async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” async def order(): print(“͝஫จ͸ʁ”) tasks = [ long_thinking(3000), long_thinking(200), long_thinking(10), ] result = await asyncio.gather(*tasks) print(result) asyncio.run(order())

Slide 208

Slide 208 text

async def order(): print(“͝஫จ͸ʁ”) tasks = [ long_thinking(3000), long_thinking(200), long_thinking(10), ] result = await asyncio.gather(*tasks) print(result) gatherを利⽤して結果をまとめて受け取る async def long_thinking(num: int): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(num) return num, “͟Δͦ͹” asyncio.run(order()) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ < ͟Δͦ͹ ͟Δͦ͹ ͟Δͦ͹ > UJNF

Slide 209

Slide 209 text

ίϧʔνϯ asyncioはこわくない λεΫ ίϧʔνϯΛΠϕϯτϧʔϓʹొ࿥ɻ ྑ͖ʹܭΒͬͯ੾Γସ͑ͯ͘ΕΔɻฒߦॲཧͯ͘͠ΕΔɻ ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await async def await λεΫ ·ͨ͸ ίϧʔνϯ create_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొ࿥ gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ

Slide 210

Slide 210 text

asyncio ⾮同期IO

Slide 211

Slide 211 text

シンプルな asyncio のサンプル async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹”

Slide 212

Slide 212 text

シンプルな asyncio のサンプル async def long_thinking(): print(“ͪΐͬͱ଴ͬͯͶ”) await asyncio.sleep(10000) return “͟Δͦ͹” asyncio.sleep(10000)

Slide 213

Slide 213 text

⾮同期IO - asyncio asyncio.sleep(10000)

Slide 214

Slide 214 text

⾮同期IO - asyncio asyncio.sleep(10000) 外部⼊⼒を待つ状態

Slide 215

Slide 215 text

⾮同期IO - asyncio asyncio.sleep(10000) 外部⼊⼒を待つ状態 •I/Oό΢ϯυ

Slide 216

Slide 216 text

⾮同期IO - asyncio •I/Oό΢ϯυ •σʔλϕʔε΁ͷ઀ଓ •WebAPIͷར༻ʹΑΔHTTP௨৴

Slide 217

Slide 217 text

考え中のお客様 asyncio.sleep(10000)

Slide 218

Slide 218 text

考え中のお客様 検索しないと決められない asyncio.sleep(10000)

Slide 219

Slide 219 text

考え中のお客様 検索しないと決められない asyncio.sleep(10000) 3⼈とも

Slide 220

Slide 220 text

考え中のお客様 検索しないと決められない asyncio.sleep(10000) HTTP通信 I/Oバウンド 3⼈とも

Slide 221

Slide 221 text

考え中のお客様 検索しないと決められない asyncio.sleep(10000) HTTP通信 I/Oバウンド 3⼈とも requests

Slide 222

Slide 222 text

考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order()) print("time: ", time() - start)

Slide 223

Slide 223 text

考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order()) print("time: ", time() - start)

Slide 224

Slide 224 text

考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order()) print("time: ", time() - start)

Slide 225

Slide 225 text

考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order()) print("time: ", time() - start) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ < 3FTQPOTF<> b͟Δͦ͹` > UJNF

Slide 226

Slide 226 text

考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") print(“ܾ·ͬͨʂ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order()) print("time: ", time() - start)

Slide 227

Slide 227 text

考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") print(“ܾ·ͬͨʂ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order()) print("time: ", time() - start) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ܾ·ͬͨʂ ͪΐͬͱ଴ͬͯͶ ܾ·ͬͨʂ ͪΐͬͱ଴ͬͯͶ ܾ·ͬͨʂ < 3FTQPOTF<> b͟Δͦ͹` > UJNF

Slide 228

Slide 228 text

考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order(), debug=True) print("time: ", time() - start)

Slide 229

Slide 229 text

考え中のお客様がgoogle検索 async def long_think(num: int): print("ͪΐͬͱ଴ͬͯͶ") response = requests.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") tasks = [long_think(3), long_think(2), long_think(1)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order(), debug=True) print("time: ", time() - start) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ UPPLTFDPOET ͪΐͬͱ଴ͬͯͶ UPPLTFDPOET ͪΐͬͱ଴ͬͯͶ UPPLTFDPOET 3FTQPOTF<> ͟Δͦ͹ > UJNF

Slide 230

Slide 230 text

asyncio イベントループ 注⽂を取 注⽂を取 注⽂を取 コ (あくまでイメージ)

Slide 231

Slide 231 text

考え中のお客様がgoogle検索 async def long_think(client, num: int): print("ͪΐͬͱ଴ͬͯͶ") response = await client.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") async with httpx.AsyncClient() as client: tasks = [long_think(client, 1), long_think(client, 2), long_think(client, 3)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order(), debug=True) print("time: ", time() - start)

Slide 232

Slide 232 text

考え中のお客様がgoogle検索 async def long_think(client, num: int): print("ͪΐͬͱ଴ͬͯͶ") response = await client.get("https://www.google.com/search?q=͓͍͍͓͠ڶഴ͸ʁ") return num, response, "͟Δͦ͹" async def order(): print("“͝஫จ͸ʁ”") async with httpx.AsyncClient() as client: tasks = [long_think(client, 1), long_think(client, 2), long_think(client, 3)] result = await asyncio.gather(*tasks) print(result) start = time() asyncio.run(order(), debug=True) print("time: ", time() - start) l͝஫จ͸ʁz ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ ͪΐͬͱ଴ͬͯͶ < 3FTQPOTF<0,> b͟Δͦ͹` UJNF

Slide 233

Slide 233 text

ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ ੾ΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ࿥͓ͯ͘͠ͱ ྑ͖ʹܭΒͬͯ੾Γସ͑ͯ͘ΕΔɻ ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await

Slide 234

Slide 234 text

ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ ੾ΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ࿥͓ͯ͘͠ͱ ྑ͖ʹܭΒͬͯ੾Γସ͑ͯ͘ΕΔɻ 登録してあるタスクをawait のタイミングで切り替える。 ただしasyncio対応が必要。 ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await

Slide 235

Slide 235 text

ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ create_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొ࿥ gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ async def await λεΫ ·ͨ͸ ίϧʔνϯ asynio.run(ίϧʔνϯ)

Slide 236

Slide 236 text

ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ create_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొ࿥ gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ async def await λεΫ ·ͨ͸ ίϧʔνϯ asynio.run(ίϧʔνϯ) まずはこれを抑えましょう

Slide 237

Slide 237 text

asyncioはこわくない Πϕϯτϧʔϓ loopΦϒδΣΫτ 触れてないもの

Slide 238

Slide 238 text

asyncioはこわくない Πϕϯτϧʔϓ 触れてないもの futureΦϒδΣΫτ loopΦϒδΣΫτ

Slide 239

Slide 239 text

asyncioはこわくない Πϕϯτϧʔϓ 触れてないもの futureΦϒδΣΫτ loopΦϒδΣΫτ ެࣜυΩϡϝϯτɿ௿ϨϕϧAPIʹ෼ྨ

Slide 240

Slide 240 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ

Slide 241

Slide 241 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ

Slide 242

Slide 242 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ python core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃ PEP 492 -- Coroutines with async and await syntax ஶऀ europython 2018 - Asyncio in Python 3 7 and 3 8

Slide 243

Slide 243 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ PEP 492 -- Coroutines with async and await syntax ஶऀ

Slide 244

Slide 244 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ PEP 492 -- Coroutines with async and await syntax ஶऀ normal ϋʔυίΞ

Slide 245

Slide 245 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ PEP 492 -- Coroutines with async and await syntax ஶऀ

Slide 246

Slide 246 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ python core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃ PEP 492 -- Coroutines with async and await syntax ஶऀ europython 2018 - Asyncio in Python 3 7 and 3 8

Slide 247

Slide 247 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ python core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃ PEP 492 -- Coroutines with async and await syntax ஶऀ europython 2018 - Asyncio in Python 3 7 and 3 8 Python 3.10 ߴϨϕϧAPI(gather/wait/sleep … ) ͷҾ਺ʹloopΦϒδΣΫτͷࢦఆ͕ෆՄ

Slide 248

Slide 248 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ python core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃ PEP 492 -- Coroutines with async and await syntax ஶऀ europython 2018 - Asyncio in Python 3 7 and 3 8 Python 3.10 ߴϨϕϧAPI(gather/wait/sleep … ) ͷҾ਺ʹloopΦϒδΣΫτͷࢦఆ͕ෆՄ loopΦϒδΣΫτ΍futureΦϒδΣΫτΛҙࣝͤͣʹasyncioར༻Մೳʹ

Slide 249

Slide 249 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ python core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃ PEP 492 -- Coroutines with async and await syntax ஶऀ europython 2018 - Asyncio in Python 3 7 and 3 8 Python 3.10 ߴϨϕϧAPI(gather/wait/sleep … ) ͷҾ਺ʹloopΦϒδΣΫτͷࢦఆ͕ෆՄ loopΦϒδΣΫτ΍futureΦϒδΣΫτΛҙࣝͤͣʹasyncioར༻Մೳʹ Ξοϓσʔτ͕଎͍

Slide 250

Slide 250 text

asyncioはこわくない 緩やかな根拠 Python 3.7 ͷΞοϓσʔτ asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ python core developer Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ ͷొஃ PEP 492 -- Coroutines with async and await syntax ஶऀ europython 2018 - Asyncio in Python 3 7 and 3 8 Python 3.10 ߴϨϕϧAPI(gather/wait/sleep … ) ͷҾ਺ʹloopΦϒδΣΫτͷࢦఆ͕ෆՄ loopΦϒδΣΫτ΍futureΦϒδΣΫτΛҙࣝͤͣʹasyncioར༻Մೳʹ Ξοϓσʔτ͕଎͍ ༗༻ͳαϯϓϧίʔυ΋աڈͷόʔδϣϯΛϕʔεʹ͍ͯ͠Δ΋ͷ΋ଟ͍

Slide 251

Slide 251 text

ίϧʔνϯ asyncioはこわくない λεΫ Πϕϯτϧʔϓ create_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొ࿥ gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ async def await λεΫ ·ͨ͸ ίϧʔνϯ asynio.run(ίϧʔνϯ) まずはこれを抑えましょう

Slide 252

Slide 252 text

asyncioの話まとめ

Slide 253

Slide 253 text

注⽂を取る - 料理を 注⽂を取る - 料理を 注⽂を取る - 料理を 並⾏処理

Slide 254

Slide 254 text

注⽂を取る 注⽂を取る 注⽂を取る 並⾏処理 ⾮同期IO

Slide 255

Slide 255 text

注⽂を取る 注⽂を取る 注⽂を取る 並⾏処理 ⾮同期IO コ asyncio

Slide 256

Slide 256 text

注⽂を取る 注⽂を取る 注⽂を取る 並⾏処理 ⾮同期IO コ asyncio ちょっとわがまま asyncio対応モジュールである必要がありました。

Slide 257

Slide 257 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理

Slide 258

Slide 258 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか)

Slide 259

Slide 259 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか) データベースアクセス

Slide 260

Slide 260 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか) データベースアクセス urllib.requests requests

Slide 261

Slide 261 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか) データベースアクセス urllib.requests requests psycopg2 mysqlclient

Slide 262

Slide 262 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか) データベースアクセス urllib.requests requests psycopg2 mysqlclient (3でasyncio/型ヒント対応)

Slide 263

Slide 263 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか) データベースアクセス urllib.requests requests psycopg2 mysqlclient (3でasyncio/型ヒント対応)

Slide 264

Slide 264 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか) データベースアクセス urllib.requests requests psycopg2 mysqlclient aiohttpやhttpx asyncpg aiomysql

Slide 265

Slide 265 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか) データベースアクセス urllib.requests requests psycopg2 mysqlclient aiohttpやhttpx asyncpg "XFTPNF IUUQTHJUIVCDPNUJNPGVSSFSBXFTPNFBTZODJP BJPMJCT IUUQTHJUIVCDPNBJPMJCT FODPEF IUUQTXXXFODPEFJPQSPKFDUT aiomysql

Slide 266

Slide 266 text

コ asyncio ちょっとわがまま 外部IOの発⽣する処理 HTTPアクセス(APIとか) データベースアクセス urllib.requests requests psycopg2 mysqlclient aiohttpやhttpx asyncpg aiomysql "XFTPNF IUUQTHJUIVCDPNUJNPGVSSFSBXFTPNFBTZODJP BJPMJCT IUUQTHJUIVCDPNBJPMJCT FODPEF IUUQTXXXFODPEFJPQSPKFDUT

Slide 267

Slide 267 text

本⽇のおしながき •ASGIΞϓϦέʔγϣϯΛ࢖ͬͨasyncioͷ࢖͍ॴ •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ •ʢFastAPIˍasyncpgΛྫʹʣ asyncpg

Slide 268

Slide 268 text

本⽇のおしながき •ASGIΞϓϦέʔγϣϯΛ࢖ͬͨasyncioͷ࢖͍ॴ •ASGI Λར༻͢Δ্Ͱඞཁͳ asyncio جૅ •ʢFastAPIˍasyncpgΛྫʹʣ asyncpg ASGIΞϓϦέʔγϣϯ

Slide 269

Slide 269 text

•ASGI = asyncioରԠ WebϑϨʔϜϫʔΫͰasyncio͕࢖͑Δ ASGIΞϓϦέʔγϣϯ •asyncioͷಘҙͳ͜ͱ = ඇಉظIO ֎෦ґଘͷσʔλऔಘ •࣮ͯ͞ࡍͷίʔυΛݟͯΈ·͠ΐ͏ •ʢFastAPIˍasyncpgΛྫʹʣ asyncpg

Slide 270

Slide 270 text

•PostgreSQLͷσʔλϕʔεΠϯλʔϑΣʔεϥΠϒϥϦ asyncpg •asyncioରԠ͍ͯ͠Δ •MagicStack ࣾͷϦϙδτϦ uvloop΋ಉ͡ϦϙδτϦ •ઌ΄Ͳ঺հͨ͠ async/await ͷPEPஶऀ Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ •ORMͰ΋ར༻ՄೳʢSQLAlchemy ΍ databases ʣ って

Slide 271

Slide 271 text

•PostgreSQLͷσʔλϕʔεΠϯλʔϑΣʔεϥΠϒϥϦ asyncpg •asyncioରԠ͍ͯ͠Δ •MagicStack ࣾͷϦϙδτϦ uvloop΋ಉ͡ϦϙδτϦ •ઌ΄Ͳ঺հͨ͠ async/await ͷPEPஶऀ Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ •ORMͰ΋ར༻ՄೳʢSQLAlchemy ΍ databases ʣ って

Slide 272

Slide 272 text

asyncpg の簡単な使いかた # ίωΫγϣϯϓʔϧΛऔಘ async def main(): async with asyncpg.create_pool(dns) as pool: await pool.execute(...) dns = "postgresql://user:pass@host:5432/database" import asyncpg

Slide 273

Slide 273 text

asyncpg の簡単な使いかた # ίωΫγϣϯϓʔϧΛऔಘ async def main(): async with asyncpg.create_pool(dns) as pool: await pool.execute(...) dns = "postgresql://user:pass@host:5432/database" import asyncpg https://magicstack.github.io/asyncpg/

Slide 274

Slide 274 text

asyncpg の簡単な使いかた # ෳ਺ͷΫΤϦΛ࣮ߦ͢Δ৔߹ acquireϝιουͰίωΫγϣϯΛऔಘ async with asyncpg.create_pool(dns) as pool: async with pool.acquire() as conn: result1 = await conn.execute("INSERT …") result2 = await conn.fetch("SELECT 1") import asyncpg async def main(): async with asyncpg.create_pool(dns) as pool: await pool.execute(...) dns = "postgresql://user:pass@host:5432/database"

Slide 275

Slide 275 text

asyncpg の簡単な使いかた async def main(): async with asyncpg.create_pool(dns) as pool: tasks = [ pool.fetchrow("SELECT * FROM users WHERE id = $1", 1), pool.fetchrow("SELECT * FROM users WHERE id = $1", 2), pool.fetchrow("SELECT * FROM users WHERE id = $1", 3), ] result = await asyncio.gather(*tasks) print(result)

Slide 276

Slide 276 text

import asyncpg dns = "postgresql:// user:pass@host:5432/database" class Database: async def create_pool(self): self.pool = await asyncpg.create_pool(dsn=dns) asyncpg と FastAPI

Slide 277

Slide 277 text

asyncpg と FastAPI app = FastAPI() db = Database() from fastapi import FastAPI, Request

Slide 278

Slide 278 text

asyncpg と FastAPI app = FastAPI() db = Database() @app.on_event("startup") async def startup(): await db.create_pool() @app.on_event("shutdown") async def shutdown(): # cleanup pass from fastapi import FastAPI, Request

Slide 279

Slide 279 text

asyncpg と FastAPI @app.middleware("http") async def db_session_middleware(request: Request, call_next): request.state.pgpool = db.pool response = await call_next(request) return response

Slide 280

Slide 280 text

asyncpg と FastAPI @app.middleware("http") async def db_session_middleware(request: Request, call_next): request.state.pgpool = db.pool response = await call_next(request) return response @app.get("/") async def sample(request: Request): print(request.state.pgpool)

Slide 281

Slide 281 text

asyncpg と FastAPI async def get_rows(conn, num: int): """औಘ""" print(“ͪΐͬͱ଴ͬͯͶ {num=}") result = await conn.fetchrow("SELECT * FROM users WHERE id = $1", num) print(“ܾ·ͬͨʂ”) return result

Slide 282

Slide 282 text

asyncpg と FastAPI @app.get("/fetch") async def fetch_many(request: Request): tasks = [get_rows(request.state.pgpool, number) for number in range(0, 100)] return await asyncio.gather(*tasks, return_exceptions=False) async def get_rows(conn, num: int): """औಘ""" print(“ͪΐͬͱ଴ͬͯͶ {num=}") result = await conn.fetchrow("SELECT * FROM users WHERE id = $1", num) print(“ܾ·ͬͨʂ”) return result

Slide 283

Slide 283 text

asyncpg と FastAPI http://127.0.0.1:8000/docs

Slide 284

Slide 284 text

asyncpg と FastAPI

Slide 285

Slide 285 text

asyncpg と FastAPI async def get_rows(conn, num: int): """औಘ""" print(“ͪΐͬͱ଴ͬͯͶ {num=}") result = await conn.fetchrow("SELECT * FROM users WHERE id = $1", num) print(“ܾ·ͬͨʂ”) return result

Slide 286

Slide 286 text

asyncpg と FastAPI INFO: Application startup complete. ͪΐͬͱ଴ͬͯͶ num=0 ͪΐͬͱ଴ͬͯͶ num=1 ͪΐͬͱ଴ͬͯͶ num=2 ͪΐͬͱ଴ͬͯͶ num=3 ͪΐͬͱ଴ͬͯͶ num=4 ... async def get_rows(conn, num: int): """औಘ""" print(“ͪΐͬͱ଴ͬͯͶ {num=}") result = await conn.fetchrow("SELECT * FROM users WHERE id = $1", num) print(“ܾ·ͬͨʂ”) return result

Slide 287

Slide 287 text

asyncpg と FastAPI INFO: Application startup complete. ͪΐͬͱ଴ͬͯͶ num=0 ͪΐͬͱ଴ͬͯͶ num=1 ͪΐͬͱ଴ͬͯͶ num=2 ͪΐͬͱ଴ͬͯͶ num=3 ͪΐͬͱ଴ͬͯͶ num=4 ... async def get_rows(conn, num: int): """औಘ""" print(“ͪΐͬͱ଴ͬͯͶ {num=}") result = await conn.fetchrow("SELECT * FROM users WHERE id = $1", num) print(“ܾ·ͬͨʂ”) return result ... ܾ·ͬͨʂ ܾ·ͬͨʂ ܾ·ͬͨʂ ܾ·ͬͨʂ INFO: 127.0.0.1:50033 - "GET /fetch INFO: 127.0.0.1:50038 - "GET /docs INFO: 127.0.0.1:50038 - "GET /opena

Slide 288

Slide 288 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ

Slide 289

Slide 289 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ

Slide 290

Slide 290 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ

Slide 291

Slide 291 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ

Slide 292

Slide 292 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ

Slide 293

Slide 293 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ •ύʔπ͝ͱʹajaxͰऔಘ 👍 •1APIͰ·ͱΊͯऔಘ 👍 ઃܭʹΑΔ

Slide 294

Slide 294 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ •ύʔπ͝ͱʹajaxͰऔಘ 👍 •1APIͰ·ͱΊͯऔಘ 👍 ઃܭʹΑΔ WSGI/ASGI WSGI/ASGI

Slide 295

Slide 295 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ •ύʔπ͝ͱʹajaxͰऔಘ 👍 •1APIͰ·ͱΊͯऔಘ 👍 ઃܭʹΑΔ WSGI/ASGI WSGI/ASGI

Slide 296

Slide 296 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ •ύʔπ͝ͱʹajaxͰऔಘ 👍 •1APIͰ·ͱΊͯऔಘ 👍 ઃܭʹΑΔ WSGI/ASGI WSGI/ASGI

Slide 297

Slide 297 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ •ྫ͑͹ECαΠτͷΑ͏ͳΞϓϦέʔγϣϯ

Slide 298

Slide 298 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ •ྫ͑͹ECαΠτͷΑ͏ͳΞϓϦέʔγϣϯ •ಛఆͷॲཧ͚ͩ֎෦APIΛ࣮ߦ͢ΔΞϓϦ

Slide 299

Slide 299 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ •ྫ͑͹ECαΠτͷΑ͏ͳΞϓϦέʔγϣϯ •ಛఆͷॲཧ͚ͩ֎෦APIΛ࣮ߦ͢ΔΞϓϦ WebΞϓϦέʔγϣϯ͸ɺ ଟ͘ͷσʔλ΍ػೳͷ૊Έ߹ΘͤͰ͖͍ͯΔ

Slide 300

Slide 300 text

ASGIアプリケーションのユースケース •ྫ͑͹μογϡϘʔυͷΑ͏ͳΞϓϦέʔγϣϯ •ྫ͑͹ECαΠτͷΑ͏ͳΞϓϦέʔγϣϯ •ಛఆͷॲཧ͚ͩ֎෦APIΛ࣮ߦ͢ΔΞϓϦ WebΞϓϦέʔγϣϯ͸ɺ ଟ͘ͷσʔλ΍ػೳͷ૊Έ߹ΘͤͰ͖͍ͯΔ ઃܭ࣍ୈ WSGI/ASGI

Slide 301

Slide 301 text

まとめ •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔ コ

Slide 302

Slide 302 text

まとめ •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔ コ •3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ௚ײతͰΘ͔Γ΍͘͢

Slide 303

Slide 303 text

まとめ •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔ コ •FastAPI I/Oό΢ϯυͳॲཧʹ΋ؾܰʹࢼͤΔ •3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ௚ײతͰΘ͔Γ΍͘͢

Slide 304

Slide 304 text

まとめ •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔ コ •FastAPI I/Oό΢ϯυͳॲཧʹ΋ؾܰʹࢼͤΔ •3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ௚ײతͰΘ͔Γ΍͘͢ •ϢʔεέʔεΛݟۃΊΔઃܭ

Slide 305

Slide 305 text

まとめ •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔ コ •FastAPI I/Oό΢ϯυͳॲཧʹ΋ؾܰʹࢼͤΔ •asyncio͕ར༻ՄೳͳASGIΞϓϦέʔγϣϯΛબ୒͓ͯ͘͠ •3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ௚ײతͰΘ͔Γ΍͘͢ •ϢʔεέʔεΛݟۃΊΔઃܭ

Slide 306

Slide 306 text

まとめ •asyncio ଟগ͜Θ͘ͳ͘ͳͬͨͰ͠ΐ͏͔ コ •FastAPI I/Oό΢ϯυͳॲཧʹ΋ؾܰʹࢼͤΔ •asyncio͕ར༻ՄೳͳASGIΞϓϦέʔγϣϯΛબ୒͓ͯ͘͠ •3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ௚ײతͰΘ͔Γ΍͘͢ •ϢʔεέʔεΛݟۃΊΔઃܭ •EAFPʢڐՄΑΓँࡑ ϚʔϑΟͷ๏ଇʣ👍

Slide 307

Slide 307 text

•ίϧʔνϯ͸ා͘ͳ͍ - Minimum Viable Programmer https://www.rhoboro.com/2019/02/09/coroutine-abstract.html •Using Asyncio in Python - Oreilly & Associates Inc 謝辞 •Yury Selivanov - Asyncio in Python 3 7 and 3 8 https://www.youtube.com/watch?v=ReXxO_azV-w •asyncioͷTaskʹؔ͢Δجૅ஌ࣝ https://aish.dev/python/20200711_asyncio_task.html •To many many internet articles, great books and member. 🙏

Slide 308

Slide 308 text

ご静聴ありがとうございました 👋