File size: 4,571 Bytes
ea02521
2a06b1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import gradio as gr
import fal_client
import os
from typing import Optional

# It is recommended to create this as a Secret on your Hugging Face Space
# For example: FAL_KEY = "fal_key_..."
FAL_KEY = os.getenv("FAL_KEY", "")

# Set the key for the fal_client
if FAL_KEY:
    fal_client.api_key = FAL_KEY

def get_fal_key():
    """Checks for the FAL_KEY and raises a Gradio error if it's not set."""
    if not FAL_KEY:
        raise gr.Error("FAL_KEY is not set. Please add it to your Hugging Face Space secrets.")

def generate_image(prompt: str, image: Optional[str] = None) -> str:
    """
    Generates or edits an image.
    - If an image filepath is provided, it performs image-to-image editing.
    - Otherwise, it performs text-to-image generation.
    """
    get_fal_key()

    if image:
        # Image-to-Image: Upload the local file to get a public URL
        image_url = fal_client.upload_file(image)
        result = fal_client.run(
            "fal-ai/nano-banana/edit",
            arguments={
                "prompt": prompt,
                "image_url": image_url,
            },
        )
    else:
        # Text-to-Image
        result = fal_client.run(
            "fal-ai/nano-banana",
            arguments={
                "prompt": prompt,
            },
        )
    return result["images"][0]["url"]

def multi_image_edit(prompt: str, images: list[str]) -> list[str]:
    """Edits multiple images based on a text prompt."""
    get_fal_key()

    if not images:
        raise gr.Error("Please upload at least one image.")

    output_images = []
    for image_path in images:
        # Upload each image and get its URL
        image_url = fal_client.upload_file(image_path)
        result = fal_client.run(
            "fal-ai/nano-banana/edit",
            arguments={
                "prompt": prompt,
                "image_url": image_url,
            },
        )
        output_images.append(result["images"][0]["url"])

    return output_images

# --- Gradio App UI ---
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# Nano Banana Image Generation")
    gr.Markdown("Generate or edit images with FAL. **Sign in with Hugging Face to begin.**")
    
    login_button = gr.LoginButton()
    
    # This entire Column will be hidden until the user logs in
    main_interface = gr.Column(visible=False)

    with main_interface:
        gr.Markdown("## Welcome! You are logged in.")
        with gr.Tabs():
            with gr.TabItem("Generate"):
                with gr.Row():
                    with gr.Column(scale=1):
                        prompt_input = gr.Textbox(label="Prompt", placeholder="A delicious looking pizza")
                        image_input = gr.Image(type="filepath", label="Input Image (Optional)")
                        generate_button = gr.Button("Generate", variant="primary")
                    with gr.Column(scale=1):
                        generate_output = gr.Image(label="Output")
                
                generate_button.click(
                    generate_image,
                    inputs=[prompt_input, image_input],
                    outputs=[generate_output],
                )

            with gr.TabItem("Multi-Image Edit"):
                with gr.Row():
                    with gr.Column(scale=1):
                        multi_prompt_input = gr.Textbox(label="Prompt", placeholder="Make it black and white")
                        multi_image_input = gr.Gallery(label="Input Images", file_types=["image"])
                        multi_edit_button = gr.Button("Edit Images", variant="primary")
                    with gr.Column(scale=1):
                        multi_image_output = gr.Gallery(label="Output Images")
                
                multi_edit_button.click(
                    multi_image_edit,
                    inputs=[multi_prompt_input, multi_image_input],
                    outputs=[multi_image_output],
                )

    def show_app_on_login(profile: Optional[gr.OAuthProfile] = None):
        """
        Controls the visibility of the main UI.
        Gradio automatically injects `gr.OAuthProfile` if the user is logged in.
        """
        if profile:
            return gr.update(visible=True)
        return gr.update(visible=False)

    # When the app loads or the user logs in/out, this function will be called.
    # It receives the user's profile (or None) and updates the UI visibility.
    demo.load(show_app_on_login, inputs=None, outputs=main_interface)

if __name__ == "__main__":
    demo.launch()