File size: 4,198 Bytes
6b509f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#
# 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

    @staticmethod  # 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