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

XFEstudio/gpt4free

refactor: improve image response handling, adjust aspect ratio defaults, and fix filename construction

- In PollinationsAI.py, modified get_image method to initialize responses set and manage concurrent image fetches with asyncio tasks, adding a while loop to yield responses as they complete - Changed response index in get_image from 1 to 0 to align with zero-based indexing - Introduced 'responses' set and 'finished' counter outside inner get_image function for proper progress tracking - Updated gather() usage to run all get_image tasks concurrently after loop - In __init__.py, enhanced use_aspect_ratio function: added checks if width and height are None before assigning aspect ratio-based defaults - Assigned default width and height values for aspect ratios "1:1", "16:9", and "9:16" if not already specified in extra_body - In copy_images.py, corrected get_filename function to convert tags to strings before joining with '+', ensuring proper filename formatting - In response.py, refined is_content function to exclude Reasoning objects where is_thinking and token are both None - Removed __eq__ method from Reasoning class to prevent comparison issues - In web_search.py, simplified import by removing unused datetime and date modules

362c2f0f
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

6 个文件 +46 -33
Modified g4f/Provider/PollinationsAI.py +18 -7
@@ -1,5 +1,6 @@
1 1 from __future__ import annotations
2 2
3 import time
3 4 import json
4 5 import random
5 6 import requests
@@ -350,24 +351,34 @@ class PollinationsAI(AsyncGeneratorProvider, ProviderModelMixin):
350 351 prompt = quote_plus(prompt)[:2048-len(cls.image_api_endpoint)-len(query)-8]
351 352 url = f"{cls.image_api_endpoint}prompt/{prompt}?{query}"
352 353 def get_image_url(i: int, seed: Optional[int] = None):
353 if i == 1:
354 if i == 0:
354 355 if not cache and seed is None:
355 356 seed = random.randint(0, 2**32)
356 357 else:
357 358 seed = random.randint(0, 2**32)
358 359 return f"{url}&seed={seed}" if seed else url
359 360 async with ClientSession(headers=DEFAULT_HEADERS, connector=get_connector(proxy=proxy)) as session:
360 async def get_image(i: int, seed: Optional[int] = None):
361 responses = set()
362 finished = 0
363 async def get_image(responses: set, i: int, seed: Optional[int] = None):
364 nonlocal finished
365 start = time.time()
361 366 async with session.get(get_image_url(i, seed), allow_redirects=False, headers={"referer": referrer}) as response:
362 367 try:
363 368 await raise_for_status(response)
364 369 except Exception as e:
365 370 debug.error(f"Error fetching image: {e}")
366 return str(response.url)
367 return str(response.url)
368 yield ImageResponse(await asyncio.gather(*[
369 get_image(i, seed) for i in range(int(n))
370 ]), prompt)
371 responses.add(Reasoning(status=f"Image #{i+1} generated in {time.time() - start:.2f}s"))
372 responses.add(ImageResponse(str(response.url), prompt))
373 finished += 1
374 tasks = []
375 for i in range(int(n)):
376 tasks.append(asyncio.create_task(get_image(responses, i, seed)))
377 while finished < n or len(responses) > 0:
378 while len(responses) > 0:
379 yield responses.pop()
380 await asyncio.sleep(0.1)
381 await asyncio.gather(*tasks)
371 382
372 383 @classmethod
373 384 async def _generate_text(
Modified g4f/image/__init__.py +19 -18
@@ -287,24 +287,25 @@ def to_input_audio(audio: ImageType, filename: str = None) -> str:
287 287
288 288 def use_aspect_ratio(extra_body: dict, aspect_ratio: str) -> Image:
289 289 extra_body = {key: value for key, value in extra_body.items() if value is not None}
290 if aspect_ratio == "1:1":
291 extra_body = {
292 "width": 1024,
293 "height": 1024,
294 **extra_body
295 }
296 elif aspect_ratio == "16:9":
297 extra_body = {
298 "width": 832,
299 "height": 480,
300 **extra_body
301 }
302 elif aspect_ratio == "9:16":
303 extra_body = {
304 "width": 480,
305 "height": 832,
306 **extra_body
307 }
290 if extra_body.get("width") is None or extra_body.get("height") is None:
291 if aspect_ratio == "1:1":
292 extra_body = {
293 "width": extra_body.get("width", 1024),
294 "height": extra_body.get("height", 1024),
295 **extra_body
296 }
297 elif aspect_ratio == "16:9":
298 extra_body = {
299 "width": extra_body.get("width", 832),
300 "height": extra_body.get("height", 480),
301 **extra_body
302 }
303 elif aspect_ratio == "9:16":
304 extra_body = {
305 "width": extra_body.get("width", 480),
306 "height": extra_body.get("height", 832),
307 **extra_body
308 }
308 309 return extra_body
309 310
310 311 class ImageDataResponse():
Modified g4f/image/copy_images.py +1 -1
@@ -79,7 +79,7 @@ async def save_response_media(response: StreamResponse, prompt: str, tags: list[
79 79 def get_filename(tags: list[str], alt: str, extension: str, image: str) -> str:
80 80 return "".join((
81 81 f"{int(time.time())}_",
82 f"{secure_filename('+'.join([tag for tag in tags if tag]))}+" if tags else "",
82 f"{secure_filename('+'.join([str(tag) for tag in tags if tag]))}+" if tags else "",
83 83 f"{secure_filename(alt)}_",
84 84 hashlib.sha256(image.encode()).hexdigest()[:16],
85 85 extension
Modified g4f/providers/base_provider.py +2 -0
@@ -61,6 +61,8 @@ PARAMETER_EXAMPLES = {
61 61 "conversation": {"conversation_id": "550e8400-e29b-11d4-a716-...", "message_id": "550e8400-e29b-11d4-a716-..."},
62 62 "seed": 42,
63 63 "tools": [],
64 "width": 1024,
65 "height": 1024,
64 66 }
65 67
66 68 class AbstractProvider(BaseProvider):
Modified g4f/providers/response.py +5 -6
@@ -7,7 +7,11 @@ from abc import abstractmethod
7 7 from urllib.parse import quote_plus, unquote_plus
8 8
9 9 def is_content(chunk):
10 return isinstance(chunk, (str, MediaResponse, AudioResponse, Reasoning, ToolCalls))
10 if isinstance(chunk, Reasoning):
11 if chunk.is_thinking is None and chunk.token is None:
12 return False
13 return True
14 return isinstance(chunk, (str, MediaResponse, AudioResponse, ToolCalls))
11 15
12 16 def quote_url(url: str) -> str:
13 17 """
@@ -203,11 +207,6 @@ class Reasoning(ResponseType):
203 207 return f"{self.status}\n"
204 208 return ""
205 209
206 def __eq__(self, other: Reasoning):
207 return (self.token == other.token and
208 self.status == other.status and
209 self.is_thinking == other.is_thinking)
210
211 210 def get_dict(self) -> Dict:
212 211 """Return a dictionary representation of the reasoning."""
213 212 if self.label is not None:
Modified g4f/tools/web_search.py +1 -1
@@ -5,7 +5,7 @@ import json
5 5 import hashlib
6 6 from pathlib import Path
7 7 from urllib.parse import urlparse, quote_plus
8 from datetime import datetime, date
8 from datetime import date
9 9 import asyncio
10 10
11 11 # Optional dependencies