Spaces:
Running
Running
import gradio as gr | |
from app_logic import ( | |
build_space_from_image, | |
get_username_from_token, | |
preview_image_contents, | |
update_file_preview | |
) | |
def main_ui(): | |
with gr.Blocks(theme=gr.themes.Soft(), title="Image-to-Space Builder") as demo: | |
gr.Markdown( | |
""" | |
# 🖼️ Image-to-Space Builder | |
## Create a new Hugging Face Space directly from a repo-embedded image. | |
This tool extracts the file structure and content from an encrypted image (created with a tool like KeyLock) | |
and uses it to build and deploy a new Hugging Face Space. | |
""" | |
) | |
file_data_state = gr.State([]) | |
with gr.Row(): | |
with gr.Column(scale=1): | |
gr.Markdown("### 1. Upload & Preview Image") | |
repo_image_input = gr.Image(label="Repo-Embedded Image (PNG)", type="pil") | |
image_password_input = gr.Textbox(label="Image Decryption Password", type="password") | |
preview_button = gr.Button("Preview Contents", variant="secondary") | |
gr.Markdown("---") | |
gr.Markdown("### 2. Configure Your New Space") | |
api_token_input = gr.Textbox( | |
label="Hugging Face API Token (hf_xxx)", | |
type="password", | |
placeholder="Enter your write-permission token" | |
) | |
owner_input = gr.Textbox( | |
label="Owner (Username/Org)", | |
placeholder="Autofills from token if left blank" | |
) | |
space_name_input = gr.Textbox(label="New Space Name", placeholder="e.g., my-new-app") | |
sdk_input = gr.Dropdown( | |
label="Space SDK", | |
choices=["gradio", "streamlit", "docker", "static"], | |
value="gradio" | |
) | |
gr.Markdown("---") | |
gr.Markdown("### 3. Build It!") | |
create_button = gr.Button("Create Space from Image", variant="primary") | |
with gr.Column(scale=2): | |
gr.Markdown("### Status & Result") | |
output_status_md = gr.Markdown(label="Status") | |
with gr.Column(visible=False) as file_browser_ui: | |
gr.Markdown("### Image Contents Preview") | |
file_selector_dd = gr.Dropdown(label="Select file to preview", interactive=True) | |
file_preview_code = gr.Code(language="python", interactive=False, label="File Content") | |
def autofill_owner_if_empty(api_token, current_owner): | |
if not current_owner.strip(): | |
return get_username_from_token(api_token) | |
return current_owner | |
api_token_input.blur( | |
fn=autofill_owner_if_empty, | |
inputs=[api_token_input, owner_input], | |
outputs=[owner_input] | |
) | |
preview_button.click( | |
fn=preview_image_contents, | |
inputs=[repo_image_input, image_password_input], | |
outputs=[ | |
output_status_md, | |
file_browser_ui, | |
file_selector_dd, | |
file_preview_code, | |
file_data_state | |
] | |
) | |
file_selector_dd.change( | |
fn=update_file_preview, | |
inputs=[file_selector_dd, file_data_state], | |
outputs=[file_preview_code] | |
) | |
create_button.click( | |
fn=build_space_from_image, | |
inputs=[ | |
api_token_input, | |
repo_image_input, | |
image_password_input, | |
space_name_input, | |
owner_input, | |
sdk_input | |
], | |
outputs=[output_status_md] | |
) | |
return demo | |
if __name__ == "__main__": | |
demo = main_ui() | |
demo.launch(show_error=True, ssr_mode=False) |