Rất nhiều dịch vụ (thời tiết, tỷ giá, mạng xã hội, AI) cung cấp API. Bài này dạy gửi yêu cầu HTTP, xử lý JSON, tham số, header, lỗi và giữ khóa API an toàn.
Bạn sẽ học được
- Hiểu HTTP: phương thức, mã trạng thái, header
- Gửi GET/POST bằng requests
- Xử lý lỗi, timeout, thử lại
- Bảo vệ khóa API bằng biến môi trường
Thuật ngữ cần biết
- API
- Giao diện để chương trình trao đổi dữ liệu.
- Endpoint
- Địa chỉ URL của một chức năng API.
- Status code
- Mã kết quả: 200 thành công, 404 không tìm thấy, 500 lỗi máy chủ.
- API key
- Khóa xác thực khi gọi API.
Khái niệm và lý thuyết
Một lời gọi API gồm: phương thức (GET lấy, POST tạo, PUT/PATCH sửa, DELETE xóa), URL, header (định dạng, xác thực), body (dữ liệu gửi đi). Máy chủ trả về mã trạng thái và thân phản hồi, thường là JSON.
| Mã | Ý nghĩa |
|---|---|
| 2xx | Thành công (200 OK, 201 Created) |
| 4xx | Lỗi phía người gọi (400 sai dữ liệu, 401 chưa xác thực, 404, 429 gọi quá nhiều) |
| 5xx | Lỗi phía máy chủ |
GET với requests
import requests
r = requests.get(
"https://api.open-meteo.com/v1/forecast",
params={"latitude": 21.33, "longitude": 103.91, "current": "temperature_2m"}, # Sơn La
timeout=10,
)
r.raise_for_status() # ném lỗi nếu 4xx/5xx
du_lieu = r.json()
print("Nhiệt độ Sơn La:", du_lieu["current"]["temperature_2m"], "°C")POST và xác thực
import os
API_KEY = os.environ["MY_API_KEY"] # đọc từ biến môi trường, không ghi thẳng vào mã
r = requests.post(
"https://httpbin.org/post",
json={"ten": "An", "diem": 9},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=10,
)
print(r.status_code, r.json()["json"])Xử lý lỗi
from requests.exceptions import RequestException
def lay_json(url, lan_thu=3):
for i in range(lan_thu):
try:
r = requests.get(url, timeout=5)
r.raise_for_status()
return r.json()
except RequestException as e:
print(f"Lần {i + 1} lỗi: {e}")
return Nonehttpx: bất đồng bộ
import asyncio, httpx
async def main():
async with httpx.AsyncClient(timeout=10) as client:
urls = [f"https://jsonplaceholder.typicode.com/posts/{i}" for i in range(1, 6)]
kq = await asyncio.gather(*(client.get(u) for u in urls))
print([r.json()["title"][:20] for r in kq])
asyncio.run(main())httpx có API gần giống requests nhưng hỗ trợ async, gọi song song nhiều API nhanh hơn nhiều (chi tiết async ở Bài 19).
Mẹo hay
Thử API trước bằng trình duyệt hoặc tiện ích REST Client của VS Code để biết cấu trúc JSON, rồi mới viết mã.
Lưu ý
Luôn đặt timeout; không có timeout, chương trình có thể treo mãi khi máy chủ không phản hồi. Tôn trọng giới hạn số lần gọi (rate limit) của API.
Thực hành
- Lấy nhiệt độ hiện tại của 5 tỉnh Tây Bắc từ Open-Meteo, in bảng.
- Lấy danh sách bài viết từ jsonplaceholder, lưu ra JSON.
- Viết hàm có thử lại khi lỗi, dùng thời gian chờ tăng dần.
- Dùng httpx gọi song song 20 URL và so sánh thời gian với requests.
Tóm tắt bài học
- HTTP: phương thức, URL, header, body, mã trạng thái.
- requests cho đồng bộ, httpx cho cả async.
- raise_for_status, timeout, thử lại để chắc chắn.
- Khóa API đặt trong biến môi trường.