broadfield-dev commited on
Commit
f558e4b
ยท
verified ยท
1 Parent(s): 0da8126

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -42
app.py CHANGED
@@ -3,7 +3,11 @@ from app_logic import (
3
  create_space,
4
  view_space_files,
5
  update_space_file,
 
 
6
  )
 
 
7
 
8
  # Gradio interface
9
  def main_ui():
@@ -11,32 +15,69 @@ def main_ui():
11
  gr.Markdown(
12
  """
13
  # ๐Ÿ› ๏ธ Hugging Face Space Builder
14
- Create, view, and update Hugging Face Spaces with a custom file structure defined via markdown input.
 
15
  """
16
  )
17
 
18
- with gr.Row():
19
- with gr.Column(scale=1):
20
- api_token_input = gr.Textbox(
21
- label="Hugging Face API Token",
22
- type="password",
23
- placeholder="Enter your HF token (hf_xxx)",
24
- info="Get your token from hf.co/settings/tokens. Needs 'write' access for creating/updating spaces."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  )
26
- with gr.Column(scale=2):
27
- gr.Markdown(" ") # Spacer or additional info can go here
28
-
 
 
 
29
  with gr.Tabs():
30
  with gr.TabItem("๐Ÿš€ Create New Space"):
 
31
  with gr.Row():
32
  space_name_create_input = gr.Textbox(label="Space Name", placeholder="my-awesome-app (no slashes)", scale=2)
33
  owner_create_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank for your HF username", scale=1)
34
-
35
  sdk_create_input = gr.Dropdown(
36
- label="Space SDK",
37
- choices=["gradio", "streamlit", "docker", "static"],
38
- value="gradio",
39
- info="Select the type of Space (Gradio, Streamlit, etc.)."
40
  )
41
  markdown_input_create = gr.Textbox(
42
  label="Markdown File Structure & Content",
@@ -47,21 +88,15 @@ Example:
47
  # ```python
48
  print("Hello World!")
49
  # ```
50
-
51
- ### File: README.md
52
- # ```markdown
53
- # My Awesome App
54
- This is a test.
55
- # ```
56
- """, # Triple backticks within the example are commented out for display
57
- lines=15,
58
- interactive=True,
59
- info="Define files using '### File: path/to/your/file.ext' followed by content, optionally in ```code blocks```."
60
  )
61
  create_btn = gr.Button("Create Space", variant="primary")
62
  create_output_md = gr.Markdown(label="Result")
63
 
64
  with gr.TabItem("๐Ÿ“„ View Space Files"):
 
65
  with gr.Row():
66
  space_name_view_input = gr.Textbox(label="Space Name", placeholder="my-existing-app (no slashes)", scale=2)
67
  owner_view_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank if it's your space", scale=1)
@@ -69,44 +104,42 @@ This is a test.
69
  view_output_md = gr.Markdown(label="Files in Space")
70
 
71
  with gr.TabItem("โœ๏ธ Update Space File"):
 
72
  with gr.Row():
73
  space_name_update_input = gr.Textbox(label="Space Name", placeholder="my-target-app (no slashes)", scale=2)
74
  owner_update_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank if it's your space", scale=1)
75
-
76
  file_path_update_input = gr.Textbox(
77
- label="File Path in Repository",
78
- placeholder="e.g., app.py or src/utils.py",
79
- info="The full path to the file within the space you want to update/create."
80
- )
81
  file_content_update_input = gr.Textbox(
82
- label="New File Content",
83
- placeholder="Enter the complete new content for the file.",
84
- lines=10,
85
- interactive=True
86
  )
87
  commit_message_update_input = gr.Textbox(
88
- label="Commit Message",
89
- placeholder="e.g., Update app.py with new feature",
90
- info="Describe the changes you're making."
91
  )
92
  update_btn = gr.Button("Update File", variant="primary")
93
  update_output_md = gr.Markdown(label="Result")
94
 
95
  # Event handlers
 
 
96
  create_btn.click(
97
  fn=create_space,
98
- inputs=[api_token_input, space_name_create_input, owner_create_input, sdk_create_input, markdown_input_create],
99
  outputs=create_output_md,
100
  )
101
  view_btn.click(
102
  fn=view_space_files,
103
- inputs=[api_token_input, space_name_view_input, owner_view_input],
104
  outputs=view_output_md,
105
  )
106
  update_btn.click(
107
  fn=update_space_file,
108
  inputs=[
109
- api_token_input,
110
  space_name_update_input,
111
  owner_update_input,
112
  file_path_update_input,
@@ -115,7 +148,6 @@ This is a test.
115
  ],
116
  outputs=update_output_md,
117
  )
118
-
119
  return demo
120
 
121
  if __name__ == "__main__":
 
3
  create_space,
4
  view_space_files,
5
  update_space_file,
6
+ load_token_from_image_and_set_env, # New import
7
+ KEYLOCK_DECODE_AVAILABLE # New import
8
  )
9
+ # PIL Image for type hint if needed, though gr.Image handles it
10
+ # from PIL import Image
11
 
12
  # Gradio interface
13
  def main_ui():
 
15
  gr.Markdown(
16
  """
17
  # ๐Ÿ› ๏ธ Hugging Face Space Builder
18
+ Create, view, and update Hugging Face Spaces.
19
+ Provide your Hugging Face API token directly or load it from a steganographic image.
20
  """
21
  )
22
 
23
+ # --- Authentication Section ---
24
+ with gr.Accordion("๐Ÿ”‘ Authentication Methods", open=True):
25
+ gr.Markdown(
26
+ """
27
+ **Token Precedence:**
28
+ 1. If a token is successfully loaded from an image (and `HF_TOKEN` is set in the environment), it will be used.
29
+ 2. Otherwise, the token entered in the 'Enter API Token Directly' textbox will be used.
30
+ 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.
31
+ """
32
+ )
33
+ gr.Markdown("---")
34
+ gr.Markdown("### Method 1: Enter API Token Directly")
35
+ api_token_ui_input = gr.Textbox( # Renamed to avoid confusion with resolved_api_token
36
+ label="Hugging Face API Token (hf_xxx)",
37
+ type="password",
38
+ placeholder="Enter your HF token OR load from image below",
39
+ info="Get from hf.co/settings/tokens. Needs 'write' access. This is used if image loading fails or is not used."
40
+ )
41
+
42
+ if KEYLOCK_DECODE_AVAILABLE:
43
+ gr.Markdown("---")
44
+ gr.Markdown("### Method 2: Load API Token from Steganographic Image")
45
+ with gr.Row():
46
+ keylock_image_input = gr.Image(
47
+ label="Stego Image (PNG containing HF_TOKEN)",
48
+ type="pil", # Pass PIL image to backend
49
+ # sources=["upload"], # Optional: Restrict to upload only
50
+ # height=200, # Optional: for display consistency
51
+ # width=200,
52
+ )
53
+ keylock_password_input = gr.Textbox(
54
+ label="Image Password",
55
+ type="password",
56
+ placeholder="Password for image decryption"
57
+ )
58
+ keylock_decode_button = gr.Button("Load Token from Image", variant="secondary")
59
+ keylock_status_output = gr.Markdown(label="Image Decoding Status", value="Status will appear here...")
60
+
61
+ keylock_decode_button.click(
62
+ fn=load_token_from_image_and_set_env,
63
+ inputs=[keylock_image_input, keylock_password_input],
64
+ outputs=[keylock_status_output]
65
  )
66
+ else:
67
+ gr.Markdown(
68
+ "_(Image decoding feature (KeyLock-Decode) is disabled as the library could not be imported.)_"
69
+ )
70
+
71
+ # --- Main Application Tabs ---
72
  with gr.Tabs():
73
  with gr.TabItem("๐Ÿš€ Create New Space"):
74
+ # ... (rest of the Create Space UI, inputs will use api_token_ui_input)
75
  with gr.Row():
76
  space_name_create_input = gr.Textbox(label="Space Name", placeholder="my-awesome-app (no slashes)", scale=2)
77
  owner_create_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank for your HF username", scale=1)
 
78
  sdk_create_input = gr.Dropdown(
79
+ label="Space SDK", choices=["gradio", "streamlit", "docker", "static"], value="gradio",
80
+ info="Select the type of Space."
 
 
81
  )
82
  markdown_input_create = gr.Textbox(
83
  label="Markdown File Structure & Content",
 
88
  # ```python
89
  print("Hello World!")
90
  # ```
91
+ """,
92
+ lines=15, interactive=True,
93
+ info="Define files using '### File: path/to/your/file.ext' followed by content."
 
 
 
 
 
 
 
94
  )
95
  create_btn = gr.Button("Create Space", variant="primary")
96
  create_output_md = gr.Markdown(label="Result")
97
 
98
  with gr.TabItem("๐Ÿ“„ View Space Files"):
99
+ # ... (rest of the View Space Files UI, inputs will use api_token_ui_input)
100
  with gr.Row():
101
  space_name_view_input = gr.Textbox(label="Space Name", placeholder="my-existing-app (no slashes)", scale=2)
102
  owner_view_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank if it's your space", scale=1)
 
104
  view_output_md = gr.Markdown(label="Files in Space")
105
 
106
  with gr.TabItem("โœ๏ธ Update Space File"):
107
+ # ... (rest of the Update Space File UI, inputs will use api_token_ui_input)
108
  with gr.Row():
109
  space_name_update_input = gr.Textbox(label="Space Name", placeholder="my-target-app (no slashes)", scale=2)
110
  owner_update_input = gr.Textbox(label="Owner Username/Org", placeholder="Leave blank if it's your space", scale=1)
 
111
  file_path_update_input = gr.Textbox(
112
+ label="File Path in Repository", placeholder="e.g., app.py or src/utils.py",
113
+ info="The full path to the file within the space."
114
+ )
 
115
  file_content_update_input = gr.Textbox(
116
+ label="New File Content", placeholder="Enter the complete new content for the file.",
117
+ lines=10, interactive=True
 
 
118
  )
119
  commit_message_update_input = gr.Textbox(
120
+ label="Commit Message", placeholder="e.g., Update app.py with new feature",
121
+ info="Describe the changes."
 
122
  )
123
  update_btn = gr.Button("Update File", variant="primary")
124
  update_output_md = gr.Markdown(label="Result")
125
 
126
  # Event handlers
127
+ # Pass the UI token input to all backend functions.
128
+ # The backend's _get_api_token helper will decide the actual token to use.
129
  create_btn.click(
130
  fn=create_space,
131
+ inputs=[api_token_ui_input, space_name_create_input, owner_create_input, sdk_create_input, markdown_input_create],
132
  outputs=create_output_md,
133
  )
134
  view_btn.click(
135
  fn=view_space_files,
136
+ inputs=[api_token_ui_input, space_name_view_input, owner_view_input],
137
  outputs=view_output_md,
138
  )
139
  update_btn.click(
140
  fn=update_space_file,
141
  inputs=[
142
+ api_token_ui_input,
143
  space_name_update_input,
144
  owner_update_input,
145
  file_path_update_input,
 
148
  ],
149
  outputs=update_output_md,
150
  )
 
151
  return demo
152
 
153
  if __name__ == "__main__":