Nymbo commited on
Commit
dd21ab3
·
verified ·
1 Parent(s): 76ebcb5

enabling MCP server

Browse files
Files changed (1) hide show
  1. app.py +83 -29
app.py CHANGED
@@ -4,8 +4,8 @@ import io
4
  import random
5
  import os
6
  import time
 
7
  from PIL import Image
8
- from deep_translator import GoogleTranslator
9
  import json
10
 
11
  # Project by Nymbo
@@ -15,36 +15,76 @@ API_TOKEN = os.getenv("HF_READ_TOKEN")
15
  headers = {"Authorization": f"Bearer {API_TOKEN}"}
16
  timeout = 100
17
 
18
- # Function to query the API and return the generated image
19
- def query(prompt, is_negative=False, steps=35, cfg_scale=7, sampler="DPM++ 2M Karras", seed=-1, strength=0.7, width=1024, height=1024):
20
- if prompt == "" or prompt is None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  return None
22
 
23
  key = random.randint(0, 999)
24
-
25
- API_TOKEN = random.choice([os.getenv("HF_READ_TOKEN")])
26
- headers = {"Authorization": f"Bearer {API_TOKEN}"}
27
-
28
- # Translate the prompt from Russian to English if necessary
29
- prompt = GoogleTranslator(source='ru', target='en').translate(prompt)
30
- print(f'\033[1mGeneration {key} translation:\033[0m {prompt}')
31
 
32
- # Add some extra flair to the prompt
33
- prompt = f"{prompt} | ultra detail, ultra elaboration, ultra quality, perfect."
34
- print(f'\033[1mGeneration {key}:\033[0m {prompt}')
35
-
36
- # Prepare the payload for the API call, including width and height
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  payload = {
38
- "inputs": prompt,
39
- "is_negative": is_negative,
40
- "steps": steps,
41
- "cfg_scale": cfg_scale,
42
- "seed": seed if seed != -1 else random.randint(1, 1000000000),
43
- "strength": strength,
44
- "parameters": {
45
- "width": width, # Pass the width to the API
46
- "height": height # Pass the height to the API
47
- }
48
  }
49
 
50
  # Send the request to the API and handle the response
@@ -55,12 +95,12 @@ def query(prompt, is_negative=False, steps=35, cfg_scale=7, sampler="DPM++ 2M Ka
55
  if response.status_code == 503:
56
  raise gr.Error(f"{response.status_code} : The model is being loaded")
57
  raise gr.Error(f"{response.status_code}")
58
-
59
  try:
60
  # Convert the response content into an image
61
  image_bytes = response.content
62
  image = Image.open(io.BytesIO(image_bytes))
63
- print(f'\033[1mGeneration {key} completed!\033[0m ({prompt})')
64
  return image
65
  except Exception as e:
66
  print(f"Error when trying to open the image: {e}")
@@ -110,7 +150,21 @@ with gr.Blocks(theme='Nymbo/Nymbo_Theme', css=css) as app:
110
  image_output = gr.Image(type="pil", label="Image Output", elem_id="gallery")
111
 
112
  # Bind the button to the query function with the added width and height inputs
113
- text_button.click(query, inputs=[text_prompt, negative_prompt, steps, cfg, method, seed, strength, width, height], outputs=image_output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
  # Launch the Gradio app
116
  app.launch(show_api=True, share=False, mcp_server=True)
 
4
  import random
5
  import os
6
  import time
7
+ from typing import Optional
8
  from PIL import Image
 
9
  import json
10
 
11
  # Project by Nymbo
 
15
  headers = {"Authorization": f"Bearer {API_TOKEN}"}
16
  timeout = 100
17
 
18
+ def query(
19
+ prompt: str,
20
+ negative_prompt: str = "",
21
+ steps: int = 35,
22
+ cfg_scale: float = 7,
23
+ sampler: str = "DPM++ 2M Karras",
24
+ seed: int = -1,
25
+ strength: float = 0.7,
26
+ width: int = 1024,
27
+ height: int = 1024,
28
+ ) -> Optional[Image.Image]:
29
+ """Generate an image from a text prompt using FLUX.1-Krea via the Hugging Face Inference API.
30
+
31
+ This function is exposed as an MCP tool via Gradio. It accepts common text-to-image
32
+ parameters and returns a single generated image.
33
+
34
+ Args:
35
+ prompt: The main text prompt describing the desired image. Required.
36
+ negative_prompt: Text describing what should be avoided in the image.
37
+ steps: Number of denoising steps (quality vs speed). Typical range 1–100.
38
+ cfg_scale: Classifier-free guidance scale (adherence to prompt). Typical range 1–20.
39
+ sampler: Sampling/scheduler method name. If unsupported by the backend, it may be ignored.
40
+ seed: Random seed. Use -1 for a random seed on each call.
41
+ strength: Image-to-image strength (0–1). Not used for pure text-to-image but included for compatibility.
42
+ width: Output image width in pixels. Usually multiples of 32.
43
+ height: Output image height in pixels. Usually multiples of 32.
44
+
45
+ Returns:
46
+ A PIL.Image if generation succeeds; otherwise None.
47
+
48
+ Raises:
49
+ gr.Error: If the backend returns a non-200 HTTP status.
50
+ """
51
+ if not prompt:
52
  return None
53
 
54
  key = random.randint(0, 999)
 
 
 
 
 
 
 
55
 
56
+ api_token = os.getenv("HF_READ_TOKEN")
57
+ if not api_token:
58
+ raise gr.Error("Missing HF_READ_TOKEN environment variable.")
59
+
60
+ headers = {"Authorization": f"Bearer {api_token}"}
61
+
62
+ # Slightly augment the prompt for higher quality
63
+ prompt_aug = f"{prompt} | ultra detail, ultra elaboration, ultra quality, perfect."
64
+ print(f'\033[1mGeneration {key}:\033[0m {prompt_aug}')
65
+
66
+ # Compute seed value
67
+ seed_value = seed if seed != -1 else random.randint(1, 1_000_000_000)
68
+
69
+ # Prepare payload aligned with HF Inference API conventions
70
+ parameters = {
71
+ "num_inference_steps": steps,
72
+ "guidance_scale": cfg_scale,
73
+ "width": width,
74
+ "height": height,
75
+ "seed": seed_value,
76
+ # Best-effort: some backends accept scheduler/sampler names; safe to send.
77
+ "scheduler": sampler,
78
+ }
79
+ if negative_prompt and negative_prompt.strip():
80
+ parameters["negative_prompt"] = negative_prompt
81
+ # Include strength only if meaningful
82
+ if 0 < strength <= 1:
83
+ parameters["strength"] = strength
84
+
85
  payload = {
86
+ "inputs": prompt_aug,
87
+ "parameters": parameters,
 
 
 
 
 
 
 
 
88
  }
89
 
90
  # Send the request to the API and handle the response
 
95
  if response.status_code == 503:
96
  raise gr.Error(f"{response.status_code} : The model is being loaded")
97
  raise gr.Error(f"{response.status_code}")
98
+
99
  try:
100
  # Convert the response content into an image
101
  image_bytes = response.content
102
  image = Image.open(io.BytesIO(image_bytes))
103
+ print(f'\033[1mGeneration {key} completed!\033[0m ({prompt_aug})')
104
  return image
105
  except Exception as e:
106
  print(f"Error when trying to open the image: {e}")
 
150
  image_output = gr.Image(type="pil", label="Image Output", elem_id="gallery")
151
 
152
  # Bind the button to the query function with the added width and height inputs
153
+ text_button.click(
154
+ query,
155
+ inputs=[
156
+ text_prompt,
157
+ negative_prompt,
158
+ steps,
159
+ cfg,
160
+ method,
161
+ seed,
162
+ strength,
163
+ width,
164
+ height,
165
+ ],
166
+ outputs=image_output,
167
+ )
168
 
169
  # Launch the Gradio app
170
  app.launch(show_api=True, share=False, mcp_server=True)