714 lines
12 KiB
Markdown
714 lines
12 KiB
Markdown
# API Design Document
|
|
|
|
## Base URL
|
|
|
|
```
|
|
Development: http://localhost:8000/api/v1
|
|
Production: https://api.planet.example.com/api/v1
|
|
WebSocket: ws://localhost:8000/ws
|
|
```
|
|
|
|
---
|
|
|
|
## Authentication
|
|
|
|
### Login
|
|
```http
|
|
POST /api/v1/auth/login
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"username": "admin",
|
|
"password": "admin123"
|
|
}
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
"token_type": "bearer",
|
|
"expires_in": 900,
|
|
"user": {
|
|
"id": 1,
|
|
"username": "admin",
|
|
"role": "super_admin"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response (401 Unauthorized)**
|
|
```json
|
|
{
|
|
"detail": "Invalid credentials"
|
|
}
|
|
```
|
|
|
|
### Refresh Token
|
|
```http
|
|
POST /api/v1/auth/refresh
|
|
Authorization: Bearer <refresh_token>
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"access_token": "new_access_token",
|
|
"expires_in": 900
|
|
}
|
|
```
|
|
|
|
### Logout
|
|
```http
|
|
POST /api/v1/auth/logout
|
|
Authorization: Bearer <access_token>
|
|
```
|
|
|
|
### Get Current User
|
|
```http
|
|
GET /api/v1/auth/me
|
|
Authorization: Bearer <access_token>
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"username": "admin",
|
|
"email": "admin@example.com",
|
|
"role": "super_admin",
|
|
"is_active": true,
|
|
"created_at": "2024-01-15T10:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Users Management
|
|
|
|
### List Users
|
|
```http
|
|
GET /api/v1/users
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- page: int (default: 1)
|
|
- page_size: int (default: 20, max: 100)
|
|
- role: string (optional)
|
|
- is_active: boolean (optional)
|
|
- search: string (optional)
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total": 45,
|
|
"page": 1,
|
|
"page_size": 20,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"username": "admin",
|
|
"email": "admin@example.com",
|
|
"role": "super_admin",
|
|
"is_active": true,
|
|
"last_login": "2024-01-20T15:30:00Z",
|
|
"created_at": "2024-01-15T10:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Get User
|
|
```http
|
|
GET /api/v1/users/{user_id}
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Create User
|
|
```http
|
|
POST /api/v1/users
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"username": "newuser",
|
|
"email": "newuser@example.com",
|
|
"password": "securepassword123",
|
|
"role": "operator"
|
|
}
|
|
```
|
|
|
|
**Response (201 Created)**
|
|
```json
|
|
{
|
|
"id": 46,
|
|
"username": "newuser",
|
|
"email": "newuser@example.com",
|
|
"role": "operator",
|
|
"is_active": true,
|
|
"created_at": "2024-01-20T10:00:00Z"
|
|
}
|
|
```
|
|
|
|
### Update User
|
|
```http
|
|
PUT /api/v1/users/{user_id}
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"email": "updated@example.com",
|
|
"role": "admin",
|
|
"is_active": true
|
|
}
|
|
```
|
|
|
|
### Delete User
|
|
```http
|
|
DELETE /api/v1/users/{user_id}
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Change Password
|
|
```http
|
|
POST /api/v1/users/{user_id}/change-password
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"old_password": "oldpassword",
|
|
"new_password": "newpassword123"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Data Sources
|
|
|
|
### List Data Sources
|
|
```http
|
|
GET /api/v1/datasources
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- module: string (L1, L2, L3, L4)
|
|
- is_active: boolean
|
|
- priority: string (P0, P1)
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total": 9,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"name": "TOP500",
|
|
"module": "L1",
|
|
"priority": "P0",
|
|
"frequency": "4h",
|
|
"is_active": true,
|
|
"last_run": "2024-01-20T08:00:00Z",
|
|
"last_status": "success",
|
|
"next_run": "2024-01-20T12:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Get Data Source
|
|
```http
|
|
GET /api/v1/datasources/{source_id}
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Create Data Source
|
|
```http
|
|
POST /api/v1/datasources
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"name": "New Source",
|
|
"module": "L1",
|
|
"priority": "P1",
|
|
"frequency": "1h",
|
|
"collector_class": "CustomCollector",
|
|
"config": {
|
|
"api_url": "https://api.example.com/data",
|
|
"auth_type": "bearer",
|
|
"api_key": "${env:API_KEY}"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Update Data Source
|
|
```http
|
|
PUT /api/v1/datasources/{source_id}
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"frequency": "30m",
|
|
"is_active": true
|
|
}
|
|
```
|
|
|
|
### Enable/Disable Data Source
|
|
```http
|
|
POST /api/v1/datasources/{source_id}/enable
|
|
POST /api/v1/datasources/{source_id}/disable
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Test Data Source
|
|
```http
|
|
POST /api/v1/datasources/{source_id}/test
|
|
Authorization: Bearer <token>
|
|
|
|
Response (200 OK)
|
|
{
|
|
"status": "success",
|
|
"data_count": 150,
|
|
"execution_time_ms": 1250
|
|
}
|
|
```
|
|
|
|
### Get Data Source Logs
|
|
```http
|
|
GET /api/v1/datasources/{source_id}/logs
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- page: int
|
|
- page_size: int
|
|
- status: string (success, failed, running)
|
|
- start_date: datetime
|
|
- end_date: datetime
|
|
```
|
|
|
|
---
|
|
|
|
## Tasks
|
|
|
|
### List Tasks
|
|
```http
|
|
GET /api/v1/tasks
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- datasource_id: int
|
|
- status: string
|
|
- start_date: datetime
|
|
- end_date: datetime
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total": 156,
|
|
"data": [
|
|
{
|
|
"id": 1234,
|
|
"datasource_id": 1,
|
|
"datasource_name": "TOP500",
|
|
"status": "success",
|
|
"started_at": "2024-01-20T08:00:00Z",
|
|
"completed_at": "2024-01-20T08:01:15Z",
|
|
"records_processed": 500,
|
|
"error_message": null
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Get Task
|
|
```http
|
|
GET /api/v1/tasks/{task_id}
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Trigger Manual Run
|
|
```http
|
|
POST /api/v1/datasources/{source_id}/trigger
|
|
Authorization: Bearer <token>
|
|
|
|
Response (202 Accepted)
|
|
{
|
|
"task_id": 1567,
|
|
"message": "Task queued successfully"
|
|
}
|
|
```
|
|
|
|
### Cancel Running Task
|
|
```http
|
|
POST /api/v1/tasks/{task_id}/cancel
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
---
|
|
|
|
## Dashboard Data
|
|
|
|
### Overview Stats
|
|
```http
|
|
GET /api/v1/dashboard/stats
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total_datasources": 9,
|
|
"active_datasources": 8,
|
|
"tasks_today": 45,
|
|
"success_rate": 97.8,
|
|
"last_updated": "2024-01-20T10:30:00Z",
|
|
"alerts": {
|
|
"critical": 0,
|
|
"warning": 2,
|
|
"info": 5
|
|
}
|
|
}
|
|
```
|
|
|
|
### Data Summary by Module
|
|
```http
|
|
GET /api/v1/dashboard/summary
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"L1": {
|
|
"datasources": 5,
|
|
"total_records": 12500,
|
|
"last_updated": "2024-01-20T10:00:00Z"
|
|
},
|
|
"L2": {
|
|
"datasources": 4,
|
|
"total_records": 8300,
|
|
"last_updated": "2024-01-20T09:45:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Recent Activity
|
|
```http
|
|
GET /api/v1/dashboard/activity
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- limit: int (default: 20)
|
|
```
|
|
|
|
---
|
|
|
|
## GPU Clusters (L1 Data)
|
|
|
|
### List GPU Clusters
|
|
```http
|
|
GET /api/v1/data/gpu-clusters
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- country: string
|
|
- min_gpu_count: int
|
|
- order_by: string (gpu_count, flops, rank)
|
|
- order: string (asc, desc)
|
|
- page: int
|
|
- page_size: int
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total": 1500,
|
|
"page": 1,
|
|
"page_size": 50,
|
|
"data": [
|
|
{
|
|
"id": "epoch-gpu-001",
|
|
"name": "Frontier",
|
|
"country": "US",
|
|
"city": "Oak Ridge, TN",
|
|
"lat": 35.9327,
|
|
"lng": -84.3107,
|
|
"organization": "Oak Ridge National Laboratory",
|
|
"gpu_count": 37888,
|
|
"gpu_type": "AMD MI250X",
|
|
"total_flops": 1.54e9,
|
|
"rank": 1,
|
|
"last_updated": "2024-01-15T00:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Get GPU Cluster Detail
|
|
```http
|
|
GET /api/v1/data/gpu-clusters/{cluster_id}
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### GPU Cluster Statistics
|
|
```http
|
|
GET /api/v1/data/gpu-clusters/stats
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total_clusters": 1500,
|
|
"total_gpu_count": 2500000,
|
|
"by_country": {
|
|
"US": {"count": 800, "gpu_share": 0.45},
|
|
"CN": {"count": 350, "gpu_share": 0.20},
|
|
"EU": {"count": 200, "gpu_share": 0.15}
|
|
},
|
|
"top_10_clusters": [...]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Submarine Cables (L2 Data)
|
|
|
|
### List Submarine Cables
|
|
```http
|
|
GET /api/v1/data/submarine-cables
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- status: string (active, planned, decommissioned)
|
|
- country: string
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total": 436,
|
|
"data": [
|
|
{
|
|
"id": "cable-001",
|
|
"name": "FASTER",
|
|
"length_km": 11600,
|
|
"owners": ["Google", "中国移动", "NEC"],
|
|
"capacity_tbps": 60,
|
|
"status": "active",
|
|
"landing_points": [
|
|
{"country": "US", "city": "San Francisco", "lat": 37.7749, "lng": -122.4194},
|
|
{"country": "JP", "city": "Tokyo", "lat": 35.6762, "lng": 139.6503}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## IXP Nodes (L2 Data)
|
|
|
|
### List IXPs
|
|
```http
|
|
GET /api/v1/data/ixps
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- country: string
|
|
- region: string
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total": 1200,
|
|
"data": [
|
|
{
|
|
"id": "ixp-001",
|
|
"name": "Equinix Ashburn",
|
|
"country": "US",
|
|
"city": "Ashburn, VA",
|
|
"member_count": 250,
|
|
"traffic_tbps": 15.5,
|
|
"ixp_db_id": "EQ-AS1"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Alerts
|
|
|
|
### List Alerts
|
|
```http
|
|
GET /api/v1/alerts
|
|
Authorization: Bearer <token>
|
|
|
|
Query Parameters:
|
|
- severity: string (critical, warning, info)
|
|
- status: string (active, acknowledged, resolved)
|
|
- datasource_id: int
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total": 12,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"severity": "warning",
|
|
"datasource_id": 2,
|
|
"datasource_name": "Epoch AI",
|
|
"message": "API response time > 30s",
|
|
"status": "active",
|
|
"created_at": "2024-01-20T09:30:00Z",
|
|
"acknowledged_by": null
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Acknowledge Alert
|
|
```http
|
|
POST /api/v1/alerts/{alert_id}/acknowledge
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Resolve Alert
|
|
```http
|
|
POST /api/v1/alerts/{alert_id}/resolve
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"resolution": "API rate limit adjusted"
|
|
}
|
|
```
|
|
|
|
### Alert Rules Configuration
|
|
```http
|
|
GET /api/v1/alerts/rules
|
|
POST /api/v1/alerts/rules
|
|
PUT /api/v1/alerts/rules/{rule_id}
|
|
DELETE /api/v1/alerts/rules/{rule_id}
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
---
|
|
|
|
## System Configuration
|
|
|
|
### Get Config
|
|
```http
|
|
GET /api/v1/config
|
|
Authorization: Bearer <token> (admin only)
|
|
```
|
|
|
|
### Update Config
|
|
```http
|
|
PUT /api/v1/config
|
|
Authorization: Bearer <token> (admin only)
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"data_retention_days": 30,
|
|
"refresh_interval": 300,
|
|
"timezone": "Asia/Shanghai"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Audit Logs
|
|
|
|
### List Audit Logs
|
|
```http
|
|
GET /api/v1/audit-logs
|
|
Authorization: Bearer <token> (admin only)
|
|
|
|
Query Parameters:
|
|
- user_id: int
|
|
- action: string
|
|
- resource: string
|
|
- start_date: datetime
|
|
- end_date: datetime
|
|
- page: int
|
|
- page_size: int
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"total": 1500,
|
|
"data": [
|
|
{
|
|
"id": 10001,
|
|
"user_id": 1,
|
|
"username": "admin",
|
|
"action": "user.update",
|
|
"resource": "users",
|
|
"resource_id": 5,
|
|
"detail": {"changes": {"role": ["viewer", "operator"]}},
|
|
"ip_address": "192.168.1.100",
|
|
"created_at": "2024-01-20T10:30:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Health Check
|
|
|
|
### System Health
|
|
```http
|
|
GET /health
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"version": "1.0.0",
|
|
"uptime_seconds": 86400,
|
|
"components": {
|
|
"database": "healthy",
|
|
"redis": "healthy",
|
|
"celery": "healthy"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Readiness
|
|
```http
|
|
GET /ready
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
```json
|
|
{
|
|
"ready": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Error Codes
|
|
|
|
| Code | Description |
|
|
|------|-------------|
|
|
| 400 | Bad Request - Invalid input |
|
|
| 401 | Unauthorized - Invalid/missing token |
|
|
| 403 | Forbidden - Insufficient permissions |
|
|
| 404 | Not Found - Resource doesn't exist |
|
|
| 422 | Validation Error - Data validation failed |
|
|
| 429 | Rate Limited - Too many requests |
|
|
| 500 | Internal Server Error |
|
|
| 503 | Service Unavailable |
|