XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/gpt4free

fix: Update API endpoints and improve authentication handling in PollinationsAI provider

233fb6fc
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

1 个文件 +28 -27
Modified g4f/Provider/PollinationsAI.py +28 -27
@@ -24,6 +24,7 @@ from ..providers.response import ImageResponse, Reasoning, VideoResponse, JsonRe
24 24 from ..tools.media import render_messages
25 25 from ..tools.run_tools import AuthManager
26 26 from ..cookies import get_cookies_dir
27 from ..tools.files import secure_filename
27 28 from .template.OpenaiTemplate import read_response
28 29 from .. import debug
29 30
@@ -31,7 +32,6 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
31 32 label = "Pollinations AI 🌸"
32 33 url = "https://pollinations.ai"
33 34 login_url = "https://enter.pollinations.ai"
34 api_key = "pk", "_B9YJX5SBohhm2ePq"
35 35 active_by_default = True
36 36 working = True
37 37 supports_system_message = True
@@ -44,7 +44,9 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
44 44 gen_text_api_endpoint = "https://gen.pollinations.ai/v1/chat/completions"
45 45 image_models_endpoint = "https://gen.pollinations.ai/image/models"
46 46 text_models_endpoint = "https://gen.pollinations.ai/text/models"
47 BALANCE_ENDPOINT = "https://gen.pollinations.ai/account/balance"
47 balance_endpoint = "https://api.gpt4free.workers.dev/api/pollinations/account/balance"
48 worker_api_endpoint = "https://api.gpt4free.workers.dev/api/pollinations/chat/completions"
49 worker_models_endpoint = "https://api.gpt4free.workers.dev/api/pollinations/text/models"
48 50
49 51 # Models configuration
50 52 default_model = "openai"
@@ -56,8 +58,6 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
56 58 image_models = [default_image_model, "turbo", "kontext"]
57 59 audio_models = {}
58 60 vision_models = [default_vision_model]
59 _gen_models_loaded = False
60 _free_models_loaded = False
61 61 model_aliases = {
62 62 "gpt-4.1-nano": "openai-fast",
63 63 "llama-4-scout": "llamascout",
@@ -74,12 +74,15 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
74 74 }
75 75 swap_model_aliases = {v: k for k, v in model_aliases.items()}
76 76 balance: Optional[float] = None
77 current_models_endpoint: Optional[str] = None
77 78
78 79 @classmethod
79 80 def get_balance(cls, api_key: str, timeout: Optional[float] = None) -> Optional[float]:
80 81 try:
81 headers = {"authorization": f"Bearer {api_key}"}
82 response = requests.get(cls.BALANCE_ENDPOINT, headers=headers, timeout=timeout)
82 headers = None
83 if api_key:
84 headers = {"authorization": f"Bearer {api_key}"}
85 response = requests.get(cls.balance_endpoint, headers=headers, timeout=timeout)
83 86 response.raise_for_status()
84 87 data = response.json()
85 88 cls.balance = float(data.get("balance", 0.0))
@@ -103,17 +106,18 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
103 106
104 107 if not api_key:
105 108 api_key = AuthManager.load_api_key(cls)
106 if not api_key or api_key.startswith("g4f_") or api_key.startswith("gfs_"):
107 api_key = "".join(cls.api_key)
108
109 if cls.balance or cls.balance is None and cls.get_balance(api_key, timeout) and cls.balance > 0:
110 debug.log(f"Authenticated with Pollinations AI using API key.")
109 if (not api_key or api_key.startswith("g4f_") or api_key.startswith("gfs_")) and cls.balance or cls.balance is None and cls.get_balance(api_key, timeout) and cls.balance > 0:
110 debug.log(f"Authenticated with Pollinations AI using G4F API.")
111 models_url = cls.worker_models_endpoint
112 elif api_key:
113 debug.log(f"Using Pollinations AI with provided API key.")
114 models_url = cls.gen_text_api_endpoint
111 115 else:
112 116 debug.log(f"Using Pollinations AI without authentication.")
113 api_key = None
117 models_url = cls.text_models_endpoint
114 118
115 if not cls._free_models_loaded or api_key and not cls._gen_models_loaded:
116 path = Path(get_cookies_dir()) / "models" / datetime.today().strftime('%Y-%m-%d') / f"{cls.__name__}{'-auth' if api_key else ''}.json"
119 if cls.current_models_endpoint != models_url:
120 path = Path(get_cookies_dir()) / "models" / datetime.today().strftime('%Y-%m-%d') / f"{secure_filename(models_url)}.json"
117 121 if path.exists():
118 122 try:
119 123 data = path.read_text()
@@ -180,10 +184,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
180 184 cls.swap_model_aliases = {v: k for k, v in cls.model_aliases.items()}
181 185
182 186 finally:
183 if api_key:
184 cls._gen_models_loaded = True
185 else:
186 cls._free_models_loaded = True
187 cls.current_models_endpoint = models_url
187 188 # Return unique models across all categories
188 189 all_models = cls.text_models.copy()
189 190 all_models.extend(cls.image_models)
@@ -262,7 +263,7 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
262 263 has_audio = True
263 264 break
264 265 model = "openai-audio" if has_audio else cls.default_model
265 if cls.get_models(api_key=api_key, timeout=kwargs.get("timeout")):
266 if cls.get_models(api_key=api_key, timeout=kwargs.get("timeout", 15)):
266 267 if model in cls.model_aliases:
267 268 model = cls.model_aliases[model]
268 269 debug.log(f"Using model: {model}")
@@ -480,17 +481,17 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
480 481 seed=None if "tools" in extra_body else seed,
481 482 **extra_body
482 483 )
484 if (not api_key or api_key.startswith("g4f_") or api_key.startswith("gfs_")) and cls.balance and cls.balance > 0:
485 endpoint = cls.worker_api_endpoint
486 elif api_key:
487 endpoint = cls.gen_text_api_endpoint
488 else:
489 endpoint = cls.text_api_endpoint
483 490 headers = None
484 if api_key and not api_key.startswith("g4f_") and not api_key.startswith("gfs_"):
491 if api_key:
485 492 headers = {"authorization": f"Bearer {api_key}"}
486 elif cls.balance and cls.balance > 0:
487 headers = {"authorization": f"Bearer {''.join(cls.api_key)}"}
488 493 yield JsonRequest.from_dict(data)
489 if headers:
490 url = cls.gen_text_api_endpoint
491 else:
492 url = cls.text_api_endpoint
493 async with session.post(url, json=data, headers=headers) as response:
494 async with session.post(endpoint, json=data, headers=headers) as response:
494 495 if response.status in (400, 500):
495 496 debug.error(f"Error: {response.status} - Bad Request: {data}")
496 497 async for chunk in read_response(response, stream, format_media_prompt(messages), cls.get_dict(),