파이썬 웹 서비스

WSGI 규약과 ASGI 규약

  • 파이썬 웹서버는 웹 브라우저로부터 받은 호출에 따라 미리 정해진 파이썬 함수를 실행하고 그 결과를 다시 웹브라우저에게 전달한다.
  • 이 때 호출될 파이썬 함수가 어떻게 구현되어 있어야 하고 이 함수를 어떤 식으로 호출하는가는 미리 정한 규약을 따라야 한다.
  • WSGI(Web Server Gateway Interface) 규약은 동기적으로 파이썬 코드를 실행하는 경우 사용되는 규약
  • ASGI(Asynchronous Server Gateway Interface) 규약은 비동기적으로 파이썬 코드를 실행하는 경우 사용되는 규약

WSGI 웹 서버

  • WSGI 웹 서버에 제공되는 파이썬 함수는 다음과 같이 구현되어야 한다.
# wsgi_app_module1.py

from collections.abc import Callable, Iterable

def app(env: dict, start_response:  Callable) -> Iterable[bytes]:
  # env에 있는 입력 정보를 처리하여 출력 데이터 생성
  data = b"Hello, World!"
  # start_response 함수를 호출하여 상태, 헤더, 예외 전송
  start_response("200 OK", [
        ("Content-Type", "text/plain"),
        ("Content-Length", str(len(data))),
    ])
  # 결과를 이터러블 객체로 반환
  return [data]
```
  • WSGI 규약에 따라 만들어진 대표적인 웹 서버는 gunicorn 서버이다. (윈도우즈 OS에서는 사용불가)
  • gunicorn 서버는 다음과 같이 웹서버 코드를 가진 모듈 이름과 함수 이름을 인수로 주어 가동한다.
  • 모듈은 임포트 가능해야 한다. 즉 gunicorn 명령을 실행하는 디렉토리에 있거나 위치가 sys.path 경로내에 포함되어 있어야 한다.
$ gunicorn wsgi_app_module1:app

ASGI 웹 서버

  • ASGI 웹 서버에 제공되는 파이썬 함수는 다음과 같이 구현되어야 한다.
  • WSGI 규약과 달리 결과를 반환하지 않고 상태정보나 헤더정보처럼 send 함수로 보낸다.
# asgi_app_module1.py

from typing import Callable

async def app(
    scope: dict,
    receive: Callable,
    send: Callable,
) -> None:
    # body가 있는 경우 receive 함수를 호출하여 정보 입수
    # event = await receive()
    data = b"Hello, world!"

    # 상태 코드와 헤더 전송
    await send({
        "type": "http.response.start",
        "status": 200,
        "headers": [(b"content-type", b"text/plain")],
    })

    # 응답 본문 전송
    await send({
        "type": "http.response.body",
        "body": data,
    })
  • ASGI 규약에 따라 만들어진 대표적인 웹 서버는 uvicorn 서버
  • 가동 방식은 gunicorn과 같다.
$ unvicorn asgi_app_module1:app

웹 프레임워크

  • 웹 프레임워크는 웹 서버가 사용할 애플리케이션 코드를 구현하는 것을 도와주는 파이썬 패키지
  • 복잡한 웹 애플리케이션을 구조화하여 개발할 수 있는 체계를 제공
  • 웹 애플리케이션 구현시 공통적으로 필요한 로그인 처리, 세션 처리, 데이터베이스 연결 등에 필요한 자료구조나 함수 등을 제공
  • 대표적 웹 프레임워크
    • flask: 소형 웹 프레임워크. WSGI 지원
    • django: 자체 ORM, 템플릿, 관리자 UI 등을 포함하는 풀스택 웹 프레임워크, WSGI/ASGI 모두 지원
    • starlette: 소형 웹 프레임워크. ASGI 지원

starlette

  • 비동기 ASGI 전용 웹 프레임워크
# starlette1.py

from starlette.applications import Starlette
from starlette.responses import PlainTextResponse
from starlette.routing import Route


async def homepage(request):
    return PlainTextResponse("Hello, world!")


app = Starlette(debug=True, routes=[
    Route('/', homepage),
])