From 035daa225be058447a946b8e8b9ad1ef9b1e9a1f Mon Sep 17 00:00:00 2001 From: hlohaus <983577+hlohaus@users.noreply.github.com> Date: Thu, 6 Feb 2025 21:24:59 +0100 Subject: Add FluxDev to G4F provider Improve image preview in FluxDev Add zerogpu_token to FluxDev Add HuggingSpace header in Demo Add new window button in Demo --- g4f/Provider/hf_space/BlackForestLabsFlux1Dev.py | 24 +++++++--- .../hf_space/BlackForestLabsFlux1Schnell.py | 10 ++-- g4f/Provider/hf_space/G4F.py | 30 ++++++++++-- g4f/Provider/hf_space/Janus_Pro_7B.py | 17 +++++-- g4f/Provider/hf_space/raise_for_status.py | 24 ++++++++++ g4f/gui/client/demo.html | 54 +++++++++++++++++----- g4f/gui/client/static/js/chat.v1.js | 6 ++- 7 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 g4f/Provider/hf_space/raise_for_status.py diff --git a/g4f/Provider/hf_space/BlackForestLabsFlux1Dev.py b/g4f/Provider/hf_space/BlackForestLabsFlux1Dev.py index 60e6820d..dbd9fa0a 100644 --- a/g4f/Provider/hf_space/BlackForestLabsFlux1Dev.py +++ b/g4f/Provider/hf_space/BlackForestLabsFlux1Dev.py @@ -4,13 +4,16 @@ import json from aiohttp import ClientSession from ...typing import AsyncResult, Messages -from ...providers.response import ImageResponse, ImagePreview +from ...providers.response import ImageResponse, ImagePreview, JsonConversation from ...errors import ResponseError from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin from ..helper import format_image_prompt +from .Janus_Pro_7B import get_zerogpu_token +from .raise_for_status import raise_for_status class BlackForestLabsFlux1Dev(AsyncGeneratorProvider, ProviderModelMixin): url = "https://black-forest-labs-flux-1-dev.hf.space" + space = "black-forest-labs/FLUX.1-dev" api_endpoint = "/gradio_api/call/infer" working = True @@ -27,7 +30,6 @@ class BlackForestLabsFlux1Dev(AsyncGeneratorProvider, ProviderModelMixin): model: str, messages: Messages, prompt: str = None, - api_key: str = None, proxy: str = None, width: int = 1024, height: int = 1024, @@ -35,6 +37,9 @@ class BlackForestLabsFlux1Dev(AsyncGeneratorProvider, ProviderModelMixin): num_inference_steps: int = 28, seed: int = 0, randomize_seed: bool = True, + cookies: dict = None, + zerogpu_token: str = None, + zerogpu_uuid: str = "[object Object]", **kwargs ) -> AsyncResult: model = cls.get_model(model) @@ -42,18 +47,23 @@ class BlackForestLabsFlux1Dev(AsyncGeneratorProvider, ProviderModelMixin): "Content-Type": "application/json", "Accept": "application/json", } - if api_key is not None: - headers["Authorization"] = f"Bearer {api_key}" async with ClientSession(headers=headers) as session: prompt = format_image_prompt(messages, prompt) data = { "data": [prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps] } - async with session.post(f"{cls.url}{cls.api_endpoint}", json=data, proxy=proxy) as response: - response.raise_for_status() + if zerogpu_token is None: + zerogpu_uuid, zerogpu_token = await get_zerogpu_token(cls.space, session, JsonConversation(), cookies) + headers = { + "x-zerogpu-token": zerogpu_token, + "x-zerogpu-uuid": zerogpu_uuid, + } + headers = {k: v for k, v in headers.items() if v is not None} + async with session.post(f"{cls.url}{cls.api_endpoint}", json=data, proxy=proxy, headers=headers) as response: + await raise_for_status(response) event_id = (await response.json()).get("event_id") async with session.get(f"{cls.url}{cls.api_endpoint}/{event_id}") as event_response: - event_response.raise_for_status() + await raise_for_status(event_response) event = None async for chunk in event_response.content: if chunk.startswith(b"event: "): diff --git a/g4f/Provider/hf_space/BlackForestLabsFlux1Schnell.py b/g4f/Provider/hf_space/BlackForestLabsFlux1Schnell.py index 1f051bf7..4e313ae1 100644 --- a/g4f/Provider/hf_space/BlackForestLabsFlux1Schnell.py +++ b/g4f/Provider/hf_space/BlackForestLabsFlux1Schnell.py @@ -6,9 +6,9 @@ import json from ...typing import AsyncResult, Messages from ...providers.response import ImageResponse from ...errors import ResponseError -from ...requests.raise_for_status import raise_for_status from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin from ..helper import format_image_prompt +from .raise_for_status import raise_for_status class BlackForestLabsFlux1Schnell(AsyncGeneratorProvider, ProviderModelMixin): url = "https://black-forest-labs-flux-1-schnell.hf.space" @@ -38,13 +38,9 @@ class BlackForestLabsFlux1Schnell(AsyncGeneratorProvider, ProviderModelMixin): ) -> AsyncResult: model = cls.get_model(model) - width = max(32, width - (width % 8)) height = max(32, height - (height % 8)) - - if prompt is None: - prompt = format_image_prompt(messages) - + prompt = format_image_prompt(messages, prompt) payload = { "data": [ prompt, @@ -72,7 +68,7 @@ class BlackForestLabsFlux1Schnell(AsyncGeneratorProvider, ProviderModelMixin): event_type = event_parts[0].split(b': ')[1] data = event_parts[1] if event_type == b'error': - raise ResponseError(f"Error generating image: {data}") + raise ResponseError(f"Error generating image: {data.decode(errors='ignore')}") elif event_type == b'complete': json_data = json.loads(data) image_url = json_data[0]['url'] diff --git a/g4f/Provider/hf_space/G4F.py b/g4f/Provider/hf_space/G4F.py index 53bec3f4..e8cd8017 100644 --- a/g4f/Provider/hf_space/G4F.py +++ b/g4f/Provider/hf_space/G4F.py @@ -6,9 +6,14 @@ import asyncio from ...typing import AsyncResult, Messages from ...providers.response import ImageResponse, Reasoning -from ...requests.raise_for_status import raise_for_status from ..helper import format_image_prompt, get_random_string -from .Janus_Pro_7B import Janus_Pro_7B, JsonConversation, get_zerogpu_token +from .Janus_Pro_7B import Janus_Pro_7B, get_zerogpu_token +from .BlackForestLabsFlux1Dev import BlackForestLabsFlux1Dev +from .raise_for_status import raise_for_status + +class FluxDev(BlackForestLabsFlux1Dev): + url = "https://roxky-flux-1-dev.hf.space" + space = "roxky/FLUX.1-dev" class G4F(Janus_Pro_7B): label = "G4F framework" @@ -19,8 +24,8 @@ class G4F(Janus_Pro_7B): referer = f"{api_url}?__theme=light" default_model = "flux" - model_aliases = {"flux-schnell": default_model, "flux-dev": default_model} - image_models = [Janus_Pro_7B.default_image_model, default_model, *model_aliases.keys()] + model_aliases = {"flux-schnell": default_model} + image_models = [Janus_Pro_7B.default_image_model, default_model, "flux-dev", *model_aliases.keys()] models = [Janus_Pro_7B.default_model, *image_models] @classmethod @@ -38,6 +43,21 @@ class G4F(Janus_Pro_7B): zerogpu_uuid: str = "[object Object]", **kwargs ) -> AsyncResult: + if model == "flux-dev": + async for chunk in FluxDev.create_async_generator( + model, messages, + proxy=proxy, + prompt=prompt, + width=width, + height=height, + seed=seed, + cookies=cookies, + zerogpu_token=zerogpu_token, + zerogpu_uuid=zerogpu_uuid, + **kwargs + ): + yield chunk + return if cls.default_model not in model: async for chunk in super().create_async_generator( model, messages, @@ -96,6 +116,6 @@ class G4F(Janus_Pro_7B): task.add_done_callback(background_tasks.discard) while background_tasks: yield Reasoning(status=f"Generating {time.time() - started:.2f}s") - await asyncio.sleep(0.5) + await asyncio.sleep(0.2) yield await task yield Reasoning(status=f"Finished {time.time() - started:.2f}s") \ No newline at end of file diff --git a/g4f/Provider/hf_space/Janus_Pro_7B.py b/g4f/Provider/hf_space/Janus_Pro_7B.py index 604c6547..49b4f5bb 100644 --- a/g4f/Provider/hf_space/Janus_Pro_7B.py +++ b/g4f/Provider/hf_space/Janus_Pro_7B.py @@ -17,6 +17,7 @@ from ...image import to_bytes, is_accepted_format from ...cookies import get_cookies from ...errors import ResponseError from ... import debug +from .raise_for_status import raise_for_status class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin): space = "deepseek-ai/Janus-Pro-7B" @@ -125,6 +126,7 @@ class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin): async with cls.run("get", session, prompt, conversation, None, seed) as response: response: StreamResponse = response + counter = 3 async for line in response.iter_lines(): decoded_line = line.decode(errors="replace") if decoded_line.startswith('data: '): @@ -134,11 +136,18 @@ class Janus_Pro_7B(AsyncGeneratorProvider, ProviderModelMixin): yield Reasoning(status=json_data["log"]) if json_data.get('msg') == 'progress': - if 'progress_data' in json_data and json_data['progress_data']: - progress = json_data['progress_data'][0] - yield Reasoning(status=f"{progress['desc']} {progress['index']}/{progress['length']}") + if 'progress_data' in json_data: + if json_data['progress_data']: + progress = json_data['progress_data'][0] + yield Reasoning(status=f"{progress['desc']} {progress['index']}/{progress['length']}") + else: + yield Reasoning(status=f"Generating") + + elif json_data.get('msg') == 'heartbeat': + yield Reasoning(status=f"Generating{''.join(['.' for i in range(counter)])}") + counter += 1 - if json_data.get('msg') == 'process_completed': + elif json_data.get('msg') == 'process_completed': if 'output' in json_data and 'error' in json_data['output']: json_data['output']['error'] = json_data['output']['error'].split(" + @@ -193,22 +224,21 @@
- +
+ + +

Get Access Token

-