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에서는, 사용자가 선택한 주제 & 카테고리를 기반으로


    TechTinkerer's에서 더 알아보기

    구독을 신청하면 최신 게시물을 이메일로 받아볼 수 있습니다.

    댓글 남기기

    ← 뒤로

    응답해 주셔서 감사합니다. ✨

    TechTinkerer's에서 더 알아보기

    지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

    계속 읽기

    TechTinkerer's에서 더 알아보기

    지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

    계속 읽기