seawolf2357's picture
Update app.py
f7e8a67 verified
raw
history blame
15.4 kB
from flask import Flask, render_template, request, redirect, url_for, jsonify, session
import requests
import os
import json
from datetime import timedelta
import logging
# ๋กœ๊น… ์„ค์ •
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
app = Flask(__name__)
app.secret_key = os.urandom(24) # ์„ธ์…˜ ์•”ํ˜ธํ™”๋ฅผ ์œ„ํ•œ ๋น„๋ฐ€ ํ‚ค
app.permanent_session_lifetime = timedelta(days=7) # ์„ธ์…˜ ์œ ์ง€ ๊ธฐ๊ฐ„ ์„ค์ •
# ์ข‹์•„์š” ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ ํ•จ์ˆ˜ - ๋””๋ฒ„๊น… ๊ฐœ์„ 
def get_liked_repos(token):
headers = {"Authorization": f"Bearer {token}"}
liked_models = {}
# 1. API์— ์ง์ ‘ ์งˆ์˜
endpoints = [
"/api/me/likes",
"/api/me/liked-repos",
"/api/me/favorites"
]
logger.debug(f"ํ† ํฐ์œผ๋กœ ์ข‹์•„์š” ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ ์‹œ๋„ (ํ† ํฐ ์ผ๋ถ€: {token[:4]}...)")
for endpoint in endpoints:
logger.debug(f"์—”๋“œํฌ์ธํŠธ ์‹œ๋„: {endpoint}")
try:
full_url = f"https://huggingface.co{endpoint}"
logger.debug(f"API ํ˜ธ์ถœ: {full_url}")
response = requests.get(full_url, headers=headers)
logger.debug(f"์‘๋‹ต ์ƒํƒœ: {response.status_code}")
if response.ok:
data = response.json()
logger.debug(f"์‘๋‹ต ๋ฐ์ดํ„ฐ ํƒ€์ž…: {type(data)}")
logger.debug(f"๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ: {str(data)[:200]}")
if isinstance(data, list):
logger.debug(f"๋ชฉ๋ก ๊ธธ์ด: {len(data)}")
for i, model in enumerate(data[:5]): # ์ฒ˜์Œ 5๊ฐœ๋งŒ ๋กœ๊น…
logger.debug(f"๋ชจ๋ธ {i}: {model}")
if isinstance(model, dict):
# ๋‹ค์–‘ํ•œ API ์‘๋‹ต ๊ตฌ์กฐ ์ฒ˜๋ฆฌ
if 'owner' in model and 'name' in model:
model_id = f"{model['owner']}/{model['name']}"
liked_models[model_id] = True
logger.debug(f"์ถ”๊ฐ€๋œ ๋ชจ๋ธ ID: {model_id}")
elif 'id' in model:
liked_models[model['id']] = True
logger.debug(f"์ถ”๊ฐ€๋œ ๋ชจ๋ธ ID: {model['id']}")
elif 'modelId' in model:
liked_models[model['modelId']] = True
logger.debug(f"์ถ”๊ฐ€๋œ ๋ชจ๋ธ ID: {model['modelId']}")
else:
# ๋‹ค๋ฅธ ํ•„๋“œ ํ™•์ธ
logger.debug(f"๋ชจ๋ธ ํ‚ค: {list(model.keys())}")
# ์ง์ ‘ owner/repo ํ˜•์‹ ์ถ”์ถœ ์‹œ๋„
if 'repo' in model and 'rowner' in model:
model_id = f"{model['rowner']}/{model['repo']}"
liked_models[model_id] = True
logger.debug(f"์ถ”๊ฐ€๋œ ๋ชจ๋ธ ID: {model_id}")
elif isinstance(data, dict):
logger.debug(f"๊ฐ์ฒด ํ‚ค: {list(data.keys())}")
# ๊ฐ์ฒด ๊ตฌ์กฐ์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌ
if 'models' in data and isinstance(data['models'], list):
for model in data['models']:
if isinstance(model, dict) and 'id' in model:
liked_models[model['id']] = True
logger.debug(f"์ถ”๊ฐ€๋œ ๋ชจ๋ธ ID: {model['id']}")
else:
# ๋‹จ์ˆœ ํ‚ค-๊ฐ’ ๊ตฌ์กฐ๋ผ๋ฉด
for key in data:
liked_models[key] = True
logger.debug(f"์ถ”๊ฐ€๋œ ํ‚ค: {key}")
logger.debug(f"์ด ์ข‹์•„์š” ํ•ญ๋ชฉ ์ˆ˜: {len(liked_models)}")
if len(liked_models) > 0:
logger.debug("์ข‹์•„์š” ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ ์„ฑ๊ณต!")
return liked_models
else:
logger.debug(f"API ์˜ค๋ฅ˜: {response.text}")
except Exception as e:
logger.error(f"์—”๋“œํฌ์ธํŠธ {endpoint} ์˜ค๋ฅ˜: {str(e)}")
# 2. ์ˆ˜๋™ ์ŠคํŽ˜์ด์Šค/๋ชจ๋ธ ํ™•์ธ (API๊ฐ€ ์‹คํŒจํ•œ ๊ฒฝ์šฐ)
logger.debug("API ์กฐํšŒ ์‹คํŒจ, ์ˆ˜๋™ ์ŠคํŽ˜์ด์Šค/๋ชจ๋ธ ํ™•์ธ ์‹œ๋„")
try:
# "me" ํŽ˜์ด์ง€ ์ ‘๊ทผํ•ด์„œ HTML์—์„œ ์ข‹์•„์š” ์ •๋ณด ์ฐพ๊ธฐ
response = requests.get("https://huggingface.co/me/likes", headers=headers)
if response.ok:
logger.debug("์ข‹์•„์š” ํŽ˜์ด์ง€ ๊ฐ€์ ธ์˜ค๊ธฐ ์„ฑ๊ณต")
# ์—ฌ๊ธฐ์„œ HTML ํŒŒ์‹ฑํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๋ณต์žกํ•˜๋ฏ€๋กœ ์ƒ๋žต
except Exception as e:
logger.error(f"์ˆ˜๋™ ํ™•์ธ ์˜ค๋ฅ˜: {str(e)}")
# 3. API ๊ฒฐ๊ณผ ํ™•์ธ ํŽ˜์ด์ง€ ์ถ”๊ฐ€ (๋””๋ฒ„๊น…์šฉ)
@app.route('/api/debug-likes', methods=['GET'])
def debug_likes():
if 'token' not in session:
return jsonify({'success': False, 'message': '๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.'})
headers = {"Authorization": f"Bearer {session['token']}"}
results = {}
for endpoint in ["/api/me/likes", "/api/me/liked-repos", "/api/me/favorites"]:
try:
response = requests.get(f"https://huggingface.co{endpoint}", headers=headers)
results[endpoint] = {
'status': response.status_code,
'ok': response.ok,
'data': response.json() if response.ok else None
}
except Exception as e:
results[endpoint] = {'error': str(e)}
return jsonify(results)
# ์ข‹์•„์š” ์ƒํƒœ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ๋นˆ ๊ฐ์ฒด ๋ฐ˜ํ™˜
logger.debug("์ข‹์•„์š” ๋ชฉ๋ก ์—†์Œ, ๋นˆ ๊ฐ์ฒด ๋ฐ˜ํ™˜")
return liked_models
# ๋ฉ”์ธ ์•ฑ์šฉ ํ”Œ๋ž˜๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋””๋ฒ„๊น… ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€
def add_debug_endpoints(app):
@app.route('/api/debug-likes', methods=['GET'])
def debug_likes():
if 'token' not in session:
return jsonify({'success': False, 'message': '๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.'})
headers = {"Authorization": f"Bearer {session['token']}"}
results = {}
for endpoint in ["/api/me/likes", "/api/me/liked-repos", "/api/me/favorites"]:
try:
response = requests.get(f"https://huggingface.co{endpoint}", headers=headers)
results[endpoint] = {
'status': response.status_code,
'ok': response.ok
}
# ์„ฑ๊ณตํ•œ ๊ฒฝ์šฐ์—๋งŒ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
if response.ok:
try:
results[endpoint]['data'] = response.json()
except Exception as e:
results[endpoint]['parse_error'] = str(e)
except Exception as e:
results[endpoint] = {'error': str(e)}
# ํ˜„์žฌ ์„ธ์…˜์— ์ €์žฅ๋œ ์ข‹์•„์š” ๋ชฉ๋ก ๋ฐ˜ํ™˜
results['current_session_likes'] = {
'count': len(session.get('liked_models', {})),
'items': list(session.get('liked_models', {}).keys())
}
return jsonify(results)
@app.route('/api/debug-urls', methods=['GET'])
def debug_urls():
# ๋ชจ๋ธ ์ •๋ณด ์ถ”์ถœ ๋””๋ฒ„๊น…
from urllib.parse import urlparse
test_urls = [
"https://huggingface.co/spaces/ginipick/Tech_Hangman_Game",
"https://huggingface.co/models/meta/llama-2",
"https://huggingface.co/meta/llama-2"
]
results = {}
for url in test_urls:
try:
parsed = urlparse(url)
path_parts = parsed.path.split('/')
path_parts = [p for p in path_parts if p] # ๋นˆ ๋ฌธ์ž์—ด ์ œ๊ฑฐ
result = {
'parsed_url': {
'scheme': parsed.scheme,
'netloc': parsed.netloc,
'path': parsed.path,
'path_parts': path_parts
}
}
# ๊ฒฝ๋กœ ํŒŒ์‹ฑ
if len(path_parts) >= 2:
if path_parts[0] == 'spaces' or path_parts[0] == 'models':
result['extract'] = {
'type': path_parts[0],
'owner': path_parts[1],
'repo': path_parts[2] if len(path_parts) > 2 else None,
'full_id': f"{path_parts[1]}/{path_parts[2]}" if len(path_parts) > 2 else f"{path_parts[1]}"
}
else:
result['extract'] = {
'type': 'models', # ๊ธฐ๋ณธ๊ฐ’
'owner': path_parts[0],
'repo': path_parts[1] if len(path_parts) > 1 else None,
'full_id': f"{path_parts[0]}/{path_parts[1]}" if len(path_parts) > 1 else f"{path_parts[0]}"
}
results[url] = result
except Exception as e:
results[url] = {'error': str(e)}
return jsonify(results)
# ์ด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ง์ ‘ ์‹คํ–‰๋˜๋ฉด ํ…Œ์ŠคํŠธ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘
if __name__ == '__main__':
test_app = Flask(__name__)
test_app.secret_key = os.urandom(24)
# ์„ธ์…˜ ์ฟ ํ‚ค ์„ค์ •
test_app.config['SESSION_COOKIE_SECURE'] = False # HTTPS ์—†์ด๋„ ์ž‘๋™
test_app.config['SESSION_COOKIE_HTTPONLY'] = True
add_debug_endpoints(test_app)
@test_app.route('/')
def home():
return '''
<h1>ํ—ˆ๊น…ํŽ˜์ด์Šค ์ข‹์•„์š” ๋””๋ฒ„๊ฑฐ</h1>
<p>๋‹ค์Œ ์—”๋“œํฌ์ธํŠธ๋กœ ์ ‘์†ํ•˜์„ธ์š”:</p>
<ul>
<li><a href="/login-form">๋กœ๊ทธ์ธ ํŽ˜์ด์ง€</a></li>
<li><a href="/api/debug-likes">์ข‹์•„์š” API ๋””๋ฒ„๊ทธ (๋กœ๊ทธ์ธ ํ•„์š”)</a></li>
<li><a href="/api/debug-urls">URL ํŒŒ์‹ฑ ๋””๋ฒ„๊ทธ</a></li>
</ul>
'''
@test_app.route('/login-form')
def login_form():
return '''
<!DOCTYPE html>
<html>
<head>
<title>ํ† ํฐ ๋กœ๊ทธ์ธ</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; }
input { width: 100%; padding: 8px; margin: 10px 0; }
button { padding: 10px 15px; background: #4CAF50; color: white; border: none; cursor: pointer; }
.result { margin-top: 20px; padding: 10px; border: 1px solid #ddd; display: none; }
pre { background: #f5f5f5; padding: 10px; overflow-x: auto; }
</style>
</head>
<body>
<h1>ํ—ˆ๊น…ํŽ˜์ด์Šค ํ† ํฐ ํ…Œ์ŠคํŠธ</h1>
<p>ํ—ˆ๊น…ํŽ˜์ด์Šค API ํ† ํฐ์„ ์ž…๋ ฅํ•˜์„ธ์š”:</p>
<input type="password" id="tokenInput" placeholder="API ํ† ํฐ" />
<button id="loginBtn">๋กœ๊ทธ์ธ</button>
<div id="result" class="result">
<h3>๊ฒฐ๊ณผ</h3>
<pre id="resultContent"></pre>
</div>
<script>
const loginBtn = document.getElementById('loginBtn');
const tokenInput = document.getElementById('tokenInput');
const result = document.getElementById('result');
const resultContent = document.getElementById('resultContent');
loginBtn.addEventListener('click', async () => {
const token = tokenInput.value.trim();
if (!token) {
alert('ํ† ํฐ์„ ์ž…๋ ฅํ•˜์„ธ์š”');
return;
}
try {
const formData = new FormData();
formData.append('token', token);
const response = await fetch('/api/login-test', {
method: 'POST',
body: formData
});
const data = await response.json();
result.style.display = 'block';
resultContent.textContent = JSON.stringify(data, null, 2);
if (data.success) {
// ์„ฑ๊ณต ์‹œ ์ข‹์•„์š” ๋ชฉ๋ก ํŽ˜์ด์ง€๋กœ ์ด๋™
setTimeout(() => {
window.location.href = '/api/debug-likes';
}, 2000);
}
} catch (error) {
result.style.display = 'block';
resultContent.textContent = `์˜ค๋ฅ˜: ${error.message}`;
}
});
</script>
</body>
</html>
'''
@test_app.route('/api/login-test', methods=['POST'])
def login_test():
token = request.form.get('token', '')
if not token:
return jsonify({'success': False, 'message': 'ํ† ํฐ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.'})
session['token'] = token
# ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
user_info = None
for endpoint in ["https://huggingface.co/api/whoami-v2", "https://huggingface.co/api/whoami"]:
try:
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(endpoint, headers=headers)
if response.ok:
user_info = response.json()
break
except Exception as e:
logger.error(f"์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ ์˜ค๋ฅ˜: {str(e)}")
if not user_info:
return jsonify({'success': False, 'message': '์œ ํšจํ•˜์ง€ ์•Š์€ ํ† ํฐ์ž…๋‹ˆ๋‹ค.'})
# ์‚ฌ์šฉ์ž ์ด๋ฆ„ ์ฐพ๊ธฐ
username = None
if 'name' in user_info:
username = user_info['name']
elif 'user' in user_info and 'username' in user_info['user']:
username = user_info['user']['username']
elif 'username' in user_info:
username = user_info['username']
else:
username = '์ธ์ฆ๋œ ์‚ฌ์šฉ์ž'
session['username'] = username
# ์ข‹์•„์š” ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ
liked_models = get_liked_repos(token)
session['liked_models'] = liked_models
return jsonify({
'success': True,
'username': username,
'liked_models_count': len(liked_models),
'liked_models_sample': list(liked_models.keys())[:5] if liked_models else []
})
# ๋””๋ฒ„๊น… ์„œ๋ฒ„ ์‹คํ–‰
logger.info("๋””๋ฒ„๊น… ์„œ๋ฒ„ ์‹œ์ž‘ (ํฌํŠธ 7860)")
test_app.run(host='0.0.0.0', port=7860, debug=True)