REST API để giám sát và điều khiển workers, quản lý config, và xem execution logs.
Thông Tin Chung
| |
|---|
| Base URL | http://localhost:8686 |
| Authentication | Không (Public API) |
| Content-Type | application/json |
| Swagger UI | http://localhost:8686/docs |
| ReDoc | http://localhost:8686/redoc |
1. Health Check
GET /health
Kiểm tra API server có đang hoạt động.
Response
| Trường | Kiểu | Mô tả |
|---|
status | string | Luôn là "ok" |
2. Schedule Workers
Giá Trị Status
| Status | Mô tả |
|---|
IDLE | Sẵn sàng, chờ cron trigger hoặc chạy thủ công |
RUNNING | Đang chạy |
COMPLETED | Chạy xong (tạm thời, sẽ về IDLE hoặc DISABLE) |
ERROR | Lỗi khi chạy (tạm thời, sẽ về IDLE hoặc DISABLE) |
DISABLE | Bị tắt — cron không trigger được, vẫn cho phép chạy thủ công |
GET /schedules/
Lấy danh sách tất cả schedule workers và trạng thái.
Response
Object với key là schedule_id.
{
"test_schedule": {
"id": "test_schedule",
"name": "Test Schedule Worker",
"cron": "* * * * *",
"lock": false,
"lock_ttl": 0,
"status": "IDLE",
"task_id": null,
"last_result": null,
"error": null,
"config": []
}
}
| Trường | Kiểu | Mô tả |
|---|
id | string | ID worker |
name | string | Tên hiển thị |
cron | string | Cron expression (minute hour dom month dow) |
lock | boolean | Có dùng distributed lock không |
lock_ttl | integer | Lock TTL (giây) |
status | string | Trạng thái hiện tại |
task_id | string | null | Celery task ID (nếu đang chạy) |
last_result | string | null | Kết quả lần chạy gần nhất |
error | string | null | Lỗi gần nhất |
config | array | Config riêng worker [{key, value}] |
GET /schedules/{schedule_id}/status
Xem trạng thái chi tiết một schedule worker.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
schedule_id | string | ID của schedule worker |
Response
Giống cấu trúc một item trong GET /schedules/.
| Status Code | Điều kiện |
|---|
404 | schedule_id không tồn tại |
POST /schedules/{schedule_id}/run
Trigger worker chạy ngay 1 lần. Hoạt động cả khi DISABLE — DISABLE chỉ chặn cron, không chặn chạy thủ công.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
schedule_id | string | ID của schedule worker |
Response
{
"success": true,
"task_id": "c7f846d0-..."
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
task_id | string | Celery task ID để theo dõi |
| Status Code | Điều kiện |
|---|
400 | Schedule không tồn tại hoặc lỗi hệ thống |
POST /schedules/{schedule_id}/cancel
Huỷ task đang chạy. Status được khôi phục về pre_run_status (IDLE hoặc DISABLE).
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
schedule_id | string | ID của schedule worker |
Response
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
task_id | string | Task ID đã bị huỷ |
| Status Code | Điều kiện |
|---|
400 | Không tìm thấy hoặc không có task đang chạy |
POST /schedules/{schedule_id}/enable
Bật schedule worker. Status → IDLE. Cron trigger được kích hoạt.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
schedule_id | string | ID của schedule worker |
Response
{
"success": true,
"id": "test_schedule",
"status": "IDLE"
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
id | string | ID worker |
status | string | Status mới (IDLE) |
| Status Code | Điều kiện |
|---|
404 | schedule_id không tồn tại |
POST /schedules/{schedule_id}/disable
Tắt schedule worker. Nếu đang chạy sẽ bị cancel. Cron trigger bị chặn. Status → DISABLE.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
schedule_id | string | ID của schedule worker |
Response
{
"success": true,
"id": "test_schedule",
"status": "DISABLE"
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
id | string | ID worker |
status | string | Status mới (DISABLE) |
| Status Code | Điều kiện |
|---|
404 | schedule_id không tồn tại |
3. WebSocket Workers
Giá Trị Status
| Status | Mô tả |
|---|
RUNNING | Đang hoạt động (kết nối hoặc đang reconnect) |
STOP | Đã dừng (chủ đích hoặc chưa start) |
ERROR | Lỗi kết nối không mong muốn |
GET /websockets/
Lấy danh sách tất cả WebSocket workers và trạng thái.
Response
Object với key là ws_id.
{
"ws_vcbs_quote_tick": {
"id": "ws_vcbs_quote_tick",
"name": "VCBs Quote Tick WebSocket Listener",
"url": "wss://wsc.vcsc.com.vn/wss/vcbs/quote/tick",
"restart_policy": "exponential_backoff",
"restart_max_attempts": 3,
"status": "RUNNING",
"connected": true,
"last_action": {
"event": "recv",
"time": "2026-03-17T10:30:00+00:00"
},
"config": []
}
}
| Trường | Kiểu | Mô tả |
|---|
id | string | ID worker |
name | string | Tên hiển thị |
url | string | WebSocket URL |
restart_policy | string | "none" hoặc "exponential_backoff" |
restart_max_attempts | integer | Số lần reconnect tối đa (0 = vô hạn) |
status | string | Trạng thái hiện tại |
connected | boolean | Đang kết nối hay không |
last_action | object | null | {event: "send"|"recv", time: "ISO timestamp"} |
config | array | Config riêng worker [{key, value}] |
GET /websockets/{ws_id}/status
Xem trạng thái chi tiết một WebSocket worker.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
ws_id | string | ID của WebSocket worker |
Response
Giống cấu trúc một item trong GET /websockets/.
| Status Code | Điều kiện |
|---|
404 | ws_id không tồn tại |
POST /websockets/{ws_id}/start
Start WebSocket worker. Lệnh được gửi qua Celery task để thực thi trong Worker process.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
ws_id | string | ID của WebSocket worker |
Response
{
"success": true,
"task_id": "...",
"note": "sent_to_worker"
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
task_id | string | Celery task ID |
note | string | "sent_to_worker" — lệnh đã gửi đến worker process |
| Status Code | Điều kiện |
|---|
404 | ws_id không tồn tại |
POST /websockets/{ws_id}/stop
Stop WebSocket worker. Ngắt kết nối nếu đang chạy. Status → STOP.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
ws_id | string | ID của WebSocket worker |
Response
{
"success": true,
"task_id": "...",
"note": "sent_to_worker"
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
task_id | string | Celery task ID |
note | string | "sent_to_worker" |
| Status Code | Điều kiện |
|---|
404 | ws_id không tồn tại |
4. Execution Logs
Giá Trị Filter
created_from:
| Giá trị | Mô tả |
|---|
SCHEDULE_WORKER | Log từ schedule worker |
WEBSOCKET_LISTENER | Log từ WebSocket worker |
SYSTEM | Log hệ thống |
type:
| Giá trị | Mô tả |
|---|
TRACE | Trace level |
DEBUG | Debug level |
INFO | Thông tin |
SUCCESS | Thành công |
WARNING | Cảnh báo |
ERROR | Lỗi |
CRITICAL | Lỗi nghiêm trọng |
GET /logs/
Truy vấn execution logs với bộ lọc và phân trang.
Query Parameters
| Tham số | Kiểu | Mặc định | Mô tả |
|---|
created_by | string | — | Lọc theo worker ID |
created_from | string | — | SCHEDULE_WORKER, WEBSOCKET_LISTENER, SYSTEM |
type | string | — | TRACE, DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL |
limit | integer | 50 | Số lượng kết quả (1-500) |
offset | integer | 0 | Offset phân trang |
Response
{
"count": 2,
"offset": 0,
"limit": 50,
"data": [
{
"id": 10,
"created_from": "SCHEDULE_WORKER",
"created_by": "test_schedule",
"type": "INFO",
"value": "Schedule executed successfully",
"created_at": "2026-03-17 12:00:00"
}
]
}
| Trường | Kiểu | Mô tả |
|---|
count | integer | Số lượng kết quả trả về |
offset | integer | Offset hiện tại |
limit | integer | Limit hiện tại |
data | array | Danh sách log entries |
Cấu trúc mỗi log entry:
| Trường | Kiểu | Mô tả |
|---|
id | integer | ID log |
created_from | string | Nguồn tạo log |
created_by | string | null | Worker ID |
type | string | Mức log |
value | string | Nội dung log |
created_at | string | Thời gian tạo |
DELETE /logs/
Xoá logs khớp với bộ lọc. Không truyền filter = xoá toàn bộ.
Query Parameters
| Tham số | Kiểu | Mô tả |
|---|
created_by | string | Lọc theo worker ID |
created_from | string | SCHEDULE_WORKER, WEBSOCKET_LISTENER, SYSTEM |
type | string | TRACE, DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL |
Response
| Trường | Kiểu | Mô tả |
|---|
deleted | integer | Số lượng logs đã xoá |
5. Configs
Config Priority Chain
Khi đọc config qua GET /configs/{key}, hệ thống áp dụng thứ tự ưu tiên:
- Config riêng worker (
worker_id cụ thể) — cao nhất
- Config chung (
worker_id = null)
- Biến môi trường
- settings.py — thấp nhất
GET /configs/
Lấy danh sách tất cả config entries.
Query Parameters
| Tham số | Kiểu | Mặc định | Mô tả |
|---|
worker_id | string | — | Lọc theo worker_id. Không truyền = lấy tất cả |
Response
[
{
"id": 1,
"worker_id": null,
"key": "LOG_LEVEL",
"value": "INFO",
"description": "Global log level",
"created_at": "2026-03-17 10:00:00",
"updated_at": "2026-03-17 10:00:00"
}
]
| Trường | Kiểu | Mô tả |
|---|
id | integer | ID config |
worker_id | string | null | Null = global config |
key | string | Tên config key |
value | string | Giá trị |
description | string | null | Mô tả |
created_at | string | Thời gian tạo |
updated_at | string | Thời gian cập nhật |
GET /configs/{key}
Lấy giá trị config theo key, áp dụng priority chain.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
key | string | Tên config key |
Query Parameters
| Tham số | Kiểu | Mô tả |
|---|
worker_id | string | Nếu có, áp dụng priority chain với worker config |
Response
{
"key": "LOG_LEVEL",
"worker_id": null,
"value": "INFO"
}
| Trường | Kiểu | Mô tả |
|---|
key | string | Tên config key |
worker_id | string | null | Worker ID (nếu có) |
value | string | Giá trị config |
| Status Code | Điều kiện |
|---|
404 | Key không tồn tại ở bất kỳ level nào |
POST /configs/
Tạo hoặc cập nhật config entry.
Request Body
{
"key": "LOG_LEVEL",
"value": "DEBUG",
"description": "Override log level for test_ws",
"worker_id": "test_ws"
}
| Trường | Kiểu | Bắt buộc | Mô tả |
|---|
key | string | Có | Tên config key |
value | string | Có | Giá trị |
description | string | Không | Mô tả config |
worker_id | string | Không | Null hoặc bỏ qua = global config. Có giá trị = config riêng worker |
Response
{
"success": true,
"key": "LOG_LEVEL",
"worker_id": "test_ws",
"value": "DEBUG"
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
key | string | Config key |
worker_id | string | null | Worker ID |
value | string | Giá trị đã set |
DELETE /configs/{key}
Xoá config entry.
Path Parameters
| Tham số | Kiểu | Mô tả |
|---|
key | string | Tên config key cần xoá |
Query Parameters
| Tham số | Kiểu | Mô tả |
|---|
worker_id | string | Chỉ xoá config riêng worker đó. Không truyền = xoá config chung |
Response
{
"success": true,
"key": "LOG_LEVEL",
"worker_id": "test_ws"
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
key | string | Config key đã xoá |
worker_id | string | null | Worker ID |
| Status Code | Điều kiện |
|---|
404 | Key không tồn tại |
POST /configs/reload
Force reload config cache từ DB. Hữu ích khi thay đổi config trực tiếp trong DB.
Response
{
"success": true,
"message": "Config cache reloaded"
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả thao tác |
message | string | "Config cache reloaded" |
6. Sync
POST /sync/seed-workers
Quét workers đăng ký trong code → tạo record mới trong DB cho worker chưa có. Không ảnh hưởng worker đã tồn tại.
Response
{
"success": true,
"seeded": {
"new_schedules": 1,
"new_websockets": 0
}
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả |
seeded | object | {new_schedules: int, new_websockets: int} |
POST /sync/db-to-redis
Đọc trạng thái worker từ DB và đẩy lên Redis. Cron/URL luôn lấy từ code, chỉ status (enabled/disabled) từ DB.
Response
{
"success": true,
"synced": {
"schedules": 3,
"websockets": 2
}
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả |
synced | object | {schedules: int, websockets: int} |
POST /sync/full
Chạy seed trước, rồi sync. Tương đương gọi seed-workers + db-to-redis.
Response
{
"success": true,
"seeded": {
"new_schedules": 0,
"new_websockets": 0
},
"synced": {
"schedules": 3,
"websockets": 2
}
}
| Trường | Kiểu | Mô tả |
|---|
success | boolean | Kết quả |
seeded | object | {new_schedules: int, new_websockets: int} |
synced | object | {schedules: int, websockets: int} |
7. Danh Sách Worker IDs Hiện Có
Schedule Workers
| ID | Tên | Cron | Lock |
|---|
test_schedule | Test Schedule Worker | * * * * * | No |
crawl_funds_fmarket_eod | Funds FMarket EOD Crawl | 0 0 * * * | Yes (300s) |
crawl_fcafe_news_daily | FCAFE News Daily Crawl | 0 0 1 * * | Yes (300s) |
WebSocket Workers
| ID | Tên | Restart Policy | Max Attempts |
|---|
test_ws | Test WebSocket Worker | none | — |
ws_vcbs_quote_tick | VCBs Quote Tick | exponential_backoff | 3 |
8. Polling Pattern
Vì các tác vụ chạy nền (background), frontend nên sử dụng polling (gọi API định kỳ) để cập nhật trạng thái UI.
const { data: schedules } = useQuery({
queryKey: ['schedules'],
queryFn: () => fetch('/schedules/').then(r => r.json()),
refetchInterval: 2000,
});
| Status Code | Mô tả |
|---|
200 | Thành công |
400 | Bad Request — lỗi logic (schedule đang chạy, không có task_id,...) |
404 | Not Found — worker_id hoặc config key không tồn tại |
422 | Validation Error — tham số không hợp lệ (FastAPI tự động) |
500 | Internal Server Error |
{
"detail": "Schedule 'unknown_id' not found"
}