| import os |
| import shutil |
| import gradio as gr |
| from huggingface_hub import HfApi, snapshot_download |
|
|
| def fetch_files(source_repo, hf_token): |
| if not hf_token.strip() or not source_repo.strip(): |
| yield gr.update(), gr.update(), "Error: Token and Source Repo required.", [] |
| return |
| |
| api = HfApi(token=hf_token.strip()) |
| try: |
| yield gr.update(), gr.update(), f"Fetching files from '{source_repo}'...", [] |
| files = api.list_repo_files(repo_id=source_repo.strip(), repo_type="model") |
| files.sort() |
| |
| yield ( |
| gr.update(visible=True), |
| gr.update(choices=files, value=files), |
| f"Success: Fetched {len(files)} files. Uncheck the ones to exclude.", |
| files |
| ) |
| except Exception as e: |
| yield gr.update(visible=False), gr.update(), f"Error: {str(e)}", [] |
|
|
|
|
| def clone_gated_model(source_repo, target_repo, hf_token, selected_files, all_files): |
| if not target_repo.strip(): |
| yield "Error: Target repo required." |
| return |
| |
| api = HfApi(token=hf_token.strip()) |
| local_dir = "./tmp_clone_dir" |
| |
| |
| files_to_ignore = list(set(all_files) - set(selected_files)) |
| |
| try: |
| yield f"1. Creating private target repo '{target_repo}'..." |
| api.create_repo(repo_id=target_repo.strip(), repo_type="model", private=True, exist_ok=True) |
| |
| yield f"2. Downloading selected files from '{source_repo}' to Space disk..." |
| snapshot_download( |
| repo_id=source_repo.strip(), |
| repo_type="model", |
| local_dir=local_dir, |
| token=hf_token.strip(), |
| ignore_patterns=files_to_ignore if files_to_ignore else None |
| ) |
| |
| yield f"3. Uploading clean files to '{target_repo}'..." |
| api.upload_folder( |
| folder_path=local_dir, |
| repo_id=target_repo.strip(), |
| repo_type="model", |
| commit_message="Initial commit: Cloned gated model" |
| ) |
| |
| yield f"Success! Model cloned. View it here: https://huggingface.co/{target_repo.strip()}" |
| |
| except Exception as e: |
| yield f"An error occurred: {str(e)}" |
| |
| finally: |
| if os.path.exists(local_dir): |
| shutil.rmtree(local_dir, ignore_errors=True) |
|
|
|
|
| with gr.Blocks(title="Gated Model Cloner") as demo: |
| gr.Markdown("# 📑 Clean Gated Model Cloner") |
| gr.Markdown("Downloads a gated model to the Space's local disk, then uploads a clean copy to your account.") |
| |
| with gr.Row(): |
| hf_token = gr.Textbox(label="HF Token (Write)", type="password") |
| |
| with gr.Row(): |
| source_repo = gr.Textbox(label="Source Gated Repo", placeholder="e.g., meta-llama/Llama-3.2-1B") |
| fetch_btn = gr.Button("1. Fetch Files", variant="secondary") |
| |
| all_files_state = gr.State([]) |
| |
| with gr.Group(visible=False) as selection_group: |
| file_checkboxes = gr.CheckboxGroup(label="Select files to keep") |
| target_repo = gr.Textbox(label="Target Repo", placeholder="e.g., username/clean-llama") |
| clone_btn = gr.Button("2. Clone Selected Files", variant="primary") |
| |
| output_logs = gr.Textbox(label="Status Logs", interactive=False) |
| |
| fetch_btn.click( |
| fn=fetch_files, |
| inputs=[source_repo, hf_token], |
| outputs=[selection_group, file_checkboxes, output_logs, all_files_state] |
| ) |
| |
| clone_btn.click( |
| fn=clone_gated_model, |
| inputs=[source_repo, target_repo, hf_token, file_checkboxes, all_files_state], |
| outputs=output_logs |
| ) |
|
|
| if __name__ == "__main__": |
| demo.queue().launch(theme=gr.themes.Soft()) |