【基于 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级风),打伞时需注意防风,建议选择抗风性
较好的雨具。雨天能见度较低,开车请保持车距,小心慢行。