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

XFEstudio/gpt4free

Update requirements

18014298
hlohaus <hlohaus@users.noreply.github.com>
提交于

代码差异

10 个文件 +37 -13
Modified g4f/Provider/template/OpenaiTemplate.py +4 -0
@@ -91,6 +91,10 @@ class OpenaiTemplate(AsyncGeneratorProvider, ProviderModelMixin, RaiseErrorMixin
91 91 base_url = cls.base_url
92 92 if not cls.is_provider_api_key(api_key):
93 93 base_url = cls.backup_url
94 if base_url is None:
95 raise NotImplementedError("No base_url or backup_url specified.")
96 if base_url.startswith("https://g4f.space/") and not api_key:
97 api_key = AppConfig.g4f_space_api_key
94 98 elif cls.models_needs_auth and not api_key:
95 99 raise MissingAuthError("API key is required.")
96 100 response = requests.get(f"{base_url}/models", headers=cls.get_headers(False, api_key), verify=cls.ssl, timeout=timeout)
Modified g4f/cli/__init__.py +9 -6
@@ -339,16 +339,19 @@ def main():
339 339 mode_parser = ArgumentParser(description="Select mode to run g4f in.", exit_on_error=False)
340 340 mode_parser.add_argument("mode", nargs="?", choices=["api", "gui", "client", "mcp", "auth", "dev", "systray", "tray"], default="api", help="Mode to run g4f in (default: api).")
341 341
342 # Preserve original remaining so the API parser gets all args if mode
343 # detection fails (e.g. `python -m g4f --port 8080` without a mode prefix).
344 original_remaining = remaining
345 342 try:
346 343 try:
347 344 args, remaining = mode_parser.parse_known_args(remaining)
348 345 except argparse.ArgumentError:
349 parser = get_api_parser(exit_on_error=False)
350 args = parser.parse_args(remaining)
351 run_api_args(args)
346 try:
347 parser = get_tray_parser(exit_on_error=False)
348 args = parser.parse_args(remaining)
349 run_tray_args(args)
350 except (argparse.ArgumentError, ImportError) as e:
351 print(e)
352 parser = get_api_parser(exit_on_error=False)
353 args = parser.parse_args(remaining)
354 run_api_args(args)
352 355 return
353 356 if args.mode == "auth":
354 357 parser = get_auth_parser()
Modified g4f/config.py +3 -1
@@ -52,6 +52,7 @@ class AppConfig:
52 52 timeout: int = DEFAULT_TIMEOUT
53 53 stream_timeout: int = DEFAULT_STREAM_TIMEOUT
54 54 disable_custom_api_key: bool = False
55 g4f_space_api_key: Optional[str] = None
55 56
56 57 @classmethod
57 58 def set_config(cls, **data):
@@ -67,4 +68,5 @@ class AppConfig:
67 68 cls.proxy = os.environ.get("G4F_PROXY", cls.proxy)
68 69 cls.model = os.environ.get("G4F_MODEL", cls.model)
69 70 cls.provider = os.environ.get("G4F_PROVIDER", cls.provider)
70 cls.disable_custom_api_key = os.environ.get("G4F_DISABLE_CUSTOM_API_KEY", str(cls.disable_custom_api_key)).lower() in ("true", "1", "yes")
71 cls.disable_custom_api_key = os.environ.get("G4F_DISABLE_CUSTOM_API_KEY", str(cls.disable_custom_api_key)).lower() in ("true", "1", "yes")
72 cls.g4f_space_api_key = os.environ.get("G4F_SPACE_API_KEY", cls.g4f_space_api_key)
Modified g4f/mcp/pa_provider.py +1 -0
@@ -224,6 +224,7 @@ def _make_restricted_import(allowed: FrozenSet[str]):
224 224 # Block the entire Provider package; only specific safe submodules are
225 225 # explicitly permitted via _ALLOWED_G4F_SUBPATHS below.
226 226 "g4f.Provider",
227 "g4f.config"
227 228 })
228 229
229 230 # Explicit allowlist for g4f sub-paths that would otherwise be blocked.
Modified g4f/providers/any_provider.py +6 -1
@@ -8,6 +8,7 @@ from ..errors import ModelNotFoundError
8 8 from ..image import is_data_an_audio
9 9 from ..providers.retry_provider import RotatedProvider
10 10 from ..providers.config_provider import RouterConfig, ConfigModelProvider
11 from ..client.factory import AbstractClientFactory
11 12 from ..Provider import __getattr__
12 13 from .base_provider import AsyncGeneratorProvider, ProviderModelMixin
13 14 from .. import Provider
@@ -469,6 +470,8 @@ class AnyProvider(AsyncGeneratorProvider, AnyModelProviderMixin):
469 470 for provider, alias in cls.model_map[model].items():
470 471 try:
471 472 provider_cls = Provider.__map__[provider]
473 if provider_cls.model_aliases is None:
474 provider_cls.model_aliases = {}
472 475 if model not in provider_cls.model_aliases:
473 476 provider_cls.model_aliases[model] = alias
474 477 providers.append(provider_cls)
@@ -501,6 +504,8 @@ class AnyProvider(AsyncGeneratorProvider, AnyModelProviderMixin):
501 504 if not has_api_key:
502 505 providers.sort(key=lambda p: bool(getattr(p, "needs_auth", False)))
503 506
507 providers.append(AbstractClientFactory.create_provider(None, "default"))
508
504 509 if len(providers) == 0:
505 510 raise ModelNotFoundError(
506 511 f"AnyProvider: Model {model} not found in any provider."
@@ -510,7 +515,7 @@ class AnyProvider(AsyncGeneratorProvider, AnyModelProviderMixin):
510 515 f"AnyProvider: Using providers: {[provider.__name__ for provider in providers]} for model '{model}'"
511 516 )
512 517
513 async for chunk in RotatedProvider(providers).create_async_generator(
518 async for chunk in RotatedProvider(providers, False).create_async_generator(
514 519 model, messages, stream=stream, media=media, api_key=api_key, **kwargs
515 520 ):
516 521 yield chunk
Modified g4f/providers/base_provider.py +2 -2
@@ -268,7 +268,7 @@ class AsyncGeneratorProvider(AbstractProvider):
268 268 class ProviderModelMixin:
269 269 default_model: str = None
270 270 models: list[str] = []
271 model_aliases: dict[str, str] = {}
271 model_aliases: Optional[dict[str, str]] = None
272 272 models_count: dict = {}
273 273 image_models: list = []
274 274 vision_models: list = []
@@ -292,7 +292,7 @@ class ProviderModelMixin:
292 292 def get_model(cls, model: str, **kwargs) -> str:
293 293 if not model and cls.default_model is not None:
294 294 model = cls.default_model
295 if model in cls.model_aliases:
295 if cls.model_aliases is not None and model in cls.model_aliases:
296 296 alias = cls.model_aliases[model]
297 297 if isinstance(alias, list):
298 298 selected_model = random.choice(alias)
Modified g4f/providers/retry_provider.py +1 -1
@@ -14,7 +14,7 @@ from ..errors import RetryProviderError, RetryNoProviderError
14 14
15 15 def _resolve_model(provider: Type[BaseProvider], model: str) -> str:
16 16 alias = model or getattr(provider, "default_model", None)
17 if hasattr(provider, "model_aliases"):
17 if getattr(provider, "model_aliases"):
18 18 alias = provider.model_aliases.get(model, model)
19 19 if isinstance(alias, list):
20 20 alias = random.choice(alias)
Modified requirements-slim.txt +3 -1
@@ -19,4 +19,6 @@ a2wsgi
19 19 python-dotenv
20 20 ddgs
21 21 cloudscraper
22 PyYAML
22 PyYAML
23 websocket-client
24 pystray
Modified requirements.txt +3 -1
@@ -21,4 +21,6 @@ ddgs
21 21 cloudscraper
22 22 numpy
23 23 PyYAML
24 prompt_optimizer
24 prompt_optimizer
25 websocket-client
26 pystray
Modified setup.py +5 -0
@@ -43,6 +43,9 @@ EXTRA_REQUIRE = {
43 43 "wasmtime",
44 44 "numpy",
45 45 "PyYAML",
46 "prompt_optimizer",
47 "websocket-client",
48 "pystray",
46 49 ],
47 50 'slim': [
48 51 "curl_cffi>=0.6.2",
@@ -65,6 +68,8 @@ EXTRA_REQUIRE = {
65 68 "aiofile",
66 69 "cloudscraper",
67 70 "PyYAML",
71 "websocket-client",
72 "pystray",
68 73 ],
69 74 "image": [
70 75 "pillow",