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

[PyCon KR 2019] aiohttp tutorial

[PyCon KR 2019] aiohttp tutorial

Joongi Kim

August 16, 2019
Tweet

More Decks by Joongi Kim

Other Decks in Programming

Transcript

  1. § CTO @ Lablup Inc. § https://github.com/achimnol § Python 3.3

    시절부터 asyncio 써왔음 (표준라이브러리 등재는 3.4) About Me
  2. § asyncio in 1 slide § Introduction to aiohttp §

    Server-side push vs. WebSockets § async-await in Javascript § Let's build a simple chat app Contents
  3. § 비동기 I/O(연산 아님!)를 이벤트루프 기반으로 코루틴 형식으로 표현 및

    실행 · 내부적으로는 generator처럼 취급됨 § async def로 코루틴 함수(coroutine function)를 선언 · 동기 코드에서 비동기 코드로 진입 : asyncio.run(f()) · 흐름 분기(=새로운 "micro-thread" 생성) : asyncio.create_task(f()) · 흐름 유지(=함수호출) : await f() · 추가 편의 기능 : async for, async with asyncio in 1 slide Python 3.7에서 추가된 사용자 친화 API
  4. § HTTP client & server for asyncio · asyncio 초기

    기여자인 Andrew Svetlov가 주도하여 개발한 프레임워크 · server 코드는 Flask와 유사한 느낌으로 개발 가능 aiohttp import aiohttp import asyncio async def fetch(session, url): async with session.get(url) as response: return await response.text() async def main(): async with aiohttp.ClientSession() as session: html = await fetch(session, 'https://python.org') print(html) asyncio.run(main()) from aiohttp import web async def handle(request): name = request.match_info.get('name', "Anonymous") text = "Hello, " + name return web.Response(text=text) app = web.Application() app.add_routes([web.get('/', handle), web.get('/{name}', handle)]) web.run_app(app) https://aiohttp.readthedocs.io/en/stable/
  5. § HTTP 1.0 & 1.1 · Request-Response · Header +

    Body § HTML 5 · Server-side push: 단방향 서버측 push (브라우저 내장 long-polling) (Content-Type: text/event-stream) · WebSockets: 양방향 실시간 커뮤니케이션 (binary protocol) Interactive HTTP
  6. § Promise API의 안과 밖을 뒤집어 콜백을 코루틴으로 표현 ·

    콜백은 매번 예외 처리 핸들러를 따로 달아줘야 하지만, 코루틴에서는 여러 Promise 호출을 표준 try-catch 블록으로 묶어서 예외 처리 가능 § Python에서는 asyncio.run()을 통해 코루틴으로 진입한다면, Javascript에서는 Promise API를 통해 코루틴으로 진입 async-await in Javascript async function myfunc() { let resp = await fetch("some-url", { method: "POST", body: JSON.stringify({...}), }); let data = await resp.json(); return data; } myfunc().then((result) => { console.log("result", result); }).catch((err) => { console.log("error", err); });
  7. § 구현 명세 · 브라우저로 접속하면 채팅 UI가 뜰 것

    (대화내역 + 입력칸) · 브라우저 접속 세션 별로 랜덤 user ID 생성 및 할당 (쿠키 + 서버측 세션) · 한 세션에서 타이핑한 메시지가 다른 세션들에서도 모두 보여야 함 § 힌트 : aiohttp, aiohttp_session, aiohttp_sse, aioredis 패키지를 써봅시다 § 변형 : POST + SSE 대신 WebSocket을 사용해서 구현해봅시다 (또는 그 반대) Let's build aiohttp chat app