diff options
Diffstat (limited to 'g4f/Provider/nexra')
-rw-r--r-- | g4f/Provider/nexra/NexraBing.py | 141 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraBlackbox.py | 117 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraChatGPT.py | 66 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraChatGPT4o.py | 114 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraChatGptV2.py | 113 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraChatGptWeb.py | 75 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraDallE.py | 69 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraDallE2.py | 79 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraDalleMini.py | 66 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraEmi.py | 69 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraFluxPro.py | 68 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraGeminiPro.py | 80 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraLLaMA31.py | 91 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraMidjourney.py | 71 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraProdiaAI.py | 92 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraQwen.py | 114 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraSD15.py | 70 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraSD21.py | 75 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraSDLora.py | 81 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraSDTurbo.py | 81 | ||||
-rw-r--r-- | g4f/Provider/nexra/__init__.py | 3 |
21 files changed, 752 insertions, 983 deletions
diff --git a/g4f/Provider/nexra/NexraBing.py b/g4f/Provider/nexra/NexraBing.py index 716e9254..28f0b117 100644 --- a/g4f/Provider/nexra/NexraBing.py +++ b/g4f/Provider/nexra/NexraBing.py @@ -1,96 +1,93 @@ from __future__ import annotations -from aiohttp import ClientSession -from aiohttp.client_exceptions import ContentTypeError - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin -from ..helper import format_prompt import json +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider +from ..helper import format_prompt -class NexraBing(AsyncGeneratorProvider, ProviderModelMixin): +class NexraBing(AbstractProvider, ProviderModelMixin): label = "Nexra Bing" url = "https://nexra.aryahcr.cc/documentation/bing/en" api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" - working = False - supports_gpt_4 = False - supports_stream = False + working = True + supports_stream = True - default_model = 'Bing (Balanced)' - models = ['Bing (Balanced)', 'Bing (Creative)', 'Bing (Precise)'] + default_model = 'Balanced' + models = [default_model, 'Creative', 'Precise'] model_aliases = { - "gpt-4": "Bing (Balanced)", - "gpt-4": "Bing (Creative)", - "gpt-4": "Bing (Precise)", + "gpt-4": "Balanced", + "gpt-4": "Creative", + "gpt-4": "Precise", } @classmethod - def get_model_and_style(cls, model: str) -> tuple[str, str]: - # Default to the default model if not found - model = cls.model_aliases.get(model, model) - if model not in cls.models: - model = cls.default_model - - # Extract the base model and conversation style - base_model, conversation_style = model.split(' (') - conversation_style = conversation_style.rstrip(')') - return base_model, conversation_style - + def get_model(cls, model: str) -> str: + if model in cls.models: + return model + elif model in cls.model_aliases: + return cls.model_aliases[model] + else: + return cls.default_model + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, - proxy: str = None, stream: bool = False, + proxy: str = None, markdown: bool = False, **kwargs - ) -> AsyncResult: - base_model, conversation_style = cls.get_model_and_style(model) - + ) -> CreateResult: + model = cls.get_model(model) + headers = { - "Content-Type": "application/json", - "origin": cls.url, - "referer": f"{cls.url}/chat", + 'Content-Type': 'application/json' + } + + data = { + "messages": [ + { + "role": "user", + "content": format_prompt(messages) + } + ], + "conversation_style": model, + "markdown": markdown, + "stream": stream, + "model": "Bing" } - async with ClientSession(headers=headers) as session: - prompt = format_prompt(messages) - data = { - "messages": [ - { - "role": "user", - "content": prompt - } - ], - "conversation_style": conversation_style, - "markdown": markdown, - "stream": stream, - "model": base_model - } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - try: - # Read the entire response text - text_response = await response.text() - # Split the response on the separator character - segments = text_response.split('\x1e') - - complete_message = "" - for segment in segments: - if not segment.strip(): - continue - try: - response_data = json.loads(segment) - if response_data.get('message'): - complete_message = response_data['message'] - if response_data.get('finish'): - break - except json.JSONDecodeError: - raise Exception(f"Failed to parse segment: {segment}") + + response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=True) + + return cls.process_response(response) + + @classmethod + def process_response(cls, response): + if response.status_code != 200: + yield f"Error: {response.status_code}" + return + + full_message = "" + for chunk in response.iter_content(chunk_size=None): + if chunk: + messages = chunk.decode('utf-8').split('\x1e') + for message in messages: + try: + json_data = json.loads(message) + if json_data.get('finish', False): + return + current_message = json_data.get('message', '') + if current_message: + new_content = current_message[len(full_message):] + if new_content: + yield new_content + full_message = current_message + except json.JSONDecodeError: + continue - # Yield the complete message - yield complete_message - except ContentTypeError: - raise Exception("Failed to parse response content type.") + if not full_message: + yield "No message received" diff --git a/g4f/Provider/nexra/NexraBlackbox.py b/g4f/Provider/nexra/NexraBlackbox.py index a8b4fca1..be048fdd 100644 --- a/g4f/Provider/nexra/NexraBlackbox.py +++ b/g4f/Provider/nexra/NexraBlackbox.py @@ -1,24 +1,22 @@ from __future__ import annotations import json -from aiohttp import ClientSession, ClientTimeout, ClientError +import requests -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider +from ..helper import format_prompt -class NexraBlackbox(AsyncGeneratorProvider, ProviderModelMixin): +class NexraBlackbox(AbstractProvider, ProviderModelMixin): label = "Nexra Blackbox" url = "https://nexra.aryahcr.cc/documentation/blackbox/en" api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" working = True supports_stream = True - default_model = 'blackbox' + default_model = "blackbox" models = [default_model] - - model_aliases = { - "blackboxai": "blackbox", - } + model_aliases = {"blackboxai": "blackbox",} @classmethod def get_model(cls, model: str) -> str: @@ -28,74 +26,75 @@ class NexraBlackbox(AsyncGeneratorProvider, ProviderModelMixin): return cls.model_aliases[model] else: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, + stream: bool, proxy: str = None, - stream: bool = False, markdown: bool = False, websearch: bool = False, **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - payload = { - "messages": [{"role": msg["role"], "content": msg["content"]} for msg in messages], + data = { + "messages": [ + { + "role": "user", + "content": format_prompt(messages) + } + ], "websearch": websearch, "stream": stream, "markdown": markdown, "model": model } - - timeout = ClientTimeout(total=600) # 10 minutes timeout - try: - async with ClientSession(headers=headers, timeout=timeout) as session: - async with session.post(cls.api_endpoint, json=payload, proxy=proxy) as response: - if response.status != 200: - error_text = await response.text() - raise Exception(f"Error: {response.status} - {error_text}") - - content = await response.text() - - # Split content by Record Separator character - parts = content.split('\x1e') - full_message = "" - links = [] + response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=stream) - for part in parts: - if part: - try: - json_response = json.loads(part) - - if json_response.get("message"): - full_message = json_response["message"] # Overwrite instead of append - - if isinstance(json_response.get("search"), list): - links = json_response["search"] # Overwrite instead of extend - - if json_response.get("finish", False): - break - - except json.JSONDecodeError: - pass - - if full_message: - yield full_message.strip() + if stream: + return cls.process_streaming_response(response) + else: + return cls.process_non_streaming_response(response) - if payload["websearch"] and links: - yield "\n\n**Source:**" - for i, link in enumerate(links, start=1): - yield f"\n{i}. {link['title']}: {link['link']}" + @classmethod + def process_non_streaming_response(cls, response): + if response.status_code == 200: + try: + full_response = "" + for line in response.iter_lines(decode_unicode=True): + if line: + data = json.loads(line) + if data.get('finish'): + break + message = data.get('message', '') + if message: + full_response = message + return full_response + except json.JSONDecodeError: + return "Error: Unable to decode JSON response" + else: + return f"Error: {response.status_code}" - except ClientError: - raise - except Exception: - raise + @classmethod + def process_streaming_response(cls, response): + previous_message = "" + for line in response.iter_lines(decode_unicode=True): + if line: + try: + data = json.loads(line) + if data.get('finish'): + break + message = data.get('message', '') + if message and message != previous_message: + yield message[len(previous_message):] + previous_message = message + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/NexraChatGPT.py b/g4f/Provider/nexra/NexraChatGPT.py index f9f49139..fc5051ee 100644 --- a/g4f/Provider/nexra/NexraChatGPT.py +++ b/g4f/Provider/nexra/NexraChatGPT.py @@ -1,24 +1,20 @@ from __future__ import annotations -from aiohttp import ClientSession import json +import requests -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ..helper import format_prompt - -class NexraChatGPT(AsyncGeneratorProvider, ProviderModelMixin): +class NexraChatGPT(AbstractProvider, ProviderModelMixin): label = "Nexra ChatGPT" url = "https://nexra.aryahcr.cc/documentation/chatgpt/en" api_endpoint = "https://nexra.aryahcr.cc/api/chat/gpt" working = True - supports_gpt_35_turbo = True - supports_gpt_4 = True - supports_stream = False default_model = 'gpt-3.5-turbo' - models = ['gpt-4', 'gpt-4-0613', 'gpt-4-0314', 'gpt-4-32k-0314', 'gpt-3.5-turbo', 'gpt-3.5-turbo-16k', 'gpt-3.5-turbo-0613', 'gpt-3.5-turbo-16k-0613', 'gpt-3.5-turbo-0301', 'text-davinci-003', 'text-davinci-002', 'code-davinci-002', 'gpt-3', 'text-curie-001', 'text-babbage-001', 'text-ada-001', 'davinci', 'curie', 'babbage', 'ada', 'babbage-002', 'davinci-002'] + models = ['gpt-4', 'gpt-4-0613', 'gpt-4-0314', 'gpt-4-32k-0314', default_model, 'gpt-3.5-turbo-16k', 'gpt-3.5-turbo-0613', 'gpt-3.5-turbo-16k-0613', 'gpt-3.5-turbo-0301', 'text-davinci-003', 'text-davinci-002', 'code-davinci-002', 'gpt-3', 'text-curie-001', 'text-babbage-001', 'text-ada-001', 'davinci', 'curie', 'babbage', 'ada', 'babbage-002', 'davinci-002'] model_aliases = { "gpt-4": "gpt-4-0613", @@ -46,7 +42,6 @@ class NexraChatGPT(AsyncGeneratorProvider, ProviderModelMixin): "gpt-3": "davinci-002", } - @classmethod def get_model(cls, model: str) -> str: if model in cls.models: @@ -55,35 +50,40 @@ class NexraChatGPT(AsyncGeneratorProvider, ProviderModelMixin): return cls.model_aliases[model] else: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, proxy: str = None, + markdown: bool = False, **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' + } + + data = { + "messages": [], + "prompt": format_prompt(messages), + "model": model, + "markdown": markdown } - async with ClientSession(headers=headers) as session: - prompt = format_prompt(messages) - data = { - "messages": messages, - "prompt": prompt, - "model": model, - "markdown": False - } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - response_text = await response.text() - try: - if response_text.startswith('_'): - response_text = response_text[1:] - response_data = json.loads(response_text) - yield response_data.get('gpt', '') - except json.JSONDecodeError: - yield '' + + response = requests.post(cls.api_endpoint, headers=headers, json=data) + + return cls.process_response(response) + + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + data = response.json() + return data.get('gpt', '') + except json.JSONDecodeError: + return "Error: Unable to decode JSON response" + else: + return f"Error: {response.status_code}" diff --git a/g4f/Provider/nexra/NexraChatGPT4o.py b/g4f/Provider/nexra/NexraChatGPT4o.py index 62144163..126d32b8 100644 --- a/g4f/Provider/nexra/NexraChatGPT4o.py +++ b/g4f/Provider/nexra/NexraChatGPT4o.py @@ -1,74 +1,86 @@ from __future__ import annotations -from aiohttp import ClientSession +import json +import requests -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ..helper import format_prompt -import json -class NexraChatGPT4o(AsyncGeneratorProvider, ProviderModelMixin): +class NexraChatGPT4o(AbstractProvider, ProviderModelMixin): label = "Nexra ChatGPT4o" url = "https://nexra.aryahcr.cc/documentation/chatgpt/en" api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" working = True - supports_gpt_4 = True - supports_stream = False + supports_stream = True - default_model = 'gpt-4o' + default_model = "gpt-4o" models = [default_model] - + @classmethod def get_model(cls, model: str) -> str: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, + stream: bool, proxy: str = None, + markdown: bool = False, **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json", + 'Content-Type': 'application/json' } - async with ClientSession(headers=headers) as session: - data = { - "messages": [ - { - "role": "user", - "content": format_prompt(messages) - } - ], - "stream": False, - "markdown": False, - "model": model - } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - buffer = "" - last_message = "" - async for chunk in response.content.iter_any(): - chunk_str = chunk.decode() - buffer += chunk_str - while '{' in buffer and '}' in buffer: - start = buffer.index('{') - end = buffer.index('}', start) + 1 - json_str = buffer[start:end] - buffer = buffer[end:] - try: - json_obj = json.loads(json_str) - if json_obj.get("finish"): - if last_message: - yield last_message - return - elif json_obj.get("message"): - last_message = json_obj["message"] - except json.JSONDecodeError: - pass - - if last_message: - yield last_message + + data = { + "messages": [ + { + "role": "user", + "content": format_prompt(messages) + } + ], + "stream": stream, + "markdown": markdown, + "model": model + } + + response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=stream) + + if stream: + return cls.process_streaming_response(response) + else: + return cls.process_non_streaming_response(response) + + @classmethod + def process_non_streaming_response(cls, response): + if response.status_code == 200: + try: + content = response.text.lstrip('') + data = json.loads(content) + return data.get('message', '') + except json.JSONDecodeError: + return "Error: Unable to decode JSON response" + else: + return f"Error: {response.status_code}" + + @classmethod + def process_streaming_response(cls, response): + full_message = "" + for line in response.iter_lines(decode_unicode=True): + if line: + try: + line = line.lstrip('') + data = json.loads(line) + if data.get('finish'): + break + message = data.get('message', '') + if message and message != full_message: + yield message[len(full_message):] + full_message = message + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/NexraChatGptV2.py b/g4f/Provider/nexra/NexraChatGptV2.py index c0faf93a..1ff42705 100644 --- a/g4f/Provider/nexra/NexraChatGptV2.py +++ b/g4f/Provider/nexra/NexraChatGptV2.py @@ -1,27 +1,22 @@ from __future__ import annotations -from aiohttp import ClientSession import json +import requests -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ..helper import format_prompt - -class NexraChatGptV2(AsyncGeneratorProvider, ProviderModelMixin): +class NexraChatGptV2(AbstractProvider, ProviderModelMixin): label = "Nexra ChatGPT v2" url = "https://nexra.aryahcr.cc/documentation/chatgpt/en" api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" working = True - supports_gpt_4 = True supports_stream = True default_model = 'chatgpt' models = [default_model] - - model_aliases = { - "gpt-4": "chatgpt", - } + model_aliases = {"gpt-4": "chatgpt"} @classmethod def get_model(cls, model: str) -> str: @@ -31,63 +26,67 @@ class NexraChatGptV2(AsyncGeneratorProvider, ProviderModelMixin): return cls.model_aliases[model] else: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, + stream: bool, proxy: str = None, - stream: bool = False, markdown: bool = False, **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' + } + + data = { + "messages": [ + { + "role": "user", + "content": format_prompt(messages) + } + ], + "stream": stream, + "markdown": markdown, + "model": model } + + response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=stream) - async with ClientSession(headers=headers) as session: - prompt = format_prompt(messages) - data = { - "messages": [ - { - "role": "user", - "content": prompt - } - ], - "stream": stream, - "markdown": markdown, - "model": model - } + if stream: + return cls.process_streaming_response(response) + else: + return cls.process_non_streaming_response(response) - async with session.post(f"{cls.api_endpoint}", json=data, proxy=proxy) as response: - response.raise_for_status() + @classmethod + def process_non_streaming_response(cls, response): + if response.status_code == 200: + try: + content = response.text.lstrip('') + data = json.loads(content) + return data.get('message', '') + except json.JSONDecodeError: + return "Error: Unable to decode JSON response" + else: + return f"Error: {response.status_code}" - if stream: - # Streamed response handling (stream=True) - collected_message = "" - async for chunk in response.content.iter_any(): - if chunk: - decoded_chunk = chunk.decode().strip().split("\x1e") - for part in decoded_chunk: - if part: - message_data = json.loads(part) - - # Collect messages until 'finish': true - if 'message' in message_data and message_data['message']: - collected_message = message_data['message'] - - # When finish is true, yield the final collected message - if message_data.get('finish', False): - yield collected_message - return - else: - # Non-streamed response handling (stream=False) - response_data = await response.json(content_type=None) - - # Yield the message directly from the response - if 'message' in response_data and response_data['message']: - yield response_data['message'] - return + @classmethod + def process_streaming_response(cls, response): + full_message = "" + for line in response.iter_lines(decode_unicode=True): + if line: + try: + line = line.lstrip('') + data = json.loads(line) + if data.get('finish'): + break + message = data.get('message', '') + if message: + yield message[len(full_message):] + full_message = message + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/NexraChatGptWeb.py b/g4f/Provider/nexra/NexraChatGptWeb.py index d14a2162..f82694d4 100644 --- a/g4f/Provider/nexra/NexraChatGptWeb.py +++ b/g4f/Provider/nexra/NexraChatGptWeb.py @@ -1,29 +1,21 @@ from __future__ import annotations -from aiohttp import ClientSession, ContentTypeError import json +import requests -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ..helper import format_prompt - -class NexraChatGptWeb(AsyncGeneratorProvider, ProviderModelMixin): +class NexraChatGptWeb(AbstractProvider, ProviderModelMixin): label = "Nexra ChatGPT Web" url = "https://nexra.aryahcr.cc/documentation/chatgpt/en" - api_endpoint = "https://nexra.aryahcr.cc/api/chat/{}" working = True - supports_gpt_35_turbo = True - supports_gpt_4 = True - supports_stream = True - default_model = 'gptweb' + default_model = "gptweb" models = [default_model] - - model_aliases = { - "gpt-4": "gptweb", - } - + model_aliases = {"gpt-4": "gptweb"} + api_endpoints = {"gptweb": "https://nexra.aryahcr.cc/api/chat/gptweb"} @classmethod def get_model(cls, model: str) -> str: @@ -33,37 +25,40 @@ class NexraChatGptWeb(AsyncGeneratorProvider, ProviderModelMixin): return cls.model_aliases[model] else: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, proxy: str = None, markdown: bool = False, **kwargs - ) -> AsyncResult: + ) -> CreateResult: + model = cls.get_model(model) + api_endpoint = cls.api_endpoints.get(model, cls.api_endpoints[cls.default_model]) + headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - async with ClientSession(headers=headers) as session: - prompt = format_prompt(messages) - data = { - "prompt": prompt, - "markdown": markdown - } - model = cls.get_model(model) - endpoint = cls.api_endpoint.format(model) - async with session.post(endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - response_text = await response.text() - - # Remove leading underscore if present - if response_text.startswith('_'): - response_text = response_text[1:] - - try: - response_data = json.loads(response_text) - yield response_data.get('gpt', response_text) - except json.JSONDecodeError: - yield response_text + + data = { + "prompt": format_prompt(messages), + "markdown": markdown + } + + response = requests.post(api_endpoint, headers=headers, json=data) + + return cls.process_response(response) + + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.lstrip('_') + json_response = json.loads(content) + return json_response.get('gpt', '') + except json.JSONDecodeError: + return "Error: Unable to decode JSON response" + else: + return f"Error: {response.status_code}" diff --git a/g4f/Provider/nexra/NexraDallE.py b/g4f/Provider/nexra/NexraDallE.py index 9c8ad12d..f605c6d0 100644 --- a/g4f/Provider/nexra/NexraDallE.py +++ b/g4f/Provider/nexra/NexraDallE.py @@ -1,66 +1,63 @@ from __future__ import annotations -from aiohttp import ClientSession import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse - -class NexraDallE(AsyncGeneratorProvider, ProviderModelMixin): +class NexraDallE(AbstractProvider, ProviderModelMixin): label = "Nexra DALL-E" url = "https://nexra.aryahcr.cc/documentation/dall-e/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" working = True - - default_model = 'dalle' + + default_model = "dalle" models = [default_model] @classmethod def get_model(cls, model: str) -> str: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, proxy: str = None, response: str = "url", # base64 or url **kwargs - ) -> AsyncResult: - # Retrieve the correct model to use + ) -> CreateResult: model = cls.get_model(model) - # Format the prompt from the messages - prompt = messages[0]['content'] - headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - payload = { - "prompt": prompt, + + data = { + "prompt": messages[-1]["content"], "model": model, "response": response } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) - async with ClientSession(headers=headers) as session: - async with session.post(cls.api_endpoint, json=payload, proxy=proxy) as response: - response.raise_for_status() - text_data = await response.text() + result = cls.process_response(response) + yield result - try: - # Parse the JSON response - json_start = text_data.find('{') - json_data = text_data[json_start:] - data = json.loads(json_data) - - # Check if the response contains images - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][0] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") + else: + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/NexraDallE2.py b/g4f/Provider/nexra/NexraDallE2.py index 6b46e8cb..2a36b6e6 100644 --- a/g4f/Provider/nexra/NexraDallE2.py +++ b/g4f/Provider/nexra/NexraDallE2.py @@ -1,74 +1,63 @@ from __future__ import annotations -from aiohttp import ClientSession import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse - -class NexraDallE2(AsyncGeneratorProvider, ProviderModelMixin): +class NexraDallE2(AbstractProvider, ProviderModelMixin): label = "Nexra DALL-E 2" url = "https://nexra.aryahcr.cc/documentation/dall-e/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" working = True - - default_model = 'dalle2' + + default_model = "dalle2" models = [default_model] - model_aliases = { - "dalle-2": "dalle2", - } @classmethod def get_model(cls, model: str) -> str: - if model in cls.models: - return model - elif model in cls.model_aliases: - return cls.model_aliases[model] - else: - return cls.default_model - + return cls.default_model + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, proxy: str = None, response: str = "url", # base64 or url **kwargs - ) -> AsyncResult: - # Retrieve the correct model to use + ) -> CreateResult: model = cls.get_model(model) - # Format the prompt from the messages - prompt = messages[0]['content'] - headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - payload = { - "prompt": prompt, + + data = { + "prompt": messages[-1]["content"], "model": model, "response": response } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) - async with ClientSession(headers=headers) as session: - async with session.post(cls.api_endpoint, json=payload, proxy=proxy) as response: - response.raise_for_status() - text_data = await response.text() + result = cls.process_response(response) + yield result - try: - # Parse the JSON response - json_start = text_data.find('{') - json_data = text_data[json_start:] - data = json.loads(json_data) - - # Check if the response contains images - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][0] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") + else: + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/NexraDalleMini.py b/g4f/Provider/nexra/NexraDalleMini.py deleted file mode 100644 index 7fcc7a81..00000000 --- a/g4f/Provider/nexra/NexraDalleMini.py +++ /dev/null @@ -1,66 +0,0 @@ -from __future__ import annotations - -from aiohttp import ClientSession -import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin -from ...image import ImageResponse - - -class NexraDalleMini(AsyncGeneratorProvider, ProviderModelMixin): - label = "Nexra DALL-E Mini" - url = "https://nexra.aryahcr.cc/documentation/dall-e/en" - api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" - working = True - - default_model = 'dalle-mini' - models = [default_model] - - @classmethod - def get_model(cls, model: str) -> str: - return cls.default_model - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - response: str = "url", # base64 or url - **kwargs - ) -> AsyncResult: - # Retrieve the correct model to use - model = cls.get_model(model) - - # Format the prompt from the messages - prompt = messages[0]['content'] - - headers = { - "Content-Type": "application/json" - } - payload = { - "prompt": prompt, - "model": model, - "response": response - } - - async with ClientSession(headers=headers) as session: - async with session.post(cls.api_endpoint, json=payload, proxy=proxy) as response: - response.raise_for_status() - text_data = await response.text() - - try: - # Parse the JSON response - json_start = text_data.find('{') - json_data = text_data[json_start:] - data = json.loads(json_data) - - # Check if the response contains images - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][0] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) diff --git a/g4f/Provider/nexra/NexraEmi.py b/g4f/Provider/nexra/NexraEmi.py index 0d3ed6ba..c26becec 100644 --- a/g4f/Provider/nexra/NexraEmi.py +++ b/g4f/Provider/nexra/NexraEmi.py @@ -1,66 +1,63 @@ from __future__ import annotations -from aiohttp import ClientSession import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse - -class NexraEmi(AsyncGeneratorProvider, ProviderModelMixin): +class NexraEmi(AbstractProvider, ProviderModelMixin): label = "Nexra Emi" url = "https://nexra.aryahcr.cc/documentation/emi/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" working = True - - default_model = 'emi' + + default_model = "emi" models = [default_model] @classmethod def get_model(cls, model: str) -> str: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, proxy: str = None, response: str = "url", # base64 or url **kwargs - ) -> AsyncResult: - # Retrieve the correct model to use + ) -> CreateResult: model = cls.get_model(model) - # Format the prompt from the messages - prompt = messages[0]['content'] - headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - payload = { - "prompt": prompt, + + data = { + "prompt": messages[-1]["content"], "model": model, "response": response } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) - async with ClientSession(headers=headers) as session: - async with session.post(cls.api_endpoint, json=payload, proxy=proxy) as response: - response.raise_for_status() - text_data = await response.text() + result = cls.process_response(response) + yield result - try: - # Parse the JSON response - json_start = text_data.find('{') - json_data = text_data[json_start:] - data = json.loads(json_data) - - # Check if the response contains images - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][0] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") + else: + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/NexraFluxPro.py b/g4f/Provider/nexra/NexraFluxPro.py index 1dbab633..cfb26385 100644 --- a/g4f/Provider/nexra/NexraFluxPro.py +++ b/g4f/Provider/nexra/NexraFluxPro.py @@ -1,19 +1,16 @@ from __future__ import annotations -from aiohttp import ClientSession import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse - -class NexraFluxPro(AsyncGeneratorProvider, ProviderModelMixin): - label = "Nexra Flux PRO" +class NexraFluxPro(AbstractProvider, ProviderModelMixin): url = "https://nexra.aryahcr.cc/documentation/flux-pro/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" working = True - + default_model = 'flux' models = [default_model] model_aliases = { @@ -28,47 +25,46 @@ class NexraFluxPro(AsyncGeneratorProvider, ProviderModelMixin): return cls.model_aliases[model] else: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, proxy: str = None, response: str = "url", # base64 or url **kwargs - ) -> AsyncResult: - # Retrieve the correct model to use + ) -> CreateResult: model = cls.get_model(model) - # Format the prompt from the messages - prompt = messages[0]['content'] - headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - payload = { - "prompt": prompt, + + data = { + "prompt": messages[-1]["content"], "model": model, "response": response } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) - async with ClientSession(headers=headers) as session: - async with session.post(cls.api_endpoint, json=payload, proxy=proxy) as response: - response.raise_for_status() - text_data = await response.text() + result = cls.process_response(response) + yield result - try: - # Parse the JSON response - json_start = text_data.find('{') - json_data = text_data[json_start:] - data = json.loads(json_data) - - # Check if the response contains images - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][0] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") + else: + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/NexraGeminiPro.py b/g4f/Provider/nexra/NexraGeminiPro.py index fb0b096b..e4e6a8ec 100644 --- a/g4f/Provider/nexra/NexraGeminiPro.py +++ b/g4f/Provider/nexra/NexraGeminiPro.py @@ -1,42 +1,42 @@ from __future__ import annotations -from aiohttp import ClientSession import json -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin -from ..helper import format_prompt -from ...typing import AsyncResult, Messages +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider +from ..helper import format_prompt -class NexraGeminiPro(AsyncGeneratorProvider, ProviderModelMixin): +class NexraGeminiPro(AbstractProvider, ProviderModelMixin): label = "Nexra Gemini PRO" url = "https://nexra.aryahcr.cc/documentation/gemini-pro/en" api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" - working = False + working = True supports_stream = True - + default_model = 'gemini-pro' models = [default_model] @classmethod def get_model(cls, model: str) -> str: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, + stream: bool, proxy: str = None, - stream: bool = False, markdown: bool = False, **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - + data = { "messages": [ { @@ -44,25 +44,43 @@ class NexraGeminiPro(AsyncGeneratorProvider, ProviderModelMixin): "content": format_prompt(messages) } ], - "markdown": markdown, "stream": stream, + "markdown": markdown, "model": model } + + response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=stream) + + if stream: + return cls.process_streaming_response(response) + else: + return cls.process_non_streaming_response(response) - async with ClientSession(headers=headers) as session: - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - buffer = "" - async for chunk in response.content.iter_any(): - if chunk.strip(): # Check if chunk is not empty - buffer += chunk.decode() - while '\x1e' in buffer: - part, buffer = buffer.split('\x1e', 1) - if part.strip(): - try: - response_json = json.loads(part) - message = response_json.get("message", "") - if message: - yield message - except json.JSONDecodeError as e: - print(f"JSONDecodeError: {e}") + @classmethod + def process_non_streaming_response(cls, response): + if response.status_code == 200: + try: + content = response.text.lstrip('') + data = json.loads(content) + return data.get('message', '') + except json.JSONDecodeError: + return "Error: Unable to decode JSON response" + else: + return f"Error: {response.status_code}" + + @classmethod + def process_streaming_response(cls, response): + full_message = "" + for line in response.iter_lines(decode_unicode=True): + if line: + try: + line = line.lstrip('') + data = json.loads(line) + if data.get('finish'): + break + message = data.get('message', '') + if message: + yield message[len(full_message):] + full_message = message + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/NexraLLaMA31.py b/g4f/Provider/nexra/NexraLLaMA31.py deleted file mode 100644 index d461f2b2..00000000 --- a/g4f/Provider/nexra/NexraLLaMA31.py +++ /dev/null @@ -1,91 +0,0 @@ -from __future__ import annotations - -from aiohttp import ClientSession -import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin -from ..helper import format_prompt - - -class NexraLLaMA31(AsyncGeneratorProvider, ProviderModelMixin): - label = "Nexra LLaMA 3.1" - url = "https://nexra.aryahcr.cc/documentation/llama-3.1/en" - api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" - working = True - supports_stream = True - - default_model = 'llama-3.1' - models = [default_model] - model_aliases = { - "llama-3.1-8b": "llama-3.1", - } - - @classmethod - def get_model(cls, model: str) -> str: - if model in cls.models: - return model - elif model in cls.model_aliases: - return cls.model_aliases.get(model, cls.default_model) - else: - return cls.default_model - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - stream: bool = False, - markdown: bool = False, - **kwargs - ) -> AsyncResult: - model = cls.get_model(model) - - headers = { - "Content-Type": "application/json" - } - - async with ClientSession(headers=headers) as session: - prompt = format_prompt(messages) - data = { - "messages": [ - { - "role": "user", - "content": prompt - } - ], - "stream": stream, - "markdown": markdown, - "model": model - } - - async with session.post(f"{cls.api_endpoint}", json=data, proxy=proxy) as response: - response.raise_for_status() - - if stream: - # Streamed response handling - collected_message = "" - async for chunk in response.content.iter_any(): - if chunk: - decoded_chunk = chunk.decode().strip().split("\x1e") - for part in decoded_chunk: - if part: - message_data = json.loads(part) - - # Collect messages until 'finish': true - if 'message' in message_data and message_data['message']: - collected_message = message_data['message'] - - # When finish is true, yield the final collected message - if message_data.get('finish', False): - yield collected_message - return - else: - # Non-streamed response handling - response_data = await response.json(content_type=None) - - # Yield the message directly from the response - if 'message' in response_data and response_data['message']: - yield response_data['message'] - return diff --git a/g4f/Provider/nexra/NexraMidjourney.py b/g4f/Provider/nexra/NexraMidjourney.py index e43cb164..c427f8a0 100644 --- a/g4f/Provider/nexra/NexraMidjourney.py +++ b/g4f/Provider/nexra/NexraMidjourney.py @@ -1,66 +1,63 @@ from __future__ import annotations -from aiohttp import ClientSession import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse - -class NexraMidjourney(AsyncGeneratorProvider, ProviderModelMixin): +class NexraMidjourney(AbstractProvider, ProviderModelMixin): label = "Nexra Midjourney" url = "https://nexra.aryahcr.cc/documentation/midjourney/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" - working = False - - default_model = 'midjourney' + working = True + + default_model = "midjourney" models = [default_model] @classmethod def get_model(cls, model: str) -> str: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, proxy: str = None, response: str = "url", # base64 or url **kwargs - ) -> AsyncResult: - # Retrieve the correct model to use + ) -> CreateResult: model = cls.get_model(model) - # Format the prompt from the messages - prompt = messages[0]['content'] - headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - payload = { - "prompt": prompt, + + data = { + "prompt": messages[-1]["content"], "model": model, "response": response } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) - async with ClientSession(headers=headers) as session: - async with session.post(cls.api_endpoint, json=payload, proxy=proxy) as response: - response.raise_for_status() - text_data = await response.text() + result = cls.process_response(response) + yield result - try: - # Parse the JSON response - json_start = text_data.find('{') - json_data = text_data[json_start:] - data = json.loads(json_data) - - # Check if the response contains images - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][0] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") + else: + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/NexraProdiaAI.py b/g4f/Provider/nexra/NexraProdiaAI.py index 9d82ab9b..de997fce 100644 --- a/g4f/Provider/nexra/NexraProdiaAI.py +++ b/g4f/Provider/nexra/NexraProdiaAI.py @@ -1,18 +1,16 @@ from __future__ import annotations -from aiohttp import ClientSession import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse - -class NexraProdiaAI(AsyncGeneratorProvider, ProviderModelMixin): +class NexraProdiaAI(AbstractProvider, ProviderModelMixin): label = "Nexra Prodia AI" url = "https://nexra.aryahcr.cc/documentation/prodia/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" - working = False + working = True default_model = 'absolutereality_v181.safetensors [3d9d4d2b]' models = [ @@ -83,8 +81,7 @@ class NexraProdiaAI(AsyncGeneratorProvider, ProviderModelMixin): 'toonyou_beta6.safetensors [980f6b15]', ] - model_aliases = { - } + model_aliases = {} @classmethod def get_model(cls, model: str) -> str: @@ -96,9 +93,13 @@ class NexraProdiaAI(AsyncGeneratorProvider, ProviderModelMixin): return cls.default_model @classmethod - async def create_async_generator( + def get_model(cls, model: str) -> str: + return cls.default_model + + @classmethod + def create_completion( cls, - model: str, # Select from the list of models + model: str, messages: Messages, proxy: str = None, response: str = "url", # base64 or url @@ -107,41 +108,44 @@ class NexraProdiaAI(AsyncGeneratorProvider, ProviderModelMixin): sampler: str = "DPM++ 2M Karras", # Select from these: "Euler","Euler a","Heun","DPM++ 2M Karras","DPM++ SDE Karras","DDIM" negative_prompt: str = "", # Indicates what the AI should not do **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - async with ClientSession(headers=headers) as session: - prompt = messages[0]['content'] - data = { - "prompt": prompt, - "model": "prodia", - "response": response, - "data": { - "model": model, - "steps": steps, - "cfg_scale": cfg_scale, - "sampler": sampler, - "negative_prompt": negative_prompt - } + + data = { + "prompt": messages[-1]["content"], + "model": "prodia", + "response": response, + "data": { + "model": model, + "steps": steps, + "cfg_scale": cfg_scale, + "sampler": sampler, + "negative_prompt": negative_prompt } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - text_data = await response.text() - - if response.status == 200: - try: - json_start = text_data.find('{') - json_data = text_data[json_start:] - - data = json.loads(json_data) - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][-1] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) + } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) + + result = cls.process_response(response) + yield result + + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') # Remove leading underscores + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") else: - yield ImageResponse(f"Request failed with status: {response.status}", prompt) + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/NexraQwen.py b/g4f/Provider/nexra/NexraQwen.py index 8bdf5475..7f944e44 100644 --- a/g4f/Provider/nexra/NexraQwen.py +++ b/g4f/Provider/nexra/NexraQwen.py @@ -1,14 +1,13 @@ from __future__ import annotations -from aiohttp import ClientSession import json +import requests -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ..helper import format_prompt - -class NexraQwen(AsyncGeneratorProvider, ProviderModelMixin): +class NexraQwen(AbstractProvider, ProviderModelMixin): label = "Nexra Qwen" url = "https://nexra.aryahcr.cc/documentation/qwen/en" api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" @@ -21,66 +20,67 @@ class NexraQwen(AsyncGeneratorProvider, ProviderModelMixin): @classmethod def get_model(cls, model: str) -> str: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, + stream: bool, proxy: str = None, - stream: bool = False, markdown: bool = False, **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json", - "accept": "application/json", - "origin": cls.url, - "referer": f"{cls.url}/chat", + 'Content-Type': 'application/json' + } + + data = { + "messages": [ + { + "role": "user", + "content": format_prompt(messages) + } + ], + "stream": stream, + "markdown": markdown, + "model": model } - async with ClientSession(headers=headers) as session: - prompt = format_prompt(messages) - data = { - "messages": [ - { - "role": "user", - "content": prompt - } - ], - "markdown": markdown, - "stream": stream, - "model": model - } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - - complete_message = "" - - # If streaming, process each chunk separately - if stream: - async for chunk in response.content.iter_any(): - if chunk: - try: - # Decode the chunk and split by the delimiter - parts = chunk.decode('utf-8').split('\x1e') - for part in parts: - if part.strip(): # Ensure the part is not empty - response_data = json.loads(part) - message_part = response_data.get('message') - if message_part: - complete_message = message_part - except json.JSONDecodeError: - continue + + response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=stream) + + if stream: + return cls.process_streaming_response(response) + else: + return cls.process_non_streaming_response(response) - # Yield the final complete message - if complete_message: - yield complete_message - else: - # Handle non-streaming response - text_response = await response.text() - response_data = json.loads(text_response) - message = response_data.get('message') - if message: - yield message + @classmethod + def process_non_streaming_response(cls, response): + if response.status_code == 200: + try: + content = response.text.lstrip('') + data = json.loads(content) + return data.get('message', '') + except json.JSONDecodeError: + return "Error: Unable to decode JSON response" + else: + return f"Error: {response.status_code}" + + @classmethod + def process_streaming_response(cls, response): + full_message = "" + for line in response.iter_lines(decode_unicode=True): + if line: + try: + line = line.lstrip('') + data = json.loads(line) + if data.get('finish'): + break + message = data.get('message', '') + if message is not None and message != full_message: + yield message[len(full_message):] + full_message = message + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/NexraSD15.py b/g4f/Provider/nexra/NexraSD15.py index 03b35013..860a132f 100644 --- a/g4f/Provider/nexra/NexraSD15.py +++ b/g4f/Provider/nexra/NexraSD15.py @@ -1,18 +1,16 @@ from __future__ import annotations import json -from aiohttp import ClientSession +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin - - -class NexraSD15(AsyncGeneratorProvider, ProviderModelMixin): +class NexraSD15(AbstractProvider, ProviderModelMixin): label = "Nexra Stable Diffusion 1.5" url = "https://nexra.aryahcr.cc/documentation/stable-diffusion/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" - working = False + working = True default_model = 'stablediffusion-1.5' models = [default_model] @@ -29,42 +27,46 @@ class NexraSD15(AsyncGeneratorProvider, ProviderModelMixin): return cls.model_aliases[model] else: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, proxy: str = None, response: str = "url", # base64 or url **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json", + 'Content-Type': 'application/json' } - async with ClientSession(headers=headers) as session: - data = { - "prompt": messages, - "model": model, - "response": response - } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - text_response = await response.text() - - # Clean the response by removing unexpected characters - cleaned_response = text_response.strip('__') + + data = { + "prompt": messages[-1]["content"], + "model": model, + "response": response + } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) - if not cleaned_response.strip(): - raise ValueError("Received an empty response from the server.") + result = cls.process_response(response) + yield result - try: - json_response = json.loads(cleaned_response) - image_url = json_response.get("images", [])[0] - # Create an ImageResponse object - image_response = ImageResponse(images=image_url, alt="Generated Image") - yield image_response - except json.JSONDecodeError: - raise ValueError("Unable to decode JSON from the received text response.") + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") + else: + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/NexraSD21.py b/g4f/Provider/nexra/NexraSD21.py deleted file mode 100644 index 46cd6611..00000000 --- a/g4f/Provider/nexra/NexraSD21.py +++ /dev/null @@ -1,75 +0,0 @@ -from __future__ import annotations - -import json -from aiohttp import ClientSession -from ...image import ImageResponse - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin - - -class NexraSD21(AsyncGeneratorProvider, ProviderModelMixin): - label = "Nexra Stable Diffusion 2.1" - url = "https://nexra.aryahcr.cc/documentation/stable-diffusion/en" - api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" - working = False - - default_model = 'stablediffusion-2.1' - models = [default_model] - - model_aliases = { - "sd-2.1": "stablediffusion-2.1", - } - - @classmethod - def get_model(cls, model: str) -> str: - if model in cls.models: - return model - elif model in cls.model_aliases: - return cls.model_aliases[model] - else: - return cls.default_model - - @classmethod - async def create_async_generator( - cls, - model: str, - messages: Messages, - proxy: str = None, - response: str = "url", # base64 or url - **kwargs - ) -> AsyncResult: - model = cls.get_model(model) - - headers = { - "Content-Type": "application/json", - } - async with ClientSession(headers=headers) as session: - # Directly use the messages as the prompt - data = { - "prompt": messages, - "model": model, - "response": response, - "data": { - "prompt_negative": "", - "guidance_scale": 9 - } - } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - response.raise_for_status() - text_response = await response.text() - - # Clean the response by removing unexpected characters - cleaned_response = text_response.strip('__') - - if not cleaned_response.strip(): - raise ValueError("Received an empty response from the server.") - - try: - json_response = json.loads(cleaned_response) - image_url = json_response.get("images", [])[0] - # Create an ImageResponse object - image_response = ImageResponse(images=image_url, alt="Generated Image") - yield image_response - except json.JSONDecodeError: - raise ValueError("Unable to decode JSON from the received text response.") diff --git a/g4f/Provider/nexra/NexraSDLora.py b/g4f/Provider/nexra/NexraSDLora.py index a33afa04..a12bff1a 100644 --- a/g4f/Provider/nexra/NexraSDLora.py +++ b/g4f/Provider/nexra/NexraSDLora.py @@ -1,28 +1,26 @@ from __future__ import annotations -from aiohttp import ClientSession import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse - -class NexraSDLora(AsyncGeneratorProvider, ProviderModelMixin): +class NexraSDLora(AbstractProvider, ProviderModelMixin): label = "Nexra Stable Diffusion Lora" url = "https://nexra.aryahcr.cc/documentation/stable-diffusion/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" - working = False + working = True - default_model = 'sdxl-lora' + default_model = "sdxl-lora" models = [default_model] @classmethod def get_model(cls, model: str) -> str: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, @@ -31,38 +29,41 @@ class NexraSDLora(AsyncGeneratorProvider, ProviderModelMixin): guidance: str = 0.3, # Min: 0, Max: 5 steps: str = 2, # Min: 2, Max: 10 **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - async with ClientSession(headers=headers) as session: - prompt = messages[0]['content'] - data = { - "prompt": prompt, - "model": model, - "response": response, - "data": { - "guidance": guidance, - "steps": steps - } + + data = { + "prompt": messages[-1]["content"], + "model": model, + "response": response, + "data": { + "guidance": guidance, + "steps": steps } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - text_data = await response.text() - - if response.status == 200: - try: - json_start = text_data.find('{') - json_data = text_data[json_start:] - - data = json.loads(json_data) - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][-1] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) + } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) + + result = cls.process_response(response) + yield result + + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") else: - yield ImageResponse(f"Request failed with status: {response.status}", prompt) + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/NexraSDTurbo.py b/g4f/Provider/nexra/NexraSDTurbo.py index da1428b8..865b4522 100644 --- a/g4f/Provider/nexra/NexraSDTurbo.py +++ b/g4f/Provider/nexra/NexraSDTurbo.py @@ -1,28 +1,26 @@ from __future__ import annotations -from aiohttp import ClientSession import json - -from ...typing import AsyncResult, Messages -from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +import requests +from ...typing import CreateResult, Messages +from ..base_provider import ProviderModelMixin, AbstractProvider from ...image import ImageResponse - -class NexraSDTurbo(AsyncGeneratorProvider, ProviderModelMixin): +class NexraSDTurbo(AbstractProvider, ProviderModelMixin): label = "Nexra Stable Diffusion Turbo" url = "https://nexra.aryahcr.cc/documentation/stable-diffusion/en" api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" - working = False + working = True - default_model = 'sdxl-turbo' + default_model = "sdxl-turbo" models = [default_model] @classmethod def get_model(cls, model: str) -> str: return cls.default_model - + @classmethod - async def create_async_generator( + def create_completion( cls, model: str, messages: Messages, @@ -31,38 +29,41 @@ class NexraSDTurbo(AsyncGeneratorProvider, ProviderModelMixin): strength: str = 0.7, # Min: 0, Max: 1 steps: str = 2, # Min: 1, Max: 10 **kwargs - ) -> AsyncResult: + ) -> CreateResult: model = cls.get_model(model) - + headers = { - "Content-Type": "application/json" + 'Content-Type': 'application/json' } - async with ClientSession(headers=headers) as session: - prompt = messages[0]['content'] - data = { - "prompt": prompt, - "model": model, - "response": response, - "data": { - "strength": strength, - "steps": steps - } + + data = { + "prompt": messages[-1]["content"], + "model": model, + "response": response, + "data": { + "strength": strength, + "steps": steps } - async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: - text_data = await response.text() - - if response.status == 200: - try: - json_start = text_data.find('{') - json_data = text_data[json_start:] - - data = json.loads(json_data) - if 'images' in data and len(data['images']) > 0: - image_url = data['images'][-1] - yield ImageResponse(image_url, prompt) - else: - yield ImageResponse("No images found in the response.", prompt) - except json.JSONDecodeError: - yield ImageResponse("Failed to parse JSON. Response might not be in JSON format.", prompt) + } + + response = requests.post(cls.api_endpoint, headers=headers, json=data) + + result = cls.process_response(response) + yield result + + @classmethod + def process_response(cls, response): + if response.status_code == 200: + try: + content = response.text.strip() + content = content.lstrip('_') # Remove the leading underscore + data = json.loads(content) + if data.get('status') and data.get('images'): + image_url = data['images'][0] + return ImageResponse(images=[image_url], alt="Generated Image") else: - yield ImageResponse(f"Request failed with status: {response.status}", prompt) + return "Error: No image URL found in the response" + except json.JSONDecodeError as e: + return f"Error: Unable to decode JSON response. Details: {str(e)}" + else: + return f"Error: {response.status_code}, Response: {response.text}" diff --git a/g4f/Provider/nexra/__init__.py b/g4f/Provider/nexra/__init__.py index c2e6b2f6..6121fdc0 100644 --- a/g4f/Provider/nexra/__init__.py +++ b/g4f/Provider/nexra/__init__.py @@ -6,15 +6,12 @@ from .NexraChatGptV2 import NexraChatGptV2 from .NexraChatGptWeb import NexraChatGptWeb from .NexraDallE import NexraDallE from .NexraDallE2 import NexraDallE2 -from .NexraDalleMini import NexraDalleMini from .NexraEmi import NexraEmi from .NexraFluxPro import NexraFluxPro from .NexraGeminiPro import NexraGeminiPro -from .NexraLLaMA31 import NexraLLaMA31 from .NexraMidjourney import NexraMidjourney from .NexraProdiaAI import NexraProdiaAI from .NexraQwen import NexraQwen from .NexraSD15 import NexraSD15 -from .NexraSD21 import NexraSD21 from .NexraSDLora import NexraSDLora from .NexraSDTurbo import NexraSDTurbo |