|
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) |