Spaces:
Running
Running
| 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 - %(name)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) # ์ธ์ ์ ์ง ๊ธฐ๊ฐ ์ค์ | |
| # ํ๊น ํ์ด์ค URL ๋ชฉ๋ก (๊ฐ๋ตํ) | |
| HUGGINGFACE_URLS = [ | |
| "https://huggingface.co/spaces/ginipick/Tech_Hangman_Game", | |
| "https://huggingface.co/spaces/openfree/deepseek_r1_API", | |
| "https://huggingface.co/spaces/ginipick/open_Deep-Research" | |
| ] | |
| # ํ๊น ํ์ด์ค ์ธ์ฆ ํ์ธ (๋๋ฒ๊น ๊ฐ์ ) | |
| def validate_token(token): | |
| logger.debug(f"ํ ํฐ ๊ฒ์ฆ ์๋ (ํ ํฐ ์ผ๋ถ: {token[:4]}...)") | |
| headers = {"Authorization": f"Bearer {token}"} | |
| # ์ฌ๋ฌ ์๋ํฌ์ธํธ ์๋ | |
| api_endpoints = [ | |
| "https://huggingface.co/api/whoami", | |
| "https://huggingface.co/api/whoami-v2" | |
| ] | |
| for endpoint in api_endpoints: | |
| try: | |
| logger.debug(f"API ์๋ํฌ์ธํธ ์๋: {endpoint}") | |
| response = requests.get(endpoint, headers=headers) | |
| # ์๋ต ๋ก๊น | |
| logger.debug(f"API ์๋ต ์ํ ์ฝ๋: {response.status_code}") | |
| logger.debug(f"API ์๋ต ํค๋: {response.headers}") | |
| if response.ok: | |
| logger.debug("ํ ํฐ ๊ฒ์ฆ ์ฑ๊ณต!") | |
| return True, response.json() | |
| else: | |
| logger.debug(f"ํ ํฐ ๊ฒ์ฆ ์คํจ - ์๋ต: {response.text}") | |
| except Exception as e: | |
| logger.error(f"API ํธ์ถ ์ค ์ค๋ฅ ๋ฐ์: {str(e)}") | |
| # ๋ชจ๋ API ํธ์ถ ์คํจ | |
| return False, None | |
| # ํ ํฐ ๊ฒ์ฆ ํ ์คํธ API | |
| def test_token(): | |
| token = request.form.get('token', '') | |
| if not token: | |
| return jsonify({'success': False, 'message': 'ํ ํฐ์ ์ ๋ ฅํด์ฃผ์ธ์.'}) | |
| # ์์ธ ๋๋ฒ๊น ์ ๋ณด ์์ง | |
| debug_info = {} | |
| # ํ ํฐ ํ์ ํ์ธ | |
| is_valid_format = token.startswith('hf_') | |
| debug_info['token_format'] = 'hf_ ์ ๋์ฌ ์์' if is_valid_format else '์ ๋์ฌ ์์' | |
| # ์ง์ API ํธ์ถ ํ ์คํธ | |
| test_endpoints = [ | |
| "https://huggingface.co/api/whoami", | |
| "https://huggingface.co/api/whoami-v2", | |
| "https://huggingface.co/api/models/meta/llama" | |
| ] | |
| endpoint_results = {} | |
| for endpoint in test_endpoints: | |
| try: | |
| headers = {"Authorization": f"Bearer {token}"} | |
| response = requests.get(endpoint, headers=headers, timeout=5) | |
| endpoint_results[endpoint] = { | |
| 'status_code': response.status_code, | |
| 'success': response.ok, | |
| 'content_type': response.headers.get('Content-Type', 'unknown'), | |
| 'response_sample': str(response.text)[:100] + '...' if response.text else 'Empty response' | |
| } | |
| except Exception as e: | |
| endpoint_results[endpoint] = {'error': str(e)} | |
| debug_info['endpoint_tests'] = endpoint_results | |
| # ์ต์ข ํ๋จ | |
| is_valid = any(result.get('success', False) for result in endpoint_results.values()) | |
| return jsonify({ | |
| 'success': is_valid, | |
| 'debug_info': debug_info, | |
| 'message': 'ํ ํฐ์ด ์ ํจํฉ๋๋ค.' if is_valid else '์ ํจํ์ง ์์ ํ ํฐ์ ๋๋ค.' | |
| }) | |
| # ๊ธฐ๋ณธ ํํ์ด์ง (๋๋ฒ๊น ํ๋ฉด ํฌํจ) | |
| def home(): | |
| return render_template('debug_index.html') | |
| if __name__ == '__main__': | |
| # templates ํด๋ ์์ฑ | |
| os.makedirs('templates', exist_ok=True) | |
| # ๋๋ฒ๊น ์ฉ HTML ์์ฑ | |
| with open('templates/debug_index.html', 'w', encoding='utf-8') as f: | |
| f.write(''' | |
| <!DOCTYPE html> | |
| <html lang="ko"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ํ๊น ํ์ด์ค ํ ํฐ ๋๋ฒ๊ฑฐ</title> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| line-height: 1.6; | |
| margin: 0; | |
| padding: 20px; | |
| color: #333; | |
| } | |
| h1, h2 { | |
| color: #333; | |
| } | |
| .container { | |
| max-width: 800px; | |
| margin: 0 auto; | |
| } | |
| .card { | |
| border: 1px solid #ddd; | |
| border-radius: 5px; | |
| padding: 20px; | |
| margin-bottom: 20px; | |
| background-color: #f9f9f9; | |
| } | |
| input[type="password"] { | |
| width: 100%; | |
| padding: 10px; | |
| margin: 10px 0; | |
| border: 1px solid #ccc; | |
| border-radius: 4px; | |
| } | |
| button { | |
| padding: 10px 15px; | |
| background-color: #4CAF50; | |
| color: white; | |
| border: none; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| } | |
| button:hover { | |
| background-color: #45a049; | |
| } | |
| .result { | |
| margin-top: 20px; | |
| padding: 15px; | |
| border-radius: 5px; | |
| display: none; | |
| } | |
| .success { | |
| background-color: #dff0d8; | |
| color: #3c763d; | |
| } | |
| .error { | |
| background-color: #f2dede; | |
| color: #a94442; | |
| } | |
| pre { | |
| background-color: #f5f5f5; | |
| padding: 10px; | |
| border-radius: 5px; | |
| overflow-x: auto; | |
| white-space: pre-wrap; | |
| } | |
| .loading { | |
| display: none; | |
| margin-top: 10px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>ํ๊น ํ์ด์ค ํ ํฐ ๋๋ฒ๊ฑฐ</h1> | |
| <div class="card"> | |
| <h2>ํ ํฐ ํ ์คํธ</h2> | |
| <p>ํ๊น ํ์ด์ค API ํ ํฐ์ ์ ๋ ฅํ์ฌ ์ ํจ์ฑ์ ํ ์คํธํฉ๋๋ค.</p> | |
| <input type="password" id="tokenInput" placeholder="ํ๊น ํ์ด์ค API ํ ํฐ ์ ๋ ฅ (hf_๋ก ์์)" /> | |
| <button id="testButton">ํ ํฐ ํ ์คํธ</button> | |
| <div id="loading" class="loading">ํ ์คํธ ์ค...</div> | |
| <div id="result" class="result"> | |
| <h3>ํ ์คํธ ๊ฒฐ๊ณผ</h3> | |
| <p id="resultMessage"></p> | |
| <div id="detailsContainer"> | |
| <h4>์์ธ ์ ๋ณด</h4> | |
| <pre id="resultDetails"></pre> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="card"> | |
| <h2>๋๋ฒ๊น ํ</h2> | |
| <ul> | |
| <li>ํ ํฐ์ <code>hf_</code>๋ก ์์ํด์ผ ํฉ๋๋ค.</li> | |
| <li>ํ ํฐ์ ๊ณต๋ฐฑ ์์ด ์ ๋ ฅํด์ผ ํฉ๋๋ค.</li> | |
| <li>ํ ํฐ์ด ๋ง๋ฃ๋์ง ์์๋์ง ํ์ธํ์ธ์.</li> | |
| <li>ํ ํฐ์ ์ ์ ํ ๊ถํ(์ต์ READ)์ด ์๋์ง ํ์ธํ์ธ์.</li> | |
| <li>๋คํธ์ํฌ ์ ํ์ด ์๋ ํ๊ฒฝ์ธ์ง ํ์ธํ์ธ์.</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <script> | |
| // ์์ ์ฐธ์กฐ | |
| const tokenInput = document.getElementById('tokenInput'); | |
| const testButton = document.getElementById('testButton'); | |
| const loading = document.getElementById('loading'); | |
| const result = document.getElementById('result'); | |
| const resultMessage = document.getElementById('resultMessage'); | |
| const resultDetails = document.getElementById('resultDetails'); | |
| // ํ ํฐ ํ ์คํธ ํจ์ | |
| async function testToken() { | |
| const token = tokenInput.value.trim(); | |
| if (!token) { | |
| alert('ํ ํฐ์ ์ ๋ ฅํด์ฃผ์ธ์.'); | |
| return; | |
| } | |
| // UI ์ ๋ฐ์ดํธ | |
| loading.style.display = 'block'; | |
| result.style.display = 'none'; | |
| try { | |
| // FormData ์์ฑ | |
| const formData = new FormData(); | |
| formData.append('token', token); | |
| // API ํธ์ถ | |
| const response = await fetch('/api/test-token', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| const data = await response.json(); | |
| // ๊ฒฐ๊ณผ ํ์ | |
| result.className = `result ${data.success ? 'success' : 'error'}`; | |
| resultMessage.textContent = data.message; | |
| resultDetails.textContent = JSON.stringify(data.debug_info, null, 2); | |
| result.style.display = 'block'; | |
| } catch (error) { | |
| result.className = 'result error'; | |
| resultMessage.textContent = `์ค๋ฅ ๋ฐ์: ${error.message}`; | |
| resultDetails.textContent = error.stack || '์์ธ ์ ๋ณด ์์'; | |
| result.style.display = 'block'; | |
| } finally { | |
| loading.style.display = 'none'; | |
| } | |
| } | |
| // ์ด๋ฒคํธ ๋ฆฌ์ค๋ | |
| testButton.addEventListener('click', testToken); | |
| tokenInput.addEventListener('keypress', (event) => { | |
| if (event.key === 'Enter') { | |
| testToken(); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> | |
| ''') | |
| # ํ๊น ํ์ด์ค ์คํ์ด์ค์์๋ 7860 ํฌํธ ์ฌ์ฉ | |
| app.run(host='0.0.0.0', port=7860, debug=True) |