티스토리 뷰
FastAPI를 사용하여 OpenAI LLM(ChatGPT 모델 등)에 요청을 보내고 응답을 받는 서버를 구축하는 것은 매우 인기 있는 조합입니다.
FastAPI의 비동기(Asynchronous) 처리 능력과 OpenAI Python SDK의 비동기 클라이언트(AsyncOpenAI)를 결합하면, 외부 API 호출 대기 시간 동안 서버가 차단(blocking)되지 않아 높은 성능을 유지할 수 있습니다.
다음은 단계별 구현 가이드입니다.
1. 사전 준비 및 환경 설정
먼저 필요한 라이브러리를 설치하고 환경 변수를 설정해야 합니다.
필수 라이브러리 설치:
pip install fastapi uvicorn openai python-dotenv
fastapi: 웹 프레임워크
• uvicorn: ASGI 서버 (FastAPI 실행용)
• openai: OpenAI 공식 Python SDK (v1.0.0 이상 버전 사용 권장)
• python-dotenv: .env 파일에서 API 키를 안전하게 로드하기 위함
환경 변수 설정 (.env):
프로젝트 루트 디렉토리에 .env 파일을 만들고 OpenAI API 키를 저장합니다. (이 파일은 절대로 git 등에 커밋하면 안 됩니다.)
# .env 파일 내용
OPENAI_API_KEY=sk-your-actual-openai-api-key-here
2. 기본 구현 (단순 요청/응답)
가장 기본적인 형태의 구현입니다. 사용자의 프롬프트를 받아 OpenAI에 전달하고, 완성된 답변 전체를 받아 반환합니다.
main.py 파일을 작성합니다.
# main.py
import os
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from openai import AsyncOpenAI # 비동기 클라이언트 사용
from dotenv import load_dotenv
# 1. 환경 변수 로드 (.env 파일에서 API 키 가져오기)
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
raise ValueError("OPENAI_API_KEY 환경 변수가 설정되지 않았습니다.")
# 2. OpenAI 비동기 클라이언트 초기화
# FastAPI의 async 특성을 살리기 위해 동기 클라이언트(OpenAI) 대신 비동기 클라이언트를 사용합니다.
client = AsyncOpenAI(api_key=OPENAI_API_KEY)
# 3. FastAPI 앱 초기화
app = FastAPI()
# 4. 요청 및 응답 데이터 모델 정의 (Pydantic 활용)
# 요청 바디 구조 정의
class ChatRequest(BaseModel):
prompt: str
model: str = "gpt-3.5-turbo" # 기본값 설정, gpt-4o 등으로 변경 가능
temperature: float = 0.7
# 응답 바디 구조 정의
class ChatResponse(BaseModel):
reply: str
# 5. 엔드포인트 정의 (POST 방식)
@app.post("/chat", response_model=ChatResponse)
async def chat_with_openai(request: ChatRequest):
"""
사용자의 프롬프트를 받아 OpenAI GPT 모델에 요청하고 응답을 반환합니다.
"""
try:
# OpenAI API 비동기 호출 (await 키워드 중요)
response = await client.chat.completions.create(
model=request.model,
messages=[
# 시스템 메시지로 AI의 역할 부여 가능
{"role": "system", "content": "당신은 도움이 되는 AI 어시스턴트입니다. 한국어로 대답해주세요."},
# 사용자 메시지
{"role": "user", "content": request.prompt}
],
temperature=request.temperature,
max_tokens=500, # 필요한 경우 응답 길이 제한
)
# 응답에서 텍스트 내용 추출
ai_reply_content = response.choices[0].message.content
return ChatResponse(reply=ai_reply_content)
except Exception as e:
# 에러 발생 시 처리 (예: API 키 오류, 요청 한도 초과 등)
print(f"OpenAI API Error: {e}")
raise HTTPException(status_code=500, detail=str(e))
# 실행 방법 주석
# uvicorn main:app --reload
실행 및 테스트:
1. 터미널에서 실행: uvicorn main:app --reload
2. 브라우저에서 Swagger UI 접속: http://127.0.0.1:8000/docs
3. POST /chat 엔드포인트 테스트:
• "Try it out" 클릭
• Request body에 아래 JSON 입력 후 "Execute":