[LLM] Flaskで簡易 /speak APIを作成

from flask import Flask, request, send_file, jsonify
from gtts import gTTS
import os
import tempfile
from datetime import datetime

app = Flask(__name__)

@app.route('/speak', methods=['POST'])
def speak():
    """
    テキストを音声に変換するAPI
    
    リクエスト例:
    {
        "text": "こんにちは、世界",
        "lang": "ja",
        "slow": false
    }
    """
    try:
        # リクエストからJSONデータを取得
        data = request.get_json()
        
        if not data or 'text' not in data:
            return jsonify({'error': 'text パラメータが必要です'}), 400
        
        text = data['text']
        lang = data.get('lang', 'ja')  # デフォルトは日本語
        slow = data.get('slow', False)  # ゆっくり話すかどうか
        
        if not text.strip():
            return jsonify({'error': 'テキストが空です'}), 400
        
        # 一時ファイルを作成
        temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.mp3')
        temp_filename = temp_file.name
        temp_file.close()
        
        # TTSで音声ファイルを生成
        tts = gTTS(text=text, lang=lang, slow=slow)
        tts.save(temp_filename)
        
        # 音声ファイルを返す
        response = send_file(
            temp_filename,
            mimetype='audio/mpeg',
            as_attachment=True,
            download_name=f'speech_{datetime.now().strftime("%Y%m%d_%H%M%S")}.mp3'
        )
        
        # レスポンス送信後にファイルを削除
        @response.call_on_close
        def cleanup():
            try:
                os.unlink(temp_filename)
            except Exception as e:
                print(f"一時ファイルの削除に失敗: {e}")
        
        return response
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.route('/speak/languages', methods=['GET'])
def get_languages():
    """サポートされている言語のリストを返す"""
    languages = {
        'ja': '日本語',
        'en': '英語',
        'zh-cn': '中国語(簡体字)',
        'zh-tw': '中国語(繁体字)',
        'ko': '韓国語',
        'es': 'スペイン語',
        'fr': 'フランス語',
        'de': 'ドイツ語',
        'it': 'イタリア語',
        'pt': 'ポルトガル語',
    }
    return jsonify(languages)


@app.route('/health', methods=['GET'])
def health_check():
    """ヘルスチェック用エンドポイント"""
    return jsonify({'status': 'ok'})


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

$ curl -X POST http://localhost:5000/speak \ \
-H “Content-Type: application/json” \
-d ‘{“text”:”こんにちは、世界”, “lang”:”ja”}’ \
–output speech.mp3
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 18096 100 18048 100 48 34083 90 –:–:– –:–:– –:–:– 34207

なるほど。textをPOSTしていますが、gptからのレスポンスをそのまま出力しても良さそうですね。。