Apidog

올인원 협업 API 개발 플랫폼

API 설계

API 문서

API 디버깅

API 모킹

API 자동화 테스트

Python FastAPI를 사용하여 API 엔드포인트 로그 기록하는 방법

FastAPI는 표준 Python 타입 힌트를 기반으로 한 Python 3.7+용 API 구축을 위한 현대적이고 고성능의 웹 프레임워크입니다. 여러 가지 장점이 있습니다: * 고성능: FastAPI는 속도를 위해 설계되었으며, 비동기 프로그래밍을 활용해 초당 수천 개의 요청을 처리합니다. * 자동 문서화: Swagger UI와 ReDoc을 사용해 상호작용하는 API 문서를 자동 생성합니다. * 타입 검사: FastAPI는 Python의 타입 힌트를 사용해 자동 데이터 검증 및 직렬화를 제공합니다.

Young-jae

Young-jae

Updated on December 20, 2024

FastAPI는 Python 3.7+에서 표준 Python 타입 힌트를 기반으로 API를 구축하기 위한 현대적이고 고성능 웹 프레임워크입니다. 여러 가지 장점을 제공합니다:

  • 고성능: FastAPI는 속도를 위해 최적화되어 있으며, 비동기 프로그래밍을 활용하여 초당 수천 개의 요청을 처리할 수 있습니다.
  • 자동 문서화: Swagger UI와 ReDoc을 사용하여 상호작용 가능한 API 문서를 자동으로 생성합니다.
  • 타입 검사: FastAPI는 Python의 타입 힌트를 사용하여 자동 데이터 검증과 직렬화를 제공합니다.

FastAPI 애플리케이션을 만드는 방법은 다음과 같습니다:

from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
    return {"Hello": "World"}

웹 스택에서의 FastAPI

FastAPI를 신뢰할 수 있는 가이드로 하여 분주한 웹 환경을 탐색하는 모습을 상상해 보세요. 우리의 개요 다이어그램(그림 1)은 FastAPI가 웹 스택에 원활하게 통합되는 방식을 명확하고 매력적으로 보여줍니다.

상단에는 클라이언트 요청이 있습니다 — 이는 애플리케이션에 접근하려는 사용자의 일상적인 상호작용입니다. FastAPI는 이러한 요청과 서버 간의 역동적인 다리 역할을 합니다. 데이터를 신속하고 효율적으로 처리할 수 있도록 설계되어 있어 모든 상호작용이 원활하고 반응성이 뛰어납니다.

FastAPI 애플리케이션 아래에는 마법이 일어나는 간소화된 프로세스가 자리하고 있습니다. FastAPI는 속도와 성능으로 잘 알려져 있으며, 요청을 번개처럼 빠르고 정확하게 처리합니다. 이는 당신의 니즈를 이해하고 예측하는 최고의 비서가 있는 것과 같으며, 기록적인 시간 내에 응답을 제공합니다.

마지막으로, 그림 1은 응답이 클라이언트로 돌아가는 과정을 보여줍니다. FastAPI는 이러한 응답이 빠를 뿐만 아니라 매우 신뢰할 수 있도록 보장하며, 전체 사용자 경험을 향상시킵니다.

그러니 웹 애플리케이션을 향상시키기 위한 강력하고 효율적이며 사용자 친화적인 솔루션을 찾고 있다면 FastAPI가 최상의 선택입니다. 다이어그램을 통해 FastAPI가 그 탁월한 기능으로 웹 스택을 어떻게 변화시킬 수 있는지 살펴보세요.

그림 1

엔드포인트 호출 개요

엔드포인트 호출은 특정 API 엔드포인트에 요청을 전송하여 정의된 작업을 실행하는 과정을 말합니다. FastAPI에서는 라우트를 정의하고 수신 요청을 처리하는 것이 포함됩니다.

엔드포인트 생성:

FastAPI에서는 데코레이터를 사용하여 엔드포인트를 정의합니다. 각 데코레이터는 HTTP 메서드 및 URL 경로에 해당합니다.

작동 방식은 다음과 같습니다: from fastapi import FastAPI

from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

이 설정을 통해 사용자는 ID로 특정 항목을 요청할 수 있으며, 애플리케이션은 깔끔한 JSON 형식으로 그들이 원하는 정보를 신속하게 제공합니다;

  • @app.get(“/items/{item_id}”)는 item_id가 경로 매개변수인 GET 엔드포인트를 정의합니다.
  • 함수 read_item은 요청을 처리하고 JSON 응답을 반환합니다.

상상을 해보세요: 요청이 애플리케이션을 통해 여행하고 있는 모습, 그리고 우리의 엔드포인트 다이어그램(그림 2)은 그 모험을 보여주는 지도와 같습니다.

먼저, 요청은 엔드포인트를 향해 나아가며 환영받고 여정을 시작합니다. 이것을 요청을 준비하고 대기시키는 환영의 게이트로 생각해 보세요. 다음에는 매개변수가 있습니다. 이들은 요청이 가야 할 정확한 장소를 안내하는 특별한 지침이나 세부사항과 같습니다.

요청이 모든 세부사항을 정리한 후에는 요청 처리 단계에 도달합니다. 이 단계를 요청이 처리되고 올바른 결과를 얻기 위해 필요한 모든 작업이 수행되는 핵심 작용으로 생각해 보세요.

마지막으로, 요청은 응답과 함께 여정을 마무리합니다. 이는 요청 결과가 깔끔하게 포장되어 시작 지점으로 다시 전송되는 최종 목적지와 같습니다.

그래서 그림 2는 단순한 흐름도가 아닙니다 — 모든 요청이 시스템을 통해 어떻게 이동하는지, 적절한 처리를 받고 완벽한 응답으로 돌아오는지를 시각적으로 보여주는 이야기입니다.

그림 2

API에서 로깅의 중요성
로깅은 API 모니터링, 디버깅 및 유지 관리에 매우 중요합니다. 개발자에게 다음을 도와줍니다:

  • 요청 및 응답 추적: API 사용 방식을 이해하고 문제를 해결할 수 있습니다.
  • 성능 모니터링: 성능 병목 현상을 식별하고 API를 최적화할 수 있습니다.
  • 감사 및 보안: 준수 및 보안 감사를 위해 API 사용 기록을 유지합니다.

작동 방식은 다음과 같습니다:
Python의 내장 로깅 모듈을 사용하여 FastAPI 애플리케이션에 로깅을 추가할 수 있습니다:

import logging
from fastapi import FastAPI
app = FastAPI()
# 로깅 구성
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    logger.info(f"Received request for item_id: {item_id} with query: {q}")
    return {"item_id": item_id, "q": q}

이 설정과 함께 로깅이 어떻게 작동하는지 살펴보겠습니다.

먼저, logging.basicConfig는 로그를 처리하는 방법에 대한 규칙을 설정하는 것과 같습니다. 로그가 어디로 가는지, 어떻게 형식화되는지를 결정하는 곳입니다. 이는 중요한 정보를 캡처하기 위한 로깅 도구를 설정하는 것입니다.

다음은 logger.info입니다. 이곳에서 마법이 일어납니다. logger.info를 호출하면 정보 메시지를 로그에 추가하는 것입니다. 이 경우 요청에 대한 세부정보를 기록하는 것입니다. 이는 발생하는 일을 기록하는 메모를 작성하는 것과 같아, 나중에 참조할 수 있는 기록을 남기는 것입니다.

이제 로깅 흐름도 (그림 3)에 대해 설명하겠습니다. 이 다이어그램은 요청이 처음부터 끝까지 기록되는 방식을 보여주는 시각적 가이드와 같습니다. 로깅 구성 설정부터 메시지를 캡처하고 기록하는 과정까지의 여정을 알려줍니다. 이 모든 조각들이 어떻게 완벽하게 결합되어 애플리케이션의 활동을 추적하는지를 볼 수 있는 유용한 방법입니다.

그림 3

버전 2 엔드포인트를 위한 FastAPI 설정

FastAPI의 세계에 오신 것을 환영합니다! Python으로 API를 구축하기 위한 가장 빠른 프레임워크 중 하나의 힘을 활용하고 싶다면, 당신은 올바른 곳에 있습니다. 기존 API를 버전 2로 업그레이드하든 새로 시작하든, 이 가이드는 시작하는 데 필요한 모든 것을 안내합니다. FastAPI 및 Uvicorn 설치부터 프로젝트 구조 설정, 기본 애플리케이션 제작까지, 우리는 당신을 도와드립니다. 시작해 봅시다!

1. FastAPI 및 Uvicorn 설치

왜 FastAPI인가? FastAPI는 속도, 단순성 및 현대적인 기능으로 유명합니다. 이는 빠르면서도 유지 관리가 용이한 API 구축에 적합합니다.

왜 Uvicorn인가? Uvicorn은 FastAPI 애플리케이션을 실행하는 데 이상적인 고성능 ASGI 서버입니다. 비동기 작업을 지원하므로 확장 가능한 애플리케이션에 적합합니다.

시작하기:

FastAPI 및 Uvicorn을 설치하려면 다음 명령을 실행하세요:pip install fastapi uvicorn

주목할 만한 기능:

  • FastAPI: 상호작용 문서화, 검증 및 비동기 지원을 자동으로 제공합니다.
  • Uvicorn: 개발 및 프로덕션 환경에 적합한 고속 ASGI 서버 역할을 합니다.

개발 환경을 설정하고 모든 것이 어떻게 어우러지는지 보려고 합니다. 설치 흐름도(그림 4)는 FastAPI와 Uvicorn이 웹 애플리케이션을 원활하게 실행하는 방식을 보여주는 지도와 같습니다.

FastAPI를 애플리케이션의 요청 및 응답 뒤의 모든 마법을 처리하는 강력한 API 프레임워크로 생각해 보세요. 이는 애플리케이션의 두뇌와 같아 데이터를 처리하고 상호작용을 관리합니다.

이제 Uvicorn은 FastAPI에 생명을 불어넣는 서버입니다. 이는 배경에서 신뢰할 수 있는 엔진으로, FastAPI가 수신 요청을 처리하고 효율적으로 응답을 제공하도록 합니다.

이 다이어그램은 개발 설정 내에서 FastAPI와 Uvicorn이 어떻게 상호작용하는지 시각화하는 데 도움이 됩니다. 이를 통해 두 가지 관계가 어떻게 서로 어우러져 서버 및 애플리케이션 프레임워크의 더 큰 그림에 어떻게 적합한지를 보여줍니다. 각각의 조각이 전체에 기여하는 방식을 이해하는 유용한 방법입니다.

그림 4
그림 4

2. 프로젝트 구조 및 의존성

프로젝트를 정리하는 이유는? 잘 구조화된 프로젝트는 애플리케이션을 유지 관리하고 확장하는 데 도움이 될 뿐만 아니라 다른 사람들과의 협업을 매끄럽고 효율적으로 만듭니다.

설정 방법:

1. 프로젝트 디렉토리 생성: 프로젝트 파일을 디렉토리로 정리합니다.

2. 의존성 정의: requirements.txt를 사용하여 모든 패키지를 나열하여 다음과 같이 쉽게 설치할 수 있습니다:pip install -r requirements.txt

프로젝트 구조 다이어그램(그림 5)을 코드베이스의 청사진으로 생각해 보세요. 모든 것이 프로젝트 내에서 어떻게 구성되는지를 상세히 보여주는 지도와 같습니다.

새 프로젝트를 설정하면서 엔드포인트, 모델 및 스키마와 같은 다양한 부분을 어디에 두어야 할지 고민하고 있다고 상상해 보세요. 이 다이어그램은 각 부분이 어디에 가야 하는지를 쉽게 볼 수 있게 해줍니다.

이는 잘 정리된 파일 캐비닛을 갖고 있는 것과 같습니다. API 엔드포인트를 찾기 위해서는 어떤 서랍을 열어야 할지 정확히 알고 있으며, 데이터 모델을 파일에 저장하고, 스키마를 보관할 공간이 있습니다. 구조를 시각화함으로써 모든 구성 요소가 어떻게 결합되어 있으며, 프로젝트를 깔끔하고 관리하기 쉽게 유지할 수 있는지를 신속하게 이해할 수 있습니다.

그림 5

• app/main.py: FastAPI 애플리케이션의 핵심입니다.
• app/api/v2/endpoints.py: 버전 2 엔드포인트를 정의하는 곳입니다.
• requirements.txt: 프로젝트의 모든 의존성을 나열하는 파일입니다.

3. 기본 FastAPI 애플리케이션 만들기

단순하게 시작하는 이유는? 단순하고 기능적인 애플리케이션은 더 복잡한 기능을 추가하는 데 필요한 단계에 대한 기초를 마련합니다. 더 깊이 파고들기 전에 FastAPI의 핵심 구성 요소를 이해하도록 보장합니다.

기본 애플리케이션 작동 방식:

# app/main.py
from fastapi import FastAPI

app = FastAPI()

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

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "query": q}

애플리케이션 실행하기:

FastAPI 애플리케이션이 작동하는 모습을 보려면 다음을 실행하세요:

uvicorn app.main:app --reload

브라우저에서 http://127.0.0.1:8000를 방문하면 API가 작동하는 것을 볼 수 있습니다. 인터랙티브 API 문서를 확인하는 것도 잊지 마세요:

http://127.0.0.1:8000/docs.

주목할 만한 기능:


• 상호작용 문서화: 자동으로 생성되며 /docs /redoc를 통해 접근할 수 있습니다.
• 비동기 지원: FastAPI는 비동기 작업을 통해 높은 동시성을 수행할 수 있습니다.

FastAPI 애플리케이션을 통해 요청을 추적하여 그 과정을 선보인다고 상상해 보세요. 기본 애플리케이션 흐름도는 그림 6에서 요청의 과정이 실제로 어떻게 진행되는지를 보여주는 단계별 가이드와 같습니다.

작동 방식은 다음과 같습니다: 요청이 들어오고 다이어그램은 그것이 처리되는 방식을 정확하게 보여줍니다. 먼저 FastAPI 애플리케이션은 요청을 수신합니다 — 이는 애플리케이션이 수신 데이터를 환영하는 출발 지점으로 생각해 보세요.

다음으로, 다이어그램은 이 요청이 처리되는 여정을 간략하게 설명합니다. 여기에는 애플리케이션이 수행하는 데이터베이스와의 상호작용이나 기타 모든 작업이 포함됩니다.

마지막으로, 애플리케이션이 모든 것을 마무리하고 응답을 다시 보내는 방식을 보여줍니다. 이것은 패키지가 창고에 도착한 순간부터 고객에게 배달될 때까지 추적하는 것과 같습니다.

그림 6

버전 2 엔드포인트를 위한 FastAPI 설정이 쉬우며 확실히 그럴 가치가 있습니다. FastAPI의 강력한 기능과 Uvicorn의 빠른 속도를 통해 곧 효율적이고 확장 가능한 API를 구축할 수 있습니다.

버전 2 엔드포인트로 로깅 향상하기

견고하고 확장 가능한 웹 애플리케이션을 구축하는 데 있어 로깅은 단순한 기능이 아니라 애플리케이션의 상태 모니터링, 디버깅 및 유지 관리에 중요한 요소입니다. FastAPI를 사용하면 고급 로깅 기능을 활용하여 애플리케이션이 원활하게 실행되고 문제가 즉시 해결되도록 할 수 있습니다. 이 가이드에서는 버전 2 엔드포인트에 중점을 두고 FastAPI로 로깅 설정을 향상시키는 방법을 안내하겠습니다. 시작해 봅시다!

FastAPI 로깅 기능 소개

FastAPI는 애플리케이션 행동을 추적하고 문제를 진단하는 데 필수적인 로깅을 위한 내장 지원을 제공합니다. 로깅은 이벤트, 오류 및 애플리케이션의 다른 중요한 발생을 기록할 수 있는 방법을 제공합니다. 이 기능은 애플리케이션 성능과 사용자 상호작용을 이해하는 데 중요합니다.

로깅의 중요성:

• 디버깅: 코드에서 문제를 신속하게 식별하고 해결할 수 있습니다.

• 모니터링: 애플리케이션의 상태 및 성능을 추적합니다.

• 감사: 보안 및 준수를 위해 사용자 행동 및 시스템 변경 사항을 기록합니다.

FastAPI는 Python의 표준 로깅 라이브러리와 원활하게 통합되며, 유연하고 강력한 로깅 구성을 허용합니다.

그림 7

로깅이 FastAPI와 어떻게 맞물리는지 간단하게 살펴보겠습니다:

  1. FastAPI 박스: 중앙의 “FastAPI Application”이 파란색으로 강조되어 설정의 핵심으로 나타납니다.
  2. 로깅 수준: INFO (녹색), DEBUG (주황색), ERROR (빨간색) 등 다양한 로깅 수준이 화살표로 FastAPI와 연결되어 있습니다.
  3. Python 로깅 시스템: 이것은 오른쪽에 금색으로 표시되어 있으며 FastAPI의 모든 로그 메시지를 처리합니다.

그림 7은 FastAPI가 Python의 로깅 라이브러리와 어떻게 작동하는지를 보여주며, 서로 다른 로그 수준이 애플리케이션과 어떻게 상호작용하는지를 설명합니다.

로깅 구성 설정하기

FastAPI에서 로깅을 구성하는 것은 요구 사항에 맞는 로깅 구성을 설정하는 것을 포함합니다. 로깅 수준을 정의하고, 메시지 형식을 설정하며, 로그가 출력될 위치(콘솔, 파일 등)를 지정할 수 있습니다.

로깅 구성 단계:

  1. 로깅 모듈 가져오기: Python의 logging 모듈을 사용하여 구성을 설정합니다.
  2. 로깅 구성 정의: 로깅 수준, 형식 및 핸들러를 설정합니다.
  3. FastAPI에서 로깅 초기화: 구성을 FastAPI 애플리케이션에 적용합니다.

FastAPI에서 로깅을 위한 기본 설정은 다음과 같습니다:

import logging
from fastapi import FastAPI

# 로깅 구성
logging.basicConfig(level=logging.INFO,  # 필요에 따라 수준 조정
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    handlers=[logging.StreamHandler()])  # 콘솔로 로그를 출력합니다.

app = FastAPI()

@app.get("/")
def read_root():
    logging.info("루트 엔드포인트에 접근했습니다.")
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int):
    logging.debug(f"요청된 항목: {item_id}")
    if item_id > 10:
        logging.error("항목 ID가 너무 높습니다.")
    return {"item_id": item_id}

주목할 만한 기능:
• 로깅 수준: INFO, DEBUG, ERROR — 로그의 상세도를 조절하기 위한 다양한 수준을 사용하세요.
• 사용자 정의 핸들러: 로그를 파일, 원격 서버 또는 다른 대상으로 전송합니다.
• 메시지 형식 지정: 타임스탬프 및 로그 수준 등을 포함하도록 로그 메시지 형식을 사용자 정의하세요.

그림 8

로깅이 어떻게 설정되는지 간단하게 살펴보겠습니다:

  1. 로깅 구성: 상단에는 로깅 구성이 발생하는 위치가 금색 상자로 표시되어 있습니다.
  2. 애플리케이션 구성 요소: 세 가지 파란색 상자가 로그가 생성되는 애플리케이션의 다양한 부분을 나타냅니다.
  3. 로거: 녹색 상자가 이러한 로그를 모아 목적지로 안내합니다.
  4. 핸들러: 두 개의 오렌지색 상자가 로그를 처리하고 형식화하는 파일 및 콘솔 핸들러를 나타냅니다.
  5. 목적지: 오른쪽의 보라색 상자는 로그가 최종 목적지에 도달하는 방식을 나타내며, 로그 파일이나 콘솔입니다.

그림 8에 설명된 이 흐름도는 로그 메시지가 애플리케이션에서 최종 목적지로 어떻게 이동하는지를 쉽게 볼 수 있게 해줍니다.

로깅을 위한 버전 2 엔드포인트 구현하기

FastAPI를 사용하면 버전 2 엔드포인트가 로깅을 위한 향상된 기능을 제공합니다. FastAPI의 표준 로깅을 기반으로 엔드포인트에 대해 보다 복잡한 로깅 전략을 구현할 수 있습니다.

주요 고려사항:

• 구조적 로깅: 세부적이고 실행 가능한 정보를 캡처하기 위해 구조적 로그를 사용합니다.

• 향상된 오류 처리: 문제를 효과적으로 진단하기 위해 상세한 오류 정보를 기록합니다.

• 성능 메트릭: 요청 지속 시간 및 처리량과 같은 성능 메트릭을 추적합니다.

버전 2 엔드포인트에서 로깅을 구현하는 방법은 다음과 같습니다:

from fastapi import FastAPI, Request
import logging

app = FastAPI()

# 향상된 로깅 구성
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    handlers=[logging.FileHandler("app.log"), logging.StreamHandler()])

@app.post("/log")
async def log_endpoint(request: Request):
    body = await request.json()
    logging.info(f"수신된 요청 본문: {body}")
    return {"status": "logged"}

@app.get("/performance")
def performance_metrics():
    # 성능 메트릭 로깅 예시
    start_time = logging.datetime.now()
    # 처리 시뮬레이션
    logging.info(f"성능 메트릭 요청 시간: {start_time}")
    return {"metrics": "sample_metrics"}

주목할 만한 기능:
• 비동기 로깅: 더 나은 성능을 위해 비동기 방식으로 로깅을 처리합니다.
• 파일 로깅: 영구 저장을 위해 파일에 로그를 저장합니다.
• 성능 로깅: 성능 메트릭을 캡처하고 분석합니다.

그림 9

요청에서 로깅이 어떻게 작동하는지 간단히 조사해 봅시다:
1. 요청 박스: 이 연한 파란색 상자는 들어오는 요청이 시작되는 위치입니다.
2. 로그 유형:
• INFO 로그는 녹색으로 표시됩니다.
• ERROR 로그는 빨간색입니다.
• DEBUG 로그는 금색입니다.
3. 핸들러: 로그는 다음으로 이동합니다:
• 파일 핸들러(파란색).
• 콘솔 핸들러(파란색).
4. 목적지: 로그는 다음과 같이 최종 목적지에 도달합니다:
로그 파일 또는 콘솔(보라색).
그림 9는 요청이 다양한 로그 유형으로 이어지며, 그런 다음 확인하고 최종 목적지로 안내되는지를 보여줍니다. 이를 올바르게 설정하면 명확한 통찰력을 얻고 FastAPI 애플리케이션을 원활하게 실행할 수 있습니다.

고급 로깅 기능 및 모범 사례

FastAPI 애플리케이션에서 로깅은 단순히 콘솔에 메시지를 기록하는 것을 넘어섭니다. 이는 문제 추적, 성능 모니터링 및 오류 관리를 효과적으로 지원하는 강력한 시스템을 구축하는 것입니다. 고급 로깅 기능과 모범 사례를 활용함으로써 로그를 애플리케이션을 유지 관리하고 확장하는 데 유용한 도구로 만들 수 있습니다.

여기에서는 FastAPI의 고급 로깅 기능 몇 가지를 살펴보겠습니다. 로깅을 위한 의존성 주입, 로그 메시지 사용자 정의 및 예외 및 오류를 처리하기 위한 모범 사례에 중점을 둡니다.

로깅을 위한 의존성 주입 사용하기

FastAPI의 의존성 주입은 매우 강력한 기능이며, 로깅에도 확장됩니다. 각 함수에서 로깅을 별도로 구성하는 대신, 이를 라우트에 주입하여 코드를 더 깔끔하고 확장 가능하게 만들 수 있습니다.

로깅에 의존성 주입을 사용하는 이유는?
• 일관성: 모든 엔드포인트에서 일관된 로깅 구성을 보장합니다.
• 재사용성: 중복 코드를 피하고 중앙에서 로깅 구성을 정의하고 사용할 수 있습니다.
• 유연성: 개별 엔드포인트 코드를 변경하지 않고도 로깅 설정을 수정하기 쉽습니다.
FastAPI의 Depends 함수를 사용하여 로깅 인스턴스를 주입하는 방법은 다음과 같습니다:

import logging
from fastapi import FastAPI, Depends

app = FastAPI()

# 로깅 구성
def get_logger():
    logger = logging.getLogger("app_logger")
    logger.setLevel(logging.INFO)
    if not logger.handlers:
        handler = logging.StreamHandler()
        handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
        logger.addHandler(handler)
    return logger

@app.get("/items/")
def read_items(logger=Depends(get_logger)):
    logger.info("항목 엔드포인트에 접근했습니다.")
    return {"message": "항목을 가져오는 중입니다."}

주목할 만한 기능:
• 중앙 집중식 로거 구성: 의존성 주입을 사용하여 로거를 한 번만 정의하면 됩니다.
• 자동 주입: FastAPI는 필요에 따라 로거를 자동으로 엔드포인트에 제공합니다.

그림 10

그림 10은 의존성 주입 흐름을 설명합니다. 요청이 로그로 전환되고, 어떻게 처리되는지, 최종적으로 어디에 저장되는지를 보여줍니다. 이는 FastAPI 애플리케이션을 원활하게 유지하고 명확한 로깅을 통해 관리하기 위함입니다.

의존성 주입 흐름도 주요 내용:
• 클라이언트 요청: 클라이언트가 FastAPI 애플리케이션에 요청을 보내는 출발점입니다.
• FastAPI 엔드포인트: 의존성 주입이 발생하는 FastAPI의 엔드포인트를 나타냅니다.
• DI를 통한 로거 주입: FastAPI의 의존성 주입 메커니즘을 사용하여 엔드포인트에 로거가 주입되는 모습을 보여줍니다.
• 로깅(요청 정보): 요청 방법, 경로 및 기타 유용한 정보를 로그합니다.
• FastAPI 응답: 요청을 로깅한 후 클라이언트에게 반환되는 응답입니다.

로그 메시지 사용자 정의
로그 메시지를 사용자 정의할 수 있는 기능은 로그를 유용하고 실행 가능하게 만드는 데 중요합니다. 기본 로그는 항상 충분한 상황을 제공하지 않을 수 있으며, 특히 프로덕션 환경에서는 더욱 그러합니다. FastAPI의 Python 로깅 모듈 통합은 로그에 사용자 정의 세부 정보를 추가하는 것을 쉽게 만들어줍니다.


로그 메시지를 사용자 정의하기 위한 주요 전략:
• 요청 정보 추가: IP 주소, 헤더 및 경로와 같은 요청 세부 정보를 포함합니다.
• 맥락 정보 추가: 현재 엔드포인트 또는 작업에 관련된 정보를 로그에 포함하여 로그를 사용자 정의합니다. 사용자 행동이나 특정 리소스 세부 정보 등이 될 수 있습니다.
• 가독성을 위한 형식 지정: 로그를 구조적으로 작성하거나 JSON 형식을 사용하여 가독성을 높이고 ELK 스택과 같은 로깅 도구와의 통합을 용이하게 합니다.


요청 세부 정보와 함께 로그 메시지를 사용자 정의하는 방법은 다음과 같습니다:

from fastapi import Request

@app.middleware("http")
async def log_requests(request: Request, call_next):
    logger = logging.getLogger("custom_logger")
    logger.info(f"수신 요청: {request.method} {request.url}")
    response = await call_next(request)
    logger.info(f"응답 상태: {response.status_code}")
    return response

주목할 만한 기능:
• 로깅을 위한 미들웨어: 이 미들웨어는 들어오는 요청과 나가는 응답을 모두 기록합니다.
• 사용자 정의 정보: 요청 방법, URL 및 응답 상태와 같은 특정 세부 정보를 기록할 수 있습니다.

그림 11

사용자 정의 로깅 흐름는 그림 11에서 시스템을 통해 요청을 추적하는 가이드 역할을 합니다. 요청이 미들웨어를 통해 이동하며 사용자 정의 세부 정보와 함께 기록되고, 프로세스가 진행되는 동안 응답도 기록됩니다. 이 차트는 사용자 정의 로그 메시지가 추가되는 주요 지점을 강조하여 모든 것이 어떻게 추적되고 기록되는지를 명확하게 보여줍니다.

예외 및 오류 처리

애플리케이션에서 오류가 발생할 때 로깅은 근본 원인을 추적하는 데 중요한 역할을 합니다. FastAPI의 예외 처리 기능과 로깅이 결합되어 자세한 오류 정보를 캡처하고 기록하여 사용자에게 민감한 세부 사항을 노출하지 않도록 합니다.

예외 로깅을 위한 모범 사례:
• 상세 오류 정보 기록: 스택 추적, 오류 메시지 및 요청 맥락을 캡처합니다.
• 다양한 오류 수준 로깅: 적절한 로그 수준인 ERROR 또는 CRITICAL을 사용하여 예외를 일반 로그 항목과 구분합니다.
• 과도한 로깅 방지: 민감한 정보를 기록하거나 로그가 복잡해지지 않도록 주의합니다.
FastAPI에서 예외를 처리하고 로깅하는 방법은 다음과 같습니다:

from fastapi import HTTPException
import logging

@app.get("/items/{item_id}")
def read_item(item_id: int, logger=Depends(get_logger)):
    try:
        if item_id > 100:
            raise HTTPException(status_code=404, detail="항목을 찾을 수 없습니다.")
        logger.info(f"{item_id} 항목을 성공적으로 가져왔습니다.")
        return {"item_id": item_id}
    except HTTPException as e:
        logger.error(f"{item_id} 항목을 가져오는 중 오류 발생: {e.detail}")
        raise e

주목할 만한 기능:
• 구조적 예외 로깅: 예외 발생 시 상세한 정보를 기록하여 항목 ID와 오류 세부 정보를 포함합니다.
• 부드러운 오류 처리: 문제를 기록하고 추가 분석을 위해 HTTP 예외를 발생시킵니다.

그림 12

예외 로깅 흐름도는 FastAPI 애플리케이션에서 예외가 어떻게 처리되는지를 보여줍니다. 흐름 표현은 다음과 같습니다:
정규 흐름: 클라이언트가 요청을 보냄 미들웨어가 이를 처리 엔드포인트가 응답을 생성 클라이언트가 응답을 수신.
• 예외 흐름: 엔드포인트에서 예외가 발생하면 이를 기록하고 사용자 정의 오류 응답이 클라이언트에게 전송됩니다.


고급 로깅 모범 사례를 활용함으로써 애플리케이션의 신뢰성과 유지 관리 용이성을 향상시킬 수 있습니다. 좋은 로깅은 문제를 조기에 발견하고 모든 것이 원활하게 실행될 수 있도록 도와줍니다. 이러한 모범 관행을 수용하면 더 적은 두통과 더 강력한 FastAPI 애플리케이션을 만들 수 있습니다!

API 테스트 및 디버깅

API 개발의 영역에서 테스트 및 디버깅은 견고하고 신뢰할 수 있는 애플리케이션을 보장하는 최고의 동맹입니다. FastAPI 엔드포인트를 테스트하고 디버깅하여 예상대로 작동하고 실제 시나리오를 우아하게 처리할 준비가 되었는지 확인할 수 있습니다.

엔드포인트에 대한 테스트 작성

왜 테스트를 해야 할까요? 테스트는 버그가 사용자에게 발견되기 전에 잡아주는 안전망입니다. FastAPI 애플리케이션의 경우, 엔드포인트에 대한 테스트를 작성하면 각 요청과 응답이 기대에 부합하는지 확인할 수 있으며, 예상치 못한 동작의 위험을 최소화합니다.

  1. 단위 테스트로 시작: FastAPI의 테스트 클라이언트를 사용해 개별 엔드포인트에 대한 단위 테스트를 작성하세요. 이는 API의 핵심 기능을 검증하는 데 도움이 됩니다.
from fastapi.testclient import TestClient
from myapp import app

client = TestClient(app)

def test_read_main():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Hello World"}
그림 13

새 앱을 만들었다고 상상하고 이제 모든 부분을 철저히 테스트해야 할 때입니다. 바로 여기서 테스트 커버리지 다이어그램이 유용한 역할을 합니다. 애플리케이션의 시각적 산도로, 테스트로 잘 커버되고 있는 영역과 조금 더 신경 써야 할 부분을 보여줍니다.

다이어그램에서는 엔드포인트, 모델, 데이터베이스, 서비스, 유틸리티 및 미들웨어와 같은 애플리케이션의 다양한 구성 요소를 나타내는 여러 색의 직사각형을 볼 수 있습니다. 각 색상은 시스템의 서로 다른 부분을 강조하여 한눈에 쉽게 구별할 수 있도록 해줍니다.

재미있는 점은 이러한 구성 요소 중 일부가 체크 표시가 되어 있어 철저히 테스트되었음을 나타내고, 어떤 구성 요소는 빨간색 점선 화살표와 함께 "커버되지 않음"이라는 레이블이 붙어 있어, "이 앱의 일부는 아직 테스트되지 않아 위험할 수 있습니다"라는 경고를 알려줍니다.

따라서 이 다이어그램은 단순히 예쁜 그림이 아니라, 테스트 커버리지를 식별하고 애플리케이션의 중요한 부분을 놓치지 않도록 도와주는 실용적인 도구입니다. 테스트 노력의 결과물이 잘 반영되고 있는지, 더 나아가야 할 방향을 알려주는 명확한 시각을 제공합니다.

2. 통합 테스트로 확장: 애플리케이션의 다양한 구성 요소가 함께 어떻게 작동하는지 테스트합니다. 예를 들어, 데이터베이스 상호작용 및 외부 API 호출이 제대로 작동하는지 확인합니다.

def test_create_item():
    response = client.post("/items/", json={"name": "item1", "price": 10.0})
    assert response.status_code == 201
    assert response.json() == {"name": "item1", "price": 10.0, "id": 1}
그림 14

3. 테스트 스위트를 활용: 테스트를 스위트로 구성하여 테스트 프로세스를 간소화하고 포괄적인 커버리지를 보장합니다. pytest와 같은 도구를 사용하여 테스트 실행을 자동화할 수 있습니다.

# pytest를 사용하여 모든 테스트 실행
pytest --maxfail=1 --disable-warnings -q

일반 문제 디버깅

디버깅은 프로그래밍의 탐정 작업과 같습니다. 문제의 근본 원인을 추적하고 효율적으로 해결하는 것입니다.

  1. 로깅을 효과적으로 사용: 애플리케이션의 흐름을 추적하고 문제가 발생하는 위치를 파악하기 위해 강력한 로깅을 추가합니다. 다양한 로그 수준 (INFO, DEBUG, ERROR)을 활용해 적절한 세부 정보를 캡처합니다.
import logging

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

def some_function():
    logger.info("함수 시작")
    try:
        # 예외를 발생시킬 수 있는 코드
        pass
    except Exception as e:
        logger.error(f"오류 발생: {e}")
그림 15

2. FastAPI의 디버그 모드 활용: FastAPI 애플리케이션을 실행할 때 디버그 모드를 활성화하여 문제의 출처를 안내하는 자세한 오류 메시지와 스택 추적을 받을 수 있습니다.

uvicorn myapp:app --reload --debug

3. 상호작용 디버깅: pdb와 같은 디버깅 도구나 통합 개발 환경(IDE) 디버거를 사용하여 코드를 단계별로 실행하고 변수의 상태를 실시간으로 검사합니다.

import pdb

def my_function():
    pdb.set_trace()  # 이 줄에서 디버거를 시작합니다.
    # 디버그할 코드

API 테스트를 위한 모범 사례

앞으로 나아갈 때 개선할 여지는 항상 있습니다. 로그가 중요도에 따라 필터링되는 사용자 정의 로거를 추가하거나 외부 모니터링 도구를 통합하여 자세한 분석을 캡처하는 것을 고려하세요.

API가 발전함에 따라 강력한 오류 처리구조적 로깅에 투자하는 것이 서비스 확장 및 유지 관리를 위해 더욱 중요해질 것입니다. 엔드포인트 버전 관리를 신중하게 수행하는 것도 이전 버전과의 호환성을 보장하면서 시스템 아키텍처를 지속적으로 개선하는 데 도움이 됩니다.

또한 성능 최적화라는 추가 영역은 비동기 요청 처리를 도입함으로써 응답 시간을 크게 향상시킬 수 있습니다. 게다가, 사용자 수요가 증가함에 따라 API를 캐싱 메커니즘이나 로드 밸런서와 통합하는 것도 인프라를 확장하는 데 도움이 될 수 있습니다.

API 테스트 프로세스를 문서화하는 것도 잊지 마세요. 테스트는 API 관리의 필수 부분이며 이를 문서화함으로써 투명성과 신뢰성을 확보할 수 있습니다. APIDog를 사용하면 API 테스트와 문서화 프로세스를 하나의 일관된 워크플로로 통합하여 간소화할 수 있습니다.

  • API 문서화에 있어 정확성과 관련성을 유지하는 것이 중요합니다. 이를 보장하는 가장 효과적인 방법 중 하나는 문서화 프로세스를 자동화하는 것입니다. APIDog는 API 문서화를 자동으로 처리하여 문서가 항상 최신 상태로 유지되도록 보장하는 솔루션을 제공합니다.
button
  • 예를 들어, 새로운 API 버전에서 매개변수를 추가하거나 제거하거나 이름을 바꾸면 APIDog는 이러한 변경 사항이 실제로 라이브로 전환될 때 문서에 자동으로 반영됩니다. 이 접근 방식은 문서의 일관성을 유지하고 오류를 줄이며 개발자 경험을 향상시키는 데 매우 효과적이라는 것을 증명했습니다.

다음은 APIDog가 생성한 API 문서의 예입니다:

  • APIDog와 함께 API 문서화를 자동으로 처리하면 사용자가 항상 최신 정보에 접근할 수 있도록 보장합니다.
button

최종 생각

마무리하면서 이 논의 동안 다룬 핵심 사항을 요약해 보겠습니다. FastAPI는 효율적이고 확장 가능한 API 구축을 위한 힘과 단순성을 나타냅니다.

API를 특정 사용 사례에 맞게 조정할수록 더 강력하고 효율적이 됩니다. 여기서 멈추지 마세요 — 한계를 뛰어넘고 고급 통합을 실험하며 커뮤니티와 경험을 공유하세요.

더 깊이 탐색하고 새로운 아이디어를 테스트하며 더 많은 통찰력 가져오기 위해 돌아오세요. 함께 좋은 API를 독특한 API로 변화시킬 수 있습니다. API 능력을 향상시킬 준비가 되셨나요?

FastAPI의 세계와 그 제공하는 모든 것을 더 깊이 파고들어 봅시다!

EXAONE 3.0 7.8B 모델을 로컬에서 실행하는 방법튜토리얼

EXAONE 3.0 7.8B 모델을 로컬에서 실행하는 방법

이 글에서는 EXAONE 3.0 7.8B 모델을 자신의 컴퓨터에서 설치하고 실행하는 방법을 단계별로 상세히 알아보겠습니다

Young-jae

March 25, 2025

Claude 3.7 소넷 API에 접근하고 Apidog을 사용하여 테스트하는 방법튜토리얼

Claude 3.7 소넷 API에 접근하고 Apidog을 사용하여 테스트하는 방법

Anthropic의 최신 출시인 Claude 3.7 Sonnet에 대해 기대하고 있으며, Apidog로 테스트하면서 API를 통한 기능을 탐색하고 싶다면, 올바른 장소에 오신 것입니다. 💡시작하기 전에 간단한 팁을 드리겠습니다: 오늘 Apidog를 무료로 다운로드하여 API 테스트 프로세스를 간소화하세요. 특히 Claude 3.7 Sonnet의 강력한 기능을 탐색하는 데 적합한 도구로, 최첨단 AI 모델을 테스트하려는 개발자에게 이상적입니다!버튼 Claude 3.7 Sonnet이 중요한 이유로 시작해봅시다. Anthropic은 최근 2025년 2월 24일에 이 모델을 공개했으며, 즉시 및 단계별 응답을 위한 하이브리드 추론 기능을 갖춘 가장 지능적인 창작물로 자리 잡았습니다. 이는 코딩, 추론 등 여러 부분에서 혁신적인 변화를 가져오며, 현재 e Anthropic API, Amazon Bedrock, Google Cloud의 Vertex AI를 통해 사용할 수 있습니다. 이 튜

Young-jae

February 25, 2025

GitHub Copilot 무료: 어떻게 시작하나요?튜토리얼

GitHub Copilot 무료: 어떻게 시작하나요?

GitHub Copilot 무료 사용법을 알아보세요. 이 AI 기반 코딩 도우미에 대한 이 가이드는 VS Code와 JetBrains와 같은 인기 IDE의 설정 단계를 다루며, 무료로 스마트한 코드 제안 및 완성을 통해 생산성을 높일 수 있도록 도와줍니다!

Young-jae

December 19, 2024