import gradio as gr import requests from datetime import datetime, timedelta import pandas as pd import plotly.express as px def get_user_spaces(token): """사용자의 모든 Space 목록을 가져옵니다.""" headers = {"Authorization": f"Bearer {token}"} try: # 사용자 정보 가져오기 user_info = requests.get("https://huggingface.co/api/whoami", headers=headers) user_info.raise_for_status() username = user_info.json().get('name') if not username: return None, "사용자 정보를 가져올 수 없습니다." # 사용자의 Space 목록 가져오기 spaces_url = f"https://huggingface.co/api/spaces/{username}" spaces_response = requests.get(spaces_url, headers=headers) spaces_response.raise_for_status() return username, spaces_response.json() except requests.exceptions.RequestException as e: return None, f"API 요청 실패: {str(e)}" def get_space_visitors(owner, space_name, token): """특정 Space의 방문자 통계를 가져옵니다.""" url = f"https://huggingface.co/api/spaces/{owner}/{space_name}/metrics" headers = {"Authorization": f"Bearer {token}"} try: response = requests.get(url, headers=headers) response.raise_for_status() # 최근 7일간의 데이터만 필터링 today = datetime.now() week_ago = today - timedelta(days=7) daily_visits = {} total_visits = 0 for record in response.json(): date = datetime.fromtimestamp(record['timestamp']) if date >= week_ago: date_str = date.strftime('%Y-%m-%d') visits = record.get('visits', 0) daily_visits[date_str] = daily_visits.get(date_str, 0) + visits total_visits += visits return { 'name': space_name, 'total_visits': total_visits, 'daily_visits': daily_visits } except requests.exceptions.RequestException: return None def analyze_spaces(token): """모든 Space의 방문자 통계를 분석합니다.""" if not token: return "API 토큰을 입력해주세요.", None, None # 사용자 정보와 Space 목록 가져오기 username, spaces_data = get_user_spaces(token) if not username: return f"오류: {spaces_data}", None, None if not isinstance(spaces_data, list): return "Space 목록을 가져올 수 없습니다.", None, None # 각 Space의 방문자 통계 수집 all_stats = [] daily_data = [] for space in spaces_data: space_name = space.get('id') if space_name: stats = get_space_visitors(username, space_name, token) if stats: all_stats.append(stats) for date, visits in stats['daily_visits'].items(): daily_data.append({ 'date': date, 'space': space_name, 'visits': visits }) if not all_stats: return "방문자 통계를 가져올 수 없습니다.", None, None # 결과 텍스트 생성 result_text = f"계정: {username}\n\n" for stats in sorted(all_stats, key=lambda x: x['total_visits'], reverse=True): result_text += f"Space: {stats['name']}\n" result_text += f"총 방문자 수: {stats['total_visits']}명\n\n" # 그래프 생성 if daily_data: df = pd.DataFrame(daily_data) fig = px.line(df, x='date', y='visits', color='space', title=f'Space별 일일 방문자 수', labels={'date': '날짜', 'visits': '방문자 수', 'space': 'Space 이름'}) # 막대 그래프 생성 summary_df = pd.DataFrame([(s['name'], s['total_visits']) for s in all_stats], columns=['space', 'total_visits']) summary_fig = px.bar(summary_df, x='space', y='total_visits', title='Space별 총 방문자 수', labels={'space': 'Space 이름', 'total_visits': '총 방문자 수'}) return result_text, fig, summary_fig return result_text, None, None # Gradio 인터페이스 생성 with gr.Blocks() as app: gr.Markdown(""" # Hugging Face Space 방문자 통계 API 토큰을 입력하면 모든 Space의 방문자 통계를 확인할 수 있습니다. """) with gr.Row(): token_input = gr.Textbox(label="API 토큰", type="password") submit_btn = gr.Button("통계 확인") stats_output = gr.Textbox(label="통계 정보", lines=10) plot_output = gr.Plot(label="일별 방문자 수") summary_plot = gr.Plot(label="총 방문자 수") submit_btn.click( analyze_spaces, inputs=[token_input], outputs=[stats_output, plot_output, summary_plot] ) if __name__ == "__main__": app.launch()