Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -432,30 +432,38 @@ if __name__ == "__main__":
|
|
| 432 |
"summary": f"Smart template created for {repo_name}"
|
| 433 |
}
|
| 434 |
|
| 435 |
-
def clone(repo_git, repo_hf, sdk_type, skip_lfs, enable_smart_generation,
|
| 436 |
folder = str(uuid.uuid4())
|
| 437 |
|
| 438 |
-
#
|
| 439 |
-
if
|
| 440 |
-
hf_token =
|
| 441 |
-
|
| 442 |
-
|
| 443 |
-
|
|
|
|
|
|
|
| 444 |
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 445 |
|
| 446 |
try:
|
| 447 |
yield "🔄 Starting clone process..."
|
| 448 |
|
| 449 |
-
# HuggingFace
|
| 450 |
try:
|
| 451 |
-
login(token=hf_token)
|
| 452 |
api = HfApi(token=hf_token)
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
|
|
|
| 456 |
except Exception as e:
|
| 457 |
yield f"❌ HuggingFace authentication failed: {str(e)}"
|
| 458 |
-
yield "Please check your token or try OAuth login"
|
| 459 |
return
|
| 460 |
|
| 461 |
# URL 정규화 및 검증
|
|
@@ -1184,60 +1192,36 @@ with gr.Blocks(css=css, theme=gr.themes.Soft(
|
|
| 1184 |
</div>
|
| 1185 |
""")
|
| 1186 |
|
| 1187 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1188 |
with gr.Tab("🚀 GitHub → HF Space", elem_id="tab1"):
|
| 1189 |
-
# OAuth 로그인 섹션
|
| 1190 |
-
with gr.Group(elem_classes="input-section", visible=True) as auth_section:
|
| 1191 |
-
gr.HTML("""
|
| 1192 |
-
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 1193 |
-
padding: 20px; border-radius: 10px; color: white; margin-bottom: 20px;">
|
| 1194 |
-
<h3 style="margin: 0 0 10px 0;">🔐 HuggingFace Authentication Required</h3>
|
| 1195 |
-
<p style="margin: 5px 0;">Choose one of the following methods to authenticate:</p>
|
| 1196 |
-
</div>
|
| 1197 |
-
""")
|
| 1198 |
-
|
| 1199 |
-
with gr.Row():
|
| 1200 |
-
with gr.Column():
|
| 1201 |
-
gr.Markdown("""
|
| 1202 |
-
### Option 1: OAuth Login (Recommended)
|
| 1203 |
-
Click the button below to login with your HuggingFace account
|
| 1204 |
-
""")
|
| 1205 |
-
gr.HTML("""
|
| 1206 |
-
<a href="https://huggingface.co/login?next=%2Fsettings%2Ftokens" target="_blank">
|
| 1207 |
-
<button style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 1208 |
-
color: white; border: none; padding: 12px 24px;
|
| 1209 |
-
border-radius: 8px; font-size: 16px; font-weight: 600;
|
| 1210 |
-
cursor: pointer; width: 100%; margin: 10px 0;">
|
| 1211 |
-
🤗 Login with HuggingFace
|
| 1212 |
-
</button>
|
| 1213 |
-
</a>
|
| 1214 |
-
""")
|
| 1215 |
-
gr.Markdown("""
|
| 1216 |
-
After login:
|
| 1217 |
-
1. Go to [Settings → Access Tokens](https://huggingface.co/settings/tokens)
|
| 1218 |
-
2. Create a new token with **write** access
|
| 1219 |
-
3. Copy and paste it below
|
| 1220 |
-
""")
|
| 1221 |
-
|
| 1222 |
-
with gr.Column():
|
| 1223 |
-
gr.Markdown("""
|
| 1224 |
-
### Option 2: Direct Token Input
|
| 1225 |
-
If you already have a token, enter it here
|
| 1226 |
-
""")
|
| 1227 |
-
hf_token_input = gr.Textbox(
|
| 1228 |
-
label="HuggingFace Token",
|
| 1229 |
-
type="password",
|
| 1230 |
-
placeholder="hf_xxxxxxxxxxxxxxxxxxxxx",
|
| 1231 |
-
info="Your HF token with write access"
|
| 1232 |
-
)
|
| 1233 |
-
gr.Markdown("""
|
| 1234 |
-
**Need a token?**
|
| 1235 |
-
1. Visit [HuggingFace Tokens](https://huggingface.co/settings/tokens)
|
| 1236 |
-
2. Click "New token"
|
| 1237 |
-
3. Give it a name and select "write" role
|
| 1238 |
-
4. Copy the token here
|
| 1239 |
-
""")
|
| 1240 |
-
|
| 1241 |
with gr.Row():
|
| 1242 |
with gr.Column(scale=5):
|
| 1243 |
with gr.Group(elem_classes="input-section"):
|
|
@@ -1272,7 +1256,7 @@ with gr.Blocks(css=css, theme=gr.themes.Soft(
|
|
| 1272 |
enable_smart_generation = gr.Checkbox(
|
| 1273 |
label="🤖 AI-Powered App Generation",
|
| 1274 |
value=False,
|
| 1275 |
-
info="Generate app.py automatically"
|
| 1276 |
)
|
| 1277 |
|
| 1278 |
btn_to_hf = gr.Button("🚀 Deploy to HuggingFace",
|
|
@@ -1291,40 +1275,9 @@ with gr.Blocks(css=css, theme=gr.themes.Soft(
|
|
| 1291 |
show_copy_button=True
|
| 1292 |
)
|
| 1293 |
|
| 1294 |
-
# Token 상태 표시
|
| 1295 |
-
with gr.Row():
|
| 1296 |
-
token_status = gr.HTML("""
|
| 1297 |
-
<div id="token-status" style="background: #fef2f2; border: 1px solid #fecaca;
|
| 1298 |
-
border-radius: 8px; padding: 12px; margin-top: 10px;">
|
| 1299 |
-
<span style="color: #dc2626; font-weight: 600;">⚠️ Status:</span>
|
| 1300 |
-
<span style="color: #7f1d1d;"> No token provided. Please login or enter your token above.</span>
|
| 1301 |
-
</div>
|
| 1302 |
-
""")
|
| 1303 |
-
|
| 1304 |
-
# Token 입력시 상태 업데이트
|
| 1305 |
-
def update_token_status(token):
|
| 1306 |
-
if token and token.strip():
|
| 1307 |
-
return """
|
| 1308 |
-
<div style="background: #f0fdf4; border: 1px solid #bbf7d0;
|
| 1309 |
-
border-radius: 8px; padding: 12px; margin-top: 10px;">
|
| 1310 |
-
<span style="color: #16a34a; font-weight: 600;">✅ Status:</span>
|
| 1311 |
-
<span style="color: #14532d;"> Token provided. Ready to deploy!</span>
|
| 1312 |
-
</div>
|
| 1313 |
-
"""
|
| 1314 |
-
else:
|
| 1315 |
-
return """
|
| 1316 |
-
<div style="background: #fef2f2; border: 1px solid #fecaca;
|
| 1317 |
-
border-radius: 8px; padding: 12px; margin-top: 10px;">
|
| 1318 |
-
<span style="color: #dc2626; font-weight: 600;">⚠️ Status:</span>
|
| 1319 |
-
<span style="color: #7f1d1d;"> No token provided. Please login or enter your token above.</span>
|
| 1320 |
-
</div>
|
| 1321 |
-
"""
|
| 1322 |
-
|
| 1323 |
-
hf_token_input.change(update_token_status, inputs=[hf_token_input], outputs=[token_status])
|
| 1324 |
-
|
| 1325 |
btn_to_hf.click(
|
| 1326 |
fn=clone,
|
| 1327 |
-
inputs=[repo_git, repo_hf, sdk_choices, skip_lfs, enable_smart_generation
|
| 1328 |
outputs=output_to_hf
|
| 1329 |
)
|
| 1330 |
|
|
|
|
| 432 |
"summary": f"Smart template created for {repo_name}"
|
| 433 |
}
|
| 434 |
|
| 435 |
+
def clone(repo_git, repo_hf, sdk_type, skip_lfs, enable_smart_generation, profile: gr.OAuthProfile = None, oauth_token: gr.OAuthToken = None):
|
| 436 |
folder = str(uuid.uuid4())
|
| 437 |
|
| 438 |
+
# OAuth 인증 우선, 없으면 환경변수 사용
|
| 439 |
+
if oauth_token:
|
| 440 |
+
hf_token = oauth_token.token
|
| 441 |
+
username = profile.username if profile else None
|
| 442 |
+
yield f"✅ Authenticated via OAuth as: @{username}"
|
| 443 |
+
elif profile:
|
| 444 |
+
# Profile은 있지만 token이 없는 경우 (권한 부족)
|
| 445 |
+
yield "❌ Error: Insufficient permissions. Please logout and login again with write access."
|
| 446 |
return
|
| 447 |
+
else:
|
| 448 |
+
# OAuth 없을 때 환경변수 체크
|
| 449 |
+
hf_token = os.getenv("HF_TOKEN")
|
| 450 |
+
if not hf_token:
|
| 451 |
+
yield "❌ Error: Please login with HuggingFace using the 'Sign in with Hugging Face' button at the top."
|
| 452 |
+
return
|
| 453 |
+
username = None
|
| 454 |
|
| 455 |
try:
|
| 456 |
yield "🔄 Starting clone process..."
|
| 457 |
|
| 458 |
+
# HuggingFace API 인증
|
| 459 |
try:
|
|
|
|
| 460 |
api = HfApi(token=hf_token)
|
| 461 |
+
if not username: # OAuth로 로그인하지 않은 경우 username 가져오기
|
| 462 |
+
user_info = api.whoami()
|
| 463 |
+
username = user_info["name"]
|
| 464 |
+
yield f"✅ Authenticated as HuggingFace user: @{username}"
|
| 465 |
except Exception as e:
|
| 466 |
yield f"❌ HuggingFace authentication failed: {str(e)}"
|
|
|
|
| 467 |
return
|
| 468 |
|
| 469 |
# URL 정규화 및 검증
|
|
|
|
| 1192 |
</div>
|
| 1193 |
""")
|
| 1194 |
|
| 1195 |
+
with gr.Blocks(css=css, theme=gr.themes.Soft(
|
| 1196 |
+
primary_hue="purple",
|
| 1197 |
+
secondary_hue="purple",
|
| 1198 |
+
neutral_hue="slate"
|
| 1199 |
+
)) as demo:
|
| 1200 |
+
gr.HTML("""
|
| 1201 |
+
<div class="main-header">
|
| 1202 |
+
<h1 style="font-size: 2.5rem; margin: 0; font-weight: 700;">
|
| 1203 |
+
🔄 Repository Converter Pro
|
| 1204 |
+
</h1>
|
| 1205 |
+
<p style="font-size: 1.1rem; margin-top: 10px; opacity: 0.95;">
|
| 1206 |
+
Seamlessly transfer repositories between GitHub and HuggingFace
|
| 1207 |
+
</p>
|
| 1208 |
+
</div>
|
| 1209 |
+
""")
|
| 1210 |
+
|
| 1211 |
+
# OAuth 로그인 버튼을 상단에 배치
|
| 1212 |
+
with gr.Row():
|
| 1213 |
+
with gr.Column(scale=4):
|
| 1214 |
+
gr.LoginButton()
|
| 1215 |
+
with gr.Column(scale=8):
|
| 1216 |
+
login_status = gr.HTML("""
|
| 1217 |
+
<div style="padding: 10px; background: #fef2f2; border: 1px solid #fecaca;
|
| 1218 |
+
border-radius: 8px; margin: 5px 0;">
|
| 1219 |
+
<span style="color: #dc2626;">⚠️ Please login with HuggingFace to continue</span>
|
| 1220 |
+
</div>
|
| 1221 |
+
""")
|
| 1222 |
+
|
| 1223 |
+
with gr.Tabs(elem_classes="tabs") as main_tabs:
|
| 1224 |
with gr.Tab("🚀 GitHub → HF Space", elem_id="tab1"):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1225 |
with gr.Row():
|
| 1226 |
with gr.Column(scale=5):
|
| 1227 |
with gr.Group(elem_classes="input-section"):
|
|
|
|
| 1256 |
enable_smart_generation = gr.Checkbox(
|
| 1257 |
label="🤖 AI-Powered App Generation",
|
| 1258 |
value=False,
|
| 1259 |
+
info="Generate app.py automatically (requires FIREWORKS_API_KEY)"
|
| 1260 |
)
|
| 1261 |
|
| 1262 |
btn_to_hf = gr.Button("🚀 Deploy to HuggingFace",
|
|
|
|
| 1275 |
show_copy_button=True
|
| 1276 |
)
|
| 1277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1278 |
btn_to_hf.click(
|
| 1279 |
fn=clone,
|
| 1280 |
+
inputs=[repo_git, repo_hf, sdk_choices, skip_lfs, enable_smart_generation],
|
| 1281 |
outputs=output_to_hf
|
| 1282 |
)
|
| 1283 |
|