当前位置: 首页 > news >正文

【基于 LangChain 的异步天气查询3】OpenWeather实现实时天气查询

目录

一、项目功能概述

1、城市识别(GeoNames API)

2、天气数据获取(OpenWeather API)

3、AI 分析天气(deepseek-r1)

4、异步运行支持

5、配置文件隔离(.env)

二、注册 OpenWeatherMap API Key

1、进入官网

2、获取APIKey

三、文件结构(建议)

四、运行代码

.env

 weather_runnable.py

main.py

运行结果


这个项目是一个基于 LangChain + Deepseek-r1+ 天气 API智能天气查询助手,支持通过输入中文城市名获取该地的实时天气数据,并让 AI 提供简洁自然的建议。整体结构简洁明晰,主要功能如下:


一、项目功能概述

1、城市识别(GeoNames API)

  • 用户输入中文城市名(如“上海”)。

  • 程序使用 GeoNames 获取该城市的经纬度信息。

2、天气数据获取(OpenWeather API)

  • 通过获取到的经纬度向 OpenWeather 请求天气数据(如温度、湿度、风速等)。

  • 支持中文描述。

3、AI 分析天气(deepseek-r1)

  • 使用 LangChain 构建一个流水线:

    • 输入城市 → 抓取天气 → 用deepseek-r1生成建议。

  • 输出:自然语言的天气提示和生活建议。

4、异步运行支持

  • 使用 asyncio.run() 异步运行整个调用链,兼容现代 Python 应用场景。

5、配置文件隔离(.env

  • 使用 dotenv 管理 API 密钥,避免将敏感信息写入源码中。


二、注册 OpenWeatherMap API Key

说明:该API主要用于获取天气预报的实时详情数据

1、进入官网

打开 https://openweathermap.org/api

2、获取APIKey

进入 “API keys” 页面,获取一个 API Key(比如:your_openweather_api_key

 


三、文件结构(建议)

your_project/
├── .env
├── main.py
└── weather_runnable.py

四、运行代码

.env

#替换为自己GeoNames的用户名
GEONAMES_USERNAME=用户名#替换为自己的OpenWeather API
OPENWEATHER_API_KEY=自己的APIkey

 weather_runnable.py

# weather_runnable.pyimport os
import requests
from dotenv import load_dotenv
from langchain_core.runnables import RunnableLambda
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAIload_dotenv()GEONAMES_USERNAME = os.getenv("GEONAMES_USERNAME")
OPENWEATHER_API_KEY = os.getenv("OPENWEATHER_API_KEY")def fetch_weather(city: str) -> str:# 1. GeoNames 查询经纬度geonames_url = f"http://api.geonames.org/search?q={city}&maxRows=1&username={GEONAMES_USERNAME}&type=json"geo_response = requests.get(geonames_url)print(f"📍 GeoNames 请求: {geonames_url}")print(f"🌐 返回内容: {geo_response.text[:200]}")geo_data = geo_response.json()if "geonames" not in geo_data or len(geo_data["geonames"]) == 0:return f"❌ 无法找到城市:{city}"geo = geo_data["geonames"][0]lat = geo["lat"]lon = geo["lng"]city_name = geo["name"]# 2. 获取天气数据weather_url = (f"https://api.openweathermap.org/data/2.5/weather?"f"lat={lat}&lon={lon}&appid={OPENWEATHER_API_KEY}&units=metric&lang=zh_cn")weather_response = requests.get(weather_url)print(f"🌤️ 天气请求: {weather_url}")weather_data = weather_response.json()if "weather" not in weather_data or "main" not in weather_data:return f"❌ 无法获取 {city_name} 的天气信息"description = weather_data["weather"][0]["description"]temp = weather_data["main"]["temp"]feels_like = weather_data["main"]["feels_like"]humidity = weather_data["main"]["humidity"]wind_speed = weather_data["wind"]["speed"]# 返回结构化天气数据字符串return (f"{city_name}当前天气情况如下:\n"f"- 天气描述:{description}\n"f"- 温度:{temp}°C,体感:{feels_like}°C\n"f"- 湿度:{humidity}%\n"f"- 风速:{wind_speed} 米/秒")# LangChain 管道构建
weather = (RunnableLambda(fetch_weather)| ChatPromptTemplate.from_template("以下是某城市的天气数据,请用简洁自然的方式告诉用户需注意什么:\n\n{input}")| ChatOpenAI(model="deepseek-r1", temperature=0.5)| StrOutputParser()
)

main.py

# main.pyimport asyncio
from dotenv import load_dotenv
from weather_runnable import weatherload_dotenv()async def run():user_input = input("请输入城市名称(可中文):")result = await weather.ainvoke(user_input)print(f"\n🧠 AI 分析结果:\n{result}")if __name__ == "__main__":asyncio.run(run())

运行结果

请输入城市名称(可中文):赣州
📍 GeoNames 请求: http://api.geonames.org/search?q=赣州&maxRows=1&username=shipking&type=json
🌐 返回内容: {"totalResultsCount":8021,"geonames":[{"adminCode1":"03","lng":"114.9326","geonameId":1810638,"toponymName":"Ganzhou","countryId":"1814991","fcl":"P","population":1977253,"countryCode":"CN","name":"Ga
🌤️ 天气请求: https://api.openweathermap.org/data/2.5/weather?lat=25.84664&lon=114.9326&appid=1fed2dbcd0 c15ac60e3121fe07ae0aa4&units=metric&lang=zh_cn

🧠 AI 分析结果:
<think>
嗯,用户给了一个赣州的天气数据,需要我生成一段简洁自然的提示。首先,我得看看数据里有什么关键点。中雨、温度18度多,体感温度稍低,湿度58%,风速4.46米/秒。        

首先,中雨,这肯定要提醒带伞或者雨衣,可能还有出行注意事项,比如开车慢行,注意积水。温度18度左右,体感17.8,可能有点凉,特别是下雨的话,体感温度会更低,所以需要
建议穿外套,避免着凉。湿度58%不算特别高,但下雨的话湿度可能实际更高,不过数据里是58%,可能用户所在区域的具体情况,不过这个湿度可能不用特别强调,除非有特殊情况。
风速4米多每秒,大概3级风左右,不算特别大,但下雨加上风,可能雨伞容易被吹翻,所以提醒用结实点的伞或者注意防风。

然后要考虑用户的使用场景,可能是在准备出门,或者当天有安排,所以需要简明扼要的关键点。用户可能是普通市民,需要知道该怎么做,而不是专业的气象分析。所以需要把重点
放在带伞、保暖、防风、注意安全这些方面。

还要注意不要遗漏任何数据点,每个数据都要对应到建议里。比如湿度可能影响体感温度,但58%不算很高,可能不需要单独提,但如果有雨的话,实际湿度可能更高,所以可能间接 
提到潮湿的影响。风速虽然不大,但雨天加上风会更麻烦,所以还是要提醒。

最后检查语言是否自然,有没有专业术语,有没有不必要的细节。确保建议实用,直接相关天气情况,没有冗余信息。
</think>

赣州当前有中雨,出行请记得携带雨具并注意道路湿滑。气温18℃左右,体感微凉,建议穿防风外套避免着凉。风速约4.5米/秒(相当于3级风),打伞时需注意防风,建议选择抗风性
较好的雨具。雨天能见度较低,开车请保持车距,小心慢行。

相关文章:

  • Java—— 集合 List
  • 真人配音与AI创作有声读物
  • D. Apple Tree Traversing 【Codeforces Round 1023 (Div. 2)】
  • LeetCode 热题 100 138. 随机链表的复制
  • 实验四:网络编程
  • 如何理解编程中的递归、迭代与回归?
  • 计算机网络:家庭路由器WiFi信号的发射和手机终端接收信号原理?
  • xml与注解的区别
  • Nvidia Isaac Sim组装机器人和添加传感器,创建关节树Articulation
  • 基于协同过滤的音乐推荐系统(源码+lw+部署文档+讲解),源码可白嫖!
  • FreeRTOS Semaphore信号量-笔记
  • 为什么有了BST了,还要红黑树,红黑树有什么优点
  • MySQL 中如何进行 SQL 调优?
  • NVMe控制器之仿真平台搭建
  • 华为云Flexus+DeepSeek征文|DeepSeek-V3与R1商用服务开通体验对比全流程
  • 最小循环子数组 - 华为OD统一考试(Python题解)
  • 【Java项目脚手架系列】第五篇:Spring Boot + MyBatis项目脚手架
  • 解锁HBase:大数据存储的神秘之门
  • 使用fdisk 、gdisk管理分区
  • C++中的继承与多态
  • 呼和浩特推进新一轮国企重组整合:杜绝一项目一公司、一业务一公司
  • 101条关于减重的知识,其中一定有你不知道的
  • 71岁导演詹姆斯・弗雷病逝,曾执导《纸牌屋》、麦当娜MV
  • 新买宝马竟是“维修车”,男子发视频维权被4S店索赔100万
  • 青岛双星名人集团管理权之争:公司迁址,管理层更迭
  • 是谁提议特朗普向好莱坞征税?