first commit
This commit is contained in:
713
api_design.md
Normal file
713
api_design.md
Normal file
@@ -0,0 +1,713 @@
|
||||
# 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 |
|
||||
Reference in New Issue
Block a user