본문 바로가기

알토르

알토르 3주차 OpenAI API 연동

OpenAI API 연동

🔑 1. 로컬(개발 PC)에서 환경변수 저장

(A) Linux / Mac (bash/zsh)

export OPENAI_API_KEY="sk-xxxx"
현재 터미널 세션에서만 적용
~/.bashrc 또는 ~/.zshrc 마지막 줄에 추가
echo 'export OPENAI_API_KEY="sk-xxxx"' >> ~/.bashrc
source ~/.bashrc

(B) Windows PowerShell

setx OPENAI_API_KEY "sk-xxxx"
영구 등록돼서 새 터미널부터 적용
적용 즉시 현재 세션에는 안 먹힘 → 새 창 열어야 함

(C) .env 파일 사용 (추천)

  1. Flask 프로젝트 루트에 .env 파일 생성:
OPENAI_API_KEY=sk-xxxx
  1. python-dotenv 설치:
pip install python-dotenv
  1. app.py에 추가:
from dotenv import load_dotenv
load_dotenv()  # .env 파일 불러오기

os.getenv("OPENAI_API_KEY")로 불러오기

🔑 2. Flask 코드에서 키 불러오기

import os
api_key = os.getenv("OPENAI_API_KEY")
print(api_key)  # 잘 불러왔는지 확인

🔑 3. Vercel 같은 배포 환경에서

Vercel → 프로젝트 → Settings → Environment Variables 에
OPENAI_API_KEY=sk-xxxx 추가
Flask를 다른 클라우드(EC2, Render, Railway 등)에 배포해도 같은 방식으로 환경변수 넣어줍니다.

👉 정리하면 순서는:

  1. 환경변수에 키 저장 (export / setx / .env / 배포 환경 설정)
  2. Flask에서 os.getenv("OPENAI_API_KEY") 로 불러오기
  3. OpenAI API 클라이언트 초기화 시 사용
✅ 테스트 방법

1. .env 파일 준비
OPENAI_API_KEY=sk-xxxx


2. Flask 실행
python app.py


3. 요청 보내기 (예: PowerShell)

$headers = @{ "Content-Type" = "application/json" }
$body = @{ "username"="Juhyeok"; "message"="Hello Flask!" } | ConvertTo-Json
Invoke-RestMethod -Uri http://127.0.0.1:5000/sendMessage -Method POST -Headers $headers -Body $body

에러

import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

try:
    response = client.models.list()
    print("✅ 연결 성공, 사용 가능한 모델:", [m.id for m in response.data[:5]])
except Exception as e:
    print("❌ 연결 실패:", e)

 

 

 

app.py

from flask import Flask, request, jsonify
from flask_cors import CORS
import os
from dotenv import load_dotenv
from openai import OpenAI

# 1. 환경 변수 로드
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
    raise ValueError("OpenAI API 키가 설정되지 않았습니다. .env 확인하세요.")

# 2. Flask 앱과 CORS 설정
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "http://localhost:3000"}})

# 3. OpenAI 클라이언트 생성
client = OpenAI(api_key=api_key)

# 4. 채팅 엔드포인트
@app.route('/sendMessage', methods=['POST'])
def send_message():
    data = request.json
    username = data.get("username", "anonymous")
    message = data.get("message", "")

    # OpenAI API 호출
    try:
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": "당신은 포트폴리오를 소개하는 친절한 챗봇입니다."},
                {"role": "user", "content": message}
            ]
        )
        # 최신 SDK 기준, message가 dict 형태일 수 있음
        bot_reply = response.choices[0].message.content if hasattr(response.choices[0].message, 'content') else response.choices[0].message['content']

    except Exception as e:
        bot_reply = f"AI 호출 실패: {e}"

    print(f"[{username}] {message} -> {bot_reply}")

    return jsonify({
        "username": username,
        "user_message": message,
        "bot_reply": bot_reply
    })


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

콘솔에서는 open ai 응답 확인

채팅 UI에서 none으로 확인

chat.jsx

const data = await res.json();
setMessages((m) => [
  ...m,
  {
    id: crypto.randomUUID(),
    user: "bot",
    name: "J",
    text: data.response,---->data.bot_reply로 변경
    time: new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
  },
]);

app.py / chat.jsx = 동일 이름 확인

 

 

 

 

CORS

🔹 구조 개요

React (프론트엔드)

npm run dev → 기본적으로 http://localhost:3000 에서 실행됨

브라우저에서 열리는 주소도 http://localhost:3000

Flask (백엔드)

python app.py → http://localhost:5000 에서 실행됨

API 엔드포인트: http://localhost:5000/sendMessage

🔹 데이터 흐름

사용자가 React UI(http://localhost:3000)에서 메시지를 입력

React 코드에서 fetch("http://localhost:5000/sendMessage", {...}) 실행

브라우저가 3000번에서 5000번으로 HTTP 요청을 보냄

즉, localhost:3000 → localhost:5000

다른 포트라서 브라우저는 이걸 Cross-Origin 요청(CORS) 으로 간주

Flask 서버(5000)가 JSON 응답을 반환

React 코드가 res.json()으로 응답을 받고 setMessages로 UI 업데이트

🔹 CORS 문제 해결

브라우저는 보안 때문에 포트가 다르면 다른 출처(origin) 라고 판단합니다.
즉, localhost:3000에서 localhost:5000으로 요청하면 CORS 정책 위반이 일어날 수 있습니다.

👉 Flask 쪽에서 이미 flask_cors.CORS(app) 입력

이 설정 덕분에 React(3000번)에서 Flask(5000번)으로 요청을 정상적으로 보낼 수 있습니다.

🔹 최종적으로 정리하면

  1. 브라우저 주소창: http://localhost:3000 (React UI 접속)
  2. React 코드 내부: fetch("http://localhost:5000/sendMessage")
  3. Flask API: http://localhost:5000/sendMessage

즉, UI는 3000번에서 보이고, API 요청은 5000번으로 전달되는 구조입니다.

🔹 요청/응답 흐름

  1. 브라우저 (React UI, 포트 3000)
  1. 브라우저 → Flask (포트 5000)
  • 브라우저는 POST /sendMessage 요청을 localhost:5000으로 보냄
  • 여기서 브라우저는 프록시가 아니라 그냥 직접 5000번 서버로 요청하는 거임
  1. Flask 서버 (포트 5000)
  • 요청을 받고 request.json에서 메시지를 추출
  • OpenAI API 호출 (client.chat.completions.create)
  • 응답(bot_reply)을 JSON 형태로 브라우저에 다시 반환
{
  "username": "Ju-hyeok",
  "user_message": "안녕",
  "bot_reply": "안녕하세요! 저는 포트폴리오 챗봇이에요."
}
  1. 브라우저 ← Flask
  • React에서 res.json()으로 응답 데이터를 받고
  • setMessages([...m, { user: "bot", text: data.bot_reply }]) 호출
  • 화면에 새로운 말풍선이 추가됨

🔹 정리 (한 줄 요약)

👉 3000번 React는 UI 역할만 하고,
👉 5000번 Flask는 API 서버 역할을 해서 데이터를 돌려주고,
👉 브라우저가 두 서버를 연결해주는 통로 역할을 합니다.

즉, “3000 → 5000 → OpenAI → 5000 → 3000 → 브라우저 화면” 이런 데이터 왕복 구조

'알토르' 카테고리의 다른 글

알토르 3주차 - Browser Storage  (0) 2026.05.13
OpenAI Assistant  (0) 2026.05.12
알토르 3주차 - Fetch / Axios  (0) 2026.05.10
알토르 3주차 API Endpoint  (0) 2026.05.10
HTTP이란?  (0) 2026.05.09