Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ASGIアプリケーション入門 - こわくないasyncio基礎と非同期IO

Junya Fukuda
October 15, 2021

ASGIアプリケーション入門 - こわくないasyncio基礎と非同期IO

PyConJP2021の登壇資料です。

Junya Fukuda

October 15, 2021
Tweet

More Decks by Junya Fukuda

Other Decks in Programming

Transcript

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

    View Slide

  2. •෱ా ൏໵ʢJunya Fukudaʣʢ@JunyaFffʣ


    •גࣜձࣾ೔ຊγεςϜٕݚʢJSLʣॴଐ ௕໺ݝͷձࣾ


    •WebΤϯδχΞ


    •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ


    •Effective Python ͷಡॻձ΍ͬͯ·͢ 📚


    •ʢ͓͠͝ͱͰʣόϦϡʔϒοΫε


    •ຊ޷͖ʹѪ͞ΕΔαʔϏεΛ໨ࢦͯ͠ʢݹຊങऔɾൢചʣ
    ΪʔΫϥϘ௕໺ಡॻձ
    •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ

    View Slide

  3. ΪʔΫϥϘ௕໺OPUF
    •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ
    •εϙϯαʔάοζ


    •γϧΫεΫϦʔϯͰख࡮ΓʂΦϯε૿͠ΊͷϏοΫγϧΤοτ


    •IT΋ͦΕҎ֎ͷ΋ͷͮ͘Γ΋΍ͬͯΔίϫʔΩϯάεϖʔε


    •ϒʔεʹ͖ͯ߹ݴ༿Λฉ͍ͯܠ඼Λਃ͠ࠐΜͰͶʂ


    •എ໘͸Zen of Pythonʂେࣄͳ͜ͱΛϢʔϞΞަ͑ͯഎෛͬͯΈͯ͸ʁ

    View Slide

  4. Python実践
    •2022೥1݄ൃച༧ఆ


    •ϖʔδ਺: ະఆ


    •ֹۚ: ະఆ


    •PythonΤϯδχΞҭ੒ਪਐڠձ؂म


    •ʮPythonϥΠϒϥϦݫબϨγϐʯΛେ෯ʹՃචɺվగ!!!

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  13. って

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  17. って
    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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  21. って
    •ߴύϑΥʔϚϯε

    View Slide

  22. って
    •Fast: Very high performance, on par with NodeJS and Go


    ʢߴ଎: NodeJS ΍ Go ฒΈͷͱͯ΋ߴ͍ύϑΥʔϚϯεʣ
    https://fastapi.tiangolo.com/
    •ߴύϑΥʔϚϯε

    View Slide

  23. って
    •Fast: Very high performance, on par with NodeJS and Go


    ʢߴ଎: NodeJS ΍ Go ฒΈͷͱͯ΋ߴ͍ύϑΥʔϚϯεʣ
    https://fastapi.tiangolo.com/
    •ߴύϑΥʔϚϯε
    •͍Ζ͍Ζͳ֯౓͕͋Δ

    View Slide

  24. って
    •Fast: Very high performance, on par with NodeJS and Go


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

    View Slide

  25. って
    •Fast: Very high performance, on par with NodeJS and Go


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

    View Slide

  26. って
    •Fast: Very high performance, on par with NodeJS and Go


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

    View Slide

  27. って
    •Fast: Very high performance, on par with NodeJS and Go


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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  37. WSGI

    View Slide

  38. WSGI Web Server Gateway Interface

    View Slide

  39. WSGI Web Server Gateway Interface
    ASGI

    View Slide

  40. WSGI Web Server Gateway Interface
    ASGI Asynchronous Server Gateway Interface

    View Slide

  41. WSGI Web Server Gateway Interface
    ASGI Asynchronous Server Gateway Interface

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  54. asyncioはこわくない

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  61. asyncio めっちゃこわい

    View Slide

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

    View Slide

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

    View Slide

  64. •͜Θ͔ͬͨ
    •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/

    View Slide

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

    View Slide

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


    •DAY2 - 10.16(SAT) 16:20 - #pyconjp_2

    View Slide

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


    •DAY2 - 10.16(SAT) 16:20 - #pyconjp_2

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  78. ⾔葉を完全に理解する

    View Slide

  79. IUUQTEPDTQZUIPOPSHKBMJCSBSZBTZODJPIUNM

    View Slide

  80. 前提知識
    並⾏処理

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  84. 前提知識
    並⾏処理
    concurrent processing

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  89. イメージ重視

    View Slide

  90. 並⾏処理
    並列処理
    逐次処理

    View Slide

  91. 並⾏処理
    並列処理
    逐次処理

    View Slide

  92. 並⾏処理
    並列処理
    逐次処理

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  97. レストラン

    View Slide

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

    View Slide

  99. 注⽂をとる

    View Slide

  100. 料理を作る
    注⽂をとる

    View Slide

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

    View Slide

  102. 逐次処理

    View Slide

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

    View Slide

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

    View Slide

  105. 並列処理

    View Slide

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

    View Slide

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

    View Slide

  108. 並⾏処理

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  122. a sync io

    View Slide

  123. a sync io
    ⼊⼒

    View Slide

  124. a sync io
    同期 ⼊⼒

    View Slide

  125. a sync io
    しない 同期 ⼊⼒

    View Slide

  126. asyncio
    ⾮同期IO

    View Slide

  127. asyncio
    ⾮同期IO

    View Slide

  128. asyncio
    ⾮同期IO

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  134. asyncio

    View Slide

  135. asyncio🌷

    View Slide

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

    View Slide

  137. イベントループ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  144. レストラン

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  148. asyncio
    注⽂を取 注⽂を取 注⽂を取

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  158. 考え中のお客様

    View Slide

  159. 関数を定義
    def customers_thinking_order():


    ... # ॲཧ

    View Slide

  160. def customers_long_thinking_order():


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

    View Slide

  161. async def customers_long_thinking_order():


    asyncio.sleep(10000)


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

    View Slide

  162. 関数を実⾏
    def customers_long_thinking_order():


    time.sleep(10000)


    return “͟Δͦ͹”
    >>> print(customers_long_thinking_order())
    ͟Δͦ͹
    # ௕ߟͷͷͪ

    View Slide

  163. def customers_long_thinking_order():


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    コルーチンを実⾏
    >>> print(customers_long_thinking_order())
    async

    View Slide

  164. コルーチンを実⾏
    >>> print(customers_long_thinking_order())


    at 0x10d949ec0>
    def customers_long_thinking_order():


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    async

    View Slide

  165. コルーチンを実⾏
    >>> print(customers_long_thinking_order())


    at 0x10d949ec0>
    ݁ՌΛड͚औΕͳ͍
    def customers_long_thinking_order():


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    async

    View Slide

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

    View Slide

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

    (あくまでイメージ)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  174. async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    イベントループを作る

    View Slide

  175. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”

    View Slide

  176. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

    View Slide

  177. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ
    ͝஫จ͸ʁ


    ͪΐͬͱ଴ͬͯͶ

    View Slide

  178. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ
    ͝஫จ͸ʁ


    ͪΐͬͱ଴ͬͯͶ
    # …௕ߟͷͷͪ 😴

    View Slide

  179. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ
    ͝஫จ͸ʁ


    ͪΐͬͱ଴ͬͯͶ
    ͟Δͦ͹ # ίϧʔνϯͷ໭ΓΛ


    ड͚औͬͯprint
    # …௕ߟͷͷͪ 😴

    View Slide

  180. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ
    ͝஫จ͸ʁ


    ͪΐͬͱ଴ͬͯͶ
    ͟Δͦ͹ # ίϧʔνϯͷ໭ΓΛ


    ड͚औͬͯprint
    # …௕ߟͷͷͪ 😴

    View Slide

  181. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

    View Slide

  182. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

    View Slide

  183. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

    View Slide

  184. イベントループを作る
    def order():


    print(“͝஫จ͸ʁ”)


    menu = long_thinking()


    print(menu)
    def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    sleep(10000)


    return “͟Δͦ͹”
    order() # ࣮ߦ͢Δ

    View Slide

  185. イベントループを作る
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print(menu)
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.run(order()) # ΠϕϯτϧʔϓΛ࡞Δ

    View Slide

  186. 考え中のお客様 3⼈とも

    View Slide

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

    View Slide

  188. async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep()


    return “͟Δͦ͹”
    await の動作を確認する
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print([menu])

    View Slide

  189. async def long_thinking(num: int):


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(num)


    return num, “͟Δͦ͹”
    await の動作を確認する
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print([menu])

    View Slide

  190. await の動作を確認する
    async def order():


    print(“͝஫จ͸ʁ”)


    menu = await long_thinking()


    print([menu])
    async def long_thinking(num: int):


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(num)


    return num, “͟Δͦ͹”

    View Slide

  191. 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 の動作を確認する

    View Slide

  192. 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())


    View Slide

  193. 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

    View Slide

  194. 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())


    View Slide

  195. 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)

    View Slide

  196. 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)

    View Slide

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

    View Slide

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

    View Slide

  199. 初めてのタスク
    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())


    View Slide

  200. 初めてのタスク
    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, “͟Δͦ͹”

    View Slide

  201. 初めてのタスク
    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())


    View Slide

  202. 初めてのタスク
    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, “͟Δͦ͹”

    View Slide

  203. 初めてのタスク
    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

    View Slide

  204. 初めてのタスク
    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())


    実⾏してみましょう

    View Slide

  205. 初めてのタスク
    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, “͟Δͦ͹”

    View Slide

  206. 初めてのタスク
    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, “͟Δͦ͹”

    View Slide

  207. 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())


    View Slide

  208. 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

    View Slide

  209. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    ίϧʔνϯΛΠϕϯτϧʔϓʹొ࿥ɻ


    ྑ͖ʹܭΒͬͯ੾Γସ͑ͯ͘ΕΔɻฒߦॲཧͯ͘͠ΕΔɻ
    ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await
    async def


    await λεΫ ·ͨ͸ ίϧʔνϯ
    create_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొ࿥


    gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ

    View Slide

  210. asyncio
    ⾮同期IO

    View Slide

  211. シンプルな asyncio のサンプル
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”

    View Slide

  212. シンプルな asyncio のサンプル
    async def long_thinking():


    print(“ͪΐͬͱ଴ͬͯͶ”)


    await asyncio.sleep(10000)


    return “͟Δͦ͹”
    asyncio.sleep(10000)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  222. 考え中のお客様が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)


    View Slide

  223. 考え中のお客様が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)


    View Slide

  224. 考え中のお客様が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)


    View Slide

  225. 考え中のお客様が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

    View Slide

  226. 考え中のお客様が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)


    View Slide

  227. 考え中のお客様が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

    View Slide

  228. 考え中のお客様が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)


    View Slide

  229. 考え中のお客様が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

    View Slide

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

    (あくまでイメージ)

    View Slide

  231. 考え中のお客様が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)

    View Slide

  232. 考え中のお客様が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
    ͪΐͬͱ଴ͬͯͶ
    ͪΐͬͱ଴ͬͯͶ
    ͪΐͬͱ଴ͬͯͶ
    < 3FTQPOTF0,> b͟Δͦ͹`

    UJNF

    View Slide

  233. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    ੾ΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ࿥͓ͯ͘͠ͱ


    ྑ͖ʹܭΒͬͯ੾Γସ͑ͯ͘ΕΔɻ
    ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await

    View Slide

  234. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    ੾ΓସΘΔઌͷίϧʔνϯɻΠϕϯτϧʔϓʹొ࿥͓ͯ͘͠ͱ


    ྑ͖ʹܭΒͬͯ੾Γସ͑ͯ͘ΕΔɻ
    登録してあるタスクをawait
    のタイミングで切り替える。
    ただしasyncio対応が必要。
    ؔ਺ʹ async Λ͚ͭΔ͚ͩ ؊͸await

    View Slide

  235. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    create_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొ࿥


    gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ
    async def


    await λεΫ ·ͨ͸ ίϧʔνϯ
    asynio.run(ίϧʔνϯ)

    View Slide

  236. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    create_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొ࿥


    gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ
    async def


    await λεΫ ·ͨ͸ ίϧʔνϯ
    asynio.run(ίϧʔνϯ)
    まずはこれを抑えましょう

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  242. 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

    View Slide

  243. asyncioはこわくない 緩やかな根拠
    Python 3.7 ͷΞοϓσʔτ
    asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ
    Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ


    PEP 492 -- Coroutines with async and await syntax ஶऀ

    View Slide

  244. asyncioはこわくない 緩やかな根拠
    Python 3.7 ͷΞοϓσʔτ
    asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ
    Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ


    PEP 492 -- Coroutines with async and await syntax ஶऀ
    normal
    ϋʔυίΞ

    View Slide

  245. asyncioはこわくない 緩やかな根拠
    Python 3.7 ͷΞοϓσʔτ
    asyncio.create_task(), asyncio.gather(), asyncio.run() ͷ௥Ճ
    Yury Selivanov ʢϢʔϦʔηϦόϊϑʣࢯ


    PEP 492 -- Coroutines with async and await syntax ஶऀ

    View Slide

  246. 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

    View Slide

  247. 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ΦϒδΣΫτͷࢦఆ͕ෆՄ

    View Slide

  248. 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ར༻Մೳʹ

    View Slide

  249. 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ར༻Մೳʹ Ξοϓσʔτ͕଎͍

    View Slide

  250. 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ར༻Մೳʹ Ξοϓσʔτ͕଎͍
    ༗༻ͳαϯϓϧίʔυ΋աڈͷόʔδϣϯΛϕʔεʹ͍ͯ͠Δ΋ͷ΋ଟ͍

    View Slide

  251. ίϧʔνϯ
    asyncioはこわくない
    λεΫ
    Πϕϯτϧʔϓ
    create_task(ίϧʔνϯ) - Πϕϯτϧʔϓʹొ࿥


    gather(λεΫ ·ͨ͸ ίϧʔνϯ) - ·ͱΊͯ݁ՌΛड͚औΕΔ
    async def


    await λεΫ ·ͨ͸ ίϧʔνϯ
    asynio.run(ίϧʔνϯ)
    まずはこれを抑えましょう

    View Slide

  252. asyncioの話まとめ

    View Slide

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

    View Slide

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

    View Slide

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

    asyncio

    View Slide

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

    asyncio
    ちょっとわがまま
    asyncio対応モジュールである必要がありました。

    View Slide


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

    View Slide


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

    View Slide


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

    View Slide


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

    View Slide


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

    View Slide


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

    View Slide


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

    View Slide


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

    View Slide


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

    View Slide


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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  272. asyncpg の簡単な使いかた
    # ίωΫγϣϯϓʔϧΛऔಘ


    async def main():


    async with asyncpg.create_pool(dns) as pool:


    await pool.execute(...)


    dns = "postgresql://user:[email protected]:5432/database"
    import asyncpg


    View Slide

  273. asyncpg の簡単な使いかた
    # ίωΫγϣϯϓʔϧΛऔಘ


    async def main():


    async with asyncpg.create_pool(dns) as pool:


    await pool.execute(...)


    dns = "postgresql://user:[email protected]:5432/database"
    import asyncpg


    https://magicstack.github.io/asyncpg/

    View Slide

  274. 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:[email protected]:5432/database"

    View Slide

  275. 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)


    View Slide

  276. import asyncpg


    dns = "postgresql:// user:[email protected]:5432/database"


    class Database:


    async def create_pool(self):


    self.pool = await asyncpg.create_pool(dsn=dns)


    asyncpg と FastAPI

    View Slide

  277. asyncpg と FastAPI
    app = FastAPI()


    db = Database()


    from fastapi import FastAPI, Request


    View Slide

  278. 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


    View Slide

  279. 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


    View Slide

  280. 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)

    View Slide

  281. 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


    View Slide

  282. 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


    View Slide

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

    View Slide

  284. asyncpg と FastAPI

    View Slide

  285. 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


    View Slide

  286. 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


    View Slide

  287. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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


    ଟ͘ͷσʔλ΍ػೳͷ૊Έ߹ΘͤͰ͖͍ͯΔ

    View Slide

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


    ଟ͘ͷσʔλ΍ػೳͷ૊Έ߹ΘͤͰ͖͍ͯΔ
    ઃܭ࣍ୈ WSGI/ASGI

    View Slide

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

    View Slide

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

    •3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ௚ײతͰΘ͔Γ΍͘͢

    View Slide

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

    •FastAPI I/Oό΢ϯυͳॲཧʹ΋ؾܰʹࢼͤΔ
    •3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ௚ײతͰΘ͔Γ΍͘͢

    View Slide

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

    •FastAPI I/Oό΢ϯυͳॲཧʹ΋ؾܰʹࢼͤΔ
    •3.7Ҏ߱ߴϨϕϧAPI͕ॆ࣮ ௚ײతͰΘ͔Γ΍͘͢
    •ϢʔεέʔεΛݟۃΊΔઃܭ

    View Slide

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

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

    View Slide

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

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

    View Slide

  307. •ίϧʔνϯ͸ා͘ͳ͍ - 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. 🙏

    View Slide

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

    View Slide