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 파일 사용 (추천)
- Flask 프로젝트 루트에 .env 파일 생성:
OPENAI_API_KEY=sk-xxxx
- python-dotenv 설치:
pip install python-dotenv
- 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 등)에 배포해도 같은 방식으로 환경변수 넣어줍니다.
👉 정리하면 순서는:
- 환경변수에 키 저장 (export / setx / .env / 배포 환경 설정)
- Flask에서 os.getenv("OPENAI_API_KEY") 로 불러오기
- 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번)으로 요청을 정상적으로 보낼 수 있습니다.
🔹 최종적으로 정리하면
- 브라우저 주소창: http://localhost:3000 (React UI 접속)
- React 코드 내부: fetch("http://localhost:5000/sendMessage")
- Flask API: http://localhost:5000/sendMessage
즉, UI는 3000번에서 보이고, API 요청은 5000번으로 전달되는 구조입니다.
🔹 요청/응답 흐름
- 브라우저 (React UI, 포트 3000)
- 사용자가 메시지를 입력하고 Send 버튼을 누름
- React 코드에서 fetch("http://localhost:5000/sendMessage", {...}) 실행
- 브라우저 → Flask (포트 5000)
- 브라우저는 POST /sendMessage 요청을 localhost:5000으로 보냄
- 여기서 브라우저는 프록시가 아니라 그냥 직접 5000번 서버로 요청하는 거임
- Flask 서버 (포트 5000)
- 요청을 받고 request.json에서 메시지를 추출
- OpenAI API 호출 (client.chat.completions.create)
- 응답(bot_reply)을 JSON 형태로 브라우저에 다시 반환
{
"username": "Ju-hyeok",
"user_message": "안녕",
"bot_reply": "안녕하세요! 저는 포트폴리오 챗봇이에요."
}
- 브라우저 ← 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 |