Gemini API 연동 & 아이디어 추출
목표
- 업로드된 이미지를 Gemini API에 전달
- 사진 설명 + 핵심 키워드를 AI가 추출
- 이를 바탕으로 3~5개의 글 주제 아이디어 반환
사전 준비
Google AI Studio에서 Gemini API Key 발급
환경 변수 등록
Windows (PowerShell)
# 일시적 (터미널 열려 있는 동안만 유효) $env:GEMINI_API_KEY="여기에_발급받은_APIKEY" # 영구 등록 (다시 부팅해도 유지됨) setx GEMINI_API_KEY "여기에_발급받은_APIKEY"
확인하려면:
echo $env:GEMINI_API_KEY
Mac / Linux (bash/zsh)
# 일시적 (터미널 세션에서만 유효) export GEMINI_API_KEY="여기에_발급받은_APIKEY" # 영구 등록 (매번 자동 설정되게) echo 'export GEMINI_API_KEY="여기에_발급받은_APIKEY"' >> ~/.bashrc # 또는 zsh 사용자는 echo 'export GEMINI_API_KEY="여기에_발급받은_APIKEY"' >> ~/.zshrc # 설정 반영 source ~/.bashrc # 또는 source ~/.zshrc
확인하려면:
echo $GEMINI_API_KEY
코드 작성
app.py에 아이디어 생성 API를 추가합니다.
import os
import google.generativeai as genai
from flask import Flask, request, jsonify
from werkzeug.utils import secure_filename
# Flask 초기화
app = Flask(__name__)
# 업로드 폴더
UPLOAD_FOLDER = "uploads"
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# Gemini API 설정
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-1.5-pro")
# 허용 확장자
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# 홈
@app.route('/')
def home():
return jsonify({"message": "IdeaSnap Backend is running!"})
# 이미지 업로드 API
@app.route('/api/upload-image', methods=['POST'])
def upload_image():
if 'image' not in request.files:
return jsonify({"error": "No file part"}), 400
file = request.files['image']
if file.filename == '':
return jsonify({"error": "No selected file"}), 400
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filepath)
return jsonify({"message": "Image uploaded successfully", "file_path": filepath}), 200
return jsonify({"error": "Invalid file type"}), 400
# 아이디어 생성 API
@app.route('/api/generate-ideas', methods=['POST'])
def generate_ideas():
data = request.json
image_path = data.get("image_path")
if not image_path or not os.path.exists(image_path):
return jsonify({"error": "Invalid image path"}), 400
# 이미지 불러오기
with open(image_path, "rb") as f:
image_data = f.read()
# Gemini API 호출
prompt = """
이 이미지를 분석하고 간단히 설명해줘.
그리고 이 이미지를 바탕으로 글을 쓸 수 있는 창의적인 주제를 5개 제시해줘.
출력은 JSON 형식으로:
{
"description": "...",
"keywords": ["...", "..."],
"topics": ["...", "...", "..."]
}
"""
response = model.generate_content([prompt, {"mime_type": "image/jpeg", "data": image_data}])
return jsonify({"ideas": response.text})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
프로젝트 구조 (지금까지)
ideasnap-backend/ ├─ uploads/ # 업로드된 이미지 저장 ├─ venv/ # 가상환경 ├─ app.py # Flask 서버 메인 파일 └─ sample.jpg # 테스트용 이미지
테스트 방법
1. 먼저 이미지 업로드 (Part 3 방식과 동일)
curl -X POST http://127.0.0.1:5000/api/upload-image \ -F "image=@sample.jpg"
2. 아이디어 생성 요청
curl -X POST http://127.0.0.1:5000/api/generate-ideas \
-H "Content-Type: application/json" \
-d '{"image_path": "uploads/sample.jpg"}'
3. 예상 응답 예시
{
"ideas": "{
\"description\": \"푸른 하늘 아래 꽃이 핀 풍경\",
\"keywords\": [\"자연\", \"꽃\", \"평화\"],
\"topics\": [\"봄날의 산책\", \"자연이 주는 위로\", \"도시 속 작은 정원\"]
}"
}
다음 단계
Part 5에서는, 사용자가 선택한 주제 & 카테고리를 기반으로
댓글 남기기