From 702837a33ab1b632ecb8903cda8d45a87a7e400a Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Mon, 20 Nov 2023 13:59:14 +0100 Subject: [PATCH] Add auto support params method --- g4f/Provider/AItianhu.py | 21 +++---------- g4f/Provider/ChatBase.py | 13 +------- g4f/Provider/ChatForAi.py | 10 ------ g4f/Provider/FreeGpt.py | 10 ------ g4f/Provider/GeekGpt.py | 14 +-------- g4f/Provider/GptGo.py | 20 ++---------- g4f/Provider/Liaobots.py | 14 --------- g4f/Provider/Opchatgpts.py | 14 +-------- g4f/Provider/Ylokh.py | 19 +----------- g4f/Provider/base_provider.py | 43 +++++++++++++++++++++----- g4f/Provider/deprecated/Aibn.py | 12 ------- g4f/Provider/deprecated/Ails.py | 13 -------- g4f/Provider/deprecated/Aivvm.py | 14 +-------- g4f/Provider/deprecated/ChatgptDuo.py | 13 +------- g4f/Provider/deprecated/CodeLinkAva.py | 15 +-------- g4f/Provider/deprecated/DfeHub.py | 15 --------- g4f/Provider/deprecated/EasyChat.py | 19 +----------- g4f/Provider/deprecated/Equing.py | 13 +------- g4f/Provider/deprecated/FastGpt.py | 13 +------- g4f/Provider/deprecated/GetGpt.py | 16 ---------- g4f/Provider/deprecated/H2o.py | 20 +----------- g4f/Provider/deprecated/Lockchat.py | 14 +-------- g4f/Provider/deprecated/Myshell.py | 12 ------- g4f/Provider/deprecated/V50.py | 15 +-------- g4f/Provider/deprecated/Vitalentum.py | 16 +--------- g4f/Provider/deprecated/Wuguokai.py | 13 +------- 26 files changed, 56 insertions(+), 355 deletions(-) diff --git a/g4f/Provider/AItianhu.py b/g4f/Provider/AItianhu.py index fcf9a4fb..05ee5a20 100644 --- a/g4f/Provider/AItianhu.py +++ b/g4f/Provider/AItianhu.py @@ -71,21 +71,8 @@ class AItianhu(AsyncGeneratorProvider): if "detail" not in line: raise RuntimeError(f"Response: {line}") - - content = line["detail"]["choices"][0]["delta"].get("content") - if content: - yield content - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("proxy", "str"), - ("temperature", "float"), - ("top_p", "int"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" + if content := line["detail"]["choices"][0]["delta"].get( + "content" + ): + yield content \ No newline at end of file diff --git a/g4f/Provider/ChatBase.py b/g4f/Provider/ChatBase.py index ccc20244..996ca39a 100644 --- a/g4f/Provider/ChatBase.py +++ b/g4f/Provider/ChatBase.py @@ -58,15 +58,4 @@ class ChatBase(AsyncGeneratorProvider): for incorrect_response in cls.list_incorrect_responses: if incorrect_response in response_data: raise RuntimeError("Incorrect response") - yield stream.decode() - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" + yield stream.decode() \ No newline at end of file diff --git a/g4f/Provider/ChatForAi.py b/g4f/Provider/ChatForAi.py index 7a123f0f..afab034b 100644 --- a/g4f/Provider/ChatForAi.py +++ b/g4f/Provider/ChatForAi.py @@ -57,16 +57,6 @@ class ChatForAi(AsyncGeneratorProvider): raise RuntimeError(f"Response: {chunk.decode()}") yield chunk.decode() - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" def generate_signature(timestamp: int, message: str, id: str): buffer = f"{timestamp}:{id}:{message}:7YN8z6d6" diff --git a/g4f/Provider/FreeGpt.py b/g4f/Provider/FreeGpt.py index 22c6c9aa..15232c8d 100644 --- a/g4f/Provider/FreeGpt.py +++ b/g4f/Provider/FreeGpt.py @@ -47,16 +47,6 @@ class FreeGpt(AsyncGeneratorProvider): raise RuntimeError("Rate limit reached") yield chunk - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" def generate_signature(timestamp: int, message: str, secret: str = ""): data = f"{timestamp}:{message}:{secret}" diff --git a/g4f/Provider/GeekGpt.py b/g4f/Provider/GeekGpt.py index 8c449745..9ed9c09b 100644 --- a/g4f/Provider/GeekGpt.py +++ b/g4f/Provider/GeekGpt.py @@ -70,16 +70,4 @@ class GeekGpt(BaseProvider): raise RuntimeError(f'error | {e} :', json_data) if content: - yield content - - @classmethod - @property - def params(cls): - params = [ - ('model', 'str'), - ('messages', 'list[dict[str, str]]'), - ('stream', 'bool'), - ('temperature', 'float'), - ] - param = ', '.join([': '.join(p) for p in params]) - return f'g4f.provider.{cls.__name__} supports: ({param})' + yield content \ No newline at end of file diff --git a/g4f/Provider/GptGo.py b/g4f/Provider/GptGo.py index ac3f7fe8..be9979f2 100644 --- a/g4f/Provider/GptGo.py +++ b/g4f/Provider/GptGo.py @@ -62,21 +62,5 @@ class GptGo(AsyncGeneratorProvider): line = json.loads(line[len(start):-1]) if line["choices"][0]["finish_reason"] == "stop": break - - content = line["choices"][0]["delta"].get("content"): - if content: - yield content - - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("proxy", "str"), - ("temperature", "float"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + if content := line["choices"][0]["delta"].get("content"): + yield content \ No newline at end of file diff --git a/g4f/Provider/Liaobots.py b/g4f/Provider/Liaobots.py index 109f7e2d..807b4424 100644 --- a/g4f/Provider/Liaobots.py +++ b/g4f/Provider/Liaobots.py @@ -97,17 +97,3 @@ class Liaobots(AsyncGeneratorProvider): async for stream in response.content.iter_any(): if stream: yield stream.decode() - - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("proxy", "str"), - ("auth", "str"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" diff --git a/g4f/Provider/Opchatgpts.py b/g4f/Provider/Opchatgpts.py index 8abdf39b..8c2987fa 100644 --- a/g4f/Provider/Opchatgpts.py +++ b/g4f/Provider/Opchatgpts.py @@ -56,16 +56,4 @@ class Opchatgpts(AsyncGeneratorProvider): if line["type"] == "live": yield line["data"] elif line["type"] == "end": - break - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("proxy", "str"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + break \ No newline at end of file diff --git a/g4f/Provider/Ylokh.py b/g4f/Provider/Ylokh.py index 13692139..11fe497f 100644 --- a/g4f/Provider/Ylokh.py +++ b/g4f/Provider/Ylokh.py @@ -55,21 +55,4 @@ class Ylokh(AsyncGeneratorProvider): yield content else: chat = await response.json() - yield chat["choices"][0]["message"].get("content") - - - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("proxy", "str"), - ("timeout", "int"), - ("temperature", "float"), - ("top_p", "float"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + yield chat["choices"][0]["message"].get("content") \ No newline at end of file diff --git a/g4f/Provider/base_provider.py b/g4f/Provider/base_provider.py index 47ea6ff8..564dd77e 100644 --- a/g4f/Provider/base_provider.py +++ b/g4f/Provider/base_provider.py @@ -3,6 +3,8 @@ from __future__ import annotations from asyncio import AbstractEventLoop from concurrent.futures import ThreadPoolExecutor from abc import ABC, abstractmethod +from inspect import signature, Parameter +from types import NoneType from .helper import get_event_loop, get_cookies, format_prompt from ..typing import CreateResult, AsyncResult, Messages @@ -52,17 +54,42 @@ class BaseProvider(ABC): executor, create_func ) - + @classmethod @property def params(cls) -> str: - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" + if issubclass(cls, AsyncGeneratorProvider): + sig = signature(cls.create_async_generator) + elif issubclass(cls, AsyncProvider): + sig = signature(cls.create_async) + else: + sig = signature(cls.create_completion) + + def get_type_name(annotation: type) -> str: + if hasattr(annotation, "__name__"): + annotation = annotation.__name__ + elif isinstance(annotation, NoneType): + annotation = "None" + return str(annotation) + + args = ""; + for name, param in sig.parameters.items(): + if name in ("self", "kwargs"): + continue + if name == "stream" and not cls.supports_stream: + continue + if args: + args += ", " + args += "\n" + args += " " + name + if name != "model" and param.annotation is not Parameter.empty: + args += f": {get_type_name(param.annotation)}" + if param.default == "": + args += ' = ""' + elif param.default is not Parameter.empty: + args += f" = {param.default}" + + return f"g4f.Provider.{cls.__name__} supports: ({args}\n)" class AsyncProvider(BaseProvider): diff --git a/g4f/Provider/deprecated/Aibn.py b/g4f/Provider/deprecated/Aibn.py index 60cef1e4..0bbfb436 100644 --- a/g4f/Provider/deprecated/Aibn.py +++ b/g4f/Provider/deprecated/Aibn.py @@ -39,18 +39,6 @@ class Aibn(AsyncGeneratorProvider): response.raise_for_status() async for chunk in response.iter_content(): yield chunk.decode() - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("temperature", "float"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" def generate_signature(timestamp: int, message: str, secret: str = "undefined"): diff --git a/g4f/Provider/deprecated/Ails.py b/g4f/Provider/deprecated/Ails.py index 5244fd75..e87ceb32 100644 --- a/g4f/Provider/deprecated/Ails.py +++ b/g4f/Provider/deprecated/Ails.py @@ -77,19 +77,6 @@ class Ails(AsyncGeneratorProvider): yield token - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("temperature", "float"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" - - def _hash(json_data: dict[str, str]) -> SHA256: base_string: str = f'{json_data["t"]}:{json_data["m"]}:WI,2rU#_r:r~aF4aJ36[.Z(/8Rv93Rf:{len(json_data["m"])}' diff --git a/g4f/Provider/deprecated/Aivvm.py b/g4f/Provider/deprecated/Aivvm.py index 12fd387d..8b5a9e05 100644 --- a/g4f/Provider/deprecated/Aivvm.py +++ b/g4f/Provider/deprecated/Aivvm.py @@ -69,16 +69,4 @@ class Aivvm(BaseProvider): try: yield chunk.decode("utf-8") except UnicodeDecodeError: - yield chunk.decode("unicode-escape") - - @classmethod - @property - def params(cls): - params = [ - ('model', 'str'), - ('messages', 'list[dict[str, str]]'), - ('stream', 'bool'), - ('temperature', 'float'), - ] - param = ', '.join([': '.join(p) for p in params]) - return f'g4f.provider.{cls.__name__} supports: ({param})' + yield chunk.decode("unicode-escape") \ No newline at end of file diff --git a/g4f/Provider/deprecated/ChatgptDuo.py b/g4f/Provider/deprecated/ChatgptDuo.py index c77c6a1c..c2d2de7a 100644 --- a/g4f/Provider/deprecated/ChatgptDuo.py +++ b/g4f/Provider/deprecated/ChatgptDuo.py @@ -44,15 +44,4 @@ class ChatgptDuo(AsyncProvider): @classmethod def get_sources(cls): - return cls._sources - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + return cls._sources \ No newline at end of file diff --git a/g4f/Provider/deprecated/CodeLinkAva.py b/g4f/Provider/deprecated/CodeLinkAva.py index 64ce1af9..a909ab97 100644 --- a/g4f/Provider/deprecated/CodeLinkAva.py +++ b/g4f/Provider/deprecated/CodeLinkAva.py @@ -47,17 +47,4 @@ class CodeLinkAva(AsyncGeneratorProvider): break line = json.loads(line[6:-1]) if content := line["choices"][0]["delta"].get("content"): - yield content - - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("temperature", "float"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + yield content \ No newline at end of file diff --git a/g4f/Provider/deprecated/DfeHub.py b/g4f/Provider/deprecated/DfeHub.py index 4ea7501f..4458bac6 100644 --- a/g4f/Provider/deprecated/DfeHub.py +++ b/g4f/Provider/deprecated/DfeHub.py @@ -60,18 +60,3 @@ class DfeHub(BaseProvider): if b"content" in chunk: data = json.loads(chunk.decode().split("data: ")[1]) yield (data["choices"][0]["delta"]["content"]) - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("temperature", "float"), - ("presence_penalty", "int"), - ("frequency_penalty", "int"), - ("top_p", "int"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" diff --git a/g4f/Provider/deprecated/EasyChat.py b/g4f/Provider/deprecated/EasyChat.py index bd49c09c..3142f243 100644 --- a/g4f/Provider/deprecated/EasyChat.py +++ b/g4f/Provider/deprecated/EasyChat.py @@ -87,21 +87,4 @@ class EasyChat(BaseProvider): splitData = chunk.decode().split("data:") if len(splitData) > 1: - yield json.loads(splitData[1])["choices"][0]["delta"]["content"] - - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("temperature", "float"), - ("presence_penalty", "int"), - ("frequency_penalty", "int"), - ("top_p", "int"), - ("active_server", "int"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" + yield json.loads(splitData[1])["choices"][0]["delta"]["content"] \ No newline at end of file diff --git a/g4f/Provider/deprecated/Equing.py b/g4f/Provider/deprecated/Equing.py index 5ba125a3..076b5ac5 100644 --- a/g4f/Provider/deprecated/Equing.py +++ b/g4f/Provider/deprecated/Equing.py @@ -66,15 +66,4 @@ class Equing(BaseProvider): if b'content' in line: line_json = json.loads(line.decode('utf-8').split('data: ')[1]) if token := line_json['choices'][0]['delta'].get('content'): - yield token - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + yield token \ No newline at end of file diff --git a/g4f/Provider/deprecated/FastGpt.py b/g4f/Provider/deprecated/FastGpt.py index 17b21b37..ef69e892 100644 --- a/g4f/Provider/deprecated/FastGpt.py +++ b/g4f/Provider/deprecated/FastGpt.py @@ -74,15 +74,4 @@ class FastGpt(BaseProvider): ): yield token except: - continue - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + continue \ No newline at end of file diff --git a/g4f/Provider/deprecated/GetGpt.py b/g4f/Provider/deprecated/GetGpt.py index 0fbb5b87..a7f4695c 100644 --- a/g4f/Provider/deprecated/GetGpt.py +++ b/g4f/Provider/deprecated/GetGpt.py @@ -55,22 +55,6 @@ class GetGpt(BaseProvider): line_json = json.loads(line.decode('utf-8').split('data: ')[1]) yield (line_json['choices'][0]['delta']['content']) - @classmethod - @property - def params(cls): - params = [ - ('model', 'str'), - ('messages', 'list[dict[str, str]]'), - ('stream', 'bool'), - ('temperature', 'float'), - ('presence_penalty', 'int'), - ('frequency_penalty', 'int'), - ('top_p', 'int'), - ('max_tokens', 'int'), - ] - param = ', '.join([': '.join(p) for p in params]) - return f'g4f.provider.{cls.__name__} supports: ({param})' - def _encrypt(e: str): t = os.urandom(8).hex().encode('utf-8') diff --git a/g4f/Provider/deprecated/H2o.py b/g4f/Provider/deprecated/H2o.py index cead17e1..ba4ca507 100644 --- a/g4f/Provider/deprecated/H2o.py +++ b/g4f/Provider/deprecated/H2o.py @@ -86,22 +86,4 @@ class H2o(AsyncGeneratorProvider): f"{cls.url}/conversation/{conversationId}", proxy=proxy, ) as response: - response.raise_for_status() - - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("temperature", "float"), - ("truncate", "int"), - ("max_new_tokens", "int"), - ("do_sample", "bool"), - ("repetition_penalty", "float"), - ("return_full_text", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" + response.raise_for_status() \ No newline at end of file diff --git a/g4f/Provider/deprecated/Lockchat.py b/g4f/Provider/deprecated/Lockchat.py index 5acfbfbf..d93c9f8a 100644 --- a/g4f/Provider/deprecated/Lockchat.py +++ b/g4f/Provider/deprecated/Lockchat.py @@ -48,16 +48,4 @@ class Lockchat(BaseProvider): if b"content" in token: token = json.loads(token.decode("utf-8").split("data: ")[1]) if token := token["choices"][0]["delta"].get("content"): - yield (token) - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("temperature", "float"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" + yield (token) \ No newline at end of file diff --git a/g4f/Provider/deprecated/Myshell.py b/g4f/Provider/deprecated/Myshell.py index 85731325..2487440d 100644 --- a/g4f/Provider/deprecated/Myshell.py +++ b/g4f/Provider/deprecated/Myshell.py @@ -98,18 +98,6 @@ class Myshell(AsyncGeneratorProvider): raise RuntimeError(f"Received unexpected message: {data_type}") - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" - - def generate_timestamp() -> str: return str( int( diff --git a/g4f/Provider/deprecated/V50.py b/g4f/Provider/deprecated/V50.py index f4f4d823..e24ac2d4 100644 --- a/g4f/Provider/deprecated/V50.py +++ b/g4f/Provider/deprecated/V50.py @@ -58,17 +58,4 @@ class V50(BaseProvider): ) if "https://fk1.v50.ltd" not in response.text: - yield response.text - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("temperature", "float"), - ("top_p", "int"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + yield response.text \ No newline at end of file diff --git a/g4f/Provider/deprecated/Vitalentum.py b/g4f/Provider/deprecated/Vitalentum.py index d6ba9336..13160d94 100644 --- a/g4f/Provider/deprecated/Vitalentum.py +++ b/g4f/Provider/deprecated/Vitalentum.py @@ -50,18 +50,4 @@ class Vitalentum(AsyncGeneratorProvider): break line = json.loads(line[6:-1]) if content := line["choices"][0]["delta"].get("content"): - yield content - - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool"), - ("proxy", "str"), - ("temperature", "float"), - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + yield content \ No newline at end of file diff --git a/g4f/Provider/deprecated/Wuguokai.py b/g4f/Provider/deprecated/Wuguokai.py index 079f0541..87877198 100644 --- a/g4f/Provider/deprecated/Wuguokai.py +++ b/g4f/Provider/deprecated/Wuguokai.py @@ -54,15 +54,4 @@ class Wuguokai(BaseProvider): if len(_split) > 1: yield _split[1].strip() else: - yield _split[0].strip() - - @classmethod - @property - def params(cls): - params = [ - ("model", "str"), - ("messages", "list[dict[str, str]]"), - ("stream", "bool") - ] - param = ", ".join([": ".join(p) for p in params]) - return f"g4f.provider.{cls.__name__} supports: ({param})" \ No newline at end of file + yield _split[0].strip() \ No newline at end of file