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())