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

XFEstudio/gpt4free

fix(CI): add timeout to get_models() network requests and CI step limit

- Add timeout parameter to requests.get() in 7 provider files where timeout=5 from test was silently ignored via **kwargs - Add timeout-minutes: 5 to CI workflow as safety net - Prevents indefinite hang when Cloudflare tarpits connections on CI

e9d4370c
kqlio67 <kqlio67@users.noreply.github.com>
提交于

代码差异

8 个文件 +13 -10
Modified .github/workflows/unittest.yml +2 -0
@@ -24,6 +24,7 @@ jobs:
24 24 run: pip install -r requirements-min.txt
25 25 - name: Run tests
26 26 run: python -m etc.unittest
27 timeout-minutes: 5
27 28 - name: Set up Python 3.14
28 29 uses: actions/setup-python@v6
29 30 with:
@@ -34,6 +35,7 @@ jobs:
34 35 pip install -r requirements.txt
35 36 - name: Run tests
36 37 run: python -m etc.unittest
38 timeout-minutes: 5
37 39 - name: Save PR number
38 40 env:
39 41 PR_NUMBER: ${{ github.event.number }}
Modified g4f/Provider/DeepInfra.py +1 -1
@@ -162,7 +162,7 @@ class DeepInfra(OpenaiTemplate):
162 162 def get_models(cls, **kwargs):
163 163 if not cls.models:
164 164 url = 'https://api.deepinfra.com/models/featured'
165 response = requests.get(url)
165 response = requests.get(url, timeout=kwargs.get("timeout", 15))
166 166 models = response.json()
167 167
168 168 cls.models = {model["model_name"]: {"id": model["model_name"], **model} for model in models if model.get("type") == "text-generation" or model.get("reported_type") == "text-to-image"}
Modified g4f/Provider/glm/__init__.py +3 -2
@@ -220,14 +220,15 @@ class GLM(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
220 220 @classmethod
221 221 def get_models(cls, **kwargs) -> list:
222 222 if not cls.models:
223 response = requests.get(f"{cls.url}/api/v1/auths/")
223 response = requests.get(f"{cls.url}/api/v1/auths/", timeout=kwargs.get("timeout", 15))
224 224 auth_data = response.json()
225 225 cls.api_key = auth_data.get("token")
226 226 cls.auth_user_id = str(auth_data.get("id", ""))
227 227 cls.auth_user_name = auth_data.get("name") or auth_data.get("nickname") or "User"
228 228 response = requests.get(
229 229 f"{cls.url}/api/models",
230 headers={"Authorization": f"Bearer {cls.api_key}"}
230 headers={"Authorization": f"Bearer {cls.api_key}"},
231 timeout=kwargs.get("timeout", 15)
231 232 )
232 233 items = response.json().get("data", [])
233 234 cls.model_aliases = {
Modified g4f/Provider/local/Ollama.py +2 -2
@@ -100,7 +100,7 @@ class Ollama(OpenaiTemplate):
100 100 cls.models = []
101 101 if not api_key or AppConfig.disable_custom_api_key:
102 102 api_key = AuthManager.load_api_key(cls)
103 models = requests.get("https://ollama.com/api/tags").json()["models"]
103 models = requests.get("https://ollama.com/api/tags", timeout=kwargs.get("timeout", 15)).json()["models"]
104 104 if models:
105 105 cls.live += 1
106 106 cls.models = [model["name"] for model in models]
@@ -111,7 +111,7 @@ class Ollama(OpenaiTemplate):
111 111 else:
112 112 url = base_url.replace("/v1", "/api/tags")
113 113 try:
114 models = requests.get(url).json()["models"]
114 models = requests.get(url, timeout=kwargs.get("timeout", 15)).json()["models"]
115 115 except requests.exceptions.RequestException as e:
116 116 return cls.models
117 117 if cls.live == 0 and models:
Modified g4f/Provider/needs_auth/Puter.py +1 -1
@@ -209,7 +209,7 @@ class Puter(AsyncGeneratorProvider, ProviderModelMixin):
209 209 if not cls.models:
210 210 try:
211 211 url = cls.models_endpoint
212 cls.models = requests.get(url).json().get("models", [])
212 cls.models = requests.get(url, timeout=kwargs.get("timeout", 15)).json().get("models", [])
213 213 cls.models = [model for model in cls.models if model not in ["abuse", "costly", "fake", "model-fallback-test-1"]]
214 214 cls.live += 1
215 215 except Exception as e:
Modified g4f/Provider/needs_auth/hf/HuggingChat.py +1 -1
@@ -50,7 +50,7 @@ class HuggingChat(AsyncAuthedProvider, ProviderModelMixin):
50 50 def get_models(cls, **kwargs) -> list[str]:
51 51 if not cls.models:
52 52 try:
53 models = requests.get(f"{cls.url}/api/v2/models").json().get("json")
53 models = requests.get(f"{cls.url}/api/v2/models", timeout=kwargs.get("timeout", 15)).json().get("json")
54 54 cls.text_models = [model["id"] for model in models]
55 55 cls.models = cls.text_models + cls.image_models
56 56 cls.vision_models = [model["id"] for model in models if model["multimodal"]]
Modified g4f/Provider/needs_auth/hf/HuggingFaceInference.py +2 -2
@@ -38,12 +38,12 @@ class HuggingFaceInference(AsyncGeneratorProvider, ProviderModelMixin):
38 38 if not cls.models:
39 39 models = text_models.copy()
40 40 url = "https://huggingface.co/api/models?inference=warm&pipeline_tag=text-generation"
41 response = requests.get(url)
41 response = requests.get(url, timeout=kwargs.get("timeout", 15))
42 42 if response.ok:
43 43 extra_models = [model["id"] for model in response.json() if model.get("trendingScore", 0) >= 10]
44 44 models = extra_models + vision_models + [model for model in models if model not in extra_models]
45 45 url = "https://huggingface.co/api/models?pipeline_tag=text-to-image"
46 response = requests.get(url)
46 response = requests.get(url, timeout=kwargs.get("timeout", 15))
47 47 cls.image_models = image_models.copy()
48 48 if response.ok:
49 49 extra_models = [model["id"] for model in response.json() if model.get("trendingScore", 0) >= 20]
Modified g4f/Provider/needs_auth/hf/HuggingFaceMedia.py +1 -1
@@ -32,7 +32,7 @@ class HuggingFaceMedia(AsyncGeneratorProvider, ProviderModelMixin):
32 32 def get_models(cls, **kwargs) -> list[str]:
33 33 if not cls.models:
34 34 url = "https://huggingface.co/api/models?inference=warm&expand[]=inferenceProviderMapping"
35 response = requests.get(url)
35 response = requests.get(url, timeout=kwargs.get("timeout", 15))
36 36 if response.ok:
37 37 models = response.json()
38 38 providers = {