Spaces:
Running
Running
# | |
# SPDX-FileCopyrightText: Hadad <[email protected]> | |
# SPDX-License-Identifier: Apache-2.0 | |
# | |
import asyncio # Import asyncio to enable asynchronous waiting and retries | |
import httpx # Import the httpx library to perform asynchronous HTTP requests efficiently | |
from urllib.parse import quote # Import the quote function to safely encode strings for use in URLs | |
from src.utils.ip_generator import generate_ip # Import a custom utility function to generate random IP addresses | |
from config import auth # Import authentication configuration or credentials from the config module | |
from src.utils.tools import initialize_tools # Import a utility function to initialize and retrieve tool endpoints or resources | |
# Define a class named AudioGeneration to encapsulate functionalities related to generating audio content | |
class AudioGeneration: | |
# This class provides methods to create audio files based on text instructions and voice parameters | |
# Decorator indicating that the following method does not depend on instance state and can be called on the class itself | |
# Define an asynchronous method to create audio from a text instruction, optionally specifying a voice style | |
async def create_audio(generate_audio_instruction: str, voice: str = "echo") -> str: | |
""" | |
Generate an audio file URL by sending a request to an audio generation service. | |
This method will keep retrying until a successful response with status code 200 and audio content is received. | |
Args: | |
generate_audio_instruction (str): The textual instruction or content to convert into audio. | |
voice (str, optional): The voice style or effect to apply on the generated audio. Defaults to "echo". | |
Returns: | |
str: The URL to the generated audio file if successful. | |
Raises: | |
Exception: If the audio generation continuously fails after retries (optional, currently infinite retry). | |
""" | |
# Encode the text instruction to make it safe for inclusion in a URL path segment | |
generate_audio_instruct = quote(generate_audio_instruction) | |
# Initialize tools and retrieve the audio generation service endpoint from the returned tuple | |
_, _, audio_tool = initialize_tools() | |
# Construct the full URL by appending the encoded instruction to the audio tool's base URL | |
url = f"{audio_tool}/{generate_audio_instruct}" | |
# Define query parameters for the HTTP request specifying the model and voice to use for audio generation | |
params = { | |
"model": "openai-audio", # Specify the audio generation model to be used by the service | |
"voice": voice # Specify the desired voice style or effect | |
} | |
# Create an asynchronous HTTP client with no timeout limit to perform the request | |
async with httpx.AsyncClient(timeout=None) as client: | |
# Enter an infinite loop to keep retrying the request until success criteria are met | |
while True: | |
# Define HTTP headers for the request, including random IP address to simulate different client origins | |
headers = { | |
"X-Forwarded-For": generate_ip() # Generate and set a random IP address for the request header | |
} | |
# Send a GET request to the audio generation service with specified URL, parameters, and headers | |
resp = await client.get(url, params=params, headers=headers) | |
# Check if the response status code indicates success and the content type is an audio MPEG stream | |
if resp.status_code == 200 and 'audio/mpeg' in resp.headers.get('Content-Type', ''): | |
# Return the final URL of the generated audio resource as a string | |
return str(resp.url) | |
else: | |
# If the response is not successful, wait for a short delay before retrying to avoid hammering the server | |
await asyncio.sleep(15) # Pause for 15 second before retrying the request | |
# The loop will continue and try again without closing the connection prematurely |