From 8e2723938a280c7b525bac1d847fe80a5c2022ef Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Sun, 17 Nov 2024 15:33:18 +0200 Subject: Refactor Image Processing and Error Handling in g4f Client Module --- docs/async_client.md | 92 ++++----- docs/legacy.md | 200 +++++++++++++++++++ docs/legacy/legacy.md | 200 ------------------- docs/legacy/legacy_async_client.md | 380 ------------------------------------- g4f/client/__init__.py | 73 ++++--- 5 files changed, 282 insertions(+), 663 deletions(-) create mode 100644 docs/legacy.md delete mode 100644 docs/legacy/legacy.md delete mode 100644 docs/legacy/legacy_async_client.md diff --git a/docs/async_client.md b/docs/async_client.md index 7194c792..fe6f46ff 100644 --- a/docs/async_client.md +++ b/docs/async_client.md @@ -1,9 +1,10 @@ -# G4F - Async client API Guide -The G4F async client API is a powerful asynchronous interface for interacting with various AI models. This guide provides comprehensive information on how to use the API effectively, including setup, usage examples, best practices, and important considerations for optimal performance. + +# G4F - AsyncClient API Guide +The G4F AsyncClient API is a powerful asynchronous interface for interacting with various AI models. This guide provides comprehensive information on how to use the API effectively, including setup, usage examples, best practices, and important considerations for optimal performance. ## Compatibility Note -The G4F async client API is designed to be compatible with the OpenAI API, making it easy for developers familiar with OpenAI's interface to transition to G4F. +The G4F AsyncClient API is designed to be compatible with the OpenAI API, making it easy for developers familiar with OpenAI's interface to transition to G4F. ## Table of Contents - [Introduction](#introduction) @@ -26,7 +27,7 @@ The G4F async client API is designed to be compatible with the OpenAI API, makin ## Introduction -The G4F async client API is an asynchronous version of the standard G4F Client API. It offers the same functionality as the synchronous API but with improved performance due to its asynchronous nature. This guide will walk you through the key features and usage of the G4F async client API. +The G4F AsyncClient API is an asynchronous version of the standard G4F Client API. It offers the same functionality as the synchronous API but with improved performance due to its asynchronous nature. This guide will walk you through the key features and usage of the G4F AsyncClient API. ## Key Features @@ -39,13 +40,13 @@ The G4F async client API is an asynchronous version of the standard G4F Client A ## Getting Started -### Initializing the Client -**To use the G4F `Client`, create a new instance:** +### Initializing the AsyncClient +**To use the G4F `AsyncClient`, create a new instance:** ```python -from g4f.client import Client +from g4f.client import AsyncClient from g4f.Provider import OpenaiChat, Gemini -client = Client( +client = AsyncClient( provider=OpenaiChat, image_provider=Gemini, # Add other parameters as needed @@ -56,7 +57,7 @@ client = Client( ## Creating Chat Completions **Here’s an improved example of creating chat completions:** ```python -response = await async_client.chat.completions.create( +response = await client.chat.completions.create( model="gpt-4o-mini", messages=[ { @@ -77,9 +78,9 @@ You can adjust these parameters based on your specific needs. ### Configuration -**Configure the `Client` with additional settings:** +**Configure the `AsyncClient` with additional settings:** ```python -client = Client( +client = AsyncClient( api_key="your_api_key_here", proxies="http://user:pass@host", # Add other parameters as needed @@ -93,12 +94,12 @@ client = Client( **Generate text completions using the ChatCompletions endpoint:** ```python import asyncio -from g4f.client import Client +from g4f.client import AsyncClient async def main(): - client = Client() + client = AsyncClient() - response = await client.chat.completions.async_create( + response = await client.chat.completions.create( model="gpt-4o-mini", messages=[ { @@ -119,12 +120,12 @@ asyncio.run(main()) **Process responses incrementally as they are generated:** ```python import asyncio -from g4f.client import Client +from g4f.client import AsyncClient async def main(): - client = Client() - - stream = await client.chat.completions.async_create( + client = AsyncClient() + + stream = client.chat.completions.create( model="gpt-4", messages=[ { @@ -136,7 +137,7 @@ async def main(): ) async for chunk in stream: - if chunk.choices[0].delta.content: + if chunk.choices and chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="") asyncio.run(main()) @@ -150,14 +151,14 @@ asyncio.run(main()) import g4f import requests import asyncio -from g4f.client import Client +from g4f.client import AsyncClient async def main(): - client = Client() + client = AsyncClient() image = requests.get("https://raw.githubusercontent.com/xtekky/gpt4free/refs/heads/main/docs/cat.jpeg", stream=True).raw - response = await client.chat.completions.async_create( + response = await client.chat.completions.create( model=g4f.models.default, provider=g4f.Provider.Bing, messages=[ @@ -180,12 +181,12 @@ asyncio.run(main()) **Generate images using a specified prompt:** ```python import asyncio -from g4f.client import Client +from g4f.client import AsyncClient async def main(): - client = Client() + client = AsyncClient() - response = await client.images.async_generate( + response = await client.images.generate( prompt="a white siamese cat", model="flux" ) @@ -201,12 +202,12 @@ asyncio.run(main()) #### Base64 Response Format ```python import asyncio -from g4f.client import Client +from g4f.client import AsyncClient async def main(): - client = Client() + client = AsyncClient() - response = await client.images.async_generate( + response = await client.images.generate( prompt="a white siamese cat", model="flux", response_format="b64_json" @@ -224,13 +225,13 @@ asyncio.run(main()) **Execute multiple tasks concurrently:** ```python import asyncio -from g4f.client import Client +from g4f.client import AsyncClient async def main(): - client = Client() + client = AsyncClient() - task1 = client.chat.completions.async_create( - model="gpt-4o-mini", + task1 = client.chat.completions.create( + model=None, messages=[ { "role": "user", @@ -239,18 +240,21 @@ async def main(): ] ) - task2 = client.images.async_generate( + task2 = client.images.generate( model="flux", prompt="a white siamese cat" ) - chat_response, image_response = await asyncio.gather(task1, task2) - - print("Chat Response:") - print(chat_response.choices[0].message.content) - - print("Image Response:") - print(image_response.data[0].url) + try: + chat_response, image_response = await asyncio.gather(task1, task2) + + print("Chat Response:") + print(chat_response.choices[0].message.content) + + print("\nImage Response:") + print(image_response.data[0].url) + except Exception as e: + print(f"An error occurred: {e}") asyncio.run(main()) ``` @@ -286,7 +290,7 @@ client = AsyncClient(provider=g4f.Provider.OpenaiChat) # or -response = await client.chat.completions.async_create( +response = await client.chat.completions.create( model="gpt-4", provider=g4f.Provider.Bing, messages=[ @@ -306,7 +310,7 @@ Implementing proper error handling and following best practices is crucial when 1. **Use try-except blocks to catch and handle exceptions:** ```python try: - response = await client.chat.completions.async_create( + response = await client.chat.completions.create( model="gpt-4o-mini", messages=[ { @@ -368,7 +372,7 @@ logger = logging.getLogger(__name__) async def make_api_call(): try: - response = await client.chat.completions.async_create(...) + response = await client.chat.completions.create(...) logger.info(f"API call successful. Tokens used: {response.usage.total_tokens}") except Exception as e: logger.error(f"API call failed: {e}") @@ -387,7 +391,7 @@ def get_cached_response(query): ``` ## Conclusion -The G4F async client API provides a powerful and flexible way to interact with various AI models asynchronously. By leveraging its features and following best practices, you can build efficient and responsive applications that harness the power of AI for text generation, image analysis, and image creation. +The G4F AsyncClient API provides a powerful and flexible way to interact with various AI models asynchronously. By leveraging its features and following best practices, you can build efficient and responsive applications that harness the power of AI for text generation, image analysis, and image creation. Remember to handle errors gracefully, implement rate limiting, and monitor your API usage to ensure optimal performance and reliability in your applications. diff --git a/docs/legacy.md b/docs/legacy.md new file mode 100644 index 00000000..d5cd5a36 --- /dev/null +++ b/docs/legacy.md @@ -0,0 +1,200 @@ +### G4F - Legacy API + +#### ChatCompletion + +```python +import g4f + +g4f.debug.logging = True # Enable debug logging +g4f.debug.version_check = False # Disable automatic version checking +print(g4f.Provider.Bing.params) # Print supported args for Bing + +# Using automatic a provider for the given model +## Streamed completion +response = g4f.ChatCompletion.create( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hello"}], + stream=True, +) +for message in response: + print(message, flush=True, end='') + +## Normal response +response = g4f.ChatCompletion.create( + model=g4f.models.gpt_4, + messages=[{"role": "user", "content": "Hello"}], +) # Alternative model setting + +print(response) +``` + +##### Completion + +```python +import g4f + +allowed_models = [ + 'code-davinci-002', + 'text-ada-001', + 'text-babbage-001', + 'text-curie-001', + 'text-davinci-002', + 'text-davinci-003' +] + +response = g4f.Completion.create( + model='text-davinci-003', + prompt='say this is a test' +) + +print(response) +``` + +##### Providers + +```python +import g4f + +# Print all available providers +print([ + provider.__name__ + for provider in g4f.Provider.__providers__ + if provider.working +]) + +# Execute with a specific provider +response = g4f.ChatCompletion.create( + model="gpt-3.5-turbo", + provider=g4f.Provider.Aichat, + messages=[{"role": "user", "content": "Hello"}], + stream=True, +) +for message in response: + print(message) +``` + + +##### Image Upload & Generation + +Image upload and generation are supported by three main providers: + +- **Bing & Other GPT-4 Providers:** Utilizes Microsoft's Image Creator. +- **Google Gemini:** Available for free accounts with IP addresses outside Europe. +- **OpenaiChat with GPT-4:** Accessible for users with a Plus subscription. + +```python +import g4f + +# Setting up the request for image creation +response = g4f.ChatCompletion.create( + model=g4f.models.default, # Using the default model + provider=g4f.Provider.Gemini, # Specifying the provider as Gemini + messages=[{"role": "user", "content": "Create an image like this"}], + image=open("images/g4f.png", "rb"), # Image input can be a data URI, bytes, PIL Image, or IO object + image_name="g4f.png" # Optional: specifying the filename +) + +# Displaying the response +print(response) + +from g4f.image import ImageResponse + +# Get image links from response +for chunk in g4f.ChatCompletion.create( + model=g4f.models.default, # Using the default model + provider=g4f.Provider.OpenaiChat, # Specifying the provider as OpenaiChat + messages=[{"role": "user", "content": "Create images with dogs"}], + access_token="...", # Need a access token from a plus user + stream=True, + ignore_stream=True +): + if isinstance(chunk, ImageResponse): + print(chunk.images) # Print generated image links + print(chunk.alt) # Print used prompt for image generation +``` + +##### Using Browser + +Some providers using a browser to bypass the bot protection. They using the selenium webdriver to control the browser. The browser settings and the login data are saved in a custom directory. If the headless mode is enabled, the browser windows are loaded invisibly. For performance reasons, it is recommended to reuse the browser instances and close them yourself at the end: + +```python +import g4f +from undetected_chromedriver import Chrome, ChromeOptions +from g4f.Provider import ( + Bard, + Poe, + AItianhuSpace, + MyShell, + PerplexityAi, +) + +options = ChromeOptions() +options.add_argument("--incognito"); +webdriver = Chrome(options=options, headless=True) +for idx in range(10): + response = g4f.ChatCompletion.create( + model=g4f.models.default, + provider=g4f.Provider.MyShell, + messages=[{"role": "user", "content": "Suggest me a name."}], + webdriver=webdriver + ) + print(f"{idx}:", response) +webdriver.quit() +``` + +##### Async Support + +To enhance speed and overall performance, execute providers asynchronously. The total execution time will be determined by the duration of the slowest provider's execution. + +```python +import g4f +import asyncio + +_providers = [ + g4f.Provider.Aichat, + g4f.Provider.ChatBase, + g4f.Provider.Bing, + g4f.Provider.GptGo, + g4f.Provider.You, + g4f.Provider.Yqcloud, +] + +async def run_provider(provider: g4f.Provider.BaseProvider): + try: + response = await g4f.ChatCompletion.create_async( + model=g4f.models.default, + messages=[{"role": "user", "content": "Hello"}], + provider=provider, + ) + print(f"{provider.__name__}:", response) + except Exception as e: + print(f"{provider.__name__}:", e) + +async def run_all(): + calls = [ + run_provider(provider) for provider in _providers + ] + await asyncio.gather(*calls) + +asyncio.run(run_all()) +``` + +##### Proxy and Timeout Support + +All providers support specifying a proxy and increasing timeout in the create functions. + +```python +import g4f + +response = g4f.ChatCompletion.create( + model=g4f.models.default, + messages=[{"role": "user", "content": "Hello"}], + proxy="http://host:port", + # or socks5://user:pass@host:port + timeout=120, # in secs +) + +print(f"Result:", response) +``` + +[Return to Home](/) \ No newline at end of file diff --git a/docs/legacy/legacy.md b/docs/legacy/legacy.md deleted file mode 100644 index d5cd5a36..00000000 --- a/docs/legacy/legacy.md +++ /dev/null @@ -1,200 +0,0 @@ -### G4F - Legacy API - -#### ChatCompletion - -```python -import g4f - -g4f.debug.logging = True # Enable debug logging -g4f.debug.version_check = False # Disable automatic version checking -print(g4f.Provider.Bing.params) # Print supported args for Bing - -# Using automatic a provider for the given model -## Streamed completion -response = g4f.ChatCompletion.create( - model="gpt-3.5-turbo", - messages=[{"role": "user", "content": "Hello"}], - stream=True, -) -for message in response: - print(message, flush=True, end='') - -## Normal response -response = g4f.ChatCompletion.create( - model=g4f.models.gpt_4, - messages=[{"role": "user", "content": "Hello"}], -) # Alternative model setting - -print(response) -``` - -##### Completion - -```python -import g4f - -allowed_models = [ - 'code-davinci-002', - 'text-ada-001', - 'text-babbage-001', - 'text-curie-001', - 'text-davinci-002', - 'text-davinci-003' -] - -response = g4f.Completion.create( - model='text-davinci-003', - prompt='say this is a test' -) - -print(response) -``` - -##### Providers - -```python -import g4f - -# Print all available providers -print([ - provider.__name__ - for provider in g4f.Provider.__providers__ - if provider.working -]) - -# Execute with a specific provider -response = g4f.ChatCompletion.create( - model="gpt-3.5-turbo", - provider=g4f.Provider.Aichat, - messages=[{"role": "user", "content": "Hello"}], - stream=True, -) -for message in response: - print(message) -``` - - -##### Image Upload & Generation - -Image upload and generation are supported by three main providers: - -- **Bing & Other GPT-4 Providers:** Utilizes Microsoft's Image Creator. -- **Google Gemini:** Available for free accounts with IP addresses outside Europe. -- **OpenaiChat with GPT-4:** Accessible for users with a Plus subscription. - -```python -import g4f - -# Setting up the request for image creation -response = g4f.ChatCompletion.create( - model=g4f.models.default, # Using the default model - provider=g4f.Provider.Gemini, # Specifying the provider as Gemini - messages=[{"role": "user", "content": "Create an image like this"}], - image=open("images/g4f.png", "rb"), # Image input can be a data URI, bytes, PIL Image, or IO object - image_name="g4f.png" # Optional: specifying the filename -) - -# Displaying the response -print(response) - -from g4f.image import ImageResponse - -# Get image links from response -for chunk in g4f.ChatCompletion.create( - model=g4f.models.default, # Using the default model - provider=g4f.Provider.OpenaiChat, # Specifying the provider as OpenaiChat - messages=[{"role": "user", "content": "Create images with dogs"}], - access_token="...", # Need a access token from a plus user - stream=True, - ignore_stream=True -): - if isinstance(chunk, ImageResponse): - print(chunk.images) # Print generated image links - print(chunk.alt) # Print used prompt for image generation -``` - -##### Using Browser - -Some providers using a browser to bypass the bot protection. They using the selenium webdriver to control the browser. The browser settings and the login data are saved in a custom directory. If the headless mode is enabled, the browser windows are loaded invisibly. For performance reasons, it is recommended to reuse the browser instances and close them yourself at the end: - -```python -import g4f -from undetected_chromedriver import Chrome, ChromeOptions -from g4f.Provider import ( - Bard, - Poe, - AItianhuSpace, - MyShell, - PerplexityAi, -) - -options = ChromeOptions() -options.add_argument("--incognito"); -webdriver = Chrome(options=options, headless=True) -for idx in range(10): - response = g4f.ChatCompletion.create( - model=g4f.models.default, - provider=g4f.Provider.MyShell, - messages=[{"role": "user", "content": "Suggest me a name."}], - webdriver=webdriver - ) - print(f"{idx}:", response) -webdriver.quit() -``` - -##### Async Support - -To enhance speed and overall performance, execute providers asynchronously. The total execution time will be determined by the duration of the slowest provider's execution. - -```python -import g4f -import asyncio - -_providers = [ - g4f.Provider.Aichat, - g4f.Provider.ChatBase, - g4f.Provider.Bing, - g4f.Provider.GptGo, - g4f.Provider.You, - g4f.Provider.Yqcloud, -] - -async def run_provider(provider: g4f.Provider.BaseProvider): - try: - response = await g4f.ChatCompletion.create_async( - model=g4f.models.default, - messages=[{"role": "user", "content": "Hello"}], - provider=provider, - ) - print(f"{provider.__name__}:", response) - except Exception as e: - print(f"{provider.__name__}:", e) - -async def run_all(): - calls = [ - run_provider(provider) for provider in _providers - ] - await asyncio.gather(*calls) - -asyncio.run(run_all()) -``` - -##### Proxy and Timeout Support - -All providers support specifying a proxy and increasing timeout in the create functions. - -```python -import g4f - -response = g4f.ChatCompletion.create( - model=g4f.models.default, - messages=[{"role": "user", "content": "Hello"}], - proxy="http://host:port", - # or socks5://user:pass@host:port - timeout=120, # in secs -) - -print(f"Result:", response) -``` - -[Return to Home](/) \ No newline at end of file diff --git a/docs/legacy/legacy_async_client.md b/docs/legacy/legacy_async_client.md deleted file mode 100644 index 5ddc2671..00000000 --- a/docs/legacy/legacy_async_client.md +++ /dev/null @@ -1,380 +0,0 @@ -# G4F - Legacy AsyncClient API Guide - -**IMPORTANT: This guide refers to the old implementation of AsyncClient. The new version of G4F now supports both synchronous and asynchronous operations through a unified interface. Please refer to the [new AsyncClient documentation](https://github.com/xtekky/gpt4free/blob/main/docs/async_client.md) for the latest information.** - -This guide provides comprehensive information on how to use the G4F AsyncClient API, including setup, usage examples, best practices, and important considerations for optimal performance. - -## Compatibility Note -The G4F AsyncClient API is designed to be compatible with the OpenAI API, making it easy for developers familiar with OpenAI's interface to transition to G4F. However, please note that this is the old version, and you should migrate to the new implementation for better support and features. - -## Table of Contents - - [Introduction](#introduction) - - [Key Features](#key-features) - - [Getting Started](#getting-started) - - [Initializing the Client](#initializing-the-client) - - [Creating Chat Completions](#creating-chat-completions) - - [Configuration](#configuration) - - [Usage Examples](#usage-examples) - - [Text Completions](#text-completions) - - [Streaming Completions](#streaming-completions) - - [Using a Vision Model](#using-a-vision-model) - - [Image Generation](#image-generation) - - [Concurrent Tasks](#concurrent-tasks-with-asynciogather) - - [Available Models and Providers](#available-models-and-providers) - - [Error Handling and Best Practices](#error-handling-and-best-practices) - - [Rate Limiting and API Usage](#rate-limiting-and-api-usage) - - [Conclusion](#conclusion) - -## Introduction -This is the old version: The G4F AsyncClient API is an asynchronous version of the standard G4F Client API. It offers the same functionality as the synchronous API but with improved performance due to its asynchronous nature. This guide will walk you through the key features and usage of the G4F AsyncClient API. - -## Key Features - - **Custom Providers**: Use custom providers for enhanced flexibility. - - **ChatCompletion Interface**: Interact with chat models through the ChatCompletion class. - - **Streaming Responses**: Get responses iteratively as they are received. - - **Non-Streaming Responses**: Generate complete responses in a single call. - - **Image Generation and Vision Models**: Support for image-related tasks. - -## Getting Started -**To ignore DeprecationWarnings related to the AsyncClient, you can use the following code:*** -```python -import warnings - -# Ignore DeprecationWarning for AsyncClient -warnings.filterwarnings("ignore", category=DeprecationWarning, module="g4f.client") -``` - -### Initializing the Client -**To use the G4F `Client`, create a new instance:** -```python -from g4f.client import AsyncClient -from g4f.Provider import OpenaiChat, Gemini - -client = AsyncClient( - provider=OpenaiChat, - image_provider=Gemini, - # Add other parameters as needed -) -``` - -## Creating Chat Completions -**Here's an improved example of creating chat completions:** -```python -response = await async_client.chat.completions.create( - model="gpt-3.5-turbo", - messages=[ - { - "role": "user", - "content": "Say this is a test" - } - ] - # Add other parameters as needed -) -``` - -**This example:** - - Asks a specific question `Say this is a test` - - Configures various parameters like temperature and max_tokens for more control over the output - - Disables streaming for a complete response - -You can adjust these parameters based on your specific needs. - -### Configuration -**Configure the `AsyncClient` with additional settings:** -```python -client = Client( - api_key="your_api_key_here", - proxies="http://user:pass@host", - # Add other parameters as needed -) -``` - -## Usage Examples -### Text Completions -**Generate text completions using the ChatCompletions endpoint:** -```python -import asyncio -import warnings -from g4f.client import AsyncClient - -# Ігноруємо DeprecationWarning -warnings.filterwarnings("ignore", category=DeprecationWarning) - -async def main(): - client = AsyncClient() - - response = await client.chat.completions.async_create( - model="gpt-3.5-turbo", - messages=[ - { - "role": "user", - "content": "Say this is a test" - } - ] - ) - - print(response.choices[0].message.content) - -asyncio.run(main()) -``` - -### Streaming Completions -**Process responses incrementally as they are generated:** -```python -import asyncio -from g4f.client import AsyncClient - -async def main(): - client = AsyncClient() - - stream = await client.chat.completions.async_create( - model="gpt-4", - messages=[ - { - "role": "user", - "content": "Say this is a test" - } - ], - stream=True, - ) - - async for chunk in stream: - if chunk.choices[0].delta.content: - print(chunk.choices[0].delta.content, end="") - -asyncio.run(main()) -``` - -### Using a Vision Model -**Analyze an image and generate a description:** -```python -import g4f -import requests -import asyncio -from g4f.client import AsyncClient - -async def main(): - client = AsyncClient() - - image = requests.get("https://raw.githubusercontent.com/xtekky/gpt4free/refs/heads/main/docs/cat.jpeg", stream=True).raw - - response = await client.chat.completions.async_create( - model=g4f.models.default, - provider=g4f.Provider.Bing, - messages=[ - { - "role": "user", - "content": "What's in this image?" - } - ], - image=image - ) - - print(response.choices[0].message.content) - -asyncio.run(main()) -``` - -### Image Generation -**Generate images using a specified prompt:** -```python -import asyncio -from g4f.client import AsyncClient - -async def main(): - client = AsyncClient() - - response = await client.images.async_generate( - prompt="a white siamese cat", - model="flux" - ) - - image_url = response.data[0].url - print(f"Generated image URL: {image_url}") - -asyncio.run(main()) -``` - -#### Base64 Response Format -```python -import asyncio -from g4f.client import AsyncClient - -async def main(): - client = AsyncClient() - - response = await client.images.async_generate( - prompt="a white siamese cat", - model="flux", - response_format="b64_json" - ) - - base64_text = response.data[0].b64_json - print(base64_text) - -asyncio.run(main()) -``` - -### Concurrent Tasks with asyncio.gather -**Execute multiple tasks concurrently:** -```python -import asyncio -import warnings -from g4f.client import AsyncClient - -# Ignore DeprecationWarning for AsyncClient -warnings.filterwarnings("ignore", category=DeprecationWarning, module="g4f.client") - -async def main(): - client = AsyncClient() - - task1 = client.chat.completions.async_create( - model="gpt-3.5-turbo", - messages=[ - { - "role": "user", - "content": "Say this is a test" - } - ] - ) - - task2 = client.images.async_generate( - model="flux", - prompt="a white siamese cat" - ) - - chat_response, image_response = await asyncio.gather(task1, task2) - - print("Chat Response:") - print(chat_response.choices[0].message.content) - - print("Image Response:") - print(image_response.data[0].url) - -asyncio.run(main()) -``` - -## Available Models and Providers -This is the old version: The G4F AsyncClient supports a wide range of AI models and providers, allowing you to choose the best option for your specific use case. -**Here's a brief overview of the available models and providers:** - -### Models - - GPT-3.5-Turbo - - GPT-4 - - DALL-E 3 - - Gemini - - Claude (Anthropic) - - And more... - -### Providers - - OpenAI - - Google (for Gemini) - - Anthropic - - Bing - - Custom providers - -**To use a specific model or provider, specify it when creating the client or in the API call:** -```python -client = AsyncClient(provider=g4f.Provider.OpenaiChat) - -# or - -response = await client.chat.completions.async_create( - model="gpt-4", - provider=g4f.Provider.Bing, - messages=[ - { - "role": "user", - "content": "Hello, world!" - } - ] -) -``` - -## Error Handling and Best Practices -Implementing proper error handling and following best practices is crucial when working with the G4F AsyncClient API. This ensures your application remains robust and can gracefully handle various scenarios. **Here are some key practices to follow:** - -1. **Use try-except blocks to catch and handle exceptions:** -```python -try: - response = await client.chat.completions.async_create( - model="gpt-3.5-turbo", - messages=[ - { - "role": "user", - "content": "Hello, world!" - } - ] - ) -except Exception as e: - print(f"An error occurred: {e}") -``` - -2. **Check the response status and handle different scenarios:** -```python -if response.choices: - print(response.choices[0].message.content) -else: - print("No response generated") -``` - -3. **Implement retries for transient errors:** -```python -import asyncio -from tenacity import retry, stop_after_attempt, wait_exponential - -@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10)) -async def make_api_call(): - # Your API call here - pass -``` - -## Rate Limiting and API Usage -This is the old version: When working with the G4F AsyncClient API, it's important to implement rate limiting and monitor your API usage. This helps ensure fair usage, prevents overloading the service, and optimizes your application's performance. **Here are some key strategies to consider:** - -1. **Implement rate limiting in your application:** -```python -import asyncio -from aiolimiter import AsyncLimiter - -rate_limit = AsyncLimiter(max_rate=10, time_period=1) # 10 requests per second - -async def make_api_call(): - async with rate_limit: - # Your API call here - pass -``` - -2. **Monitor your API usage and implement logging:** -```python -import logging - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -async def make_api_call(): - try: - response = await client.chat.completions.async_create(...) - logger.info(f"API call successful. Tokens used: {response.usage.total_tokens}") - except Exception as e: - logger.error(f"API call failed: {e}") -``` - -3. **Use caching to reduce API calls for repeated queries:** -```python -from functools import lru_cache - -@lru_cache(maxsize=100) -def get_cached_response(query): - # Your API call here - pass -``` - -## Conclusion -This is the old version: The G4F AsyncClient API provides a powerful and flexible way to interact with various AI models asynchronously. By leveraging its features and following best practices, you can build efficient and responsive applications that harness the power of AI for text generation, image analysis, and image creation. - -Remember to handle errors gracefully, implement rate limiting, and monitor your API usage to ensure optimal performance and reliability in your applications. - ---- - -[Return to Home](/) diff --git a/g4f/client/__init__.py b/g4f/client/__init__.py index 5ffe9288..3adb18ef 100644 --- a/g4f/client/__init__.py +++ b/g4f/client/__init__.py @@ -247,7 +247,7 @@ class Images: """ Synchronous generate method that runs the async_generate method in an event loop. """ - return asyncio.run(self.async_generate(prompt, model, provider, response_format=response_format, proxy=proxy **kwargs)) + return asyncio.run(self.async_generate(prompt, model, provider, response_format=response_format, proxy=proxy, **kwargs)) async def async_generate(self, prompt: str, model: str = None, provider: ProviderType = None, response_format: str = "url", proxy: str = None, **kwargs) -> ImagesResponse: if provider is None: @@ -261,7 +261,7 @@ class Images: if isinstance(provider_handler, IterListProvider): if provider_handler.providers: - provider_handler = provider.providers[0] + provider_handler = provider_handler.providers[0] else: raise ValueError(f"IterListProvider for model {model} has no providers") @@ -287,44 +287,39 @@ class Images: raise NoImageResponseError(f"Unexpected response type: {type(response)}") async def _process_image_response(self, response: ImageResponse, response_format: str, proxy: str = None, model: str = None, provider: str = None) -> ImagesResponse: - async def process_image_item(session: aiohttp.ClientSession, image_data: str): - if image_data.startswith('http://') or image_data.startswith('https://'): - if response_format == "url": - return Image(url=image_data, revised_prompt=response.alt) - elif response_format == "b64_json": - # Fetch the image data and convert it to base64 - image_content = await self._fetch_image(session, image_data) - file_name = self._save_image(image_data_bytes) - b64_json = base64.b64encode(image_content).decode('utf-8') - return Image(b64_json=b64_json, url=file_name, revised_prompt=response.alt) - else: - # Assume image_data is base64 data or binary - if response_format == "url": - if image_data.startswith('data:image'): - # Remove the data URL scheme and get the base64 data - base64_data = image_data.split(',', 1)[-1] - else: - base64_data = image_data - # Decode the base64 data - image_data_bytes = base64.b64decode(base64_data) - # Convert bytes to an image + async def process_image_item(session: aiohttp.ClientSession, image_data: str): + image_data_bytes = None + if image_data.startswith("http://") or image_data.startswith("https://"): + if response_format == "url": + return Image(url=image_data, revised_prompt=response.alt) + elif response_format == "b64_json": + # Fetch the image data and convert it to base64 + image_data_bytes = await self._fetch_image(session, image_data) + b64_json = base64.b64encode(image_data_bytes).decode("utf-8") + return Image(b64_json=b64_json, url=image_data, revised_prompt=response.alt) + else: + # Assume image_data is base64 data or binary + if response_format == "url": + if image_data.startswith("data:image"): + # Remove the data URL scheme and get the base64 data + base64_data = image_data.split(",", 1)[-1] + else: + base64_data = image_data + # Decode the base64 data + image_data_bytes = base64.b64decode(base64_data) + if image_data_bytes: file_name = self._save_image(image_data_bytes) return Image(url=file_name, revised_prompt=response.alt) - elif response_format == "b64_json": - if isinstance(image_data, bytes): - file_name = self._save_image(image_data_bytes) - b64_json = base64.b64encode(image_data).decode('utf-8') - else: - b64_json = image_data # If already base64-encoded string - return Image(b64_json=b64_json, url=file_name, revised_prompt=response.alt) - - last_provider = get_last_provider(True) - async with aiohttp.ClientSession(cookies=response.get("cookies"), connector=get_connector(proxy=proxy)) as session: - return ImagesResponse( - await asyncio.gather(*[process_image_item(session, image_data) for image_data in response.get_list()]), - model=last_provider.get("model") if model is None else model, - provider=last_provider.get("name") if provider is None else provider - ) + else: + raise ValueError("Unable to process image data") + + last_provider = get_last_provider(True) + async with aiohttp.ClientSession(cookies=response.get("cookies"), connector=get_connector(proxy=proxy)) as session: + return ImagesResponse( + await asyncio.gather(*[process_image_item(session, image_data) for image_data in response.get_list()]), + model=last_provider.get("model") if model is None else model, + provider=last_provider.get("name") if provider is None else provider + ) async def _fetch_image(self, session: aiohttp.ClientSession, url: str) -> bytes: # Asynchronously fetch image data from the URL @@ -465,4 +460,4 @@ class AsyncImages(Images): async def create_variation(self, image: Union[str, bytes], model: str = None, provider: ProviderType = None, response_format: str = "url", **kwargs) -> ImagesResponse: return await self.async_create_variation( image, model, provider, response_format, **kwargs - ) \ No newline at end of file + ) -- cgit v1.2.3 From db69892c960bf321f36d47ed337f3a961947490d Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Sun, 17 Nov 2024 15:35:58 +0200 Subject: Update (README.md) --- README.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f482d0df..cd621ee8 100644 --- a/README.md +++ b/README.md @@ -72,12 +72,8 @@ Is your site on this repository and you want to take it down? Send an email to t - [Local Inference](docs/local.md) - [Configuration](#configuration) - [Full Documentation for Python API](#full-documentation-for-python-api) - - **New:** - - [Async Client API from G4F](docs/async_client.md) - - [Client API like the OpenAI Python library](docs/client.md) - - **Legacy** - - [Legacy API with python modules](docs/legacy/legacy.md) - - [Legacy AsyncClient API from G4F](docs/legacy/legacy_async_client.md) + - [Client API from G4F](docs/client.md) + - [AsyncClient API from G4F](docs/async_client.md) - [🚀 Providers and Models](docs/providers-and-models.md) - [🔗 Powered by gpt4free](#-powered-by-gpt4free) - [🤝 Contribute](#-contribute) @@ -204,12 +200,11 @@ print(f"Generated image URL: {image_url}") #### **Full Documentation for Python API** - **New:** - - **Async Client API from G4F:** [/docs/async_client](docs/async_client.md) - - **Client API like the OpenAI Python library:** [/docs/client](docs/client.md) + - **Client API from G4F:** [/docs/client](docs/client.md) + - **AsyncClient API from G4F:** [/docs/async_client](docs/async_client.md) - **Legacy:** - - **Legacy API with python modules:** [/docs/legacy/legacy](docs/legacy/legacy.md) - - **Legacy AsyncClient API from G4F:** [/docs/async_client](docs/legacy/legacy_async_client.md) + - **Legacy API with python modules:** [/docs/legacy](docs/legacy.md) #### Web UI **To start the web interface, type the following codes in python:** -- cgit v1.2.3 From c7ff15cd9423fc1c3ac257d3bbcd4a7a6aaa014d Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Sun, 17 Nov 2024 15:50:02 +0200 Subject: Update (etc/unittest/backend.py) --- etc/unittest/backend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/unittest/backend.py b/etc/unittest/backend.py index a2999c5c..e781de8a 100644 --- a/etc/unittest/backend.py +++ b/etc/unittest/backend.py @@ -46,4 +46,4 @@ class TestBackendApi(unittest.TestCase): self.skipTest(e) except MissingRequirementsError: self.skipTest("search is not installed") - self.assertEqual(5, len(result)) \ No newline at end of file + self.assertEqual(4, len(result)) -- cgit v1.2.3