remove spaces name
Browse files
app.py
CHANGED
|
@@ -7603,14 +7603,8 @@ with gr.Blocks(
|
|
| 7603 |
with gr.Row():
|
| 7604 |
btn = gr.Button("Generate", variant="secondary", size="lg", scale=2, visible=True, interactive=False)
|
| 7605 |
clear_btn = gr.Button("Clear", variant="secondary", size="sm", scale=1, visible=True)
|
| 7606 |
-
# --- Deploy
|
| 7607 |
deploy_header_md = gr.Markdown("## π Deploy Your App", visible=True)
|
| 7608 |
-
space_name_input = gr.Textbox(
|
| 7609 |
-
label="App Name (e.g. my-cool-app)",
|
| 7610 |
-
placeholder="Enter your app name to deploy",
|
| 7611 |
-
lines=1,
|
| 7612 |
-
visible=True
|
| 7613 |
-
)
|
| 7614 |
sdk_choices = [
|
| 7615 |
("Gradio (Python)", "gradio"),
|
| 7616 |
("Streamlit (Python)", "streamlit"),
|
|
@@ -7747,7 +7741,6 @@ with gr.Blocks(
|
|
| 7747 |
gr.update(),
|
| 7748 |
[],
|
| 7749 |
[],
|
| 7750 |
-
gr.update(value="", visible=False),
|
| 7751 |
gr.update(value="π Deploy App", visible=False),
|
| 7752 |
gr.update(), # keep import header as-is
|
| 7753 |
gr.update(), # keep import button as-is
|
|
@@ -7780,8 +7773,7 @@ with gr.Blocks(
|
|
| 7780 |
gr.update(value="", visible=False), # hide import textbox after submit
|
| 7781 |
loaded_history,
|
| 7782 |
history_to_chatbot_messages(loaded_history),
|
| 7783 |
-
gr.update(value=
|
| 7784 |
-
gr.update(value="Update Existing Space", visible=True),
|
| 7785 |
gr.update(visible=False), # hide import header
|
| 7786 |
gr.update(visible=False), # hide import button
|
| 7787 |
gr.update(value=framework_type) # set language dropdown to framework type
|
|
@@ -7805,7 +7797,6 @@ with gr.Blocks(
|
|
| 7805 |
gr.update(value="", visible=False), # hide import textbox after submit
|
| 7806 |
loaded_history,
|
| 7807 |
history_to_chatbot_messages(loaded_history),
|
| 7808 |
-
gr.update(value="", visible=False),
|
| 7809 |
gr.update(value="π Deploy App", visible=False),
|
| 7810 |
gr.update(visible=False), # hide import header
|
| 7811 |
gr.update(visible=False), # hide import button
|
|
@@ -8067,38 +8058,15 @@ with gr.Blocks(
|
|
| 8067 |
|
| 8068 |
|
| 8069 |
def show_deploy_components(*args):
|
| 8070 |
-
return
|
| 8071 |
|
| 8072 |
def hide_deploy_components(*args):
|
| 8073 |
-
return
|
| 8074 |
-
|
| 8075 |
-
def update_deploy_button_text(space_name):
|
| 8076 |
-
"""Update deploy button text based on whether it's a new space or update"""
|
| 8077 |
-
if "/" in space_name.strip():
|
| 8078 |
-
return gr.update(value="π Update Space")
|
| 8079 |
-
else:
|
| 8080 |
-
return gr.update(value="π Deploy App")
|
| 8081 |
|
| 8082 |
def preserve_space_info_for_followup(history):
|
| 8083 |
-
"""Check if this is a followup on an imported project
|
| 8084 |
-
|
| 8085 |
-
|
| 8086 |
-
|
| 8087 |
-
# Look for imported project pattern in history
|
| 8088 |
-
for user_msg, assistant_msg in history:
|
| 8089 |
-
if assistant_msg and 'IMPORTED PROJECT FROM HUGGING FACE SPACE' in assistant_msg:
|
| 8090 |
-
# Extract space name from the imported project info
|
| 8091 |
-
import re
|
| 8092 |
-
space_match = re.search(r'Space:\s*([^\s\n]+)', assistant_msg)
|
| 8093 |
-
if space_match:
|
| 8094 |
-
space_name = space_match.group(1)
|
| 8095 |
-
return [
|
| 8096 |
-
gr.update(value=space_name, visible=True), # Update space name
|
| 8097 |
-
gr.update(value="π Update Space", visible=True) # Update button text
|
| 8098 |
-
]
|
| 8099 |
-
|
| 8100 |
-
# No imported project found, return no changes
|
| 8101 |
-
return [gr.update(), gr.update()]
|
| 8102 |
|
| 8103 |
# Unified import event
|
| 8104 |
load_project_btn.click(
|
|
@@ -8110,7 +8078,6 @@ with gr.Blocks(
|
|
| 8110 |
load_project_url,
|
| 8111 |
history,
|
| 8112 |
history_output,
|
| 8113 |
-
space_name_input,
|
| 8114 |
deploy_btn,
|
| 8115 |
import_header_md,
|
| 8116 |
load_project_btn,
|
|
@@ -8163,11 +8130,7 @@ with gr.Blocks(
|
|
| 8163 |
).then(
|
| 8164 |
show_deploy_components,
|
| 8165 |
None,
|
| 8166 |
-
[
|
| 8167 |
-
).then(
|
| 8168 |
-
preserve_space_info_for_followup,
|
| 8169 |
-
inputs=[history],
|
| 8170 |
-
outputs=[space_name_input, deploy_btn]
|
| 8171 |
)
|
| 8172 |
|
| 8173 |
# Pressing Enter in the main input should trigger generation and collapse the sidebar
|
|
@@ -8187,11 +8150,7 @@ with gr.Blocks(
|
|
| 8187 |
).then(
|
| 8188 |
show_deploy_components,
|
| 8189 |
None,
|
| 8190 |
-
[
|
| 8191 |
-
).then(
|
| 8192 |
-
preserve_space_info_for_followup,
|
| 8193 |
-
inputs=[history],
|
| 8194 |
-
outputs=[space_name_input, deploy_btn]
|
| 8195 |
)
|
| 8196 |
|
| 8197 |
# --- Chat-based sidebar controller logic ---
|
|
@@ -8219,14 +8178,12 @@ with gr.Blocks(
|
|
| 8219 |
</div>
|
| 8220 |
"""
|
| 8221 |
|
| 8222 |
-
# Update deploy button text when space name changes
|
| 8223 |
-
space_name_input.change(update_deploy_button_text, inputs=[space_name_input], outputs=[deploy_btn])
|
| 8224 |
clear_btn.click(clear_history, outputs=[history, history_output])
|
| 8225 |
-
clear_btn.click(hide_deploy_components, None, [
|
| 8226 |
-
# Reset
|
| 8227 |
clear_btn.click(
|
| 8228 |
-
lambda:
|
| 8229 |
-
outputs=[
|
| 8230 |
)
|
| 8231 |
|
| 8232 |
# Theme switching handlers
|
|
@@ -8278,11 +8235,75 @@ with gr.Blocks(
|
|
| 8278 |
)
|
| 8279 |
|
| 8280 |
# Deploy to Spaces logic
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8281 |
|
| 8282 |
-
def
|
| 8283 |
code,
|
| 8284 |
-
|
| 8285 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8286 |
profile: gr.OAuthProfile | None = None,
|
| 8287 |
token: gr.OAuthToken | None = None
|
| 8288 |
):
|
|
@@ -8296,29 +8317,18 @@ with gr.Blocks(
|
|
| 8296 |
if not token.token or token.token == "hf_":
|
| 8297 |
return gr.update(value="Error: Invalid token. Please log in again with your Hugging Face account to get a valid write token.", visible=True)
|
| 8298 |
|
| 8299 |
-
#
|
| 8300 |
-
|
| 8301 |
-
if
|
| 8302 |
-
# This is an existing space
|
| 8303 |
-
repo_id =
|
| 8304 |
-
|
| 8305 |
-
|
| 8306 |
-
if space_username != profile.username:
|
| 8307 |
-
return gr.update(value=f"Error: You can only update your own spaces. This space belongs to {space_username}.", visible=True)
|
| 8308 |
-
|
| 8309 |
-
# Verify the user has write access to this space
|
| 8310 |
-
try:
|
| 8311 |
-
api = HfApi(token=token.token)
|
| 8312 |
-
# Try to get space info to verify access
|
| 8313 |
-
space_info = api.space_info(repo_id)
|
| 8314 |
-
if not space_info:
|
| 8315 |
-
return gr.update(value=f"Error: Could not access space {repo_id}. Please check your permissions.", visible=True)
|
| 8316 |
-
except Exception as e:
|
| 8317 |
-
return gr.update(value=f"Error: No write access to space {repo_id}. Please ensure you have the correct permissions. Error: {str(e)}", visible=True)
|
| 8318 |
else:
|
| 8319 |
-
#
|
| 8320 |
-
|
| 8321 |
-
repo_id = f"{username}/{space_name
|
|
|
|
| 8322 |
# Map language to HF SDK slug
|
| 8323 |
language_to_sdk_map = {
|
| 8324 |
"gradio": "gradio",
|
|
@@ -8861,9 +8871,9 @@ with gr.Blocks(
|
|
| 8861 |
outputs=[code_output],
|
| 8862 |
queue=False,
|
| 8863 |
).then(
|
| 8864 |
-
|
| 8865 |
-
inputs=[code_output,
|
| 8866 |
-
outputs=deploy_status
|
| 8867 |
)
|
| 8868 |
# Keep the old deploy method as fallback (if not logged in, user can still use the old method)
|
| 8869 |
# Optionally, you can keep the old deploy_btn.click for the default method as a secondary button.
|
|
|
|
| 7603 |
with gr.Row():
|
| 7604 |
btn = gr.Button("Generate", variant="secondary", size="lg", scale=2, visible=True, interactive=False)
|
| 7605 |
clear_btn = gr.Button("Clear", variant="secondary", size="sm", scale=1, visible=True)
|
| 7606 |
+
# --- Deploy components (visible by default) ---
|
| 7607 |
deploy_header_md = gr.Markdown("## π Deploy Your App", visible=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7608 |
sdk_choices = [
|
| 7609 |
("Gradio (Python)", "gradio"),
|
| 7610 |
("Streamlit (Python)", "streamlit"),
|
|
|
|
| 7741 |
gr.update(),
|
| 7742 |
[],
|
| 7743 |
[],
|
|
|
|
| 7744 |
gr.update(value="π Deploy App", visible=False),
|
| 7745 |
gr.update(), # keep import header as-is
|
| 7746 |
gr.update(), # keep import button as-is
|
|
|
|
| 7773 |
gr.update(value="", visible=False), # hide import textbox after submit
|
| 7774 |
loaded_history,
|
| 7775 |
history_to_chatbot_messages(loaded_history),
|
| 7776 |
+
gr.update(value="π Deploy App", visible=True),
|
|
|
|
| 7777 |
gr.update(visible=False), # hide import header
|
| 7778 |
gr.update(visible=False), # hide import button
|
| 7779 |
gr.update(value=framework_type) # set language dropdown to framework type
|
|
|
|
| 7797 |
gr.update(value="", visible=False), # hide import textbox after submit
|
| 7798 |
loaded_history,
|
| 7799 |
history_to_chatbot_messages(loaded_history),
|
|
|
|
| 7800 |
gr.update(value="π Deploy App", visible=False),
|
| 7801 |
gr.update(visible=False), # hide import header
|
| 7802 |
gr.update(visible=False), # hide import button
|
|
|
|
| 8058 |
|
| 8059 |
|
| 8060 |
def show_deploy_components(*args):
|
| 8061 |
+
return gr.Button(visible=True)
|
| 8062 |
|
| 8063 |
def hide_deploy_components(*args):
|
| 8064 |
+
return gr.Button(visible=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8065 |
|
| 8066 |
def preserve_space_info_for_followup(history):
|
| 8067 |
+
"""Check if this is a followup on an imported project - no longer needed with random names"""
|
| 8068 |
+
# Always return standard deploy button since we use random names
|
| 8069 |
+
return gr.update(value="π Deploy App")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8070 |
|
| 8071 |
# Unified import event
|
| 8072 |
load_project_btn.click(
|
|
|
|
| 8078 |
load_project_url,
|
| 8079 |
history,
|
| 8080 |
history_output,
|
|
|
|
| 8081 |
deploy_btn,
|
| 8082 |
import_header_md,
|
| 8083 |
load_project_btn,
|
|
|
|
| 8130 |
).then(
|
| 8131 |
show_deploy_components,
|
| 8132 |
None,
|
| 8133 |
+
[deploy_btn]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8134 |
)
|
| 8135 |
|
| 8136 |
# Pressing Enter in the main input should trigger generation and collapse the sidebar
|
|
|
|
| 8150 |
).then(
|
| 8151 |
show_deploy_components,
|
| 8152 |
None,
|
| 8153 |
+
[deploy_btn]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8154 |
)
|
| 8155 |
|
| 8156 |
# --- Chat-based sidebar controller logic ---
|
|
|
|
| 8178 |
</div>
|
| 8179 |
"""
|
| 8180 |
|
|
|
|
|
|
|
| 8181 |
clear_btn.click(clear_history, outputs=[history, history_output])
|
| 8182 |
+
clear_btn.click(hide_deploy_components, None, [deploy_btn])
|
| 8183 |
+
# Reset button text when clearing
|
| 8184 |
clear_btn.click(
|
| 8185 |
+
lambda: gr.update(value="π Deploy App"),
|
| 8186 |
+
outputs=[deploy_btn]
|
| 8187 |
)
|
| 8188 |
|
| 8189 |
# Theme switching handlers
|
|
|
|
| 8235 |
)
|
| 8236 |
|
| 8237 |
# Deploy to Spaces logic
|
| 8238 |
+
|
| 8239 |
+
def generate_random_app_name():
|
| 8240 |
+
"""Generate a random app name that's unlikely to clash with existing apps"""
|
| 8241 |
+
import random
|
| 8242 |
+
import string
|
| 8243 |
+
|
| 8244 |
+
# Common app prefixes
|
| 8245 |
+
prefixes = ["my", "cool", "awesome", "smart", "quick", "super", "mini", "auto", "fast", "easy"]
|
| 8246 |
+
# Common app suffixes
|
| 8247 |
+
suffixes = ["app", "tool", "hub", "space", "demo", "ai", "gen", "bot", "lab", "studio"]
|
| 8248 |
+
# Random adjectives
|
| 8249 |
+
adjectives = ["blue", "red", "green", "bright", "dark", "light", "swift", "bold", "clean", "fresh"]
|
| 8250 |
+
|
| 8251 |
+
# Generate different patterns
|
| 8252 |
+
patterns = [
|
| 8253 |
+
lambda: f"{random.choice(prefixes)}-{random.choice(suffixes)}-{random.randint(100, 999)}",
|
| 8254 |
+
lambda: f"{random.choice(adjectives)}-{random.choice(suffixes)}-{random.randint(10, 99)}",
|
| 8255 |
+
lambda: f"{random.choice(prefixes)}-{random.choice(adjectives)}-{random.choice(suffixes)}",
|
| 8256 |
+
lambda: f"app-{''.join(random.choices(string.ascii_lowercase, k=6))}-{random.randint(10, 99)}",
|
| 8257 |
+
lambda: f"{random.choice(suffixes)}-{''.join(random.choices(string.ascii_lowercase + string.digits, k=8))}"
|
| 8258 |
+
]
|
| 8259 |
+
|
| 8260 |
+
return random.choice(patterns)()
|
| 8261 |
|
| 8262 |
+
def deploy_with_history_tracking(
|
| 8263 |
code,
|
| 8264 |
+
language,
|
| 8265 |
+
history,
|
| 8266 |
+
profile: gr.OAuthProfile | None = None,
|
| 8267 |
+
token: gr.OAuthToken | None = None
|
| 8268 |
+
):
|
| 8269 |
+
"""Wrapper function that handles history tracking for deployments"""
|
| 8270 |
+
# Check if we have a previously deployed space in the history
|
| 8271 |
+
username = profile.username if profile else None
|
| 8272 |
+
existing_space = None
|
| 8273 |
+
|
| 8274 |
+
# Look for previous deployment in history
|
| 8275 |
+
if history and username:
|
| 8276 |
+
for user_msg, assistant_msg in history:
|
| 8277 |
+
if assistant_msg and "β
Deployed!" in assistant_msg:
|
| 8278 |
+
import re
|
| 8279 |
+
# Look for space URL pattern
|
| 8280 |
+
match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', assistant_msg)
|
| 8281 |
+
if match:
|
| 8282 |
+
existing_space = match.group(1)
|
| 8283 |
+
break
|
| 8284 |
+
elif assistant_msg and "β
Updated!" in assistant_msg:
|
| 8285 |
+
import re
|
| 8286 |
+
# Look for space URL pattern
|
| 8287 |
+
match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', assistant_msg)
|
| 8288 |
+
if match:
|
| 8289 |
+
existing_space = match.group(1)
|
| 8290 |
+
break
|
| 8291 |
+
|
| 8292 |
+
# Call the original deploy function
|
| 8293 |
+
status = deploy_to_user_space_original(code, language, existing_space, profile, token)
|
| 8294 |
+
|
| 8295 |
+
# Update history if deployment was successful
|
| 8296 |
+
updated_history = history
|
| 8297 |
+
if "β
" in status.value:
|
| 8298 |
+
action_type = "Deploy" if "Deployed!" in status.value else "Update"
|
| 8299 |
+
updated_history = history + [[f"{action_type} {language} app", status.value]]
|
| 8300 |
+
|
| 8301 |
+
return [status, updated_history]
|
| 8302 |
+
|
| 8303 |
+
def deploy_to_user_space_original(
|
| 8304 |
+
code,
|
| 8305 |
+
language,
|
| 8306 |
+
existing_space_name=None, # Pass existing space name if updating
|
| 8307 |
profile: gr.OAuthProfile | None = None,
|
| 8308 |
token: gr.OAuthToken | None = None
|
| 8309 |
):
|
|
|
|
| 8317 |
if not token.token or token.token == "hf_":
|
| 8318 |
return gr.update(value="Error: Invalid token. Please log in again with your Hugging Face account to get a valid write token.", visible=True)
|
| 8319 |
|
| 8320 |
+
# Determine if this is an update or new deployment
|
| 8321 |
+
username = profile.username
|
| 8322 |
+
if existing_space_name and existing_space_name.startswith(f"{username}/"):
|
| 8323 |
+
# This is an update to existing space
|
| 8324 |
+
repo_id = existing_space_name
|
| 8325 |
+
space_name = existing_space_name.split('/')[-1]
|
| 8326 |
+
is_update = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8327 |
else:
|
| 8328 |
+
# Generate a random space name for new deployment
|
| 8329 |
+
space_name = generate_random_app_name()
|
| 8330 |
+
repo_id = f"{username}/{space_name}"
|
| 8331 |
+
is_update = False
|
| 8332 |
# Map language to HF SDK slug
|
| 8333 |
language_to_sdk_map = {
|
| 8334 |
"gradio": "gradio",
|
|
|
|
| 8871 |
outputs=[code_output],
|
| 8872 |
queue=False,
|
| 8873 |
).then(
|
| 8874 |
+
deploy_with_history_tracking,
|
| 8875 |
+
inputs=[code_output, language_dropdown, history],
|
| 8876 |
+
outputs=[deploy_status, history]
|
| 8877 |
)
|
| 8878 |
# Keep the old deploy method as fallback (if not logged in, user can still use the old method)
|
| 8879 |
# Optionally, you can keep the old deploy_btn.click for the default method as a secondary button.
|