[FastAPI 시리즈 2편] 설치하고 첫 API 실행하기

English version

FastAPI를 공부할 때 가장 좋은 시작은 설명을 오래 읽는 것보다, 서버를 실제로 띄우고 브라우저에서 응답을 확인해 보는 것입니다. FastAPI는 Python 함수에 경로를 붙여 API를 만드는 웹 프레임워크입니다. uv는 Python 프로젝트를 초기화하고 의존성을 설치해 주는 경량 패키지 매니저입니다. uvicorn은 FastAPI 앱을 HTTP 요청에 연결해 주는 ASGI 서버입니다. 1편에서 세운 "핵심 경로만 남긴다"는 원칙을 그대로 따라 이번 글은 설치와 첫 실행에 집중합니다. 목표는 uv·FastAPI·uvicorn 역할을 구분하고, 다음 글에서 파라미터 연습으로 곧장 넘어갈 기반을 만드는 것입니다.

이번 글에서 새로 나오는 용어

  1. uv: Python 프로젝트를 빠르게 초기화하고 패키지를 설치·실행해 주는 경량 매니저로, 글 전반의 명령 예시에서 계속 사용합니다.
  2. ASGI: 비동기 Python 웹 서버가 따라야 하는 인터페이스 표준으로, uvicorn이 FastAPI 앱을 실행할 수 있게 해 주는 약속입니다.
  3. Swagger UI: FastAPI가 자동으로 제공하는 문서·테스트 페이지로, 설치 직후 /docs에서 응답을 확인할 때 등장합니다.

실습 카드

  • 예상 소요 시간: 30분
  • 사전 준비: Python 3.12, uv 설치, VS Code/터미널 준비
  • 실습 목표: uv 기반 FastAPI 프로젝트를 만들고 개발 서버를 띄운다

이 글에서 할 것

  • uv(Python 프로젝트 초기화·실행을 도와주는 경량 패키지 매니저) 기반으로 FastAPI 프로젝트 시작하기
  • 가장 간단한 API 파일 만들기
  • 브라우저에서 응답과 문서 페이지 확인하기

준비

uv가 설치되어 있다고 가정하고 프로젝트 폴더를 만듭니다.

uv init my-fastapi-app
cd my-fastapi-app

패키지 설치

uv add fastapi --extra standard

이렇게 하면 FastAPI와 개발 서버 실행에 필요한 구성까지 함께 잡을 수 있습니다.

uvicorn은 무슨 역할을 하나

여기서 가장 먼저 분명히 해야 할 점이 있습니다.

  • FastAPI: API를 어떻게 정의할지 적는 프레임워크
  • uvicorn: 그 FastAPI 앱을 실제 HTTP 서버로 실행하는 ASGI 서버

즉, FastAPI는 "규칙과 구조"를 제공하고, uvicorn은 "요청을 받아 앱을 실행하고 응답을 돌려주는 실행기" 역할을 합니다.

여기서 ASGI는 Python 비동기 웹 인터페이스 표준 정도로 이해하면 충분합니다. 처음에는 "여러 요청을 처리하는 Python 웹 서버가 따라야 하는 약속"이라고 생각해도 됩니다.

브라우저에서 요청이 들어오면 흐름은 대략 이렇게 볼 수 있습니다.

브라우저 -> uvicorn -> FastAPI 앱 -> 응답(JSON)

처음 보는 용어가 많다면 아래 그림처럼 단순하게 이해해도 충분합니다.

브라우저또는 API 클라이언트uvicorn요청을 받아 실행FastAPI 앱경로와 응답 정의JSON 응답 HTTP 요청앱 실행dict/list 반환HTTP 응답

main.py 안에 app = FastAPI()만 있다고 해서 바로 웹 서버가 되는 것은 아닙니다. 그 앱 객체를 읽어 와서 포트를 열고, 요청을 받고, 응답을 보내는 서버가 필요한데 그 역할을 하는 것이 uvicorn입니다.

이번 글에서는 uv run fastapi dev main.py를 쓰지만, 이 명령도 내부적으로는 uvicorn 기반 개발 서버를 실행합니다. 그래서 로그에 Uvicorn running on ...가 보이는 것입니다.

첫 번째 앱 만들기

main.py 파일을 만들고 아래 코드를 작성합니다.

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello FastAPI"}

@app.get("/items")
def read_items():
    return ["pencil", "eraser", "notebook"]

코드 흐름은 단순합니다.

  • app = FastAPI()로 앱 생성
  • @app.get(...)으로 경로 등록
  • 함수가 반환한 값이 JSON 응답이 됨

개발 서버 실행

uv run fastapi dev main.py

의미는 다음과 같습니다.

  • uv run: 프로젝트 환경에서 명령 실행
  • fastapi dev: FastAPI 개발 서버 실행, 내부적으로는 uvicorn 사용
  • main.py: 앱이 들어 있는 파일 지정

정상 실행되면 대체로 이런 메시지가 보입니다.

INFO:     Uvicorn running on http://127.0.0.1:8000

브라우저에서 확인하기

기본 응답 보기

브라우저에서 http://127.0.0.1:8000/로 접속하면 아래와 비슷한 JSON이 보입니다.

{"message":"Hello FastAPI"}

자동 문서 보기

FastAPI의 재미있는 점은 문서 페이지가 바로 생성된다는 것입니다.

  • http://127.0.0.1:8000/docs
  • http://127.0.0.1:8000/redoc

특히 /docs에서는 버튼을 눌러 직접 요청도 보내볼 수 있습니다.

http://127.0.0.1:8000/docs
LOCAL

Swagger UI

FastAPI Docs

OpenAPI

브라우저에서 /docs를 열면 각 경로를 펼쳐 보고, 직접 요청을 보내고, JSON 응답도 바로 확인할 수 있습니다.

이 그림은 정적인 미리보기입니다. 실제 요청은 로컬 /docs 페이지에서 Try it out으로 실행해 보세요.

default
GET /
Responses 200
{"message":"Hello FastAPI"}
GET /items
Responses 200
[{"id":1,"name":"연필"},{"id":2,"name":"공책"}]

CLI로도 한번 확인해 보기

동아리 자동화나 모니터링 스크립트에서는 브라우저 대신 CLI로 응답을 확인하는 일이 많습니다. 아래처럼 uv run python -m httpx를 사용하면 같은 가상환경 안에서 바로 요청을 보낼 수 있습니다.

uv run python -m httpx http://127.0.0.1:8000/items

응답이 리스트로 내려오는지 확인하고, 바로 다음 실습에서 사용할 데이터 구조가 맞는지 검증해 두면 나중에 앱을 만들 때 시행착오가 줄어듭니다.

자주 헷갈리는 점

python main.py가 아니라 uvicorn 계열 명령을 쓰나

FastAPI 앱은 단순 스크립트 실행이 아니라 웹 서버 위에서 돌아갑니다. 그래서 앱 객체를 읽어 와서 HTTP 요청을 처리해 줄 서버가 필요합니다. uvicorn이 바로 그 서버 역할을 하고, uv run fastapi dev main.py는 그 과정을 조금 더 편하게 감싼 명령이라고 보면 됩니다.

직접 실행하는 형태는 보통 이런 모습입니다.

uv run uvicorn main:app --reload

처음에는 fastapi dev가 더 편하고, 나중에는 uvicorn main:app --reload 형태도 함께 익히면 구조를 이해하는 데 도움이 됩니다.

포트가 이미 사용 중이면 어떻게 하나

다른 포트를 지정하면 됩니다.

uv run fastapi dev main.py --port 8001

오늘의 최소 목표

  • uv add fastapi --extra standard 실행하기
  • main.py에 첫 번째 경로 만들기
  • uv run fastapi dev main.py로 서버 띄우기
  • //docs 페이지 확인하기

실습

  • 따라 하기: uv run fastapi dev main.py로 서버를 띄우고 /, /items 응답을 각각 확인한다.
  • 확장하기: /items/{item_id} 경로를 추가해 임시 데이터를 반환하고 Swagger UI에서 호출한다.
  • 디버깅: 포트 충돌이 일어나면 --port 8001 옵션을 붙여 해결해 본다.
  • 완료 기준: 두 경로가 모두 200 응답을 내고 /docs에서 Try it out 실행이 성공한다.

마무리

이번 단계의 핵심은 "FastAPI는 함수 하나를 HTTP 응답으로 연결해 주는 구조"라는 감각을 얻는 것입니다. 일단 서버가 뜨고 JSON이 보이기 시작하면, 그다음부터는 경로 파라미터나 요청 본문도 훨씬 덜 어렵게 느껴집니다.

다음 글에서는 GET 요청을 조금 더 확장해서 경로 파라미터와 쿼리 파라미터를 구분해 보겠습니다.

💬 댓글

이 글에 대한 의견을 남겨주세요