우연히 FastAPI를 통해 웹 서버를 구축하는 프로젝트를 수행하게 되었다. 공부하던 중에 이해가 안되는 부분이 있었다. Spring 밖에 서버를 구축하는 데에 동적 페이지 부분에 있어서 꼭 필요한 Tomcat과 같은 WAS가 있어야 하는데 공식 문서 대로 보니 FastAPI는 그런 부분은 없고 Uvicorn이라는 것이 있었다. 이게 WAS인가 싶어서 찾아보니 아니었고 내가 알고 있던 것과 괴리감을 느낀 나머지 궁금증을 해결하고자 한번 정리해 보았다.
웹 서버와 외부 애플리케이션 사이의 인터페이스 규격이다. 초기 웹 개발 때 많이 사용되던 방식이다.
Python CGI, Perl CGI등의 라이브러리에 사용된다.
#!/usr/bin/python3
import cgi
form = cgi.FieldStorage()
a = form.getvalue('a')
b = form.getvalue('b')
result = int(a) * int(b)
print('Content-type: text/plain')
print()
print(f'Result:{result}')
python 웹 어플리케이션과 웹 서버 사이의 표준 인터페이스를 정의한다. 웹 서버가 클라이언트로 부터 받은 요청을 파이썬 애플리케이션 전달하여 실행하고 그 실행 결과를 돌려받기 위한 약속이다.
Flask, Django에서 채택하고 있는 기술이다.
특징
# environ은 웹 서버가 제공한 환경변수와 현재 요청에 대한 정보가 포함된 딕셔너리
# start_response: 클라이언트로 HTTP 응답을 보내는 작업을 시작하는 데 사용되는 함수
def simple_wsgi_app(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/plain')]
start_response(status, headers)
return [b"Hello WSGI World!"]
기존 CGI와의 차이점
WSGI와 비슷한 구조를 가지면서 기본적으로 요청을 비동기로 처리하는 방식이다. WSGI의 상위 버전이라고 할 수 있다. 요즘 출시된 FastAPI, Starlette에서 Uvicorn에서 사용되는 기술이다. (요즘 Django의 3.0 이상부터 지원한다고 한다)
async def application(scope, receive, send):
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
[b'content-type', b'text/plain'],
],
})
await send({
'type': 'http.response.body',
'body': b'Hello, world!',
})
uvicorn은 파이썬 용 ASGI 기반 웹서버 구현체이다. 기존 방식들과는 다르게 low-level의 비동기 프레임워크들을 지원 해준다. ( HTTP/1.1 & 웹소켓)
$ pip install uvicorn # 기본 설치
$ pip install 'uvicorn[standard]' # 최소한의 의존성 설치
$ uvicorn main:app # 실행
import uvicorn
async def app(scope, receive, send):
...
if __name__ == "__main__":
uvicorn.run("main:app", port=5000, log_level="info")
정리가 잘 된 글이네요. 도움이 됐습니다.