Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import torch | |
| from transformers import pipeline, AutoTokenizer, AutoModel | |
| import soundfile as sf | |
| import io | |
| import os | |
| from fastapi import FastAPI, HTTPException, Depends | |
| from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials | |
| from pydantic import BaseModel | |
| from typing import Optional | |
| import uvicorn | |
| import secrets | |
| from cryptography.fernet import Fernet | |
| import json | |
| # Custom API Key Setup (tera control – keys file mein store, encrypted) | |
| API_KEYS_FILE = "api_keys.json" | |
| ENCRYPTION_KEY = os.getenv("ENCRYPTION_KEY", Fernet.generate_key().decode()) # Prod mein env set kar | |
| cipher_suite = Fernet(ENCRYPTION_KEY.encode()) | |
| # Load or init API keys | |
| def load_api_keys(): | |
| if os.path.exists(API_KEYS_FILE): | |
| with open(API_KEYS_FILE, 'r') as f: | |
| return json.load(f) | |
| return {} | |
| def save_api_keys(keys): | |
| with open(API_KEYS_FILE, 'w') as f: | |
| json.dump(keys, f) | |
| api_keys = load_api_keys() # Dict like {"user1": "encrypted_key"} | |
| # Generate new API key (Gradio UI se call kar) | |
| def generate_api_key(username: str): | |
| if username in api_keys: | |
| return "Key already exists for this user!" | |
| raw_key = secrets.token_urlsafe(32) | |
| encrypted_key = cipher_suite.encrypt(raw_key.encode()).decode() | |
| api_keys[username] = encrypted_key | |
| save_api_keys(api_keys) | |
| return f"Your API Key: {raw_key} (Save it safely! Use in headers: Authorization: Bearer {raw_key})" | |
| # TTS Model Load (High Quality Indic Parler-TTS) | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| tts_pipeline = pipeline( | |
| "text-to-speech", | |
| model="ai4bharat/indic-parler-tts", | |
| tokenizer="ai4bharat/indic-parler-tts", | |
| torch_dtype=torch.float16 if device == "cuda" else torch.float32, | |
| device=device | |
| ) | |
| # Gradio TTS Function | |
| def generate_speech(text: str, voice_desc: str = "A neutral male voice speaking clearly and calmly.", language: str = "Auto (Urdu/Hindi)"): | |
| if not text.strip(): | |
| return None, "Enter some text!" | |
| # Caption for control: voice, emotion, speed etc. | |
| caption = f"{voice_desc} High quality, natural Urdu/Hindi speech with proper intonation." | |
| prompt = f"[{caption}]{text}" | |
| # Generate audio | |
| output = tts_pipeline(prompt) | |
| audio_array = output["audio"] | |
| # Save to buffer | |
| buffer = io.BytesIO() | |
| sf.write(buffer, audio_array, output["sampling_rate"]) | |
| buffer.seek(0) | |
| return buffer.getvalue(), f"Generated! Voice: {voice_desc}, Lang: {language}" | |
| # API Models | |
| class TTSRequest(BaseModel): | |
| text: str | |
| voice_desc: Optional[str] = "A neutral male voice speaking clearly and calmly." | |
| language: Optional[str] = "Auto (Urdu/Hindi)" | |
| api_key: str # Will be in headers, but for body too | |
| class APIResponse(BaseModel): | |
| audio_base64: str # Or URL if save files | |
| message: str | |
| # FastAPI Setup | |
| app = FastAPI(title="Custom Urdu/Hindi TTS API") | |
| security = HTTPBearer() | |
| async def verify_api_key(credentials: HTTPAuthorizationCredentials = Depends(security)): | |
| raw_key = credentials.credentials | |
| for user_key_enc in api_keys.values(): | |
| try: | |
| decrypted = cipher_suite.decrypt(user_key_enc.encode()).decode() | |
| if decrypted == raw_key: | |
| return True | |
| except: | |
| pass | |
| raise HTTPException(status_code=401, detail="Invalid API Key") | |
| async def api_generate_speech(request: TTSRequest, verified: bool = Depends(verify_api_key)): | |
| # Same logic as Gradio | |
| caption = f"{request.voice_desc} High quality, natural Urdu/Hindi speech with proper intonation." | |
| prompt = f"[{caption}]{request.text}" | |
| output = tts_pipeline(prompt) | |
| audio_array = output["audio"] | |
| buffer = io.BytesIO() | |
| sf.write(buffer, audio_array, output["sampling_rate"]) | |
| audio_base64 = base64.b64encode(buffer.getvalue()).decode() # Need import base64 | |
| return APIResponse(audio_base64=audio_base64, message="Success!") | |
| # Gradio Interface | |
| with gr.Blocks(title="Urdu/Hindi TTS Generator") as demo: | |
| gr.Markdown("# High Quality Urdu/Hindi TTS with Custom API Control 🔥") | |
| gr.Markdown("Enter text in Urdu/Hindi. Control voice/emotion/speed via description. Generate your own API Key below!") | |
| with gr.Tab("TTS Generator"): | |
| text_input = gr.Textbox(label="Text (Urdu/Hindi)", placeholder="اسلام آباد کا موسم آج بہت اچھا ہے۔ یا हिंदी: आज का मौसम बहुत अच्छा है।", lines=3) | |
| voice_input = gr.Textbox(label="Voice Description (e.g., 'Young female, excited and fast')", value="A neutral male voice speaking clearly and calmly.") | |
| lang_input = gr.Dropdown(["Auto (Urdu/Hindi)", "Hindi", "Urdu"], value="Auto (Urdu/Hindi)", label="Language") | |
| audio_output = gr.Audio(label="Generated Speech") | |
| generate_btn = gr.Button("Generate Speech") | |
| generate_btn.click( | |
| generate_speech, | |
| inputs=[text_input, voice_input, lang_input], | |
| outputs=[audio_output, gr.Textbox(label="Status")] | |
| ) | |
| with gr.Tab("Custom API Key Generator"): | |
| username_input = gr.Textbox(label="Your Username (for key association)", placeholder="e.g., myapp_user") | |
| key_output = gr.Textbox(label="Your New API Key", interactive=False) | |
| gen_key_btn = gr.Button("Generate My API Key") | |
| gen_key_btn.click( | |
| generate_api_key, | |
| inputs=[username_input], | |
| outputs=[key_output] | |
| ) | |
| gr.Markdown(""" | |
| ### How to Use Custom API: | |
| - POST to `/generate-speech` with JSON: `{"text": "your text", "voice_desc": "description", "language": "Auto"}` | |
| - Header: `Authorization: Bearer YOUR_KEY` | |
| - Response: JSON with `audio_base64` (decode to play). | |
| Example cURL: | |
| ``` | |
| curl -X POST "https://yourspace.hf.space/generate-speech" \ | |
| -H "Authorization: Bearer YOUR_API_KEY" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"text": "ہیلو دنیا", "voice_desc": "Cheerful female voice"}' | |
| ``` | |
| Integrate in any app (Python/JS) – full control, no HF limits directly! | |
| """) | |
| # Embed FastAPI in Gradio (run on /run for API) | |
| if __name__ == "__main__": | |
| demo.launch(server_name="0.0.0.0", server_port=7860) | |
| # For API: uvicorn.run(app, host="0.0.0.0", port=8000) # Separate if needed |