Files
weather-data-api/README.md
T
2026-06-19 13:38:17 +08:00

192 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Weather Data API
FastAPI 服务,用于接收气象站观测数据并存入 PostgreSQL,同时提供查询接口。
## 快速开始
### 1. 准备数据库
```bash
createdb weather_data
```
### 2. 配置环境变量
复制 `.env.example``.env` 并填入实际值:
```bash
cp .env.example .env
```
`.env` 内容:
```
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USER=postgres
DATABASE_PASSWORD=your_password_here
DATABASE_NAME=weather_data
```
### 3. 安装依赖
```bash
uv sync
```
### 4. 启动服务
```bash
uv run uvicorn app.main:app --reload
```
服务默认监听 `http://localhost:8000`,访问 `/docs` 查看 Swagger 文档。
---
## API 端点
### POST `/data` — 接收气象数据
请求体(JSON):
```json
{
"station_name": "北京站",
"temperature": 26.5,
"pressure": 1013.2,
"relative_humidity": 68.0
}
```
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `station_name` | string | 是 | 气象站名称 |
| `temperature` | float | 否 | 温度(摄氏度) |
| `pressure` | float | 否 | 气压(hPa |
| `relative_humidity` | float | 否 | 相对湿度(%0-100 |
成功响应(201):
```json
{
"id": 1,
"station_name": "北京站",
"temperature": 26.5,
"pressure": 1013.2,
"relative_humidity": 68.0,
"received_at": "2026-06-19T10:30:00.123456+00:00"
}
```
`received_at` 由服务端在收到数据时自动记录。
### GET `/data/{station_name}` — 查询最新数据
获取指定气象站的最新一条记录。站名支持中文,直接放在 URL 路径中即可:
```
GET /data/北京站
```
成功响应(200):
```json
{
"id": 42,
"station_name": "北京站",
"temperature": 27.1,
"pressure": 1012.8,
"relative_humidity": 65.0,
"received_at": "2026-06-19T11:45:00.654321+00:00"
}
```
未找到数据时返回 404。
### GET `/data/{station_name}/history` — 查询历史数据
获取指定时间范围内的所有记录。支持两种查询方式:
**按最近 N 小时查询:**
```
GET /data/北京站/history?hours=24
```
**按自定义时间范围查询:**
```
GET /data/北京站/history?start=2026-06-19T00:00:00&end=2026-06-19T12:00:00
```
参数说明:
| 参数 | 类型 | 说明 |
|------|------|------|
| `hours` | int | 从现在往前推 N 小时。如果同时指定了 `start`,则仅影响 `start` |
| `start` | datetime | 时间范围起点(ISO 8601 格式,UTC),不传则不限制 |
| `end` | datetime | 时间范围终点(ISO 8601 格式,UTC),不传则默认到当前时刻 |
成功响应(200):
```json
{
"station_name": "北京站",
"records": [
{
"id": 42,
"station_name": "北京站",
"temperature": 27.1,
"pressure": 1012.8,
"relative_humidity": 65.0,
"received_at": "2026-06-19T11:45:00.654321+00:00"
},
{
"id": 40,
"station_name": "北京站",
"temperature": 26.8,
"pressure": 1013.0,
"relative_humidity": 67.0,
"received_at": "2026-06-19T10:30:00.123456+00:00"
}
]
}
```
未找到匹配数据时返回空列表。
---
## 数据库表结构
| 列名 | 类型 | 说明 |
|------|------|------|
| `id` | `BIGSERIAL` | 主键,自增 |
| `station_name` | `TEXT` | 气象站名称 |
| `temperature` | `DOUBLE PRECISION` | 温度 |
| `pressure` | `DOUBLE PRECISION` | 气压 |
| `relative_humidity` | `DOUBLE PRECISION` | 相对湿度 |
| `received_at` | `TIMESTAMPTZ` | 数据接收时间(服务端自动填充) |
表上有 `(station_name, received_at DESC)` 组合索引,支持按站名和时间的高效查询。
---
## 项目结构
```
weather-data-api/
├── .env.example # 配置模板
├── pyproject.toml # 依赖声明
├── README.md
└── app/
├── __init__.py
├── config.py # 从 .env 加载数据库配置
├── database.py # asyncpg 连接池 + 数据库操作
├── models.py # Pydantic 模型
└── main.py # FastAPI 应用入口
```