2.4 CGI/WSGI 라이브러리
파이썬에는 WSGI(Web Server Gateway Interface) 규격이 정의되어있으며, 파이썬 애플리케이션을 실행하는 웹 서버는 이 규격을 준수해야한다.
WSGI는 웹 서버와 웹 애플리케이션을 연결하는 규격으로 장고와 같은 파이썬 웹 프레임워크를 개발하거나, 이런 웹 프레임워크를 아파치와 같은 웹서버와 연동할 때 사용한다.
파이썬 표준 라이브러리에는 CGI 규격을 위한 cgi 모듈과, 개선된 WSGI 규격을 구현하기위한 wsgiref 모듈이 함께 존재한다.
다만 wsgiref 모듈이 cgi모듈 기능을 포함하므로, 현재 cgi 모듈은 거의 사용되지 않는다.
2.4.1 CGI 관련 모듈
사용자의 요청은 웹 서버에 있는 파일을 그대로 요청하는 정적 요청과, 요청 시점에 따라 응답 내용이 달라지는 동적 요청이 있다.
동적 요청은 별도의 애플리케이션에서 처리하는 것이 일반적이며, 웹 서버는 동적 요청을 애플리케이션으로 넘겨주고 그 결과를 받는 기능이 필요하다.
이 때 웹서버가 사용자의 요청을 애플리케이션에 전달하고 애플리케이션의 처리 결과를 애플리케이션으로부터 되돌려받기 위한, 즉 웹서버와 애플리케이션 간 데이터를 주고 받기 위한 규격을 CGI(Common Gateway Interface)라고 한다.
파이썬 표준 라이브러리에서는 CGI 처리를 위해 cgi 모듈과 cgitb모듈을 제공한다.
- cgi 모듈 : 요청에 포함된 파라미터를 처리하기위한 FieldStorage 클래스를 정의.
- cgitb 모듈 : CGI 애플리케이션(스크립트)을 실행하는 과정에 에러가 발생하면 에러에 관한 상세 정보를 표시한다.
파이썬은 일반적으로 WSGI 기술을 사용하여 CGI처리를 하기 때문에 cgi 모듈은 자주 사용되지는 않는다.
2.4.2 WSGI 개요
기존 CGI 방식은 요청이 들어올 때마다 처리를 위한 프로세스를 생성하는 방식이기 때문에, 동일한 시간에 다수의 요청을 받으면 서버의 부하가 높아져 프로세스가 멈출 위험이 높다.
이러한 CGI의 단점을 보완하여 웹서버와 웹애플리케이션 간 연동규격을 정의한 것이 WSGI이다.
WSGI 규격만 맞다면, 어떤 웹서버에서도 파이썬 애플리케이션을 실행할 수 있다.
(Ex. Django 웹 애플리케이션 작성 -> Apache, NGINX 등 모든 웹서버에서 실행 가능)
다만, Apache나 NGINX는 일반 범용 웹서버로 WSGI 처리 기능을 가지고 있지 않다.
그래서 웹서버와 파이썬 웹애플리케이션 간 WSGI 통신 규격을 처리하는 것이 WSGI 서버(mod_wsgi, uWSGI, Gunicorn)이다.
2.4.3 WSGI 서버의 애플리케이션 처리 과정
대부분의 파이썬 웹 프레임워크는 WSGI 서버를 제공하며, 애플리케이션 개발자는 WSGI 서버에 대한 API 규격만 맞추면 웹서버와 독립적으로 애플리케이션을 작성할 수 있다.
WSGI 규격에 따라 작성된 애플리케이션에서, 웹 클라이언트의 요청을 받아 처리하는 과정은 아래와 같다.
- 웹서버에서 클라이언트의 요청을 받아 WSGI 서버로 처리를 위임한다.
- WSGI 서버는 애플리케이션을 실행하여 그 결과를 웹 서버에게 되돌려준다.
- 웹 서버는 클라이언트에게 응답 결과를 보여준다.
WSGI 규격에 따라 애플리케이션을 개발할때 중요한 규칙이 있다.
- 개발이 필요한 애플리케이션을 함수 또는 클래스의 메소드를 정의하고, 애플리케이션 함수의 인자는 다음과 같이 정의한다.
- environ : 웹프레임워크에 이미 정의되어있으며 HTTP_HOST, HTTP_USER_AGENT, SERVER_PROTOCOL과 같은 HTTP 환경 변수를 포함한다.
- start_response : 애플리케이션 내에서 응답을 시작하기 위해 반드시 호출해야하는 콜백함수이다.
- def application_name(environ, start_response) :
- start_response 함수의 인자는 다음과 같이 정의한다.
- status : 응답코드 및 응답메시지를 지정한다.(200 OK, 404 Not Found 등)
- headers : 응답헤더를 지정한다.
- 애플리케이션 함수의 리턴 값은 응답 바디에 해당하는 내용으로 리스트나 제너레이터 같은 iterable 타입이어야한다.
- iterable: "반복 가능한" 데이터타입으로, 해당 element 하나하나를 개별로 리턴할 수 있는 타입.
2.4.4 wsgiref.simple_server 모듈
파이썬 표준 라이브러리에서는 웹 프레임워크 개발자가 웹 서버와의 연동 기능을 개발할 수 있도록 wsgiref 패키지의 하위 모듈로 wsgiref.simple_server를 제공한다.
이 모듈은 WSGI서버(WSGI 규격을 준수하는 웹서버)에 대한 참조 서버(reference), 즉 개발자에게 참고가 될 수 있도록 미리 만들어놓은 WSGIServer 클래스와 WSGIRequestHandler 클래스를 정의하고 있다.
wsgiref.simple_servere 모듈을 활용하여 WSGI 서버를 만들어보자.
from wsgiref.simple_server import make_server
def my_app(environ, start_response):
status = '200 OK'
headers = [('Content-Type', 'text/plain')]
start_response(status, headers)
response = [b"This is a sample WSGI Application."]
return response
if __name__ == '__main__':
print("Started WSGI Server on port 8888...")
server = make_server('', 8888, my_app)
server.serve_forever()
- wsgiref.simple_server 모듈은 WSGI 규격을 준수하여 WSGI 서버를 작성할 수 있도록 API를 제공하고 있다.(ex. make_server(), serve_forever())
- my_app() 과 같은 애플리케이션 로직을, 호출 가능한(callable) 함수나 메소드로 정의하여, 이 함수를 make_server() 인자로 넘겨주어 WSGI 웹 서버를 만든다. 이는 애플리케이션 프로그램과 웹 서버 프로그램을 독립적으로 작성할 수 있게 해주는 WSGI 규격의 중요한 원칙에 해당된다.
- my_app() 함수가 WSGI 규격을 준수하는 애플리케이션 코드이다. 이 애플리케이션 함수에서 응답을 위한 헤더 및 바디를 구성해서 반환한다.
'Spec UP - Backend > Django로 배우는 쉽고 빠른 웹개발 파이썬 프로그래밍' 카테고리의 다른 글
chap 3. Django 프레임워크 (1) | 2024.02.27 |
---|---|
CGI / WSGI / ASGI (0) | 2024.02.21 |
chap 02. 웹 서버 라이브러리 (0) | 2024.02.20 |
chap 02. 파이썬 웹 표준 라이브러리 (1) | 2024.02.07 |
chap 01. 웹프로그래밍의 이해 (0) | 2024.02.01 |
댓글