aicodingfun commited on
Commit
2fff19b
·
verified ·
1 Parent(s): 78111ca

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +200 -0
app.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import os
4
+
5
+ if 'GOOGLE_API_KEY' not in os.environ:
6
+ print("錯誤:環境變數 'GOOGLE_API_KEY' 未設定。應用程式無法正常生成知識。")
7
+ # 設定一個虛擬值以避免程式中斷,但功能無法正常使用
8
+ os.environ['GOOGLE_API_KEY'] = "YOUR_API_KEY_HERE"
9
+ else:
10
+ print("成功從環境變數讀取 GOOGLE_API_KEY。")
11
+
12
+ client = genai.Client(api_key=os.environ["GOOGLE_API_KEY"])
13
+
14
+ # --- 核心函式定義 ---
15
+
16
+ def get_celestial_body_list():
17
+ """
18
+ 定義並回傳一個天體清單。
19
+ 為了穩定性,不實際呼叫 API,而是設計一個硬編碼的字典。
20
+
21
+ Returns:
22
+ list: 一個包含繁體中文天體名稱的列表。
23
+ """
24
+ # 這個字典可以在全域範圍被其他函式存取
25
+ global celestial_bodies_data
26
+ celestial_bodies_data = {
27
+ # --- 行星 (Planets) ---
28
+ "水星": "Mercury",
29
+ "金星": "Venus",
30
+ "地球": "Earth",
31
+ "火星": "Mars",
32
+ "木星": "Jupiter",
33
+ "土星": "Saturn",
34
+ "天王星": "Uranus",
35
+ "海王星": "Neptune",
36
+ # --- 恆星與其他 (Stars & Others) ---
37
+ "太陽": "Sun",
38
+ "月球": "Moon",
39
+ "冥王星": "Pluto",
40
+ "黑洞": "Black Hole",
41
+ # --- 星雲 (Nebulae) ---
42
+ "獵戶座星雲": "Orion Nebula",
43
+ "蟹狀星雲": "Crab Nebula",
44
+ "鷹狀星雲": "Eagle Nebula",
45
+ "馬頭星雲": "Horsehead Nebula",
46
+ # --- 星系 (Galaxies) ---
47
+ "仙女座星系": "Andromeda Galaxy",
48
+ "草帽星系": "Sombrero Galaxy",
49
+ "三角座星系": "Triangulum Galaxy",
50
+ # --- 星團 (Clusters) ---
51
+ "昴宿星團": "Pleiades",
52
+ "畢宿星團": "Hyades",
53
+ "半人馬座ω星團": "Omega Centauri",
54
+ # --- 系外行星 (Exoplanet) ---
55
+ "克卜勒-186f": "Kepler-186f"
56
+ }
57
+ return list(celestial_bodies_data.keys())
58
+
59
+ def get_nasa_image(celestial_body_name_chinese):
60
+ """
61
+ 根據選擇的中文天體名稱,從 NASA API 獲取圖片 URL。
62
+
63
+ Args:
64
+ celestial_body_name_chinese (str): 使用者從下拉選單選擇的中文天體名稱。
65
+
66
+ Returns:
67
+ str: 找到的圖片 URL,如果找不到則回傳 None。
68
+ """
69
+ # 從全域字典中查找對應的英文名稱
70
+ english_name = celestial_bodies_data.get(celestial_body_name_chinese)
71
+ if not english_name:
72
+ return None
73
+
74
+ # NASA API 端點
75
+ api_url = f"https://images-api.nasa.gov/search?q={english_name}&media_type=image"
76
+
77
+ try:
78
+ response = requests.get(api_url)
79
+ response.raise_for_status() # 如果請求失敗則發起異常
80
+ data = response.json()
81
+
82
+ # 檢查是否有回傳項目
83
+ if data['collection']['items']:
84
+ # 獲取第一張圖片的 URL
85
+ image_url = data['collection']['items'][0]['links'][0]['href']
86
+ return image_url
87
+ else:
88
+ return None
89
+ except requests.exceptions.RequestException as e:
90
+ print(f"呼叫 NASA API 時發生錯誤: {e}")
91
+ return None
92
+
93
+ def get_space_trivia(celestial_body_name_chinese):
94
+ """
95
+ 使用 Gemini API 生成關於指定天體的冷知識。
96
+
97
+ Args:
98
+ celestial_body_name_chinese (str): 使用者選擇的中文天體名稱。
99
+
100
+ Returns:
101
+ str: 由 Gemini API 生成的繁體中文冷知識文字。
102
+ """
103
+ if os.environ.get("GOOGLE_API_KEY") == "YOUR_API_KEY_HERE":
104
+ return "錯誤:Google API 金鑰未設定。"
105
+
106
+ try:
107
+ # 選擇 Gemini 模型
108
+ models = [
109
+ "gemini-2.0-flash",
110
+ "gemini-2.0-flash-lite",
111
+ "gemini-2.5-flash",
112
+ "gemini-2.5-flash-lite-preview-06-17"
113
+ ]
114
+
115
+ # 設計精確的提示 (Prompt)
116
+ prompt = f"你是一位頂尖的科普作家與天文學家,擅長用生動的比喻和一點點的幽默感,把複雜的宇宙知識變得像聽故事一樣有趣。請針對『{celestial_body_name_chinese}』這個天體,提供一個令人驚訝、課本上學不到的冷知識,並用繁體中文回答。"
117
+
118
+ # 生成內容
119
+ response = client.models.generate_content(
120
+ model=models[3],
121
+ contents=prompt
122
+ )
123
+
124
+ return response.text
125
+
126
+ except Exception as e:
127
+ print(f"呼叫 Gemini API 時發生錯誤: {e}")
128
+ return f"無法生成關於「{celestial_body_name_chinese}」的冷知識,請檢查您的 API 金鑰設定或稍後再試。"
129
+
130
+ def explore_celestial_body(celestial_body_name_chinese):
131
+ """
132
+ Gradio 的主要處理函式,整合圖片獲取和知識生成。
133
+
134
+ Args:
135
+ celestial_body_name_chinese (str): 從 Gradio 下拉選單傳來的使用者選擇。
136
+
137
+ Returns:
138
+ tuple: 包含圖片 URL 和冷知識文字的元組。
139
+ """
140
+ print(f"開始探索:{celestial_body_name_chinese}")
141
+ # 依序執行兩個任務
142
+ image_url = get_nasa_image(celestial_body_name_chinese)
143
+ trivia_text = get_space_trivia(celestial_body_name_chinese)
144
+ print("探索完成!")
145
+ return image_url, trivia_text
146
+
147
+ # --- 5. 建立並啟動 Gradio 介面 ---
148
+
149
+ # 預先載入天體列表
150
+ celestial_body_choices = get_celestial_body_list()
151
+
152
+ # Gradio 介面描述文字
153
+ APP_DESCRIPTION = """
154
+ # AI 宇宙冷知識探索家 🚀
155
+
156
+ 歡迎來到 AI 宇宙冷知識探索家!這是一個結合 NASA 與 Google Gemini AI 技術的互動應用。
157
+
158
+ **如何使用:**
159
+ 1. 從下拉式選單中選擇一個您感興趣的行星、星雲或星系。
160
+ 2. 點擊「探索!」按鈕。
161
+ 3. 應用程式將會為您呈現一張來自 NASA 的震撼照片,並由 AI 生成一則關於它的驚人冷知識!
162
+ """
163
+
164
+ # 使用 gr.Blocks() 來自訂更靈活的版面
165
+ with gr.Blocks(theme=gr.themes.Ocean()) as app:
166
+ gr.Markdown(APP_DESCRIPTION)
167
+
168
+ with gr.Row():
169
+ # 輸入元件
170
+ celestial_dropdown = gr.Dropdown(
171
+ choices=celestial_body_choices,
172
+ label="請選擇一個天體 (Select a Celestial Body)",
173
+ value="金星" # 預設值
174
+ )
175
+ # 觸發按鈕
176
+ explore_button = gr.Button("探索! (Explore!)", variant="primary")
177
+
178
+ with gr.Row():
179
+ # 輸出元件
180
+ output_image = gr.Image(label="NASA 實拍照片 (NASA Image)", type="filepath", height=400)
181
+ output_trivia = gr.Textbox(label="🚀 宇宙冷知識 (Universe Trivia)", lines=15, interactive=False)
182
+
183
+ # 設定按鈕的點擊事件
184
+ explore_button.click(
185
+ fn=explore_celestial_body,
186
+ inputs=celestial_dropdown,
187
+ outputs=[output_image, output_trivia]
188
+ )
189
+
190
+ # 提供一些範例,讓使用者可以快速體驗
191
+ gr.Examples(
192
+ examples=["木星", "仙女座星系", "蟹狀星雲"],
193
+ inputs=celestial_dropdown,
194
+ outputs=[output_image, output_trivia],
195
+ fn=explore_celestial_body,
196
+ cache_examples=True
197
+ )
198
+
199
+ # 啟動應用程式
200
+ app.launch(debug=False, share=False, show_error=True, show_api=False)