HF-privatize / app.py
broadfield-dev's picture
Update app.py
8df5ef2 verified
import gradio as gr
from huggingface_hub import HfApi
from huggingface_hub.utils import HfHubHTTPError
# --- Core Functions ---
def get_my_spaces(hf_token):
"""Fetches a list of the user's public Hugging Face Spaces."""
if not hf_token:
# Return empty values for all outputs
return [], "Please enter your Hugging Face token.", []
try:
api = HfApi(token=hf_token)
# Get the username to list spaces accurately
username = api.whoami()["name"]
spaces = api.list_spaces(author=username)
# Filter for only public spaces
public_spaces = [space.id for space in spaces if not space.private]
if not public_spaces:
return [], "Successfully connected, but you have no public spaces.", []
# Return the list of spaces for the checkboxes and the state
return public_spaces, f"Successfully listed {len(public_spaces)} public spaces.", public_spaces
except HfHubHTTPError as e:
# Handle common authentication errors
return [], f"Authentication error: Please check your token. Details: {e}", []
except Exception as e:
return [], f"An error occurred: {e}", []
def make_spaces_private(hf_token, selected_spaces, progress=gr.Progress()):
"""Sets the visibility of selected Hugging Face Spaces to private."""
if not hf_token:
return "Please enter your Hugging Face token."
if not selected_spaces:
return "Please select at least one space to make private."
progress(0, desc="Starting...")
try:
api = HfApi(token=hf_token)
log_messages = []
total_spaces = len(selected_spaces)
for i, space_id in enumerate(selected_spaces):
progress((i + 1) / total_spaces, desc=f"Processing '{space_id}'...")
try:
# --- THIS IS THE FIX ---
# We must explicitly tell the API that this is a 'space'.
api.update_repo_settings(repo_id=space_id, private=True, repo_type="space")
log_messages.append(f"βœ… Successfully made '{space_id}' private.")
except Exception as e:
log_messages.append(f"❌ Failed to make '{space_id}' private: {e}")
return "\n".join(log_messages)
except HfHubHTTPError as e:
return f"Authentication error: Please check your token. Details: {e}"
except Exception as e:
return f"An error occurred: {e}"
# --- Gradio UI ---
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown(
"""
# πŸ›‘οΈ Hugging Face Space Privacy Control
Quickly make your public Hugging Face Spaces private.
1. Create and paste a Hugging Face access token with **write** permission.
2. Click "List My Public Spaces".
3. Select the spaces you want to make private (or use "Select All").
4. Click the final button to update their privacy settings.
"""
)
with gr.Row():
hf_token_input = gr.Textbox(
label="Hugging Face Write Token",
type="password",
placeholder="hf_...",
scale=3,
)
list_spaces_button = gr.Button("List My Public Spaces", variant="secondary", scale=1)
with gr.Group():
# This (invisible) state component is the key to the select_all fix
spaces_list_state = gr.State([])
select_all_checkbox = gr.Checkbox(label="Select All / Deselect All")
spaces_checkboxes = gr.CheckboxGroup(
label="Your Public Spaces",
info="Only your public spaces are shown here."
)
make_private_button = gr.Button("Make Selected Spaces Private", variant="primary")
status_output = gr.Textbox(label="Status", interactive=False, lines=5)
# --- Event Listeners ---
def list_spaces_action(token):
"""Called when the list button is clicked. Updates the checkboxes and the state."""
spaces, message, state_list = get_my_spaces(token)
# Also reset the select_all checkbox to unchecked
return gr.update(choices=spaces, value=[]), message, state_list, gr.update(value=False)
list_spaces_button.click(
fn=list_spaces_action,
inputs=hf_token_input,
outputs=[spaces_checkboxes, status_output, spaces_list_state, select_all_checkbox]
)
def select_all_action(select_all_checked, full_list_of_spaces):
"""
Called when the "Select All" checkbox is changed.
Uses the list from the state to update the checkbox group.
"""
if select_all_checked:
return gr.update(value=full_list_of_spaces) # Select all
else:
return gr.update(value=[]) # Deselect all
select_all_checkbox.change(
fn=select_all_action,
inputs=[select_all_checkbox, spaces_list_state], # Input is from the state now
outputs=spaces_checkboxes
)
make_private_button.click(
fn=make_spaces_private,
inputs=[hf_token_input, spaces_checkboxes],
outputs=status_output
)
demo.launch()