Agent开发——Day 03 requests 库与公开 API 调用
·
Day 03 案例分析:requests 库与公开 API 调用
摘要要点
核心目标:掌握使用 Python requests 库调用 HTTP API 的基本技能,为后续调用 LLM API 打下基础。
三个核心案例:
-
免费天气 API 调用(Open-Meteo)
- 无需注册,适合初学者练习
- 使用
requests.get()和params参数 - 包含数据解析和格式化输出
-
需要 API Key 的接口调用
- 模拟 LLM API 标准结构
- 使用
headers传递认证信息(Bearer Token) - 使用
json=参数传递请求体
-
完整的错误处理机制
- 处理超时(Timeout)、连接错误(ConnectionError)、HTTP 错误
- 针对不同 HTTP 状态码(401、429、500 等)提供具体处理建议
- 实现防御性编程
关键知识点:
- HTTP GET/POST 方法区别
- JSON 数据格式处理
- 状态码含义(200、404、500 等)
- Query 参数和 Headers 的使用
raise_for_status()简化错误检查timeout参数防止请求挂起
实践建议:将三个案例代码保存为 practice.py 并运行,通过 Open-Meteo API 立即获得实践反馈。
今日目标
掌握用 Python requests 库调用 HTTP API,为后续调用 LLM API 打基础。
核心概念速览
| 概念 | 通俗理解 |
|---|---|
| HTTP GET | 从服务器"取"数据,像打开网页 |
| HTTP POST | 向服务器"发"数据,像提交表单 |
| JSON | 数据格式,类似 Python 字典 |
| 状态码 | 200=成功,404=找不到,500=服务器出错 |
| Headers | 请求头,携带认证信息(API Key 就放这里) |
| Query 参数 | URL 问号后的参数,如 ?city=Beijing |
案例一:调用免费天气 API(Open-Meteo)
Open-Meteo 是免费无需注册的天气 API,非常适合练习。
完整代码
import requests
import json
def get_weather(latitude: float, longitude: float) -> dict:
"""调用 Open-Meteo API 获取当前天气"""
url = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": latitude,
"longitude": longitude,
"current": "temperature_2m,wind_speed_10m,weather_code",
"timezone": "Asia/Shanghai"
}
response = requests.get(url, params=params, timeout=10)
response.raise_for_status() # 状态码不是 2xx 就抛异常
return response.json()
def describe_weather(data: dict) -> str:
"""把 API 返回的数据转成人类可读的描述"""
current = data["current"]
temp = current["temperature_2m"]
wind = current["wind_speed_10m"]
weather_codes = {
0: "晴天", 1: "基本晴天", 2: "部分多云", 3: "阴天",
45: "有雾", 51: "小毛毛雨", 61: "小雨", 63: "中雨", 65: "大雨",
71: "小雪", 73: "中雪", 75: "大雪", 80: "阵雨", 95: "雷阵雨"
}
weather = weather_codes.get(current["weather_code"], "未知天气")
return f"当前天气:{weather},气温 {temp}°C,风速 {wind} km/h"
if __name__ == "__main__":
# 北京坐标
data = get_weather(39.9042, 116.4074)
print(describe_weather(data))
# 打印完整 JSON 结构(帮助理解 API 返回格式)
print("\n--- 原始 JSON ---")
print(json.dumps(data["current"], indent=2, ensure_ascii=False))
执行流程拆解
1. 构造 URL + params → requests 自动拼成完整 URL
https://api.open-meteo.com/v1/forecast?latitude=39.9042&longitude=116.4074&...
2. requests.get() 发送 HTTP 请求 → 服务器返回 Response 对象
3. response.raise_for_status() → 状态码检查(防御性编程)
4. response.json() → 把返回的 JSON 字符串解析成 Python dict
5. 从 dict 中提取需要的字段 → 组装成人类可读字符串
关键知识点
params={}字典会被自动 URL 编码,不用手动拼字符串timeout=10防止请求永久挂起(真实项目必加)raise_for_status()是最简洁的错误检查方式
案例二:调用需要 API Key 的接口(模拟 LLM API 结构)
这个案例展示如何传递认证信息,结构和你以后调用 Claude/OpenAI API 完全一样。
import requests
def call_api_with_auth(api_key: str, prompt: str) -> str:
"""模拟调用需要认证的 API(结构与 LLM API 相同)"""
url = "https://httpbin.org/post" # httpbin 是一个回显请求内容的测试 API
headers = {
"Authorization": f"Bearer {api_key}", # Bearer Token 认证(LLM API 标准格式)
"Content-Type": "application/json"
}
body = {
"model": "some-model",
"messages": [
{"role": "user", "content": prompt}
]
}
response = requests.post(url, headers=headers, json=body, timeout=10)
response.raise_for_status()
# httpbin 会把你发的请求原样返回,可以检查你发出的内容是否正确
echo = response.json()
print("服务器收到的 headers:", echo["headers"].get("Authorization"))
print("服务器收到的 body:", echo["json"])
return "调用成功"
if __name__ == "__main__":
call_api_with_auth("my-secret-key-123", "你好!")
为什么这个案例重要?
后面调用 Claude API 时,代码结构一模一样:
# 真实 Claude API 调用(Week 2 就会写这个)
response = requests.post(
"https://api.anthropic.com/v1/messages",
headers={
"x-api-key": "your-key",
"anthropic-version": "2023-06-01",
"Content-Type": "application/json"
},
json={
"model": "claude-opus-4-8",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}]
}
)
今天学的 headers 传认证、json= 传请求体,这两个动作在调用 LLM API 时每天都要用。
案例三:错误处理全套(真实项目级别)
import requests
from requests.exceptions import Timeout, ConnectionError, HTTPError
def robust_api_call(url: str, params: dict) -> dict | None:
"""带完整错误处理的 API 调用"""
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
return response.json()
except Timeout:
print("请求超时,请检查网络或稍后重试")
except ConnectionError:
print("网络连接失败,请检查网络设置")
except HTTPError as e:
status = e.response.status_code
if status == 401:
print("API Key 无效或过期")
elif status == 429:
print("请求频率超限(Rate Limit),请稍后重试")
elif status == 500:
print("服务器内部错误,不是你的问题")
else:
print(f"HTTP 错误:{status}")
return None
三种错误的本质区别
| 错误类型 | 原因 | 处理策略 |
|---|---|---|
Timeout |
服务器太慢或网络差 | 重试,加指数退避 |
ConnectionError |
根本连不上服务器 | 检查网络/URL |
HTTPError |
连上了但服务器拒绝 | 看状态码决定 |
今日代码练习建议
把以上三个代码片段存成 practice.py,逐一运行,观察输出结果。
Open-Meteo 不需要注册,直接可以跑通案例一。
更多推荐


所有评论(0)