매일 업데이트
2022-10-18 02:18 9 min

Python용 상위 5가지 비동기 웹 프레임워크

파이썬에서 비동기 프로그래밍은 이제 핵심적인 부분으로 자리 잡았습니다. 특히 웹 개발 분야에서는 놀라운 프레임워크들이 다양하게 제공되고 있습니다!

현재 시점에서 비동기는 파이썬 커뮤니티에서 단순한 유행어를 넘어섰습니다. 파이썬 3.5 버전에서 asyncio 라이브러리가 도입되면서, 파이썬은 웹 개발에서 Node.js의 영향을 인정하고, 언어 자체에 `async` 및 `await`라는 두 가지 새로운 키워드를 추가했습니다. 파이썬 언어가 핵심 구문을 확장하는 데 매우 신중한 점을 고려하면, 이는 파이썬 개발자들이 비동기 기능의 중요성을 얼마나 크게 인식했는지를 보여주는 중요한 변화입니다.

이러한 변화는 비동기 프로그래밍의 확산을 가속화했습니다. 새로운 라이브러리와 기존 라이브러리들이 코루틴 기능을 적극적으로 활용하기 시작했고, 비동기 프레임워크의 인기가 급증했으며, 현재에도 새로운 라이브러리들이 계속 개발되고 있습니다. Node.js와 동등하거나 그 이상의 성능을 보여주는 것이 가능해졌으며, CPU를 많이 사용하는 작업이 적은 경우에는 초당 수천 건의 요청을 처리하는 데 전혀 문제가 없습니다.

하지만 동기부여는 충분합니다!

이제 파이썬의 비동기 생태계를 살펴보고, 가장 뛰어난 비동기 프레임워크들을 알아보겠습니다.

토네이도

놀랍게도, 토네이도는 완전히 새로운 프레임워크가 아닙니다. 2009년에 처음 출시되었으며, 그 이후로 높은 동시성을 가진 안정적인 비동기 프로그래밍을 제공하는 데 주력해 왔습니다.

토네이도는 본질적으로 웹 프레임워크라기보다는 비동기 모듈의 모음으로, 웹 프레임워크 모듈을 구축하는 데에도 사용됩니다. 구체적으로는 다음과 같은 모듈들로 구성되어 있습니다.

  • 코루틴 및 기본 요소(tornado.gen, tornado.locks, tornado.queues 등)
  • 네트워킹 모듈(tornado.ioloop, tornado.iostream 등)
  • 비동기 서버 및 클라이언트(tornado.httpserver, tornado.httpclient 등)

이러한 모듈들이 결합되어 최종적인 프레임워크 모듈인 tornado.web, tornado.routing, tornado.template 등을 구성합니다.

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

토네이도는 파이썬 커뮤니티에서 강력하고 헌신적인 지지층을 보유하고 있으며, 경험 많은 개발자들이 고성능 시스템을 구축하는 데 활용합니다. 이 프레임워크는 오랫동안 동시성 문제에 대한 해결책을 제시해 왔지만, WSGI 표준을 지원하지 않고 독자적인 방식으로 개발되어 주류로 자리 잡지 못했습니다 (대부분의 파이썬 라이브러리가 여전히 동기적으로 작동한다는 점을 기억해야 합니다).

사닉

사닉은 진정한 의미에서 '현대적인' 프레임워크입니다. 파이썬 3.6 미만 버전을 지원하지 않으며, 기본적인 `async/await` 구문을 사용하여 코드를 작성하므로 가독성이 뛰어나고 불필요한 복잡성을 피할 수 있습니다. 따라서 첫 번째 HTTP 핸들러를 작성하기 전에 문서화를 숙지하고 여러가지 예외 상황에 대비하는 것이 좋습니다.

결과적으로 코드 구조가 매우 깔끔합니다. Flask나 CherryPy와 같은 다른 마이크로프레임워크에서 비동기를 일부 적용한 것과 유사합니다.

from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route("/")
async def test(request):
    return json({"hello": "world"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

사닉은 파이썬 세계에서 가장 인기 있고 사랑받는 비동기 프레임워크 중 하나입니다. 라우팅, 미들웨어, 쿠키, 버전 관리, 청사진, 클래스 기반 뷰, 정적 파일, 스트리밍, 소켓 등 프로젝트에 필요한 대부분의 기능을 기본적으로 제공하며, 템플릿, 데이터베이스 지원, 파일 I/O, 대기열 등과 같은 추가 기능은 현재로서는 비동기 라이브러리를 통해 충분히 지원이 가능합니다.

비보라

비보라는 가장 빠른 파이썬 웹 서버가 되려는 목표를 가지고 있다는 점을 제외하면 사닉과 매우 유사합니다. 실제로 웹사이트를 방문하면 다른 프레임워크들과 성능을 비교하는 차트를 바로 확인할 수 있습니다.

표에서 볼 수 있듯이, 비보라는 기존의 프레임워크보다 몇 배 더 빠르며, 가장 가까운 경쟁자인 사닉보다도 두 배 이상 빠르다고 주장합니다. 물론 벤치마크는 여러 가지 요인에 따라 달라질 수 있다는 점을 고려해야 합니다. 🙂

구문 및 기능 면에서 비보라는 사닉과 비슷하지만, (템플릿과 같은 인기 있는 라이브러리를 번들로 제공하여 즉시 사용할 수 있다는 점에서 약간 더 나을 수도 있습니다.) 사닉은 좀 더 오래되었고 더 큰 커뮤니티를 가지고 있습니다.

from vibora import Vibora, JsonResponse

app = Vibora()

@app.route('/')
async def home():
    return JsonResponse({'hello': 'world'})

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

만약 성능에 민감한 개발자라면 비보라가 훌륭한 선택이 될 수 있습니다. 다만, 현재 시점에서 비보라는 성능 향상을 위해 완전히 재작성되고 있으며, 성능 버전은 "활발한 개발 중"이라는 점에 유의해야 합니다. 이는 비보라를 미리 선택한 사람들에게는 실망스러울 수 있으며, 주요 변경 사항에 직면할 수 있지만, 파이썬 비동기 세계는 아직 초기 단계이므로 어느 것도 확정적이라고 말하기는 어렵습니다.

쿼트

만약 플라스크를 사용하는 것을 좋아하지만 비동기 지원이 부족하다면, 쿼트가 좋은 대안이 될 수 있습니다.

쿼트는 ASGI를 준수하며, 이는 널리 알려진 WSGI 표준의 후속으로 비동기 지원을 제공합니다. 쿼트의 가장 큰 특징은 플라스크와 유사할 뿐만 아니라 실제로 플라스크 API와 호환된다는 점입니다! 이 프레임워크의 개발자는 플라스크의 느낌을 그대로 유지하면서 비동기, 웹소켓, HTTP 2 지원을 추가하고 싶어했습니다. 결과적으로 쿼트의 함수는 비동기적으로 실행된다는 점을 제외하면 플라스크 문서를 통해 쿼트를 바로 배울 수 있습니다.

from quart import Quart

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'hello'

app.run()

플라스크와 거의 동일한 느낌을 받지 않으셨나요?

쿼트는 플라스크의 진화된 버전이므로, 플라스크에서 제공하는 모든 기능(라우팅, 미들웨어, 세션, 템플릿, 청사진 등)을 사용할 수 있습니다. 심지어 쿼트 내에서 플라스크 확장 기능을 직접 사용할 수도 있습니다. 한 가지 유의해야 할 점은 파이썬 3.7 이상 버전만 지원한다는 것입니다. 하지만 최신 파이썬 버전을 사용하지 않는다면 비동기가 적합한 선택이 아닐 수도 있습니다. 🙂

플라스크 경험이 없다면 문서 학습이 필요하겠지만, 쿼트는 곧 1.0 버전을 출시할 예정이며, 현재 유일하게 1.0 릴리스에 가까운 비동기 프레임워크이므로 추천할 만합니다.

패스트API

이 목록의 마지막 프레임워크이지만, 가장 인상적인 프레임워크는 패스트API입니다. 이는 API 전용 프레임워크가 아닙니다. 사실, 패스트API는 비동기 파이썬 프레임워크들을 조사하는 과정에서 발견한 가장 기능이 풍부하고 문서화가 잘 된 프레임워크였습니다.

패스트API 개발자는 Django와 같은 전통적인 프레임워크부터 Sanic과 같은 현대적인 프레임워크까지 다양한 프레임워크를 깊이 연구했으며, NestJS(Node.js, Typescript 웹 프레임워크)에서 많은 기술을 가져왔다고 합니다. 그들의 개발 철학과 다양한 프레임워크와의 비교는 여기에서 확인할 수 있습니다.

패스트API의 코드 구문은 매우 깔끔하며, 다른 프레임워크보다 더 편리하다고 주장할 수도 있습니다.

from fastapi import FastAPI

app = FastAPI()

@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}

@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

이제 패스트API를 다른 프레임워크와 차별화시키는 주요 기능들을 살펴보겠습니다.

자동 API 문서 생성: 엔드포인트를 작성하는 즉시 표준 호환 UI를 사용하여 API를 사용할 수 있습니다. SwaggerUI 및 ReDoc 등이 지원됩니다.

또한, 프레임워크는 JSON 스키마를 사용하여 자동 데이터 모델 문서를 생성합니다.

현대적인 개발: 많은 곳에서 "현대적"이라는 단어를 사용하지만, 패스트API는 실제로 "현대적"인 개발 방식을 지원하는 프레임워크입니다. 의존성 주입과 타입 힌트는 좋은 코딩 원칙을 적용할 뿐만 아니라 장기적으로 버그와 혼란을 방지하는 데 중요한 역할을 합니다.

광범위한 문서: 저는 좋은 문서에 매우 중요하게 생각합니다. 그리고 패스트API는 이 분야에서 단연 최고입니다. 사소한 내용까지 자세하게 설명하고, "주의해야 할 점"과 같은 세세한 부분까지 모두 설명하는 페이지들이 많습니다. 모든 수준의 개발자들이 쉽게 이해할 수 있도록 배려하고 있으며, 이 문서에서 느껴지는 노력은 Django 문서와 비견될 만합니다 (패스트API의 문서가 정말 좋습니다!).

기본 이상의 기능: 패스트API는 CORS, 세션, 쿠키 등과 같은 기존 도우미 외에도 웹소켓, 스트리밍 및 GraphQL을 지원합니다.

성능은 어떤가요? 패스트API는 뛰어난 Starlette 라이브러리를 기반으로 하므로, Node.js와 비슷하거나 때로는 Go와 비슷한 성능을 제공합니다. 전반적으로 패스트API가 파이썬 최고의 비동기 프레임워크로 자리매김할 것이라는 예감이 듭니다.

결론

현재 파이썬 비동기 환경은 매우 활발하게 발전하고 있습니다. 새로운 프레임워크가 등장하고, 기존 프레임워크가 재작성되고, 라이브러리들이 비동기 동작을 지원하도록 진화하고 있습니다. 파이썬에는 이벤트 루프에 대한 지원이 내장되어 있으며, 애플리케이션의 일부를 비동기적으로 만드는 것이 가능하지만, 여기에 소개된 프레임워크들을 활용하여 더 많은 기능을 쉽게 구축할 수 있습니다. 다만, 파이썬 비동기 프레임워크들은 아직 초기 단계에 있으며 빠르게 변화하고 있다는 점을 명심해야 합니다. 이러한 변화는 개발 프로세스에 영향을 미치고 비즈니스 비용을 증가시킬 수 있으므로 신중하게 접근해야 합니다!

하지만 이 모든 것을 고려했을 때, 파이썬은 이제 웹 프레임워크와 관련하여 뛰어난 성능을 제공할 수 있으며, 프로덕션 환경에서도 충분히 활용할 수 있습니다. 그동안 Node.js로 마이그레이션을 고려했다면 이제 그럴 필요가 없을 수도 있습니다! 🙂

멋지지 않나요? 오늘 파이썬 전문가가 되어보세요!

저자
Korea

기술 트렌드와 실용적인 팁을 전하는 लेखक입니다.