返回提交历史
Modified
g4f/Provider/hf_space/BlackForestLabsFlux1Dev.py
+68
-39
Modified
g4f/Provider/hf_space/G4F.py
+1
-0
Modified
g4f/gui/server/api.py
+0
-4
XFEstudio/gpt4free
Use gradio api in flux dev
69d0b098
代码差异
3 个文件
+69
-43
@@ -1,10 +1,11 @@
1
1
from __future__ import annotations
2
2
3
3
import json
4
from aiohttp import ClientSession
4
import uuid
5
5
6
6
from ...typing import AsyncResult, Messages
7
from ...providers.response import ImageResponse, ImagePreview, JsonConversation
7
from ...providers.response import ImageResponse, ImagePreview, JsonConversation, Reasoning
8
from ...requests import StreamSession
8
9
from ...errors import ResponseError
9
10
from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
10
11
from ..helper import format_image_prompt
@@ -14,7 +15,7 @@ from .raise_for_status import raise_for_status
14
15
class BlackForestLabsFlux1Dev(AsyncGeneratorProvider, ProviderModelMixin):
15
16
url = "https://black-forest-labs-flux-1-dev.hf.space"
16
17
space = "black-forest-labs/FLUX.1-dev"
17
api_endpoint = "/gradio_api/call/infer"
18
referer = f"{url}/?__theme=light"
18
19
19
20
working = True
20
21
@@ -24,6 +25,29 @@ class BlackForestLabsFlux1Dev(AsyncGeneratorProvider, ProviderModelMixin):
24
25
image_models = [default_image_model, *model_aliases.keys()]
25
26
models = image_models
26
27
28
@classmethod
29
def run(cls, method: str, session: StreamSession, conversation: JsonConversation, data: list = None):
30
headers = {
31
"accept": "application/json",
32
"content-type": "application/json",
33
"x-zerogpu-token": conversation.zerogpu_token,
34
"x-zerogpu-uuid": conversation.zerogpu_uuid,
35
"referer": cls.referer,
36
}
37
if method == "post":
38
return session.post(f"{cls.url}/gradio_api/queue/join?__theme=light", **{
39
"headers": {k: v for k, v in headers.items() if v is not None},
40
"json": {"data": data,"event_data":None,"fn_index":2,"trigger_id":4,"session_hash":conversation.session_hash}
41
42
})
43
return session.get(f"{cls.url}/gradio_api/queue/data?session_hash={conversation.session_hash}", **{
44
"headers": {
45
"accept": "text/event-stream",
46
"content-type": "application/json",
47
"referer": cls.referer,
48
}
49
})
50
27
51
@classmethod
28
52
async def create_async_generator(
29
53
cls,
@@ -43,44 +67,49 @@ class BlackForestLabsFlux1Dev(AsyncGeneratorProvider, ProviderModelMixin):
43
67
**kwargs
44
68
) -> AsyncResult:
45
69
model = cls.get_model(model)
46
headers = {
47
"Content-Type": "application/json",
48
"Accept": "application/json",
49
}
50
async with ClientSession(headers=headers) as session:
70
async with StreamSession(impersonate="chrome", proxy=proxy) as session:
51
71
prompt = format_image_prompt(messages, prompt)
52
data = {
53
"data": [prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps]
54
}
55
if zerogpu_token is None:
56
zerogpu_uuid, zerogpu_token = await get_zerogpu_token(cls.space, session, JsonConversation(), cookies)
57
headers = {
58
"x-zerogpu-token": zerogpu_token,
59
"x-zerogpu-uuid": zerogpu_uuid,
60
}
61
headers = {k: v for k, v in headers.items() if v is not None}
62
async with session.post(f"{cls.url}{cls.api_endpoint}", json=data, proxy=proxy, headers=headers) as response:
72
data = [prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps]
73
conversation = JsonConversation(zerogpu_token=zerogpu_token, zerogpu_uuid=zerogpu_uuid, session_hash=uuid.uuid4().hex)
74
if conversation.zerogpu_token is None:
75
conversation.zerogpu_uuid, conversation.zerogpu_token = await get_zerogpu_token(cls.space, session, conversation, cookies)
76
async with cls.run(f"post", session, conversation, data) as response:
63
77
await raise_for_status(response)
64
event_id = (await response.json()).get("event_id")
65
async with session.get(f"{cls.url}{cls.api_endpoint}/{event_id}") as event_response:
78
assert (await response.json()).get("event_id")
79
async with cls.run("get", session, conversation) as event_response:
66
80
await raise_for_status(event_response)
67
event = None
68
async for chunk in event_response.content:
69
if chunk.startswith(b"event: "):
70
event = chunk[7:].decode(errors="replace").strip()
81
async for chunk in event_response.iter_lines():
71
82
if chunk.startswith(b"data: "):
72
if event == "error":
73
raise ResponseError(f"GPU token limit exceeded: {chunk.decode(errors='replace')}")
74
if event in ("complete", "generating"):
75
try:
76
data = json.loads(chunk[6:])
77
if data is None:
78
continue
79
url = data[0]["url"]
80
except (json.JSONDecodeError, KeyError, TypeError) as e:
81
raise RuntimeError(f"Failed to parse image URL: {chunk.decode(errors='replace')}", e)
82
if event == "generating":
83
yield ImagePreview(url, prompt)
84
else:
85
yield ImageResponse(url, prompt)
83
try:
84
json_data = json.loads(chunk[6:])
85
if json_data is None:
86
continue
87
if json_data.get('msg') == 'log':
88
yield Reasoning(status=json_data["log"])
89
90
if json_data.get('msg') == 'progress':
91
if 'progress_data' in json_data:
92
if json_data['progress_data']:
93
progress = json_data['progress_data'][0]
94
yield Reasoning(status=f"{progress['desc']} {progress['index']}/{progress['length']}")
95
else:
96
yield Reasoning(status=f"Generating")
97
98
elif json_data.get('msg') == 'process_generating':
99
for item in json_data['output']['data'][0]:
100
if isinstance(item, dict) and "url" in item:
101
yield ImagePreview(item["url"], prompt)
102
elif isinstance(item, list) and len(item) > 2 and "url" in item[1]:
103
yield ImagePreview(item[2], prompt)
104
105
elif json_data.get('msg') == 'process_completed':
106
if 'output' in json_data and 'error' in json_data['output']:
107
json_data['output']['error'] = json_data['output']['error'].split(" <a ")[0]
108
raise ResponseError(json_data['output']['error'])
109
if 'output' in json_data and 'data' in json_data['output']:
110
yield Reasoning(status="Finished")
111
if len(json_data['output']['data']) > 0:
112
yield ImageResponse(json_data['output']['data'][0]["url"], prompt)
86
113
break
114
except (json.JSONDecodeError, KeyError, TypeError) as e:
115
raise RuntimeError(f"Failed to parse message: {chunk.decode(errors='replace')}", e)
@@ -14,6 +14,7 @@ from .raise_for_status import raise_for_status
14
14
class FluxDev(BlackForestLabsFlux1Dev):
15
15
url = "https://roxky-flux-1-dev.hf.space"
16
16
space = "roxky/FLUX.1-dev"
17
referer = f"{url}/?__theme=light"
17
18
18
19
class G4F(Janus_Pro_7B):
19
20
label = "G4F framework"
@@ -19,7 +19,6 @@ from ... import version, models
19
19
from ... import ChatCompletion, get_model_and_provider
20
20
from ... import debug
21
21
22
logger = logging.getLogger(__name__)
23
22
conversations: dict[dict[str, BaseConversation]] = {}
24
23
25
24
class Api:
@@ -156,7 +155,6 @@ class Api:
156
155
has_images="images" in kwargs,
157
156
)
158
157
except Exception as e:
159
logger.exception(e)
160
158
debug.error(e)
161
159
yield self._format_json('error', type(e).__name__, message=get_error_message(e))
162
160
return
@@ -186,7 +184,6 @@ class Api:
186
184
else:
187
185
yield self._format_json("conversation_id", conversation_id)
188
186
elif isinstance(chunk, Exception):
189
logger.exception(chunk)
190
187
debug.error(chunk)
191
188
yield self._format_json('message', get_error_message(chunk), error=type(chunk).__name__)
192
189
elif isinstance(chunk, PreviewResponse):
@@ -222,7 +219,6 @@ class Api:
222
219
yield self._format_json("content", str(chunk))
223
220
yield from self._yield_logs()
224
221
except Exception as e:
225
logger.exception(e)
226
222
debug.error(e)
227
223
yield from self._yield_logs()
228
224
yield self._format_json('error', type(e).__name__, message=get_error_message(e))