PyCon JP 2018 で発表した資料です。
『 asyncio + aiohttp で作るウェブサービス 』 https://pycon.jp/2018/event/sessions
---
This is the material I presented at PyConJP 2018.
"How to develop a web service with asyncio and aiohttp" https://pycon.jp/2018/event/sessions
1Z$PO +1 4FQ1JOF.J[VOFʰ BTZODJP BJPIUUQ ʱͰ࡞ΔɺΣϒαʔϏε)PXUPEFWFMPQBXFCTFSWJDFXJUIBTZODJP BOEBJPIUUQ
View Slide
"CPVUNF8IBUJTBTZODJP)PXUPVTFBJPIUUQ
"CPVU NFQJOFQJOF8FCNPCJMFBQQFOHJOFFSJO5PLZPIUUQTFNPKJHFOOJOKB&NPKJ(FOFSBUPSUPPMGPS4MBDL BCPVU ."6XSJUUFOCZ1ZUIPOBJPIUUQ
&NPKJ (FOFSBUPSMPWFT 1ZUIPO*NBHFQSPDFTTJOH"QQMJDBUJPOTFSWFS%FW0QT
BBTZODJP
8IBU JTBTZODJP§ "TZODISPOVT *0 FWFOUMPPQ BOEDPSPVUJOFT§ TJOHMFUISFBEFE§ MJLF+BWB4DSJQU &4PS3VCZ`T'JCFS§ 5IFTUBOEBSEMJCSBSZ 1ZUIPO§ BTZOD BXBJU LFZXPSET 1ZUIPO§ )JHIQFSGPSNBODFBOEMJHIUXFJHIU§ TVJUBCMFGPS*0CPVOEQSPDFTTJOH !
&WFOU MPPQ§ 3VOEFGBVMUFWFOUMPPQimport asyncioloop = asyncio.get_event_loop()loop.run_forever()§ 6TFPUIFSFWFOUMPPQ MJCVW CBDLFOEimport asyncioimport uvloopasyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
&WFOU MPPQ§ 3VOEFGBVMUFWFOUMPPQimport asyncioloop = asyncio.get_event_loop()loop.run_forever()§ 6TFPUIFSFWFOUMPPQ MJCVW CBDLFOEimport asyncioimport uvloopasyncio.set_event_loop_policy(uvloop.EventLoopPolicy())4UBSUEFGBVMUFWFOUMPPQGPSFWFS
&WFOU MPPQ§ 3VOEFGBVMUFWFOUMPPQimport asyncioloop = asyncio.get_event_loop()loop.run_forever()§ 6TFPUIFSFWFOUMPPQ MJCVW CBDLFOEimport asyncioimport uvloopasyncio.set_event_loop_policy(uvloop.EventLoopPolicy())$IBOHFFWFOUMPPQQPMJDZ
$PSPVUJOFT§ &BTZUPVTFDPSPVUJOFTimport asyncioasync def run():await asyncio.sleep(1)coroutine = run()print(coroutine)#=> loop = asyncio.get_event_loop()loop.run_until_complete(coroutine)
$PSPVUJOFT§ &BTZUPVTFDPSPVUJOFTimport asyncioasync def run():await asyncio.sleep(1)coroutine = run()print(coroutine)#=> loop = asyncio.get_event_loop()loop.run_until_complete(coroutine)6TFBABTZOD EFGATUBUFNFOU
$PSPVUJOFT§ &BTZUPVTFDPSPVUJOFTimport asyncioasync def run():await asyncio.sleep(1)coroutine = run()print(coroutine)#=> loop = asyncio.get_event_loop()loop.run_until_complete(coroutine)$BMMBDPSPVUJOFGVODUJPO
$PSPVUJOFT§ &BTZUPVTFDPSPVUJOFTimport asyncioasync def run():await asyncio.sleep(1)coroutine = run()print(coroutine)#=> loop = asyncio.get_event_loop()loop.run_until_complete(coroutine)8BJUVOUJMUIFDPSPVUJOFFOET
'VUVSFT§ .BLF'VUVSF GSPNDPSPVUJOFTimprot asyncioasync def identity(value):return valuefuture1 = asyncio.ensure_future(identity(1))future2 = asyncio.ensure_future(identity(2))future3 = asyncio.gather(future1, future2)loop = asyncio.get_event_loop()print(loop.run_until_complete(future3))#=> [1, 2]
'VUVSFT§ .BLF'VUVSF GSPNDPSPVUJOFTimprot asyncioasync def identity(value):return valuefuture1 = asyncio.ensure_future(identity(1))future2 = asyncio.ensure_future(identity(2))future3 = asyncio.gather(future1, future2)loop = asyncio.get_event_loop()print(loop.run_until_complete(future3))#=> [1, 2]1SPNJTF %FGGFSFE FUD
'VUVSFT§ .BLF'VUVSF GSPNDPSPVUJOFTimprot asyncioasync def identity(value):return valuefuture1 = asyncio.ensure_future(identity(1))future2 = asyncio.ensure_future(identity(2))future3 = asyncio.gather(future1, future2)loop = asyncio.get_event_loop()print(loop.run_until_complete(future3))#=> [1, 2]$PSPVUJOFT'VUVSFT
'VUVSFT§ .BLF'VUVSF GSPNDPSPVUJOFTimprot asyncioasync def identity(value):return valuefuture1 = asyncio.ensure_future(identity(1))future2 = asyncio.ensure_future(identity(2))future3 = asyncio.gather(future1, future2)loop = asyncio.get_event_loop()print(loop.run_until_complete(future3))#=> [1, 2].BLFOFXGVUVSFGSPNUXPGVUVSFT
'VUVSFT§ .BLF'VUVSF GSPNDPSPVUJOFTimprot asyncioasync def identity(value):return valuefuture1 = asyncio.ensure_future(identity(1))future2 = asyncio.ensure_future(identity(2))future3 = asyncio.gather(future1, future2)loop = asyncio.get_event_loop()print(loop.run_until_complete(future3))#=> [1, 2]8BJUVOUJMUIF'VUVSFFOET
BBJPIUUQ
8IBU JTBJPIUUQ§ "TZODISPOPVT)551DMJFOUTFSWFSGSBNFXPSL§ BTZODJP CBTFE§ 1ZUIPOSFRVJSFE§ 4FQ WSFMFBTFE§ $VSSFOUMZW§ 4VQQPSUT8FC4PDLFU 4FTTJPO $PPLJF FUD BJPMJCTBJPIUUQ
)BOEMFSTfrom aiohttp import webasync def items(request):page = request.query.get(‘page’)items = await item_repository.filter(page)return web.json_response(result)app.router.add_get(‘/items’, items)§ .7$XFCBQQGSBNFXPSL`T$POUSPMMFS§ SFDFJWFSFRVFTU SFUVSOSFTQPOTF
)BOEMFSTfrom aiohttp import webasync def items(request):page = request.query.get(‘page’)items = await item_repository.filter(page)return web.json_response(result)app.router.add_get(‘/items’, items)§ .7$XFCBQQGSBNFXPSL`T$POUSPMMFS§ SFDFJWFSFRVFTU SFUVSOSFTQPOTF"TZODISPOPVT%#BDDFTT
)BOEMFSTfrom aiohttp import webasync def items(request):page = request.query.get(‘page’)items = await item_repository.filter(page)return web.json_response(result)app.router.add_get(‘/items’, items)§ .7$XFCBQQGSBNFXPSL`T$POUSPMMFS§ SFDFJWFSFRVFTU SFUVSOSFTQPOTF"EEBOFXSPVUFUPUIFEFGBVMU63-SPVUFS
)BOEMFSTfrom aiohttp import webroutes = web.RouteTableDef()@routes.get(‘/items’)async def items(request):page = request.query.get(‘page’)items = await item_repository.filter(page)return web.json_response(result)§ 4VQQPSU'MBTLMJLFSPVUJOHEFGJOJUJPOT
.JEEMFXBSFTimport htmlminfrom aiohttp import web@web.middlewareasync def htmlmin_middleware(request, handler):response = await handler(request)if response.content_type == 'text/html':response.text = htmlmin.minify(response.text)return responseapp.middlewares.append(htmlmin_middleware())§ )5.-NJOJGZNJEEMFXBSFTBNQMF
.JEEMFXBSFTimport htmlminfrom aiohttp import web@web.middlewareasync def htmlmin_middleware(request, handler):response = await handler(request)if response.content_type == 'text/html':response.text = htmlmin.minify(response.text)return responseapp.middlewares.append(htmlmin_middleware())§ )5.-NJOJGZNJEEMFXBSFTBNQMF*OKFDUBTZODISPOPVTNJEEMFXBSF
1SPEVDUJPO§ V84(* JTOPUTVQQPSUFE!§ OHJOY (VOJDPSO BSFSFDPNNFOEFECZP⒏DJBM§ SVOTTFSWFSXJUIDVTUPNXPSLFSFOWJSPONFOUT$ gunicorn myapp:app --bind localhost:8080--worker-class aiohttp.GunicornWebWorker
$PODMVTJPOB§ BTZODJP JTBTZODISPOVT *0 FWFOUMPPQBOEDPSPVUJOFTMJCSBSZ§ BJPIUUQ JTBTZODJP CBTFEXFCBQQGSBNFXPSL§ BJPIUUQ JTTJNQMFBOEDBOCVJMEIJHIQFSGPSNBODFBQQ5IBOLZPV