Search

파이썬 웹 표준 라이브러리

가. CGI, WSGI, ASGI

1) CGI 개요

CGI(Common Gateway Interface): ‘웹 서버’와 ‘독립적인 프로그램(또는 프로세스)’ 간 연동 규격

2) CGI 주요 특징

클라이언트의 요청 발생 시 각각의 요청에 대해 웹 서버가 CGI 프로그램을 직접 호출함
→ CGI 프로그램: CGI 규격을 만족하는 독립적인 프로그램
대량 요청 전달 시, 수많은 프로세스가 한꺼번에 생성되어 메모리 요구량이 급격하게 증가함
→ 대량 요청 처리 시 과부하에 따른 시스템 이상 발생

3) WSGI 개요

WSGI(Web Server Gateway Interface): ‘웹 서버’와 ‘웹 어플리케이션’ 간 연동 규격
→ CGI의 대량 요청에 따른 과부하라는 단점을 보완하는 과정에서 등장
→ 파이썬으로 작성되어 파이썬 계열의 ‘웹 어플리케이션’에 최적화됨
→ ‘웹 어플리케이션’을 쉽게 작성할 수 있도록 설계됨
→ 파이썬 ‘웹 어플리케이션’에서는 WSGI를 통해 CGI가 처리됨
WSGI의 구현체로 mod_wsgi, uWSGI, Gunicorn 등이 있음

4) WSGI 주요 특징

WSGI는 데몬 프로세스로 동작하는 웹 어플리케이션 전용 ‘웹 어플리케이션 서버’로 분류됨
클라이언트 요청 발생 시 WSGI에서 웹 어플리케이션을 간접 생성함
→ WSGI의 어플리케이션 간접 생성 방식은 쓰레드 처리 기술과 객체 지향 기술 도입에 따라 프로세스 생성 부하가 많이 줄어들게 됨
범용 ‘웹 서버’(Apache, Nginx 등) 사용 시 파이썬 ‘웹 어플리케이션’과 ‘웹 서버’ 간 WSGI 통신 규격을 처리해주는 WSGI 서버가 필요함
→ 범용 ‘웹 서버’(Apache, Nginx 등)에는 WSGI 처리 지원 기능이 없음
간단한 어플리케이션의 경우, 범용 웹서버 대신 WSGI를 사용 가능

5) ASGI 개요

ASGI(Asynchronous Server Gateway Interface): ‘웹 서버'와 ‘웹 어플리케이션' 간 비동기, 동기 처리 지원을 포함한 연동 규격
→ WSGI의 비동기 처리 미지원이라는 단점을 보완하는 과정에서 등장
AWSGI의 구현체로 Daphne, Uvicorn, Hypercorn 등이 있음

6) ASGI 주요 특징

ASGI는 단일 비동기 호출 방식으로 설계됨
각 어플리케이션에서 복수의 송수신 이벤트가 발생 가능
어플리케이션에서 백그라운드 코루틴(background coroutine)을 지원함
→ ex) 외부의 이벤트 trigger에 대한 실시간 모니터링
ASGI는 WSGI의 상위호환으로 translation wrapper 방식으로 WSGI 어플리케이션을 ASGI 서버에서 동작하도록 지원함
→ WSGI 동작 지원 시 WSGI 어플리케이션은 threadpool에 의해 동기적으로 실행함
→ WSGI 동작 지원 시 WSGI 어플리케이션은 ASGI의 비동기 이벤트루프에서 관리되지 않음

나. 웹서버, WSGI, 어플리케이션 간 연동 방식

1) 웹 서버

클라이언트로부터 Request 수신
Request의 URL 분석
WSGIScriptAlias에 정의된 URL이라면 WSGI 서버에 처리 위임

2) WSGI 서버

WSGIScriptAlias에 정의된 wsgi.py 실행
environ, start_response 함수 호출

3) 웹 어플리케이션

environ 환경변수 처리
뷰 처리, HTTPRequest 객체 생성
start_response() 함수 호출
return HTTPResponse

4) WSGI 서버

표준 출력(stdout)에 결과 출력
웹 서버로 처리 결과 전달

4) 웹 서버

클라이언트에 Response 송신

다. ASGI 서버의 비동기 동작 방식

1) 비동기 함수 주요특징

이벤트 메시지 포맷은 파이썬의 dictionary
비동기 함수 구성요소
→ scope: connection에 대한 세부사항 명시
→ receive: 클라이언트로부터 이벤트 메시지를 받는 비동기 함수
→ send: 클라이언트에게 이벤트 메시지를 보내는 비동기 함수
async def application(scope, receive, send): event = await receive() ... await send({"type": "websocket.send", ...})
Python
복사
code from https://asgi.readthedocs.io/en/latest/introduction.html#how-does-asgi-work

2) HTTP Request 이벤트 메시지 포맷

이벤트 메시지의 type 필드에 통신 방식 명시: http request로 메시지 수신
HTTP Request의 body 값도 이하 예시와 같이 전달됨
{ "type": "http.request", "body": b"Hello World", "more_body": False, }
Python
복사
code from https://asgi.readthedocs.io/en/latest/introduction.html#how-does-asgi-work

3) WebSocket 이벤트 메시지 포맷

type 필드에 통신 방식 명시: websocket으로 메시지 송신
{ "type": "websocket.send", "text": "Hello world!", }
Python
복사
code from https://asgi.readthedocs.io/en/latest/introduction.html#how-does-asgi-work

Reference

(기초편) 파이썬 웹 프로그래밍, 김석훈, 한빛미디어
(실전편) 파이썬 웹 프로그래밍, 김석훈, 한빛미디어