FastAPI 구조 살펴보기 1

Dev Smile·2024년 11월 2일
2

FastAPI

목록 보기
4/10
post-thumbnail

FastAPI를 사용해오면서 문득 FastAPI는 어떻게 만들어졌는지에 대해서 궁금해져서 찾아보다가 좋은 글이 있어서 번역 및 내용을 추가하여 글을 작성 해보았습니다.

https://ceb10n.medium.com/understanding-fastapi-the-basics-14221665f742

구조를 살펴보기에 앞서서 먼저 FastAPI에 대해서 간단하게 설명하고 시작해보겠습니다.

1. FastAPI란?

FastAPI 공식 문서에서는 FastAPI를 아래와 같이 설명합니다.

FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트에 기초한 Python의 API를 빌드하기 위한 웹 프레임워크입니다.

간단히 말해서 FastAPI는 “API를 구축하기 위한 웹 프레임워크”라고 표현할 수 있을 것 같습니다.

그리고 문서를 계속 읽어보면, FastAPI는 처음부터 구축된 프레임워크가 아니라 다른 프레임워크인 Starlette 위에 구축된 프레임워크임을 확인할 수 있습니다.

그렇다면, Starlette가 무엇인지 살펴보겠습니다.

2. Starlette와 ASGI의 역할

2-1. Starlette은 무엇인가요?

Starlette 공식 문서를 살펴보면 아래와 같은 내용을 확인할 수 있습니다.

Starlette is a lightweight ASGI framework/toolkit, which is ideal for building async web services in Python.
( Starlette는 Python으로 비동기 웹 서비스를 구축하는 데 이상적인 가벼운 ASGI 프레임워크/툴킷입니다. )

설명을 읽어보면 ASGI 프레임워크/툴킷이라고 설명을 합니다.
이번에는 ASGI에 대해서 확인을 해봅시다.

2-2. ASGI란 무엇인가요?

[ASGI 문서](https://asgi.readthedocs.io/en/latest/index.html#:~:text=ASGI%20(,applications.)를 살펴보면 다음과 같이 설명합니다.

ASGI (Asynchronous Server Gateway Interface) is a spiritual successor to WSGI, intended to provide a standard interface between async-capable Python web servers, frameworks, and applications.
( ASGI(비동기 서버 게이트웨이 인터페이스)는 WSGI의 정신적 후계자로, 비동기 처리가 가능한 Python 웹 서버, 프레임워크, 애플리케이션 간의 표준 인터페이스를 제공하기 위해 만들어졌습니다. )

이번에는 WSGI라는 키워드가 등장하였습니다. 하나씩 올라가다보니 끝이 없습니다. 여기부터는 간단하게 설명하고 넘어가도록 하겠습니다.

WSGI를 이해하기 위해서는 CGI라는 개념을 먼저 알아야합니다. CGI (Common Gateway Interface)는 웹서버와 WAS사이의 인터페이스입니다.

WSGI는 파이썬에서 사용되는 개념으로 CGI의 단점을 보완한 개념으로 생각하시면 됩니다.

그렇다면 ASGI(비동기 서버 게이트웨이 인터페이스)는 WSGI에서 비동기 처리 부분을 개선한, 웹 서버와 파이썬 애플리케이션 간의 인터페이스를 제안하는 사양으로 설명드릴 수 있을 것 같습니다.

FastAPI 애플리케이션을 실행할 때, 요청을 애플리케이션에 전달해 줄 ASGI 서버를 사용하게 됩니다.

잘 알려진 ASGI 서버는 아래와 같은 것들이 있습니다.

2-3. 요약

FastAPI는 Starlette 위에 구축된 현대적인 파이썬 웹 프레임워크이고, Starlette는 실행을 위해 ASGI 서버가 필요한 경량 ASGI 프레임워크입니다.

3. 간단한 ASGI 애플리케이션 만들기

2번에서 FastAPI는 결국 ASGI 를 기반으로 만들어졌음을 확인할 수 있었습니다. 따라서 FastAPI가 어떻게 작동하는지 이해하기 위하여 간단한 ASGI 애플리케이션을 작성해보는 것부터 시작해보겠습니다.

ASGI에는 다음을 포함해야합니다

  • 딕셔너리와 두 개의 비동기 호출 가능한 객체를 매개변수로 받는 단일 비동기 호출 가능한 객체
async def app(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!",
    })

FastAPI가 제공하는 모든 기능, 미들웨어 및 오류 처리, OpenAPI 문서 등이 여기서부터 시작이 됩니다.

  • 코드 상세 설명: 이 코드는 비동기 방식으로 동작하는 웹 애플리케이션에서, 웹 요청에 대해 간단한 응답을 보내는 예시입니다.
    1. async def app(scope, receive, send):
      • async는 비동기 처리를 의미합니다. 즉, 이 함수는 바로 실행되지 않고, 기다릴 수 있는 작업을 할 수 있습니다.
      • def는 파이썬에서 함수를 정의하는 키워드입니다.
      • app은 이 함수의 이름입니다. 보통 웹 애플리케이션의 핵심 로직을 담고 있는 함수는 이렇게 간단하게 'app'이라고 많이 부릅니다.
      • 이 함수는 세 개의 매개변수를 받습니다.
        • scope: 이 매개변수는 요청에 대한 정보를 담고 있습니다. 예를 들어, 어떤 종류의 요청이 왔는지 알려줍니다.
        • receive: 이 함수는 요청이 오면 데이터를 받을 때 사용합니다.
        • send: 이 함수는 서버가 클라이언트(브라우저 등)에게 응답을 보낼 때 사용합니다.
    2. await send({...})
      • await는 파이썬에서 비동기 처리를 할 때 사용되는 키워드입니다. 이 말은, 이 부분이 끝날 때까지 잠시 기다렸다가, 다음 코드를 실행하겠다는 뜻입니다.
      • 첫 번째 send({...}) 함수는 웹 서버가 브라우저에게 응답의 시작을 알려줍니다. send 함수는 딕셔너리 형태의 데이터를 보내는데, 그 내용은 아래와 같습니다:
        • "type": "http.response.start": 응답의 시작이라는 것을 서버에 알려주는 메시지입니다.
        • "status": 200: 이 숫자는 HTTP 상태 코드로, 200은 요청이 성공적으로 처리되었음을 나타냅니다.
        • "headers": [[b"content-type", b"text/plain"]]: 이것은 응답의 헤더 부분을 나타냅니다. 브라우저에게 우리가 보내는 데이터가 일반 텍스트라는 것을 알려줍니다.
    3. await send({...})
      • 두 번째 send({...}) 함수는 실제 응답의 내용을 보내는 부분입니다. 여기서는 "Hello, World!"라는 메시지를 브라우저에 보냅니다.
        • "type": "http.response.body": 이 메시지는 본문(body)을 보내겠다는 것을 의미합니다.
        • "body": b"Hello, World!": 여기서 b는 바이트 형식으로 데이터를 보내는 것을 나타냅니다. 웹에서는 텍스트를 이런 바이트 형식으로 보냅니다.
    4. 요약
      • 이 코드는 웹 서버에서 요청이 들어오면, 브라우저에 "Hello, World!"라는 텍스트 응답을 보내는 아주 간단한 예제입니다. 이 과정에서 먼저 응답을 시작하고(응답 시작), 그 다음에 응답의 내용을 보냅니다(응답 본문). await는 비동기 방식으로 각 단계를 처리하는 동안 기다려주는 역할을 합니다.

이제 실제로 작동하는지 확인해 보겠습니다.

먼저 ASGI 서버를 설치합니다.

pip install uvicorn

실행해서 제대로 작동하는지 확인해 보겠습니다.

uvicorn app:app

이제 http://localhost:8000브라우저에 다음을 입력하세요:

INFO:     Started server process [4808]
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:64045 - "GET / HTTP/1.1" 200 OK

이제 Hypercorn으로 변경하여 Uvicorn에 종속되지 않았는지 확인해 봅시다.

pip install hypercorn

그리고 그것이 여전히 작동하는 것을 볼 수 있습니다:

hypercorn app:app
[2024-06-22 19:00:55 -0300] [13008] [WARNING] ASGI Framework Lifespan error, continuing without Lifespan support
[2024-06-22 19:00:55 -0300] [13008] [INFO] Running on http://127.0.0.1:8000 (CTRL + C to quit)

4. 간단한 FastAPI 복제본 만들기

이제 FastAPI의 내부 구조를 알았으므로 조금 더 알아보고 역대 가장 작고 간단한 ASGI 프레임워크를 만들어 보겠습니다.

class SimplestFrameworkEver:
    async def __call__(self, 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!",
        })

app = SimplestFrameworkEver()

그리고 다음과 같이 이전과 마찬가지로 실행할 수 있습니다.

hypercorn app:app

또는

uvicorn app:app

5. 결론 및 다음 단계

이제 FastAPI가 만들어진 기본 사항을 이해했으므로 다음글에서는 아래의 내용을 설명해보겠습니다.

  • Starllete 작동 방식
  • FastAPI가 Starllete를 확장하는 방법

0개의 댓글

관련 채용 정보