import gradio as gr import requests import os API_KEY = os.environ.get("PLANTNET_API_KEY") PROJECT = "all" API_URL = f"https://my-api.plantnet.org/v2/identify/{PROJECT}?api-key={API_KEY}" def identify_plant(image, organ): if not API_KEY: return "⚠️ 未检测到 API Key,请检查 Space 的 Secrets 配置" if image is None: return "请先上传一张植物照片" try: with open(image, "rb") as f: files = [("images", ("image.jpg", f, "image/jpeg"))] data = {"organs": [organ]} response = requests.post(API_URL, files=files, data=data, timeout=20) except requests.exceptions.Timeout: return "请求超时,请稍后重试" except requests.exceptions.RequestException as e: return f"网络请求失败:{e}" if response.status_code == 401: return "❌ API Key 无效或已过期" elif response.status_code == 429: return "⚠️ 已超出当日调用配额" elif response.status_code != 200: return f"识别失败,状态码:{response.status_code}" result = response.json() results = result.get("results", []) if not results: return "未识别到匹配物种,建议换一张更清晰的照片重试" output = [] for i, r in enumerate(results[:5], start=1): name = r["species"]["scientificNameWithoutAuthor"] family = r["species"].get("family", {}).get("scientificNameWithoutAuthor", "") common_names = r["species"].get("commonNames", []) common = "、".join(common_names[:2]) if common_names else "暂无常用名" score = r["score"] output.append(f"**{i}. {name}**({family})\n常用名:{common} 置信度:{score:.1%}") return "\n\n---\n\n".join(output) with gr.Blocks(title="植物识别助手") as demo: gr.Markdown("# 🌿 植物识别助手\n上传一张植物照片,识别引擎来自 [Pl@ntNet](https://plantnet.org)") with gr.Row(): with gr.Column(): image_input = gr.Image(type="filepath", label="上传植物照片") organ_input = gr.Dropdown( choices=["auto", "leaf", "flower", "fruit", "bark", "habit"], value="auto", label="拍摄部位", info="明确指定部位(如leaf/flower)通常比auto识别更准确" ) submit_btn = gr.Button("开始识别", variant="primary") with gr.Column(): output_text = gr.Markdown(label="识别结果") submit_btn.click(fn=identify_plant, inputs=[image_input, organ_input], outputs=output_text) gr.Markdown("---\n数据与识别能力来自 Pl@ntNet 官方 API,遵循 CC BY-SA / CC BY 授权协议。识别结果仅供参考。") demo.launch(server_name="0.0.0.0", server_port=7860)