ginipick commited on
Commit
1cfe148
·
verified ·
1 Parent(s): fccd816

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -403
app.py DELETED
@@ -1,403 +0,0 @@
1
- import gradio as gr
2
- from huggingface_hub import InferenceClient, HfApi
3
- import os
4
- import requests
5
- from typing import List, Dict, Union
6
- import traceback
7
- from PIL import Image
8
- from io import BytesIO
9
- import asyncio
10
- from gradio_client import Client
11
- import time
12
- import threading
13
- import json
14
-
15
- HF_TOKEN = os.getenv("HF_TOKEN")
16
- hf_client = InferenceClient("CohereForAI/c4ai-command-r-plus-08-2024", token=HF_TOKEN)
17
- hf_api = HfApi(token=HF_TOKEN)
18
-
19
- def get_headers():
20
- if not HF_TOKEN:
21
- raise ValueError("Hugging Face token not found in environment variables")
22
- return {"Authorization": f"Bearer {HF_TOKEN}"}
23
-
24
- def get_most_liked_spaces(limit: int = 300) -> Union[List[Dict], str]:
25
- url = "https://huggingface.co/api/spaces"
26
- params = {
27
- "sort": "likes",
28
- "direction": -1,
29
- "limit": limit,
30
- "full": "true"
31
- }
32
-
33
- try:
34
- response = requests.get(url, params=params, headers=get_headers())
35
- response.raise_for_status()
36
- return response.json()
37
- except requests.RequestException as e:
38
- return f"API request error: {str(e)}"
39
- except ValueError as e:
40
- return f"JSON decoding error: {str(e)}"
41
-
42
- def format_space(space: Dict) -> Dict:
43
- space_id = space.get('id', 'Unknown')
44
- space_name = space_id.split('/')[-1] if '/' in space_id else space_id
45
-
46
- space_author = space.get('author', 'Unknown')
47
- if isinstance(space_author, dict):
48
- space_author = space_author.get('user', space_author.get('name', 'Unknown'))
49
-
50
- space_likes = space.get('likes', 'N/A')
51
- space_url = f"https://huggingface.co/spaces/{space_id}"
52
-
53
- return {
54
- "id": space_id,
55
- "name": space_name,
56
- "author": space_author,
57
- "likes": space_likes,
58
- "url": space_url,
59
- "description": space.get('description', '')
60
- }
61
-
62
- def format_spaces(spaces: Union[List[Dict], str]) -> List[Dict]:
63
- if isinstance(spaces, str):
64
- return [{"error": spaces}]
65
-
66
- return [format_space(space) for space in spaces if isinstance(space, dict)]
67
-
68
- def summarize_space(space: Dict) -> str:
69
- system_message = "당신은 Hugging Face Space의 내용을 요약하는 AI 조수입니다. 주어진 정보를 바탕으로 간결하고 명확한 요약을 제공해주세요."
70
- user_message = f"다음 Hugging Face Space를 요약해주세요: {space['name']} by {space['author']}. 좋아요 수: {space['likes']}. URL: {space['url']}"
71
-
72
- messages = [
73
- {"role": "system", "content": system_message},
74
- {"role": "user", "content": user_message}
75
- ]
76
-
77
- try:
78
- response = hf_client.chat_completion(messages, max_tokens=400, temperature=0.7)
79
- return response.choices[0].message.content
80
- except Exception as e:
81
- return f"요약 생성 중 오류 발생: {str(e)}"
82
-
83
- def get_app_py_content(space_id: str) -> str:
84
- app_py_url = f"https://huggingface.co/spaces/{space_id}/raw/main/app.py"
85
- try:
86
- response = requests.get(app_py_url, headers=get_headers())
87
- if response.status_code == 200:
88
- return response.text # 전체 내용을 반환
89
- else:
90
- return f"app.py file not found or inaccessible for space: {space_id}"
91
- except requests.RequestException:
92
- return f"Error fetching app.py content for space: {space_id}"
93
-
94
- def get_space_structure(space_id: str) -> Dict:
95
- try:
96
- # space_id에서 owner와 repo_name을 분리
97
- owner, repo_name = space_id.split('/')
98
-
99
- # HfApi를 사용하여 파일 목록을 가져옴
100
- files = hf_api.list_repo_files(repo_id=space_id, repo_type="space")
101
-
102
- # 파일 목록을 트리 구조로 변환
103
- tree = {"type": "directory", "path": "", "tree": []}
104
- for file in files:
105
- path_parts = file.split('/')
106
- current = tree
107
- for i, part in enumerate(path_parts):
108
- if i == len(path_parts) - 1: # 파일
109
- current["tree"].append({"type": "file", "path": part})
110
- else: # 디렉토리
111
- found = False
112
- for item in current["tree"]:
113
- if item["type"] == "directory" and item["path"] == part:
114
- current = item
115
- found = True
116
- break
117
- if not found:
118
- new_dir = {"type": "directory", "path": part, "tree": []}
119
- current["tree"].append(new_dir)
120
- current = new_dir
121
-
122
- return tree
123
- except Exception as e:
124
- print(f"Error in get_space_structure: {str(e)}")
125
- return {"error": f"API request error: {str(e)}"}
126
-
127
- def format_tree_structure(tree_data: Dict, indent: str = "") -> str:
128
- formatted = ""
129
- for item in tree_data.get("tree", []):
130
- if item["type"] == "file":
131
- formatted += f"{indent}├── {item['path']}\n"
132
- elif item["type"] == "directory":
133
- formatted += f"{indent}├── {item['path']}/\n"
134
- formatted += format_tree_structure(item, indent + "│ ")
135
- return formatted
136
-
137
- def format_list_structure(tree_data: Dict) -> List[str]:
138
- formatted = []
139
- for item in tree_data.get("tree", []):
140
- if item["type"] == "file":
141
- formatted.append(item["path"])
142
- elif item["type"] == "directory":
143
- formatted.append(f"{item['path']}/")
144
- formatted.extend(format_list_structure(item))
145
- return formatted
146
-
147
- def on_select(space):
148
- try:
149
- print(f"Selected space: {space['name']}")
150
- summary = summarize_space(space)
151
- app_content = get_app_py_content(space['id'])
152
- tree_structure = get_space_structure(space['id'])
153
-
154
- info = f"선택된 Space: {space['name']} (ID: {space['id']})\n"
155
- info += f"Author: {space['author']}\n"
156
- info += f"Likes: {space['likes']}\n"
157
- info += f"URL: {space['url']}\n\n"
158
- info += f"요약:\n{summary}"
159
-
160
- tree_view = format_tree_structure(tree_structure)
161
- list_view = "\n".join(format_list_structure(tree_structure))
162
-
163
- print(f"Returning URL: {space['url']}")
164
- return info, app_content, space['url'], tree_view, list_view
165
- except Exception as e:
166
- print(f"Error in on_select: {str(e)}")
167
- print(traceback.format_exc())
168
- return f"오류가 발생했습니다: {str(e)}", "", "", "", ""
169
-
170
- def update_screenshot(url, last_url, force_update=False):
171
- print(f"Updating screenshot. Current URL: {url}, Last URL: {last_url}, Force update: {force_update}")
172
- if url and (url != last_url or force_update):
173
- screenshot = take_screenshot(url)
174
- print("Screenshot updated")
175
- return screenshot, url
176
- print("No update needed")
177
- return gr.update(), last_url
178
-
179
- def refresh_screenshot(url, last_url):
180
- print(f"Refresh button clicked. URL: {url}, Last URL: {last_url}")
181
- # 항상 강제로 업데이트
182
- return update_screenshot(url, last_url, force_update=True)
183
-
184
- def take_screenshot(url):
185
- try:
186
- print(f"Taking screenshot of URL: {url}")
187
- client = Client("ginipick/selenium-screenshot-gradio")
188
- result = client.predict(url=url, api_name="/predict")
189
- print(f"Screenshot result: {result}")
190
- if isinstance(result, str) and os.path.exists(result):
191
- return Image.open(result)
192
- else:
193
- print(f"Invalid result from API: {result}")
194
- return Image.new('RGB', (600, 360), color='lightgray')
195
- except Exception as e:
196
- print(f"Screenshot error: {str(e)}")
197
- return Image.new('RGB', (600, 360), color='lightgray')
198
-
199
- def generate_usage_guide(app_content):
200
- system_message = "당신은 Python 코드를 분석하여, 화면 보듯이 이용 방법을 설명하는 AI 조수입니다. app.py 코드를 바탕으로 코드에 대한 언급은 제외하고, 이용자 관점에서 1) 기존 유사 기술 방식괴 비교해 특징, 장점에 대해 친절하고 자세하게 상세한 사용 방법을 제공해주세요."
201
- user_message = f"다음 Python 코드를 기반으로 화면 UI/UX적 측면으로 특징과 사용 방법을 설명해주세요:\n\n{app_content}"
202
-
203
- messages = [
204
- {"role": "system", "content": system_message},
205
- {"role": "user", "content": user_message}
206
- ]
207
-
208
- try:
209
- response = hf_client.chat_completion(messages, max_tokens=4000, temperature=0.7)
210
- return response.choices[0].message.content
211
- except Exception as e:
212
- return f"사용 방법 생성 중 오류 발생: {str(e)}"
213
-
214
- def search_spaces(query: str, spaces: List[Dict]) -> List[Dict]:
215
- query = query.lower()
216
- return [
217
- space for space in spaces
218
- if query in space['name'].lower() or
219
- query in space['author'].lower() or
220
- query in space.get('description', '').lower()
221
- ]
222
-
223
-
224
-
225
- def create_ui():
226
- try:
227
- spaces_list = get_most_liked_spaces()
228
- formatted_spaces = format_spaces(spaces_list)
229
- print(f"Total spaces loaded: {len(formatted_spaces)}")
230
-
231
- css = """
232
- footer {visibility: hidden;}
233
- .minimal-button {min-width: 30px !important; height: 25px !important; line-height: 1 !important; font-size: 12px !important; padding: 2px 5px !important;}
234
- .space-row {margin-bottom: 5px !important;}
235
- #refresh-button, #manual-button, #open-space-button {
236
- width: 100% !important;
237
- margin-top: 5px !important;
238
- }
239
- #info-output, #usage-guide, #tree-view, #list-view {
240
- height: 400px !important;
241
- overflow-y: auto !important;
242
- padding-right: 10px !important;
243
- }
244
- #app-py-content {
245
- height: auto !important;
246
- max-height: none !important;
247
- overflow-y: visible !important;
248
- }
249
- .output-group {
250
- border: 1px solid #ddd;
251
- border-radius: 5px;
252
- padding: 10px;
253
- margin-bottom: 20px;
254
- }
255
- .scroll-lock {
256
- overflow: auto !important;
257
- max-height: 400px !important;
258
- }
259
- .full-height {
260
- height: auto !important;
261
- max-height: none !important;
262
- }
263
- """
264
-
265
- with gr.Blocks(css=css, theme="Nymbo/Nymbo_Theme") as demo:
266
- gr.Markdown("# 300: HuggingFace Most Liked Spaces")
267
-
268
- with gr.Row():
269
- with gr.Column(scale=1):
270
- search_input = gr.Textbox(label="Search Spaces", placeholder="Enter search query...")
271
- space_list = gr.HTML()
272
- space_state = gr.State(formatted_spaces)
273
-
274
- def update_space_list(query, spaces):
275
- filtered_spaces = search_spaces(query, spaces) if query else spaces
276
- html = "<div class='space-list'>"
277
- for i, space in enumerate(filtered_spaces):
278
- html += f"""
279
- <div class='space-row'>
280
- <span>{space['name']} by {space['author']} (Likes: {space['likes']})</span>
281
- <button class='select-space' onclick='selectSpace({i})'>선택</button>
282
- </div>
283
- """
284
- html += "</div>"
285
- return html, filtered_spaces
286
-
287
- search_input.change(update_space_list, inputs=[search_input, space_state], outputs=[space_list, space_state])
288
-
289
- with gr.Column(scale=2):
290
- with gr.Tabs():
291
- with gr.TabItem("기본 정보"):
292
- with gr.Group(elem_classes="output-group scroll-lock"):
293
- info_output = gr.Textbox(label="Space 정보 및 요약", elem_id="info-output", lines=20, max_lines=30)
294
- url_state = gr.State("")
295
- last_url_state = gr.State("")
296
-
297
- screenshot_output = gr.Image(type="pil", label="Live 화면", height=360, width=600)
298
- refresh_button = gr.Button("🔄 서비스 화면", elem_id="refresh-button")
299
- manual_button = gr.Button("선택 서비스 특징 및 사용법", elem_id="manual-button")
300
-
301
- with gr.Group(elem_classes="output-group scroll-lock"):
302
- usage_guide = gr.Textbox(label="선택 서비스 특징 및 사용법", elem_id="usage-guide", visible=False, lines=20, max_lines=30)
303
-
304
- with gr.Group(elem_classes="output-group full-height"):
305
- app_py_content = gr.Code(language="python", label="메인 소스코드", elem_id="app-py-content", lines=None, max_lines=None)
306
-
307
- open_space_button = gr.Button("선택한 Space 열기", elem_id="open-space-button")
308
-
309
- with gr.TabItem("코드 구조 분석"):
310
- with gr.Group(elem_classes="output-group scroll-lock"):
311
- tree_view = gr.Textbox(label="트리 구조", elem_id="tree-view", lines=30, max_lines=50)
312
- with gr.Group(elem_classes="output-group scroll-lock"):
313
- list_view = gr.Textbox(label="리스트 구조", elem_id="list-view", lines=30, max_lines=50)
314
-
315
- update_trigger = gr.Button("Update Screenshot", visible=False)
316
-
317
- def on_select_with_link(space_index, spaces):
318
- space = spaces[space_index]
319
- info, app_content, url, tree, list_structure = on_select(space)
320
- info += f"\n\n선택한 Space URL: {url}"
321
- return info, app_content, url, tree, list_structure
322
-
323
- def open_space_in_browser(url):
324
- if url:
325
- import webbrowser
326
- webbrowser.open(url)
327
- return f"'{url}' 주소가 새 탭에서 열렸습니다."
328
- return "선택된 Space가 없습니다."
329
-
330
- open_space_button.click(
331
- open_space_in_browser,
332
- inputs=[url_state],
333
- outputs=[gr.Textbox(label="상태 메시지")]
334
- )
335
-
336
- refresh_button.click(
337
- refresh_screenshot,
338
- inputs=[url_state, last_url_state],
339
- outputs=[screenshot_output, last_url_state]
340
- )
341
-
342
- def show_usage_guide(app_content):
343
- usage_text = generate_usage_guide(app_content)
344
- return gr.update(value=usage_text, visible=True)
345
-
346
- manual_button.click(
347
- show_usage_guide,
348
- inputs=[app_py_content],
349
- outputs=[usage_guide]
350
- )
351
-
352
- update_trigger.click(
353
- update_screenshot,
354
- inputs=[url_state, last_url_state],
355
- outputs=[screenshot_output, last_url_state]
356
- )
357
-
358
- # JavaScript 코드를 추가하기 위해 js 함수를 사용합니다.
359
- demo.load(js="""
360
- function selectSpace(index) {
361
- document.querySelector('#space-index').value = index;
362
- document.querySelector('#select-space-trigger').click();
363
- }
364
- """)
365
-
366
- # Hidden elements for space selection
367
- space_index = gr.Textbox(elem_id="space-index", visible=False)
368
- select_space_trigger = gr.Button("Hidden Select Trigger", visible=False, elem_id="select-space-trigger")
369
-
370
- select_space_trigger.click(
371
- on_select_with_link,
372
- inputs=[space_index, space_state],
373
- outputs=[info_output, app_py_content, url_state, tree_view, list_view]
374
- ).then(
375
- update_screenshot,
376
- inputs=[url_state, last_url_state],
377
- outputs=[screenshot_output, last_url_state]
378
- )
379
-
380
- demo.queue()
381
-
382
- # Start a background thread to trigger updates
383
- def trigger_updates():
384
- while True:
385
- time.sleep(5)
386
- update_trigger.click()
387
-
388
- threading.Thread(target=trigger_updates, daemon=True).start()
389
-
390
- return demo
391
-
392
- except Exception as e:
393
- print(f"Error in create_ui: {str(e)}")
394
- print(traceback.format_exc())
395
- raise
396
-
397
- if __name__ == "__main__":
398
- try:
399
- demo = create_ui()
400
- demo.launch()
401
- except Exception as e:
402
- print(f"Error in main: {str(e)}")
403
- print(traceback.format_exc())