import gradio as gr import requests from pathlib import Path import json import os def validate_github_repo(repo_url): """Validate the GitHub repository URL and extract owner/repo.""" if not repo_url.startswith(("https://github.com/", "github.com/")): return False, "Invalid GitHub URL format" parts = repo_url.replace("https://", "").replace("github.com/", "").strip("/").split("/") if len(parts) < 2: return False, "Couldn't extract owner/repo from URL" owner, repo = parts[0], parts[1] return True, (owner, repo) def check_repo_exists(owner, repo): """Check if the GitHub repository exists.""" try: response = requests.get(f"https://api.github.com/repos/{owner}/{repo}") if response.status_code == 200: return True, "Repository exists" return False, f"Repository not found (HTTP {response.status_code})" except Exception as e: return False, f"Error checking repository: {str(e)}" def generate_space_config(repo_url, hf_token, space_name, hardware, visibility, license_type, sdk): """Generate configuration for HuggingFace Space.""" # Validate GitHub URL is_valid, result = validate_github_repo(repo_url) if not is_valid: return False, result owner, repo = result # Check if repo exists exists, message = check_repo_exists(owner, repo) if not exists: return False, message # Create config config = { "name": space_name or repo, "sdk": sdk.lower(), "hardware": hardware, "visibility": visibility.lower(), "repository": repo_url, "license": license_type, "app_file": "app.py" if sdk == "Gradio" else "app/main.py" } # Generate README.md content readme_content = f"""--- title: {config['name']} emoji: 🚀 colorFrom: blue colorTo: purple sdk: {config['sdk']} sdk_version: latest app_file: {config['app_file']} pinned: false license: {config['license']} --- # {repo} on HuggingFace Spaces This is a HuggingFace Space for [{repo}]({repo_url}) GitHub repository. ## How to use 1. The app should be automatically deployed from the GitHub repository 2. Any changes pushed to the main branch will trigger a rebuild 3. Check the logs tab for deployment status """ # Generate requirements.txt if not exists requirements_content = "gradio>=3.0.0\n" if sdk == "Streamlit": requirements_content += "streamlit\n" return True, { "config": config, "readme": readme_content, "requirements": requirements_content, "next_steps": f""" ## Next Steps: 1. Create a new Space on HuggingFace: https://huggingface.co/new-space 2. Use the name: {config['name']} 3. Select {sdk} as SDK 4. Select {hardware} hardware 5. Set visibility to {visibility} 6. Add your HuggingFace token as a secret (HF_TOKEN) 7. Push these files to your Space: - README.md (with the above content) - requirements.txt (with the above content) - Your application file ({config['app_file']}) """ } with gr.Blocks() as demo: gr.Markdown(""" # 🚀 GitHub to HuggingFace Space Converter Convert your GitHub repositories into deployable HuggingFace Spaces [Built with anycoder](https://huggingface.co/spaces/akhaliq/anycoder) """) with gr.Row(): with gr.Column(): repo_url = gr.Textbox( label="GitHub Repository URL", placeholder="https://github.com/username/repo", info="Full URL to your GitHub repository" ) hf_token = gr.Textbox( label="HuggingFace Token (optional)", type="password", info="Required for private repositories", placeholder="hf_xxxxxxxxxxxxxxxx" ) space_name = gr.Textbox( label="Space Name (optional)", placeholder="Leave blank to use repo name", info="Custom name for your HuggingFace Space" ) with gr.Row(): hardware = gr.Radio( ["cpu-basic", "cpu-upgrade", "t4-small", "t4-medium", "a10g-small", "a10g-large"], value="cpu-basic", label="Hardware Tier" ) visibility = gr.Radio( ["Public", "Private"], value="Public", label="Space Visibility" ) with gr.Row(): license_type = gr.Dropdown( ["apache-2.0", "mit", "openrail", "other"], value="apache-2.0", label="License" ) sdk = gr.Radio( ["Gradio", "Streamlit"], value="Gradio", label="SDK" ) submit_btn = gr.Button("Generate Space Config", variant="primary") with gr.Column(): output_md = gr.Markdown("# Configuration will appear here") output_json = gr.JSON(label="Space Configuration") download_readme = gr.DownloadButton( "Download README.md", visible=False ) download_reqs = gr.DownloadButton( "Download requirements.txt", visible=False ) def process_form(repo_url, hf_token, space_name, hardware, visibility, license_type, sdk): success, result = generate_space_config( repo_url, hf_token, space_name, hardware, visibility, license_type, sdk ) if not success: return { output_md: gr.Markdown(f"## ❌ Error\n{result}", visible=True), output_json: None, download_readme: None, download_reqs: None } # Create temporary files for download readme_path = "README.md" reqs_path = "requirements.txt" with open(readme_path, "w") as f: f.write(result["readme"]) with open(reqs_path, "w") as f: f.write(result["requirements"]) return { output_md: gr.Markdown(result["next_steps"], visible=True), output_json: result["config"], download_readme: gr.DownloadButton( "Download README.md", value=readme_path, visible=True ), download_reqs: gr.DownloadButton( "Download requirements.txt", value=reqs_path, visible=True ) } submit_btn.click( fn=process_form, inputs=[repo_url, hf_token, space_name, hardware, visibility, license_type, sdk], outputs=[output_md, output_json, download_readme, download_reqs] ) demo.launch( theme=gr.themes.Soft(primary_hue="indigo", font=[gr.themes.GoogleFont("Inter"), "sans-serif"]), footer_links=[{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}] )