multimodalart HF Staff commited on
Commit
0bc7df2
·
verified ·
1 Parent(s): 4f9dc02

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -75
app.py CHANGED
@@ -1,8 +1,9 @@
1
  import gradio as gr
2
  import fal_client
3
- from huggingface_hub import whoami
4
  import os
5
- from typing import Optional
 
 
6
 
7
  # It is recommended to create this as a Secret on your Hugging Face Space
8
  # For example: FAL_KEY = "fal_key_..."
@@ -17,115 +18,123 @@ def get_fal_key():
17
  if not FAL_KEY:
18
  raise gr.Error("FAL_KEY is not set. Please add it to your Hugging Face Space secrets.")
19
 
20
- def generate_image(prompt: str, image: Optional[str] = None) -> str:
21
- """
22
- Generates or edits an image.
23
- - If an image filepath is provided, it performs image-to-image editing.
24
- - Otherwise, it performs text-to-image generation.
25
- """
26
  get_fal_key()
27
-
28
  if image:
29
- # Image-to-Image: Upload the local file to get a public URL
30
  image_url = fal_client.upload_file(image)
31
  result = fal_client.run(
32
  "fal-ai/nano-banana/edit",
33
- arguments={
34
- "prompt": prompt,
35
- "image_url": image_url,
36
- },
37
  )
38
  else:
39
- # Text-to-Image
40
  result = fal_client.run(
41
- "fal-ai/nano-banana",
42
- arguments={
43
- "prompt": prompt,
44
- },
45
  )
46
  return result["images"][0]["url"]
47
 
48
- def multi_image_edit(prompt: str, images: list[str]) -> list[str]:
49
- """Edits multiple images based on a text prompt."""
50
  get_fal_key()
51
-
52
  if not images:
53
- raise gr.Error("Please upload at least one image.")
54
 
55
  output_images = []
56
  for image_path in images:
57
- # Upload each image and get its URL
58
  image_url = fal_client.upload_file(image_path)
59
  result = fal_client.run(
60
  "fal-ai/nano-banana/edit",
61
- arguments={
62
- "prompt": prompt,
63
- "image_url": image_url,
64
- },
65
  )
66
  output_images.append(result["images"][0]["url"])
67
-
68
  return output_images
69
 
70
  # --- Gradio App UI ---
71
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
72
  gr.Markdown("# Nano Banana Image Generation")
73
  gr.Markdown("Generate or edit images with FAL. **Sign in with Hugging Face to begin.**")
74
-
75
  login_button = gr.LoginButton()
76
-
77
- # This entire Column will be hidden until the user logs in
78
  main_interface = gr.Column(visible=False)
79
 
80
  with main_interface:
81
- gr.Markdown("## Welcome! You are logged in.")
82
- with gr.Tabs():
83
- with gr.TabItem("Generate"):
84
- with gr.Row():
85
- with gr.Column(scale=1):
86
- prompt_input = gr.Textbox(label="Prompt", placeholder="A delicious looking pizza")
87
- image_input = gr.Image(type="filepath", label="Input Image (Optional)")
88
- generate_button = gr.Button("Generate", variant="primary")
89
- with gr.Column(scale=1):
90
- generate_output = gr.Image(label="Output")
91
-
92
- generate_button.click(
93
- generate_image,
94
- inputs=[prompt_input, image_input],
95
- outputs=[generate_output],
96
  )
97
 
98
- with gr.TabItem("Multi-Image Edit"):
99
- with gr.Row():
100
- with gr.Column(scale=1):
101
- multi_prompt_input = gr.Textbox(label="Prompt", placeholder="Make it black and white")
102
- multi_image_input = gr.Gallery(label="Input Images", file_types=["image"])
103
- multi_edit_button = gr.Button("Edit Images", variant="primary")
104
- with gr.Column(scale=1):
105
- multi_image_output = gr.Gallery(label="Output Images")
106
-
107
- multi_edit_button.click(
108
- multi_image_edit,
109
- inputs=[multi_prompt_input, multi_image_input],
110
- outputs=[multi_image_output],
111
- )
112
 
113
- def show_app_on_login(profile: Optional[gr.OAuthProfile] = None, oauth_token: gr.OAuthToken = None):
 
 
 
 
 
 
 
 
 
 
 
114
  """
115
- Controls the visibility of the main UI.
116
- Gradio automatically injects `gr.OAuthProfile` if the user is logged in.
117
  """
118
-
119
- if profile:
120
- print(profile)
121
- user = whoami(token=oauth_token.token)
122
- print(user)
123
- return gr.update(visible=True)
124
- return gr.update(visible=False)
125
-
126
- # When the app loads or the user logs in/out, this function will be called.
127
- # It receives the user's profile (or None) and updates the UI visibility.
128
- demo.load(show_app_on_login, inputs=None, outputs=main_interface)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
  if __name__ == "__main__":
131
  demo.launch()
 
1
  import gradio as gr
2
  import fal_client
 
3
  import os
4
+ from typing import Optional, List
5
+
6
+ from huggingface_hub import whoami
7
 
8
  # It is recommended to create this as a Secret on your Hugging Face Space
9
  # For example: FAL_KEY = "fal_key_..."
 
18
  if not FAL_KEY:
19
  raise gr.Error("FAL_KEY is not set. Please add it to your Hugging Face Space secrets.")
20
 
21
+ def single_image_generation(prompt: str, image: Optional[str] = None) -> str:
22
+ """Handles text-to-image or single image-to-image."""
 
 
 
 
23
  get_fal_key()
 
24
  if image:
 
25
  image_url = fal_client.upload_file(image)
26
  result = fal_client.run(
27
  "fal-ai/nano-banana/edit",
28
+ arguments={"prompt": prompt, "image_url": image_url},
 
 
 
29
  )
30
  else:
 
31
  result = fal_client.run(
32
+ "fal-ai/nano-banana", arguments={"prompt": prompt}
 
 
 
33
  )
34
  return result["images"][0]["url"]
35
 
36
+ def multi_image_edit(prompt: str, images: List[str]) -> List[str]:
37
+ """Handles multi-image editing."""
38
  get_fal_key()
 
39
  if not images:
40
+ raise gr.Error("Please upload at least one image in the 'Multiple Images' tab.")
41
 
42
  output_images = []
43
  for image_path in images:
 
44
  image_url = fal_client.upload_file(image_path)
45
  result = fal_client.run(
46
  "fal-ai/nano-banana/edit",
47
+ arguments={"prompt": prompt, "image_url": image_url},
 
 
 
48
  )
49
  output_images.append(result["images"][0]["url"])
 
50
  return output_images
51
 
52
  # --- Gradio App UI ---
53
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
54
  gr.Markdown("# Nano Banana Image Generation")
55
  gr.Markdown("Generate or edit images with FAL. **Sign in with Hugging Face to begin.**")
56
+
57
  login_button = gr.LoginButton()
58
+ pro_message = gr.Markdown(visible=False)
 
59
  main_interface = gr.Column(visible=False)
60
 
61
  with main_interface:
62
+ gr.Markdown("## Welcome, PRO User!")
63
+ with gr.Row():
64
+ with gr.Column(scale=1):
65
+ prompt_input = gr.Textbox(
66
+ label="Prompt",
67
+ placeholder="A delicious looking pizza"
 
 
 
 
 
 
 
 
 
68
  )
69
 
70
+ with gr.Tabs():
71
+ with gr.TabItem("Single Image", id="single"):
72
+ image_input = gr.Image(
73
+ type="filepath",
74
+ label="Input Image (Optional for text-to-image)"
75
+ )
76
+ with gr.TabItem("Multiple Images", id="multiple"):
77
+ gallery_input = gr.Gallery(
78
+ label="Input Images"
79
+ )
 
 
 
 
80
 
81
+ generate_button = gr.Button("Generate", variant="primary")
82
+
83
+ with gr.Column(scale=1):
84
+ # A single gallery can handle one or many images
85
+ output_gallery = gr.Gallery(label="Output")
86
+
87
+ def unified_generator(
88
+ prompt: str,
89
+ current_tab: str,
90
+ single_image: Optional[str],
91
+ multi_images: Optional[List[str]],
92
+ ) -> List[str]:
93
  """
94
+ A single handler that routes to the correct function based on the active tab.
 
95
  """
96
+ if current_tab == "multiple":
97
+ return multi_image_edit(prompt, multi_images)
98
+ else: # Handles both text-to-image and single image-to-image
99
+ result_url = single_image_generation(prompt, single_image)
100
+ return [result_url]
101
+
102
+ # The `select` event on the tabs gives us the active tab's ID
103
+ selected_tab = gr.Textbox(value="single", visible=False)
104
+ for tab in demo.load_queue[0][0].children[1].children: # Hacky way to get tabs
105
+ if isinstance(tab, gr.Tab):
106
+ tab.select(lambda: tab.id, None, selected_tab)
107
+
108
+ generate_button.click(
109
+ unified_generator,
110
+ inputs=[prompt_input, selected_tab, image_input, gallery_input],
111
+ outputs=[output_gallery],
112
+ )
113
+
114
+ def control_access(
115
+ profile: Optional[gr.OAuthProfile] = None,
116
+ oauth_token: Optional[gr.OAuthToken] = None
117
+ ):
118
+ """Controls UI visibility based on user's PRO status."""
119
+ if not profile or not oauth_token:
120
+ return gr.update(visible=False), gr.update(visible=False)
121
+ try:
122
+ user_info = whoami(token=oauth_token.token)
123
+ if user_info.get("isPro", False):
124
+ return gr.update(visible=True), gr.update(visible=False)
125
+ else:
126
+ message = (
127
+ "## ✨ Exclusive Access for PRO Users\n\n"
128
+ "Thank you for your interest! This feature is available exclusively for our Hugging Face **PRO** members.\n\n"
129
+ "To unlock this and many other benefits, please consider upgrading your account.\n\n"
130
+ "### [**Become a PRO Member Today!**](https://huggingface.co/pro)"
131
+ )
132
+ return gr.update(visible=False), gr.update(visible=True, value=message)
133
+ except Exception as e:
134
+ gr.Warning(f"Could not verify user status: {e}")
135
+ return gr.update(visible=False), gr.update(visible=False)
136
+
137
+ demo.load(control_access, inputs=None, outputs=[main_interface, pro_message])
138
 
139
  if __name__ == "__main__":
140
  demo.launch()