From 32252def150da94f12d1f3c07f977af6d8931402 Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Sun, 14 Jan 2024 15:04:37 +0100 Subject: Change doctypes style to Google Fix typo in latest_version Fix Phind Provider Add unittest worklow and main tests --- g4f/Provider/Phind.py | 8 +++-- g4f/Provider/base_provider.py | 71 ++++++++++++++++++++++++++++++++++++++ g4f/Provider/bing/create_images.py | 2 +- g4f/Provider/create_images.py | 61 +++++++++++++++++++++++++++++++- 4 files changed, 138 insertions(+), 4 deletions(-) (limited to 'g4f/Provider') diff --git a/g4f/Provider/Phind.py b/g4f/Provider/Phind.py index bb216989..9e80baa9 100644 --- a/g4f/Provider/Phind.py +++ b/g4f/Provider/Phind.py @@ -59,12 +59,16 @@ class Phind(AsyncGeneratorProvider): "rewrittenQuestion": prompt, "challenge": 0.21132115912208504 } - async with session.post(f"{cls.url}/api/infer/followup/answer", headers=headers, json=data) as response: + async with session.post(f"https://https.api.phind.com/infer/", headers=headers, json=data) as response: new_line = False async for line in response.iter_lines(): if line.startswith(b"data: "): chunk = line[6:] - if chunk.startswith(b"") or chunk.startswith(b""): + if chunk.startswith(b''): + break + if chunk.startswith(b'') or chunk.startswith(b''): + pass + elif chunk.startswith(b"") or chunk.startswith(b""): pass elif chunk: yield chunk.decode() diff --git a/g4f/Provider/base_provider.py b/g4f/Provider/base_provider.py index 3c083bda..fd92d17a 100644 --- a/g4f/Provider/base_provider.py +++ b/g4f/Provider/base_provider.py @@ -36,6 +36,17 @@ class AbstractProvider(BaseProvider): ) -> str: """ Asynchronously creates a result based on the given model and messages. + + Args: + cls (type): The class on which this method is called. + model (str): The model to use for creation. + messages (Messages): The messages to process. + loop (AbstractEventLoop, optional): The event loop to use. Defaults to None. + executor (ThreadPoolExecutor, optional): The executor for running async tasks. Defaults to None. + **kwargs: Additional keyword arguments. + + Returns: + str: The created result as a string. """ loop = loop or get_event_loop() @@ -52,6 +63,12 @@ class AbstractProvider(BaseProvider): def params(cls) -> str: """ Returns the parameters supported by the provider. + + Args: + cls (type): The class on which this property is called. + + Returns: + str: A string listing the supported parameters. """ sig = signature( cls.create_async_generator if issubclass(cls, AsyncGeneratorProvider) else @@ -90,6 +107,17 @@ class AsyncProvider(AbstractProvider): ) -> CreateResult: """ Creates a completion result synchronously. + + Args: + cls (type): The class on which this method is called. + model (str): The model to use for creation. + messages (Messages): The messages to process. + stream (bool): Indicates whether to stream the results. Defaults to False. + loop (AbstractEventLoop, optional): The event loop to use. Defaults to None. + **kwargs: Additional keyword arguments. + + Returns: + CreateResult: The result of the completion creation. """ loop = loop or get_event_loop() coro = cls.create_async(model, messages, **kwargs) @@ -104,6 +132,17 @@ class AsyncProvider(AbstractProvider): ) -> str: """ Abstract method for creating asynchronous results. + + Args: + model (str): The model to use for creation. + messages (Messages): The messages to process. + **kwargs: Additional keyword arguments. + + Raises: + NotImplementedError: If this method is not overridden in derived classes. + + Returns: + str: The created result as a string. """ raise NotImplementedError() @@ -126,6 +165,17 @@ class AsyncGeneratorProvider(AsyncProvider): ) -> CreateResult: """ Creates a streaming completion result synchronously. + + Args: + cls (type): The class on which this method is called. + model (str): The model to use for creation. + messages (Messages): The messages to process. + stream (bool): Indicates whether to stream the results. Defaults to True. + loop (AbstractEventLoop, optional): The event loop to use. Defaults to None. + **kwargs: Additional keyword arguments. + + Returns: + CreateResult: The result of the streaming completion creation. """ loop = loop or get_event_loop() generator = cls.create_async_generator(model, messages, stream=stream, **kwargs) @@ -146,6 +196,15 @@ class AsyncGeneratorProvider(AsyncProvider): ) -> str: """ Asynchronously creates a result from a generator. + + Args: + cls (type): The class on which this method is called. + model (str): The model to use for creation. + messages (Messages): The messages to process. + **kwargs: Additional keyword arguments. + + Returns: + str: The created result as a string. """ return "".join([ chunk async for chunk in cls.create_async_generator(model, messages, stream=False, **kwargs) @@ -162,5 +221,17 @@ class AsyncGeneratorProvider(AsyncProvider): ) -> AsyncResult: """ Abstract method for creating an asynchronous generator. + + Args: + model (str): The model to use for creation. + messages (Messages): The messages to process. + stream (bool): Indicates whether to stream the results. Defaults to True. + **kwargs: Additional keyword arguments. + + Raises: + NotImplementedError: If this method is not overridden in derived classes. + + Returns: + AsyncResult: An asynchronous generator yielding results. """ raise NotImplementedError() \ No newline at end of file diff --git a/g4f/Provider/bing/create_images.py b/g4f/Provider/bing/create_images.py index 29daccbd..060cd184 100644 --- a/g4f/Provider/bing/create_images.py +++ b/g4f/Provider/bing/create_images.py @@ -198,7 +198,7 @@ class CreateImagesBing: _cookies: Dict[str, str] = {} @classmethod - def create_completion(cls, prompt: str, cookies: Dict[str, str] = None, proxy: str = None) -> Generator[str]: + def create_completion(cls, prompt: str, cookies: Dict[str, str] = None, proxy: str = None) -> Generator[str, None, None]: """ Generator for creating imagecompletion based on a prompt. diff --git a/g4f/Provider/create_images.py b/g4f/Provider/create_images.py index f8a0442d..b8bcbde3 100644 --- a/g4f/Provider/create_images.py +++ b/g4f/Provider/create_images.py @@ -8,13 +8,31 @@ from ..base_provider import BaseProvider, ProviderType system_message = """ You can generate custom images with the DALL-E 3 image generator. -To generate a image with a prompt, do this: +To generate an image with a prompt, do this: Don't use images with data uri. It is important to use a prompt instead. """ class CreateImagesProvider(BaseProvider): + """ + Provider class for creating images based on text prompts. + + This provider handles image creation requests embedded within message content, + using provided image creation functions. + + Attributes: + provider (ProviderType): The underlying provider to handle non-image related tasks. + create_images (callable): A function to create images synchronously. + create_images_async (callable): A function to create images asynchronously. + system_message (str): A message that explains the image creation capability. + include_placeholder (bool): Flag to determine whether to include the image placeholder in the output. + __name__ (str): Name of the provider. + url (str): URL of the provider. + working (bool): Indicates if the provider is operational. + supports_stream (bool): Indicates if the provider supports streaming. + """ + def __init__( self, provider: ProviderType, @@ -23,6 +41,16 @@ class CreateImagesProvider(BaseProvider): system_message: str = system_message, include_placeholder: bool = True ) -> None: + """ + Initializes the CreateImagesProvider. + + Args: + provider (ProviderType): The underlying provider. + create_images (callable): Function to create images synchronously. + create_async (callable): Function to create images asynchronously. + system_message (str, optional): System message to be prefixed to messages. Defaults to a predefined message. + include_placeholder (bool, optional): Whether to include image placeholders in the output. Defaults to True. + """ self.provider = provider self.create_images = create_images self.create_images_async = create_async @@ -40,6 +68,22 @@ class CreateImagesProvider(BaseProvider): stream: bool = False, **kwargs ) -> CreateResult: + """ + Creates a completion result, processing any image creation prompts found within the messages. + + Args: + model (str): The model to use for creation. + messages (Messages): The messages to process, which may contain image prompts. + stream (bool, optional): Indicates whether to stream the results. Defaults to False. + **kwargs: Additional keywordarguments for the provider. + + Yields: + CreateResult: Yields chunks of the processed messages, including image data if applicable. + + Note: + This method processes messages to detect image creation prompts. When such a prompt is found, + it calls the synchronous image creation function and includes the resulting image in the output. + """ messages.insert(0, {"role": "system", "content": self.system_message}) buffer = "" for chunk in self.provider.create_completion(model, messages, stream, **kwargs): @@ -71,6 +115,21 @@ class CreateImagesProvider(BaseProvider): messages: Messages, **kwargs ) -> str: + """ + Asynchronously creates a response, processing any image creation prompts found within the messages. + + Args: + model (str): The model to use for creation. + messages (Messages): The messages to process, which may contain image prompts. + **kwargs: Additional keyword arguments for the provider. + + Returns: + str: The processed response string, including asynchronously generated image data if applicable. + + Note: + This method processes messages to detect image creation prompts. When such a prompt is found, + it calls the asynchronous image creation function and includes the resulting image in the output. + """ messages.insert(0, {"role": "system", "content": self.system_message}) response = await self.provider.create_async(model, messages, **kwargs) matches = re.findall(r'()', response) -- cgit v1.2.3