# main.py from fastapi import FastAPI, Query, HTTPException from fastapi.responses import FileResponse from gtts import gTTS, gTTSError # Import gTTSError for specific error handling import uuid import os # Import os module for path operations import tempfile # Import tempfile for better temporary file handling # --- Configuration --- # Use tempfile to get a cross-platform temporary directory TEMP_DIR = tempfile.gettempdir() # Ensure the temporary directory exists os.makedirs(TEMP_DIR, exist_ok=True) # --- FastAPI App Initialization --- app = FastAPI( title="gTTS API", description="A simple API to convert text to speech using Google Text-to-Speech (gTTS). Supports multiple languages including Tamil, Sinhala, and many others.", version="1.2.0", # Increment version for documentation changes ) # --- API Endpoints --- @app.get("/", tags=["General"]) def read_root(): """ Root endpoint providing a welcome message. """ return {"message": "Welcome to the gTTS API. Use the /tts endpoint to generate speech."} @app.get("/tts", tags=["Text-to-Speech"]) def text_to_speech( text: str = Query( ..., # Ellipsis makes the parameter required min_length=1, max_length=500, # Adjust max length as needed title="Text to Convert", description="The text you want to convert into speech (1-500 characters)." ), lang: str = Query( "en", # Default language is English min_length=2, max_length=10, # Allow for language codes like 'en-us', 'zh-CN' etc. title="Language Code", description="The BCP 47 language code for the speech synthesis (e.g., 'en', 'es', 'ta', 'si', 'ja', 'zh-CN'). See gTTS documentation for supported languages." ) ): """ Converts the provided text into an MP3 audio file using the specified language. - **text**: The text to synthesize (required). - **lang**: The language code (e.g., 'en', 'es', 'fr', 'ta', 'si'). Defaults to 'en'. **Crucially, gTTS must support this language code.** """ try: # Generate a unique filename in the configured temporary directory filename = os.path.join(TEMP_DIR, f"{uuid.uuid4().hex}.mp3") # Create gTTS object with text and language # Use slow=False for normal speed speech tts_object = gTTS(text=text, lang=lang, slow=False) # Save the audio file tts_object.save(filename) # Return the audio file as a response # The 'filename' parameter sets the download name for the browser return FileResponse( path=filename, media_type="audio/mpeg", filename=f"speech_{lang}.mp3" # Suggest a filename like speech_en.mp3 or speech_ta.mp3 # Consider adding background task for cleanup as mentioned in previous examples ) except gTTSError as e: # Handle specific gTTS errors (like invalid language code, network issues) detail_message = f"gTTS Error: {str(e)}. Ensure the language code '{lang}' is supported and text is appropriate for the language." # Check common error patterns if "400 (Bad Request)" in str(e) or "Language not supported" in str(e): raise HTTPException(status_code=400, detail=detail_message) elif "500 (Internal Server Error)" in str(e) or "Failed to connect" in str(e): # Treat these as potential temporary Google service issues raise HTTPException(status_code=503, detail=f"Service Error: {str(e)}. Could be a temporary issue with the TTS service.") else: # Other gTTS errors raise HTTPException(status_code=503, detail=detail_message) # 503 Service Unavailable likely except ValueError as e: # Potentially handle other value errors if gTTS raises them for certain inputs raise HTTPException(status_code=400, detail=f"Input Error: {str(e)}") except Exception as e: # Catch any other unexpected errors # Log the error for debugging # import logging # logging.exception(f"An unexpected error occurred during TTS generation for lang='{lang}'") raise HTTPException(status_code=500, detail=f"Internal Server Error: An unexpected error occurred.") # --- How to Run (Instructions) --- # 1. Save this code as `main.py`. # 2. Install necessary libraries: # pip install fastapi "uvicorn[standard]" gTTS # 3. Run the FastAPI server using Uvicorn: # uvicorn main:app --reload # # --- How to Use - Examples --- # Open your browser or use a tool like curl/Postman. # Access the TTS endpoint with the 'text' and 'lang' query parameters. # NOTE: Text containing non-ASCII characters needs to be URL-encoded. Most browsers do this automatically. # # - English (en - Default): # Text: "Hello, world!" # URL: http://127.0.0.1:8000/tts?text=Hello%2C%20world%21 # # - Spanish (es): # Text: "Hola Mundo" # URL: http://127.0.0.1:8000/tts?text=Hola%20Mundo&lang=es # # - French (fr): # Text: "Bonjour le monde" # URL: http://127.0.0.1:8000/tts?text=Bonjour%20le%20monde&lang=fr # # - German (de): # Text: "Hallo Welt" # URL: http://127.0.0.1:8000/tts?text=Hallo%20Welt&lang=de # # - Tamil (ta): # Text: "வணக்கம் உலகம்" # URL: http://127.0.0.1:8000/tts?text=%E0%AE%B5%E0%AE%A3%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AE%AE%E0%AF%8D%20%E0%AE%89%E0%AE%B2%E0%AE%95%E0%AE%AE%E0%AF%8D&lang=ta # # - Sinhala (si): # Text: "හෙලෝ ලෝකය" # URL: http://127.0.0.1:8000/tts?text=%E0%B7%84%E0%B7%99%E0%B6%BD%E0%B7%9D%20%E0%B6%BD%E0%B7%9D%E0%B6%9A%E0%B6%BA&lang=si # # - Japanese (ja): # Text: "こんにちは世界" # URL: http://127.0.0.1:8000/tts?text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C&lang=ja # # - Chinese (Mandarin, Simplified) (zh-CN): # Text: "你好世界" # URL: http://127.0.0.1:8000/tts?text=%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C&lang=zh-CN # # - Russian (ru): # Text: "Привет мир" # URL: http://127.0.0.1:8000/tts?text=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%20%D0%BC%D0%B8%D1%80&lang=ru # # - Hindi (hi): # Text: "नमस्ते दुनिया" # URL: http://127.0.0.1:8000/tts?text=%E0%A4%A8%E0%A4%AE%E0%A4%B8%E0%A5%8D%E0%A4%A4%E0%A5%87%20%E0%A4%A6%E0%A5%81%E0%A4%A8%E0%A4%BF%E0%A4%AF%E0%A4%BE&lang=hi # # - Arabic (ar): # Text: "مرحبا بالعالم" # URL: http://127.0.0.1:8000/tts?text=%D9%85%D8%B1%D8%AD%D8%A8%D8%A7%20%D8%A8%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85&lang=ar # # Find more supported language codes in the gTTS documentation or common lists of BCP 47 codes. # The API will return an MP3 file download or playback depending on your browser/client. # If you provide an unsupported language code, you should get a 400 Bad Request error.