요즘IT
위시켓
콘텐츠프로덕트 밸리
요즘 작가들컬렉션물어봐
놀이터
콘텐츠
프로덕트 밸리
요즘 작가들
컬렉션
물어봐
놀이터
새로 나온
인기
개발
AI
IT서비스
기획
디자인
비즈니스
프로덕트
커리어
트렌드
스타트업
서비스 전체보기
위시켓요즘IT
고객 문의
02-6925-4867
10:00-18:00주말·공휴일 제외
yozm_help@wishket.com
요즘IT
요즘IT 소개작가 지원
기타 문의
콘텐츠 제안하기광고 상품 보기
요즘IT 슬랙봇크롬 확장 프로그램
이용약관
개인정보 처리방침
청소년보호정책
㈜위시켓
대표이사 : 박우범
서울특별시 강남구 테헤란로 211 3층 ㈜위시켓
사업자등록번호 : 209-81-57303
통신판매업신고 : 제2018-서울강남-02337 호
직업정보제공사업 신고번호 : J1200020180019
제호 : 요즘IT
발행인 : 박우범
편집인 : 노희선
청소년보호책임자 : 박우범
인터넷신문등록번호 : 서울,아54129
등록일 : 2022년 01월 23일
발행일 : 2021년 01월 10일
© 2013 Wishket Corp.
로그인
요즘IT 소개
콘텐츠 제안하기
광고 상품 보기
개발

인상적인 프로젝트 만들려면 FastAPI 꼭 써보세요

한날
11분
1시간 전
235
에디터가 직접 고른 실무 인사이트 매주 목요일에 만나요.
newsletter_profile0명 뉴스레터 구독 중

많은 취업 준비생이나 주니어 개발자들이 포트폴리오를 확보하거나 학습을 목적으로 사이드 프로젝트, 즉 토이 프로젝트를 만듭니다.

 

저는 개발자 멘토링을 진행할 때마다, 토이 프로젝트를 만든다면 가능한 출시까지, 기왕 하는 김에 운영까지 해볼 것을 강하게 권합니다. 자신의 환경에서 실제로 사용하는 도구로 프로젝트를 완성하고 유지보수 하는 방식도 물론 좋습니다. 그럼에도 출시와 운영을 추천하는 이유는 그렇게 프로젝트를 출시하고 운영하는 과정에서 자신을 더 많이 드러낼 수 있는 요소가 담기기 때문입니다.

 

실제로는 대부분 프로젝트가 개인 작업 PC, 즉 로컬호스트(localhost)에서 구동될 뿐 출시로 이어지지 않습니다. 프로젝트를 출시하고 운영하는 것 자체가 쉽지 않은 목표이며, 이는 경력자에게도 마찬가지입니다. 하물며 거의 모든 주니어는 출시와 운영 경험이 없거나 부족합니다. 그렇기에 프로젝트를 끝내 출시하고 운영하지 못하는 일은, 어찌 보면 자연스러운(?) 현상에 가깝습니다.

 

따라서 프로젝트를 출시하고 운영하려면, 시작부터 목표 자체를 ‘출시’와 ‘운영’에 두어야 합니다. 그런 목표를 달성하려면 무엇을 해야 할지 고민하고 계획해야 합니다. 도구 선택은 더더욱 그렇습니다. 출시와 운영을 목표로 둔 프로젝트에서는 자신에게 가장 친숙하고 익숙하며 능숙한 도구가 가장 좋은 도구입니다. 구체적일수록 좋습니다. 예를 들어 Python 3.11을 가장 많이 다뤘고 익숙하다면, 굳이 Python 3.14를 선택할 이유는 없습니다. 일할 때 걸리적거리는 사소한 것들 하나하나가 여러분의 의지력을 갉아먹기 때문입니다.

 

문제는 어떤 도구는 그 자체가 지나치게 커서 능숙해지기까지 많은 비용이 들거나, 사용 그 자체에 비용이 많이 든다는 점입니다. 간단한 A를 구현하려면 도구의 299,792,458가지 요소를 알아야 하는 경우죠. 도구 자체가 문제는 아니지만, 출시와 운영을 목표로 한 토이 프로젝트에는 썩 적합하지 않습니다.

 

이런 점에서 FastAPI는 출시와 운영에 가장 적합한 도구입니다. 이번 글에서는 어떤 점에서 프로젝트를 실제로 출시하고 운영할 때 좋은지를 중심으로 FastAPI를 소개해 보겠습니다.

 

 

FastAPI

FastAPI는 2018년 말, 처음 세상에 모습을 드러낸 웹 프레임워크입니다. 떠오르는 웹 프레임워크로 주목받기 시작한 시점은 2021년에서 2022년 사이로, 자리 잡는 데 꽤 긴 시간이 걸린 셈입니다.

 

fastapi 키워드의 관심도 변화 <출처 : 구글 트렌드>

 

공식 웹사이트의 한 문장짜리 표어가 FastAPI를 아주 잘 표현합니다.

 

FastAPI framework, high performance, easy to learn, fast to code, ready for production

 

고성능이면서 학습하기 쉽고, 빠르게 개발할 수 있으며, 프로덕션 환경에서도 바로 사용할 수 있다는 의미입니다. 이 문장은 FastAPI가 처음 등장한 이후 단 한 번도 변경되지 않았습니다. 단순히 홍보로 쓴 한 문장이 아니라, FastAPI가 지향하는 철학과 방향성인 듯합니다.

 

여기서 FastAPI의 높은 성능에 대한 이야기는 주제에서 벗어나니 잠시 제껴두고, 어떤 점이 학습하기 쉬우며, 빠르게 개발하도록 하는지 알아보겠습니다.

 

 

Easy to learn

FastAPI는 구조와 흐름이 무척 간결합니다. 프레임워크에는 저마다 의도하고 지향하는 구조와 체계가 있고, 개발자가 작성한 코드는 그러한 체계 안에서 운용됩니다. 우측통행이라는 규칙을 기준으로 보도블록이나 에스컬레이터 같은 환경 요소가 그에 맞게 설계되듯, 프레임워크 역시 지향이나 철학에 따라 API를 의도적으로 설계하고 추상화하지요.

 

FastAPI의 추상화 방식은 순수(?) Python 코드를 향하는 특성을 보입니다. 마치 FastAPI를 잘 다루는 방법이 곧 Python을 잘 다루는 것이라고 말하는 듯, 웹 애플리케이션 서버 코드에서는 FastAPI의 존재감이 드러나지 않는 편입니다. 예를 들어볼게요.

 

# Django의 View 함수
def hello_world1(request):
    try:
        year = int(request.GET.get("year"))
    except (TypeError, ValueError) as e:
        raise ValidationError from e
	    
    data = {"year": year + 1}
    return JsonResponse(data)


# FastAPI의 endpoint 함수
@fastapi_router.get("/hello-world2")
async def

 

HTTP 쿼리 스트링(QueryString)으로 year를 받아 정수형으로 변환한 뒤, 1을 더한 값을 HTTP 응답으로 돌려주는 간단한 함수입니다. Django의 경우, 프레임워크에서 제공하는 request 객체가 코드에 드러납니다. 즉, 이 객체를 알아야 코드를 이해하고 작성할 수 있습니다. ‘알아야’ 한다는 건 관심사를 뜻하는데, hello_world1이라는 Python 함수의 비즈니스 로직을 테스트 코드로 작성하는 경우에도, 테스트 코드 영역에서는 Django의 request라는 존재를 알아야 하는 거죠.

 

그에 반해 FastAPI에서는 함수 시그니처와 구현단에 FastAPI의 존재가 드러나지 않습니다. year라는 매개변수가 선언된 함수일 뿐이지요. 반환값 역시 Python의 내장 자료형인 dict 형이고요.웹 애플리케이션 서버라는 관심사가 비즈니스 로직에 드러나지도 담기지도 않습니다.

 

FastAPI가 제공하는 웹 프레임워크의 구조와 API는 대부분 이러한 특성을 지향합니다.

이 점은 FastAPI를 구성하는 핵심 컴포넌트가 무엇인지 생각하면 더 신기하고 참신합니다. FastAPI는 Starlette과 Pydantic이라는 두 도구를 기둥으로 삼고 있기 때문인데요. 이 이야기는 곧 다시 볼게요.

 

중요한 점은, FastAPI가 Python의 자료형 각주(type hint, type annotation) 기능을 적극적으로 활용한다는 점입니다. 웹 프레임워크 체계를 새로 제안하기보다는 Python 문법과 기본 기능으로 사용자가 의도를 드러내도록 설계했습니다. 그 의도는 FastAPI가 받아, 웹 애플리케이션 서버 영역을 담당하는 Starlette에 전달합니다. 학습 부담이 적을 수밖에 없지요.

 

물론 학습 부담을 줄여주는 또 다른 특징도 있는데요, 이 특징은 Fast to code 속성과 함께 다루어 살펴보겠습니다.

 

 

Fast to code

FastAPI는 웹 프레임워크라는 기준으로 보면, 다소 실체가 불분명해 보입니다. 이미 널리 쓰여 검증된 도구들을 적절히 연결한 인상을 주기 때문입니다.

 

이러한 FastAPI를 받치는 두 개의 기둥은 Starlette과 Pydantic입니다. 코드 분량만 놓고 보면 FastAPI는 놀라울 만큼 적습니다. 데이터 검증과 처리는 Pydantic이 전담하고, 웹 애플리케이션 서버 역할은 Starlette이 맡기에, FastAPI는 껍데기(wrapper)만 있는 것처럼 오해가 생길 정도입니다.

 

FastAPI가 Starlette을 활용하는 방법

Starlette은 비동기(asynchronous) 방식으로 동작하는 고성능 웹 프레임워크로, 구조가 직관적이고 간결합니다. 다만 아무리 간결해도 사용해 보지 않은 새로운 도구는 생소해 학습 비용이 발생할 수밖에 없습니다. 예시 코드를 보겠습니다.

 

# Starlette의 endpoint 함수
async def hello_world1(request):
    try:
        year = request.query_params['year']
    except (TypeError, ValueError) as e:
        raise ValidationError from e
    data = {"year": year+1}
    return JSONResponse(data)

starlette_router.add_route("/hello-world1", hello_world1, ["GET"])


# FastAPI의 endpoint 함수
@fastapi_router.get("/hello-world2"

 

Starlette 코드가 Django용 코드와 매우 비슷하지요? 대개 이런 웹 프레임워크는 API나 체계가 코드에 개입합니다. FastAPI가 유독 간결한 거죠.

 

신기한 점은, Starlette을 기반으로 동작하는 FastAPI 코드와 Starlette 코드 사이의 괴리입니다. 예시에서 hello_world2 함수는 거의 순수(?)한 Python 함수입니다. 그렇다면 이 함수를 감싸고 있는 @fastapi_router.get()이라는 장식자(decorator)가 FastAPI에서 제공하는 기능일 것입니다. 이 녀석이 Starlette의 영역과 순수 Python 영역을 연결해 주겠죠.

 

이처럼 FastAPI는 자료형 각주(type hint)를 기반으로 의존성을 주입하는 기발한 방식으로, 기가 막히게 Starlette의 존재를 코드에서 감춥니다. 내부 동작과 애플리케이션 구조는 Starlette을 계승하지만, 그 API 대신 자료형 각주가 잘 정리된 Python 코드만 드러나는 것이죠.

 

그렇다면 FastAPI는 Starlette에 강결합되어, Starlette의 변화에 따라 기반이 크게 흔들릴 위험을 내재하고 있진 않을까요? 지면 한계상 자세히 설명하진 못하지만, 실제 FastAPI 코드를 들여다보면 기가 막히게 간결하면서도 의존도를 낮추는 방법을 고민한 흔적이 보입니다. FastAPI 개발자가 Starlette을 깊이 이해하고 있다는 생각이 절로 들죠.

 

FastAPI는 Starlette의 미들웨어(middleware)와 라우팅(routing)을 연계하고, 이 둘이 동작하는 ‘사이’에서 동작합니다. Starlette 입장에서는 FastAPI가 따로 개입했다기보다는, 자신이 원래 동작하는 방식대로 동작한 셈입니다. 즉, FastAPI는 Starlette을 통합해서 Starlette을 ‘사용’하는 구조가 아니라, Starlette의 동작 체계 안에서 Starlette이 FastAPI를 호출하도록 설계되어 있습니다.

 

전자의 방식으로 구현하면 Starlette에 지나치게 의존하거나, Starlette을 다소 해키(hacky)하게 쓰는 경우가 생기기 쉽습니다. 반면 후자의 방식은 Starlette이 어느 날 대대적인 개편을 하지 않는 이상, 변화에 비교적 안전하게 대응할 수 있습니다.

 

게다가 FastAPI의 몇몇 API는 Python 웹 프레임워크 생태계의 큰 축 중 하나인 Flask와 사용 방법이 비슷합니다. 많은 사람이 좋아했던 Flask의 간결하고 직관적인 API를 적극 채택해, Flask 사용자가 Starlette을 모르더라도 더 친숙하게 다가가고, FastAPI를 처음 접하는 사람에게는 오랜 시간 검증된 간단하고 쉬운 방식을 제공하는 것이죠.

 

FastAPI가 Pydantic을 녹여내는 방법

FastAPI의 또 다른 기둥, Pydantic은 몇 년 전부터 데이터 과학이나 데이터 처리 분야에서 애용되더니, 이제는 명실상부 데이터 처리 영역의 범용 도구로 자리 잡았습니다. Pydantic은 자료형 각주로 데이터 스키마를 정의하는 Python 내장 모듈인 dataclass에서 영감받은 데이터 구조체로 dataclass와 사용법도 상당히 비슷합니다.

 

# Python dataclass
@dataclass
class CreateYozmItContentPayload1:
    subject: str
    body: str
    user_id: int
    
    def __post_init__(self):
        if not self.subject:
            raise ValueError("subject는 필수 항목입니다")
        if not isinstance(self.subject, str):
                

 

예시 코드를 보면, 두 데이터 클래스를 정의하는 코드 자체는 매우 비슷합니다. 물론 비슷한 데서 끝나지는 않습니다. 

 

Pydantic은 유효성 검사(validation)를 비롯해 데이터를 다루는 데 유용하고 강력한 기능을 제공합니다. 이 차이는 한눈에 드러납니다. dataclass에는 유효성 검사 기능이 없기 때문에 __post_init__() 메서드에서 직접 구현했지만, Pydantic은 자료형 힌트를 기반으로 유효성 검사를 자동으로 적용했습니다. 그래서 예시의 Pydantic 데이터 클래스에는 별도의 유효성 검사 코드가 없는 것이지요. FastAPI와 마찬가지로, Pydantic 역시 Python의 기본 기능인 자료형 각주를 멋지게 활용한 사례입니다.

 

FastAPI는 크게 두 가지 방식으로 Pydantic을 녹여냅니다. 먼저 외부로부터 데이터를 전달받는 경우(in), 그 값을 자료형 각주로 선언하는데, 이때 동원하는 타입이 바로 Pydantic 모델(스키마)입니다. 외부에서 전달된 데이터를 이 Pydantic 모델로 각주된 자료형에 맞춰 변환하는 것입니다. 반대로 데이터를 외부로 내보낼 때(out)는, Pydantic 모델 객체를 반환하면 그 데이터를 Starlette이 Response 객체로 다루도록 변환해 전달합니다.

 

그렇게 데이터가 FastAPI로 들어오고 나가는 in/out 과정 전반에 사용하는 데이터 구현체가 Pydantic이며, 그 과정에서 Pydantic의 강력한 검증 절차를 거치게 됩니다. 부수 작용(side effect) 덩어리라고 볼 수 있는 웹 애플리케이션 서버 환경에서도 FastAPI를 활용하면 신뢰할 수 있는 형식의 데이터를 다루게 되는 이유입니다.

 

또한, Pydantic은 이미 FastAPI보다 저변이 넓습니다. Starlette은 비교적 생소할 수 있지만, 순수 Python 문법과 기능, 그리고 Flask의 편의성을 가져와 그 낯섦을 깔끔하게 감춥니다. 특이하거나 신비로운 마법을 발휘하지 않고도 Python의 기본 문법과 기능인 자료형 각주로 풀어냈기 때문에 코드 편집기의 지원도 풍부합니다.

 

이런 이유로 FastAPI 기반 코드를 작성할 때, 머릿속에 들고 있어야 할 맥락 자체가 적습니다. 그러니 구현하며 발생하는 인지 부하도 적습니다. 사람에게만 해당하는 이야기도 아닙니다. AI 코딩 에이전트 역시 컨텍스트 윈도우에 적재해야 할 웹 프레임워크 정보와 맥락 측면에서 FastAPI가 부담이 덜할 것입니다.

 

 

Ready for production

웹 애플리케이션 서버의 동작은 대개 서버 외부와 통신하는 I/O(input/output)를 주로 처리합니다. 따라서 CPU를 아주 많이 사용하거나 대용량 데이터를 메모리에 적재해 직접 처리하지 않는 편입니다. 그런 상황이 필요해지면, 그 처리를 다른 존재에 맡겨 어떻게든 웹 애플리케이션 서버 자체가 복잡한 일을 맡지 않도록 합니다.

 

예를 들어, 데이터베이스에서 1GB에 달하는 데이터를 웹 애플리케이션 서버로 가져와 이를 걸러 가공해 10KB만 클라이언트에 반환하는 방식은 대개 잘못된 문제 해결로 진단됩니다. 대신 데이터베이스에서 접근할 1GB짜리 데이터를 10KB나 1MB 수준으로 거르고 줄이거나, 1GB 데이터를 잘게 나눠 연속적으로 클라이언트에 응답(streaming)하도록 구현하지요.

 

비동기 처리는 이러한 환경에 매우 잘 어울리는 기술로, Starlette은 비동기 방식 기반으로 구현된 웹 프레임워크입니다. FastAPI의 성능이 최상위권에 속하는 이유도 여기에 있습니다. 최상위권 성능이 검증된 Starlette을 기반으로 간결하고 단순하게 유지하며 동작하기 때문입니다. 여기에 CPU 사용 비중이 높은 데이터 유효성 검증과 처리는 Pydantic이 담당하는데, Pydantic은 V2부터 핵심 구현부(core)를 Rust로 작성해 성능을 크게 끌어올렸습니다.

 

마지막으로, FastAPI가 기반으로 삼는 도구들은 이미 수년에 걸쳐 여러 실제 서비스 환경에 도입되었습니다. 그만큼 안정적이라는 의미이기도 하고, 실서비스에서 발생하는 다양한 예외 상황에 대해 참고할 자료가 많다는 뜻이기도 합니다. 생태계가 아직 작거나 복잡한 도구를 사용하는 것이 부담스러운 이유는, 실서비스 환경에서 까다로운 문제가 발생했을 때 대응하기가 쉽지 않은 데 있거든요. FastAPI는 적어도 그런 부담에서 자유롭습니다.

 

 

마치며

유튜브 영상을 요약하는 SecondB.ai라는 서비스가 있습니다. (광고 아닙니다)

 

그간 저는 유튜브와 같은 영상을 AI로 요약하는 몇몇 서비스를 써봤는데, 성능이 만족스럽지 않아 빠른 배속으로 영상을 봤습니다. 반면 이 서비스는 상당히 만족스러워 요약해 준 자료는 넘기지 않고 읽어봅니다.

 

이 SecondB 서비스 역시 FastAPI로 개발했다고 합니다. 서비스를 개발한 asbubam님이 보내온 FastAPI 추천사를 소개합니다.

 

유튜브 영상의 맥락을 최대한 유지한 요약 서비스 https://SecondB.ai 는 FastAPI 기반으로 개발되었습니다. 다수의 영상 요약 요청을 동시에 대응하기 위해 async 구조가 필수였는데, Python 초심자임에도 불구하고 FastAPI를 사용해 어렵지 않게 비동기 환경을 구성할 수 있었습니다. 특히 서비스 오픈 이후에도 프레임워크 운용에 많은 시간을 들이지 않아도 될 만큼 안정적이었고, 덕분에 서비스 개선과 기능 개발에 집중할 수 있었습니다.

 

SecondB가 실제로 토이 프로젝트로 개발하고 출시했는지까지는 확실치 않지만, 이 서비스는 작은 프로젝트의 모범적인 여정을 보여줍니다. 제품의 핵심에 집중하여 출시하고, 운영하며 빠르게 피드백 순환(loop)을 거치며 꾸준히 성공하고 있는 것이죠. 물론 asbubam님의 프로덕션 역량과 실행력에 기인한 것이 크겠지만, 그런 실행력을 발휘하는 데 FastAPI가 기여한 것입니다.

 

여러분, FastAPI 한 번 맛보시겠어요?

 

©️요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.

hello_world2
(
year:
int
) ->
dict
:
return
{
"year"
: year +
1
}
)
async
def
hello_world2
(
year:
int
) ->
dict
:
return
{
"year"
: year+
1
}
raise
ValueError(
"subject는 문자열이어야 합니다"
)
# Pydantic model class
class
CreateYozmItContentPayload2
(
BaseModel
):
subject:
str
body:
str
user_id:
int