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