Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| HF Space Auto-Deployer | |
| ---------------------- | |
| ๊ณต๊ฐ Git ๋ ํฌ์งํ ๋ฆฌ๋ฅผ Hugging Face Gradio Space๋ก ์๋ ๋ณํ ๋ฐ ๋ฐฐํฌํฉ๋๋ค. | |
| ํ์ ํ๊ฒฝ๋ณ์: | |
| - BAPI_TOKEN: Brave Search API Key | |
| - FRIENDLI_TOKEN: Friendli AI API Token | |
| - HF_TOKEN (์ ํ): ๊ธฐ๋ณธ HuggingFace ํ ํฐ | |
| """ | |
| import os | |
| import sys | |
| import json | |
| import argparse | |
| import subprocess | |
| import tempfile | |
| import textwrap | |
| import requests | |
| import shutil | |
| from pathlib import Path | |
| from typing import Optional, Dict, List | |
| import gradio as gr | |
| import git | |
| from huggingface_hub import HfApi, login | |
| # ========== Brave Search ํฌํผ ========== # | |
| def brave_search_repo(repo_url: str, count: int = 5) -> List[Dict]: | |
| """Brave Search API๋ก ๋ ํฌ์งํ ๋ฆฌ ๋ฉํ๋ฐ์ดํฐ ์์ง""" | |
| api_key = os.getenv("BAPI_TOKEN") | |
| if not api_key: | |
| raise RuntimeError("ํ๊ฒฝ๋ณ์ BAPI_TOKEN์ด ์ค์ ๋์ด ์์ง ์์ต๋๋ค.") | |
| headers = {"X-Subscription-Token": api_key, "Accept": "application/json"} | |
| params = {"q": f'site:github.com "{repo_url}"', "count": count, "search_lang": "en"} | |
| try: | |
| resp = requests.get( | |
| "https://api.search.brave.com/res/v1/web/search", | |
| headers=headers, | |
| params=params, | |
| timeout=10 | |
| ) | |
| resp.raise_for_status() | |
| return resp.json().get("web", {}).get("results", []) | |
| except Exception as e: | |
| print(f"โ ๏ธ Brave Search ๊ฒฝ๊ณ : {e}") | |
| return [] | |
| # ========== Friendli LLM ํฌํผ ========== # | |
| def friendli_generate_scaffold(context: str) -> Dict: | |
| """Friendli AI๋ก app.py ๋ฐ requirements.txt ์๋ ์์ฑ""" | |
| token = os.getenv("FRIENDLI_TOKEN") | |
| if not token: | |
| raise RuntimeError("ํ๊ฒฝ๋ณ์ FRIENDLI_TOKEN์ด ์ค์ ๋์ด ์์ง ์์ต๋๋ค.") | |
| payload = { | |
| "model": "meta-llama-3.1-70b-instruct", | |
| "messages": [ | |
| { | |
| "role": "system", | |
| "content": textwrap.dedent(""" | |
| You are an expert Hugging Face Space architect. Given repository context, | |
| generate a Gradio app that showcases the repository's functionality. | |
| Output a JSON with these keys: | |
| - app_py: Complete Gradio app code | |
| - requirements_txt: Required Python packages | |
| - need_docker: Boolean for Docker requirement | |
| - dockerfile: Dockerfile content (if need_docker is true) | |
| - summary: Brief description of the generated app | |
| Important guidelines: | |
| 1. Always use Gradio for the interface | |
| 2. Make the app functional and user-friendly | |
| 3. Include proper error handling | |
| 4. Add clear instructions in the interface | |
| 5. Use appropriate Gradio components for the task | |
| """) | |
| }, | |
| {"role": "user", "content": context} | |
| ], | |
| "max_tokens": 16384, | |
| "temperature": 0.7, | |
| "top_p": 0.9, | |
| "stream": False | |
| } | |
| headers = { | |
| "Authorization": f"Bearer {token}", | |
| "Content-Type": "application/json" | |
| } | |
| try: | |
| r = requests.post( | |
| "https://api.friendli.ai/serverless/v1/chat/completions", | |
| json=payload, | |
| headers=headers, | |
| timeout=120 | |
| ) | |
| r.raise_for_status() | |
| # JSON ์๋ต ํ์ฑ | |
| response_text = r.json()["choices"][0]["message"]["content"] | |
| # JSON ๋ธ๋ก ์ถ์ถ (```json ... ``` ํ์ ์ฒ๋ฆฌ) | |
| if "```json" in response_text: | |
| start = response_text.find("```json") + 7 | |
| end = response_text.find("```", start) | |
| response_text = response_text[start:end].strip() | |
| return json.loads(response_text) | |
| except json.JSONDecodeError as e: | |
| print(f"โ ๏ธ JSON ํ์ฑ ์ค๋ฅ: {e}") | |
| # ๊ธฐ๋ณธ Gradio ์ฑ ๋ฐํ | |
| return { | |
| "app_py": textwrap.dedent(""" | |
| import gradio as gr | |
| def main(): | |
| return "This is an auto-generated Gradio app. Please customize it based on your repository." | |
| demo = gr.Interface( | |
| fn=main, | |
| inputs=None, | |
| outputs="text", | |
| title="Auto-Generated Space", | |
| description="This Space was automatically created. Please update app.py to add your functionality." | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |
| """), | |
| "requirements_txt": "gradio>=4.0.0", | |
| "need_docker": False, | |
| "summary": "Basic Gradio template - please customize based on your repository" | |
| } | |
| # ========== ๋ฉ์ธ ๋ฐฐํฌ ๋ก์ง ========== # | |
| def deploy(repo_url: str, hf_token: str, private: bool = False, hardware: Optional[str] = None) -> str: | |
| """๋ ํฌ์งํ ๋ฆฌ๋ฅผ Gradio Space๋ก ๋ฐฐํฌํ๊ณ Space URL ๋ฐํ""" | |
| # HF ๋ก๊ทธ์ธ | |
| login(hf_token) | |
| api = HfApi(token=hf_token) | |
| # ์ฌ์ฉ์ ์ ๋ณด ๋ฐ Space ์ด๋ฆ ์์ฑ | |
| user = api.whoami()["name"] | |
| repo_name = Path(repo_url.rstrip("/")).name.lower() | |
| repo_name = repo_name.replace(".", "-").replace("_", "-") | |
| space_id = f"{user}/{repo_name}-space" | |
| print(f"๐ฆ Space ID: {space_id}") | |
| # Space ์์ฑ | |
| api.create_repo( | |
| repo_id=space_id, | |
| repo_type="space", | |
| space_sdk="gradio", | |
| private=private, | |
| exist_ok=True | |
| ) | |
| # Hardware ์ค์ (ํ์ํ ๊ฒฝ์ฐ) | |
| if hardware: | |
| try: | |
| api.request_space_hardware(repo_id=space_id, hardware=hardware) | |
| print(f"๐ฅ๏ธ Hardware ์ค์ : {hardware}") | |
| except Exception as e: | |
| print(f"โ ๏ธ Hardware ์ค์ ์คํจ: {e}") | |
| with tempfile.TemporaryDirectory() as work_dir: | |
| # 1) Brave Search๋ก ๋ฉํ๋ฐ์ดํฐ ์์ง | |
| print("๐ ๋ ํฌ์งํ ๋ฆฌ ์ ๋ณด ์์ง ์ค...") | |
| brave_meta = brave_search_repo(repo_url) | |
| # 2) ์๋ณธ ๋ ํฌ์งํ ๋ฆฌ ํด๋ก | |
| print("๐ฅ ๋ ํฌ์งํ ๋ฆฌ ํด๋ก ์ค...") | |
| src_path = Path(work_dir) / "source" | |
| git.Repo.clone_from(repo_url, src_path, depth=1) | |
| # README ์ฝ๊ธฐ | |
| readme_content = "" | |
| readme_path = src_path / "README.md" | |
| if readme_path.exists(): | |
| readme_content = readme_path.read_text(encoding="utf-8", errors="ignore")[:4000] | |
| # ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ ํ์ | |
| tree_output = subprocess.run( | |
| ["bash", "-c", f"find {src_path} -type f -name '*.py' -o -name '*.md' -o -name '*.txt' -o -name '*.json' -o -name '*.yaml' -o -name '*.yml' | head -n 50"], | |
| capture_output=True, | |
| text=True | |
| ).stdout | |
| # ์ปจํ ์คํธ ์์ฑ | |
| context = textwrap.dedent(f""" | |
| ## Repository URL | |
| {repo_url} | |
| ## Brave Search Metadata | |
| {json.dumps(brave_meta, ensure_ascii=False, indent=2)} | |
| ## Repository Structure | |
| {tree_output} | |
| ## README.md Content (first 4KB) | |
| {readme_content} | |
| Please create a Gradio app that best showcases this repository's functionality. | |
| If it's a model, create an inference interface. If it's a dataset, create a viewer. | |
| If it's a library, create a demo. Make it user-friendly and functional. | |
| """) | |
| # 3) Friendli AI๋ก ์ค์บํด๋ ์์ฑ | |
| print("๐ค AI๋ก Gradio ์ฑ ์์ฑ ์ค...") | |
| scaffold = friendli_generate_scaffold(context) | |
| # 4) Space ๋ ํฌ์งํ ๋ฆฌ ํด๋ก ๋ฐ ํ์ผ ์์ฑ | |
| print("๐ค Space์ ํ์ผ ์ ๋ก๋ ์ค...") | |
| dst_path = Path(work_dir) / "space" | |
| # HTTPS URL with token for authentication | |
| space_url = f"https://{hf_token}@huggingface.co/spaces/{space_id}" | |
| space_repo = git.Repo.clone_from(space_url, dst_path, depth=1) | |
| # ํ์ผ ์์ฑ | |
| (dst_path / "app.py").write_text(scaffold["app_py"], encoding="utf-8") | |
| (dst_path / "requirements.txt").write_text(scaffold["requirements_txt"], encoding="utf-8") | |
| if scaffold.get("need_docker"): | |
| (dst_path / "Dockerfile").write_text(scaffold["dockerfile"], encoding="utf-8") | |
| # README.md ์์ฑ | |
| readme_content = f"""--- | |
| title: {repo_name.replace("-", " ").title()} | |
| emoji: ๐ | |
| colorFrom: blue | |
| colorTo: purple | |
| sdk: gradio | |
| sdk_version: 4.44.1 | |
| app_file: app.py | |
| pinned: false | |
| --- | |
| # {repo_name.replace("-", " ").title()} | |
| Automatically deployed from: {repo_url} | |
| ## Summary | |
| {scaffold.get("summary", "Auto-generated Gradio Space")} | |
| --- | |
| *Created by HF Space Auto-Deployer* | |
| """ | |
| (dst_path / "README.md").write_text(readme_content, encoding="utf-8") | |
| # Git ์ปค๋ฐ ๋ฐ ํธ์ | |
| space_repo.index.add(["app.py", "requirements.txt", "README.md"]) | |
| if scaffold.get("need_docker"): | |
| space_repo.index.add(["Dockerfile"]) | |
| # Git ์ค์ | |
| space_repo.config_writer().set_value("user", "name", user).release() | |
| space_repo.config_writer().set_value("user", "email", f"{user}@users.noreply.huggingface.co").release() | |
| space_repo.index.commit("Initial auto-deployment") | |
| # ํธ์ | |
| origin = space_repo.remote("origin") | |
| origin.push() | |
| return f"https://huggingface.co/spaces/{space_id}" | |
| # ========== Gradio UI ========== # | |
| def launch_deploy(repo_url: str, private: bool, request: gr.Request) -> str: | |
| """Gradio UI์์ ํธ์ถ๋๋ ๋ฐฐํฌ ํจ์""" | |
| # ํ ํฐ ๊ฐ์ ธ์ค๊ธฐ (์ฐ์ ์์: Gradio ์ธ์ฆ โ ํ๊ฒฝ๋ณ์) | |
| hf_token = None | |
| # Gradio ์ธ์ฆ ํค๋ ํ์ธ | |
| auth_header = request.headers.get("authorization") | |
| if auth_header and auth_header.startswith("Bearer "): | |
| hf_token = auth_header.split(" ")[1].strip() | |
| # ํ๊ฒฝ๋ณ์ ํด๋ฐฑ | |
| if not hf_token: | |
| hf_token = os.environ.get("HF_TOKEN") | |
| if not hf_token: | |
| return """### โ ์ธ์ฆ ํ์ | |
| ๋ค์ ์ค ํ๋์ ๋ฐฉ๋ฒ์ผ๋ก ์ธ์ฆํด์ฃผ์ธ์: | |
| 1. **์ฐ์ธก ์๋จ ํ๋กํ โ Sign in with Hugging Face** | |
| 2. **Space Settings โ Variables and secrets โ HF_TOKEN ์ค์ **""" | |
| # URL ๊ฒ์ฆ | |
| repo_url = repo_url.strip() | |
| if not repo_url: | |
| return "### โ Repository URL์ ์ ๋ ฅํด์ฃผ์ธ์." | |
| if not any(repo_url.startswith(prefix) for prefix in ["https://github.com/", "http://github.com/"]): | |
| return """### โ ์๋ชป๋ URL ํ์ | |
| GitHub URL์ ์ ๋ ฅํด์ฃผ์ธ์. | |
| ์: https://github.com/username/repository""" | |
| # ๋ฐฐํฌ ์คํ | |
| try: | |
| space_url = deploy(repo_url, hf_token, private) | |
| return f"""### โ Space ๋ฐฐํฌ ์๋ฃ! | |
| ๐ ์ฑ๊ณต์ ์ผ๋ก ๋ฐฐํฌ๋์์ต๋๋ค! | |
| **Space URL**: [{space_url}]({space_url}) | |
| **๋ค์ ๋จ๊ณ:** | |
| 1. Space ํ์ด์ง ๋ฐฉ๋ฌธ | |
| 2. ๋น๋ ๋ก๊ทธ ํ์ธ (์ฐ์ธก ์๋จ "Logs" ํญ) | |
| 3. ๋น๋ ์๋ฃ ๋๊ธฐ (๋ณดํต 2-5๋ถ) | |
| 4. ํ์์ app.py ์์ | |
| --- | |
| ๐ก **ํ**: Space๊ฐ ์ ๋๋ก ์๋ํ์ง ์์ผ๋ฉด Files ํญ์์ app.py๋ฅผ ์ง์ ์์ ํ ์ ์์ต๋๋ค.""" | |
| except Exception as e: | |
| error_msg = str(e) | |
| # ์์ธํ ์ค๋ฅ ์๋ด | |
| if "BAPI_TOKEN" in error_msg: | |
| return """### โ Brave Search API ํ ํฐ ํ์ | |
| **์ค์ ๋ฐฉ๋ฒ:** | |
| 1. [Brave Search API](https://brave.com/search/api/) ๊ฐ์ | |
| 2. ๋ฌด๋ฃ API Key ๋ฐ๊ธ | |
| 3. **์ด Space์** Settings โ Variables and secrets | |
| 4. `BAPI_TOKEN` = `[๋ฐ๊ธ๋ฐ์ ํค]` ์ถ๊ฐ""" | |
| elif "FRIENDLI_TOKEN" in error_msg: | |
| return """### โ Friendli AI ํ ํฐ ํ์ | |
| **์ค์ ๋ฐฉ๋ฒ:** | |
| 1. [Friendli AI](https://friendli.ai/) ๊ฐ์ | |
| 2. API Key ๋ฐ๊ธ | |
| 3. **์ด Space์** Settings โ Variables and secrets | |
| 4. `FRIENDLI_TOKEN` = `[๋ฐ๊ธ๋ฐ์ ํค]` ์ถ๊ฐ""" | |
| elif "401" in error_msg or "403" in error_msg or "Unauthorized" in error_msg: | |
| return """### โ ์ธ์ฆ ์คํจ | |
| **ํด๊ฒฐ ๋ฐฉ๋ฒ:** | |
| 1. [ํ ํฐ ํ์ด์ง](https://huggingface.co/settings/tokens) ๋ฐฉ๋ฌธ | |
| 2. "New token" ํด๋ฆญ | |
| 3. **Write** ๊ถํ ์ฒดํฌ โ | |
| 4. Space Settings์์ HF_TOKEN ์ ๋ฐ์ดํธ""" | |
| else: | |
| return f"""### โ ๋ฐฐํฌ ์ค๋ฅ | |
| **์ค๋ฅ ๋ด์ฉ:** | |
| ``` | |
| {error_msg} | |
| ``` | |
| **์ผ๋ฐ์ ์ธ ํด๊ฒฐ ๋ฐฉ๋ฒ:** | |
| 1. Repository๊ฐ public์ธ์ง ํ์ธ | |
| 2. URL ํ์ ํ์ธ (https://github.com/user/repo) | |
| 3. ๋คํธ์ํฌ ์ฐ๊ฒฐ ํ์ธ | |
| 4. ์ ์ ํ ์ฌ์๋""" | |
| # ========== Gradio App ========== # | |
| def create_ui(): | |
| """Gradio UI ์์ฑ""" | |
| with gr.Blocks( | |
| title="HF Space Auto-Deployer", | |
| theme=gr.themes.Soft(), | |
| css=""" | |
| .main-container { | |
| max-width: 800px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| .header { | |
| text-align: center; | |
| margin-bottom: 30px; | |
| padding: 20px; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| border-radius: 10px; | |
| } | |
| .header h1 { | |
| margin: 0; | |
| font-size: 2.5em; | |
| } | |
| .header p { | |
| margin: 10px 0 0 0; | |
| opacity: 0.9; | |
| } | |
| .gr-button-primary { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; | |
| border: none !important; | |
| font-size: 1.1em !important; | |
| padding: 12px 30px !important; | |
| } | |
| .gr-button-primary:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 5px 15px rgba(0,0,0,0.2); | |
| } | |
| .status-box { | |
| padding: 20px; | |
| border-radius: 10px; | |
| margin-top: 20px; | |
| border: 1px solid #e0e0e0; | |
| background-color: #f9f9f9; | |
| } | |
| .info-box { | |
| background-color: #e3f2fd; | |
| padding: 15px; | |
| border-radius: 8px; | |
| border-left: 4px solid #2196F3; | |
| margin: 10px 0; | |
| } | |
| .examples-box { | |
| background-color: #f3e5f5; | |
| padding: 15px; | |
| border-radius: 8px; | |
| margin: 10px 0; | |
| } | |
| """ | |
| ) as demo: | |
| with gr.Column(elem_classes="main-container"): | |
| # ํค๋ | |
| gr.HTML(""" | |
| <div class="header"> | |
| <h1>๐ GitHub โ HuggingFace Space</h1> | |
| <p>AI๊ฐ ๋น์ ์ GitHub ํ๋ก์ ํธ๋ฅผ Gradio ์ฑ์ผ๋ก ๋ณํํฉ๋๋ค</p> | |
| </div> | |
| """) | |
| # ์ธ์ฆ ์๋ด | |
| gr.Markdown(""" | |
| <div class="info-box"> | |
| <b>๐ ์ธ์ฆ ๋ฐฉ๋ฒ:</b><br> | |
| โข <b>๋ฐฉ๋ฒ 1</b>: ์ฐ์ธก ์๋จ ํ๋กํ โ Sign in with Hugging Face<br> | |
| โข <b>๋ฐฉ๋ฒ 2</b>: Space Settings์์ HF_TOKEN ํ๊ฒฝ๋ณ์ ์ค์ | |
| </div> | |
| """) | |
| # ์ ๋ ฅ ํ๋ | |
| with gr.Group(): | |
| repo_input = gr.Textbox( | |
| label="๐ฆ GitHub Repository URL", | |
| placeholder="https://github.com/username/repository", | |
| info="Public repository URL์ ์ ๋ ฅํ์ธ์", | |
| lines=1 | |
| ) | |
| private_checkbox = gr.Checkbox( | |
| label="๐ Private Space๋ก ์์ฑ", | |
| value=False, | |
| info="์ฒดํฌํ๋ฉด ๋ณธ์ธ๋ง ์ ๊ทผ ๊ฐ๋ฅํ Space๊ฐ ์์ฑ๋ฉ๋๋ค" | |
| ) | |
| # ๋ฐฐํฌ ๋ฒํผ | |
| deploy_btn = gr.Button( | |
| "๐ Space ์์ฑํ๊ธฐ", | |
| variant="primary", | |
| size="lg" | |
| ) | |
| # ์ํ ์ถ๋ ฅ | |
| output_status = gr.Markdown( | |
| elem_classes="status-box", | |
| visible=False | |
| ) | |
| # ์์ | |
| gr.HTML(""" | |
| <div class="examples-box"> | |
| <b>๐ก ์์ ํ๋ก์ ํธ:</b><br> | |
| โข <code>https://github.com/gradio-app/gradio/tree/main/demo/hello_world</code><br> | |
| โข <code>https://github.com/huggingface/transformers</code><br> | |
| โข <code>https://github.com/CompVis/stable-diffusion</code> | |
| </div> | |
| """) | |
| # ์ฌ์ฉ ๊ฐ์ด๋ | |
| with gr.Accordion("๐ ์ฌ์ฉ ๊ฐ์ด๋", open=False): | |
| gr.Markdown(""" | |
| ### ์๋ ์๋ฆฌ | |
| 1. **๐ ๋ถ์**: Brave Search๋ก ๋ ํฌ์งํ ๋ฆฌ ์ ๋ณด ์์ง | |
| 2. **๐ค ์์ฑ**: Friendli AI๊ฐ ๋ง์ถคํ Gradio ์ฑ ์ฝ๋ ์์ฑ | |
| 3. **๐ค ๋ฐฐํฌ**: HuggingFace Space์ ์๋ ์ ๋ก๋ ๋ฐ ๋น๋ | |
| ### ์ง์ํ๋ ํ๋ก์ ํธ ์ ํ | |
| - โ **ML ๋ชจ๋ธ**: ์ถ๋ก ์ธํฐํ์ด์ค ์๋ ์์ฑ | |
| - โ **๋ฐ์ดํฐ์ **: ๋ฐ์ดํฐ ํ์๊ธฐ ์์ฑ | |
| - โ **๋ผ์ด๋ธ๋ฌ๋ฆฌ**: ๋ฐ๋ชจ ์ฑ ์์ฑ | |
| - โ **์ผ๋ฐ ํ๋ก์ ํธ**: ๊ธฐ๋ฅ ์ผ์ผ์ด์ค ์์ฑ | |
| ### ํ์ํ API ํค | |
| 1. **BAPI_TOKEN**: [Brave Search API](https://brave.com/search/api/) (๋ฌด๋ฃ) | |
| 2. **FRIENDLI_TOKEN**: [Friendli AI](https://friendli.ai/) (๋ฌด๋ฃ ํฌ๋ ๋ง ์ ๊ณต) | |
| ### ๋ฌธ์ ํด๊ฒฐ | |
| - **๋น๋ ์คํจ**: Space์ Logs ํญ ํ์ธ | |
| - **์ฑ ์์ **: Files ํญ์์ app.py ์ง์ ํธ์ง | |
| - **GPU ํ์**: Space Settings์์ Hardware ๋ณ๊ฒฝ | |
| """) | |
| # ์ด๋ฒคํธ ํธ๋ค๋ฌ | |
| deploy_btn.click( | |
| fn=launch_deploy, | |
| inputs=[repo_input, private_checkbox], | |
| outputs=output_status | |
| ).then( | |
| fn=lambda: gr.update(visible=True), | |
| outputs=output_status | |
| ) | |
| return demo | |
| # ========== CLI ์ง์ ========== # | |
| def main(): | |
| """CLI ์คํ์ ์ํ ๋ฉ์ธ ํจ์""" | |
| parser = argparse.ArgumentParser(description="Git ๋ ํฌ๋ฅผ Hugging Face Space๋ก ์๋ ๋ฐฐํฌ") | |
| parser.add_argument("--repo_url", help="GitHub repository URL") | |
| parser.add_argument("--hf_token", help="HuggingFace write token") | |
| parser.add_argument("--private", action="store_true", help="Create private Space") | |
| parser.add_argument("--hardware", help="GPU tier (e.g., 't4-medium')") | |
| parser.add_argument("--no-ui", action="store_true", help="Run without Gradio UI") | |
| args = parser.parse_args() | |
| # CLI ๋ชจ๋ | |
| if args.no_ui and args.repo_url and args.hf_token: | |
| try: | |
| url = deploy(args.repo_url, args.hf_token, args.private, args.hardware) | |
| print(f"โ ๋ฐฐํฌ ์ฑ๊ณต: {url}") | |
| except Exception as e: | |
| print(f"โ ๋ฐฐํฌ ์คํจ: {e}", file=sys.stderr) | |
| sys.exit(1) | |
| # Gradio UI ๋ชจ๋ | |
| else: | |
| # ํ๊ฒฝ ์ํ ์ถ๋ ฅ | |
| print("\n" + "="*60) | |
| print("๐ HF Space Auto-Deployer") | |
| print("="*60) | |
| # ํ๊ฒฝ๋ณ์ ์ฒดํฌ | |
| env_checks = [] | |
| env_checks.append("โ HF_TOKEN" if os.getenv("HF_TOKEN") else "โ ๏ธ HF_TOKEN (์ ํ์ฌํญ)") | |
| env_checks.append("โ BAPI_TOKEN" if os.getenv("BAPI_TOKEN") else "โ BAPI_TOKEN (ํ์)") | |
| env_checks.append("โ FRIENDLI_TOKEN" if os.getenv("FRIENDLI_TOKEN") else "โ FRIENDLI_TOKEN (ํ์)") | |
| print("ํ๊ฒฝ๋ณ์ ์ํ:") | |
| for check in env_checks: | |
| print(f" {check}") | |
| print("="*60 + "\n") | |
| # Gradio ์ฑ ์คํ | |
| demo = create_ui() | |
| demo.launch( | |
| share=False, | |
| server_name="0.0.0.0", | |
| server_port=7860 | |
| ) | |
| if __name__ == "__main__": | |
| main() |