Spaces:
Sleeping
Sleeping
File size: 7,657 Bytes
60d3ef3 f558e4b 8bd1285 f558e4b 8bd1285 60d3ef3 f558e4b 60d3ef3 f558e4b 6063cc9 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 f558e4b 60d3ef3 |
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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
import gradio as gr
from app_logic import (
create_space,
view_space_files,
update_space_file,
load_token_from_image_and_set_env, # New import
KEYLOCK_DECODE_AVAILABLE # New import
)
# PIL Image for type hint if needed, though gr.Image handles it
# from PIL import Image
# Gradio interface
def main_ui():
with gr.Blocks(theme=gr.themes.Soft(primary_hue=gr.themes.colors.blue, secondary_hue=gr.themes.colors.sky), title="Hugging Face Space Builder") as demo:
gr.Markdown(
"""
# π οΈ Hugging Face Space Builder
Create, view, and update Hugging Face Spaces.
Provide your Hugging Face API token directly or load it from a steganographic image.
"""
)
# --- Authentication Section ---
with gr.Accordion("π Authentication Methods", open=True):
gr.Markdown(
"""
**Token Precedence:**
1. If a token is successfully loaded from an image (and `HF_TOKEN` is set in the environment), it will be used.
2. Otherwise, the token entered in the 'Enter API Token Directly' textbox will be used.
3. If a system-wide `HF_TOKEN` environment variable was already set when this app started, it might also be used if methods 1 & 2 don't yield a token.
"""
)
gr.Markdown("---")
gr.Markdown("### Method 1: Enter API Token Directly")
api_token_ui_input = gr.Textbox( # Renamed to avoid confusion with resolved_api_token
label="Hugging Face API Token (hf_xxx)",
type="password",
placeholder="Enter your HF token OR load from image below",
info="Get from hf.co/settings/tokens. Needs 'write' access. This is used if image loading fails or is not used."
)
if KEYLOCK_DECODE_AVAILABLE:
gr.Markdown("---")
gr.Markdown("### Method 2: Load API Token from Steganographic Image")
with gr.Row():
keylock_image_input = gr.Image(
label="Stego Image (PNG containing HF_TOKEN)",
type="pil", # Pass PIL image to backend
# sources=["upload"], # Optional: Restrict to upload only
# height=200, # Optional: for display consistency
# width=200,
)
keylock_password_input = gr.Textbox(
label="Image Password",
type="password",
placeholder="Password for image decryption"
)
keylock_decode_button = gr.Button("Load Token from Image", variant="secondary")
keylock_status_output = gr.Markdown(label="Image Decoding Status", value="Status will appear here...")
keylock_decode_button.click(
fn=load_token_from_image_and_set_env,
inputs=[keylock_image_input, keylock_password_input],
outputs=[keylock_status_output]
)
else:
gr.Markdown(
"_(Image decoding feature (KeyLock-Decode) is disabled as the library could not be imported.)_"
)
# --- Main Application Tabs ---
with gr.Tabs():
with gr.TabItem("π Create New Space"):
# ... (rest of the Create Space UI, inputs will use api_token_ui_input)
with gr.Row():
space_name_create_input = gr.Textbox(label="Space Name", placeholder="my-awesome-app (no slashes)", scale=2)
owner_create_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank for your HF username", scale=1)
sdk_create_input = gr.Dropdown(
label="Space SDK", choices=["gradio", "streamlit", "docker", "static"], value="gradio",
info="Select the type of Space."
)
markdown_input_create = gr.Textbox(
label="Markdown File Structure & Content",
placeholder="""Define files using '### File: path/to/file.ext'
followed by content, optionally in code blocks.
Example:
### File: app.py
# ```python
print("Hello World!")
# ```
""",
lines=15, interactive=True,
info="Define files using '### File: path/to/your/file.ext' followed by content."
)
create_btn = gr.Button("Create Space", variant="primary")
create_output_md = gr.Markdown(label="Result")
with gr.TabItem("π View Space Files"):
# ... (rest of the View Space Files UI, inputs will use api_token_ui_input)
with gr.Row():
space_name_view_input = gr.Textbox(label="Space Name", placeholder="my-existing-app (no slashes)", scale=2)
owner_view_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank if it's your space", scale=1)
view_btn = gr.Button("List Files", variant="primary")
view_output_md = gr.Markdown(label="Files in Space")
with gr.TabItem("βοΈ Update Space File"):
# ... (rest of the Update Space File UI, inputs will use api_token_ui_input)
with gr.Row():
space_name_update_input = gr.Textbox(label="Space Name", placeholder="my-target-app (no slashes)", scale=2)
owner_update_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank if it's your space", scale=1)
file_path_update_input = gr.Textbox(
label="File Path in Repository", placeholder="e.g., app.py or src/utils.py",
info="The full path to the file within the space."
)
file_content_update_input = gr.Textbox(
label="New File Content", placeholder="Enter the complete new content for the file.",
lines=10, interactive=True
)
commit_message_update_input = gr.Textbox(
label="Commit Message", placeholder="e.g., Update app.py with new feature",
info="Describe the changes."
)
update_btn = gr.Button("Update File", variant="primary")
update_output_md = gr.Markdown(label="Result")
# Event handlers
# Pass the UI token input to all backend functions.
# The backend's _get_api_token helper will decide the actual token to use.
create_btn.click(
fn=create_space,
inputs=[api_token_ui_input, space_name_create_input, owner_create_input, sdk_create_input, markdown_input_create],
outputs=create_output_md,
)
view_btn.click(
fn=view_space_files,
inputs=[api_token_ui_input, space_name_view_input, owner_view_input],
outputs=view_output_md,
)
update_btn.click(
fn=update_space_file,
inputs=[
api_token_ui_input,
space_name_update_input,
owner_update_input,
file_path_update_input,
file_content_update_input,
commit_message_update_input,
],
outputs=update_output_md,
)
return demo
if __name__ == "__main__":
demo = main_ui()
demo.launch() |