Chuyển tới nội dung chính

API Control Guide

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 URLhttp://localhost:8686
AuthenticationKhông (Public API)
Content-Typeapplication/json
Swagger UIhttp://localhost:8686/docs
ReDochttp://localhost:8686/redoc

1. Health Check

GET /health

Kiểm tra API server có đang hoạt động.

Response

{
"status": "ok"
}
TrườngKiểuMô tả
statusstringLuôn là "ok"

2. Schedule Workers

Giá Trị Status

StatusMô tả
IDLESẵn sàng, chờ cron trigger hoặc chạy thủ công
RUNNINGĐang chạy
COMPLETEDChạy xong (tạm thời, sẽ về IDLE hoặc DISABLE)
ERRORLỗi khi chạy (tạm thời, sẽ về IDLE hoặc DISABLE)
DISABLEBị 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ườngKiểuMô tả
idstringID worker
namestringTên hiển thị
cronstringCron expression (minute hour dom month dow)
lockbooleanCó dùng distributed lock không
lock_ttlintegerLock TTL (giây)
statusstringTrạng thái hiện tại
task_idstring | nullCelery task ID (nếu đang chạy)
last_resultstring | nullKết quả lần chạy gần nhất
errorstring | nullLỗi gần nhất
configarrayConfig 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ểuMô tả
schedule_idstringID của schedule worker

Response

Giống cấu trúc một item trong GET /schedules/.

Status CodeĐiều kiện
404schedule_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 DISABLEDISABLE chỉ chặn cron, không chặn chạy thủ công.

Path Parameters

Tham sốKiểuMô tả
schedule_idstringID của schedule worker

Response

{
"success": true,
"task_id": "c7f846d0-..."
}
TrườngKiểuMô tả
successbooleanKết quả thao tác
task_idstringCelery task ID để theo dõi
Status CodeĐiều kiện
400Schedule 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ểuMô tả
schedule_idstringID của schedule worker

Response

TrườngKiểuMô tả
successbooleanKết quả thao tác
task_idstringTask ID đã bị huỷ
Status CodeĐiều kiện
400Khô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ểuMô tả
schedule_idstringID của schedule worker

Response

{
"success": true,
"id": "test_schedule",
"status": "IDLE"
}
TrườngKiểuMô tả
successbooleanKết quả thao tác
idstringID worker
statusstringStatus mới (IDLE)
Status CodeĐiều kiện
404schedule_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ểuMô tả
schedule_idstringID của schedule worker

Response

{
"success": true,
"id": "test_schedule",
"status": "DISABLE"
}
TrườngKiểuMô tả
successbooleanKết quả thao tác
idstringID worker
statusstringStatus mới (DISABLE)
Status CodeĐiều kiện
404schedule_id không tồn tại

3. WebSocket Workers

Giá Trị Status

StatusMô tả
RUNNINGĐang hoạt động (kết nối hoặc đang reconnect)
STOPĐã dừng (chủ đích hoặc chưa start)
ERRORLỗ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ườngKiểuMô tả
idstringID worker
namestringTên hiển thị
urlstringWebSocket URL
restart_policystring"none" hoặc "exponential_backoff"
restart_max_attemptsintegerSố lần reconnect tối đa (0 = vô hạn)
statusstringTrạng thái hiện tại
connectedbooleanĐang kết nối hay không
last_actionobject | null{event: "send"|"recv", time: "ISO timestamp"}
configarrayConfig 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ểuMô tả
ws_idstringID của WebSocket worker

Response

Giống cấu trúc một item trong GET /websockets/.

Status CodeĐiều kiện
404ws_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ểuMô tả
ws_idstringID của WebSocket worker

Response

{
"success": true,
"task_id": "...",
"note": "sent_to_worker"
}
TrườngKiểuMô tả
successbooleanKết quả thao tác
task_idstringCelery task ID
notestring"sent_to_worker" — lệnh đã gửi đến worker process
Status CodeĐiều kiện
404ws_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ểuMô tả
ws_idstringID của WebSocket worker

Response

{
"success": true,
"task_id": "...",
"note": "sent_to_worker"
}
TrườngKiểuMô tả
successbooleanKết quả thao tác
task_idstringCelery task ID
notestring"sent_to_worker"
Status CodeĐiều kiện
404ws_id không tồn tại

4. Execution Logs

Giá Trị Filter

created_from:

Giá trịMô tả
SCHEDULE_WORKERLog từ schedule worker
WEBSOCKET_LISTENERLog từ WebSocket worker
SYSTEMLog hệ thống

type:

Giá trịMô tả
TRACETrace level
DEBUGDebug level
INFOThông tin
SUCCESSThành công
WARNINGCảnh báo
ERRORLỗi
CRITICALLỗ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ểuMặc địnhMô tả
created_bystringLọc theo worker ID
created_fromstringSCHEDULE_WORKER, WEBSOCKET_LISTENER, SYSTEM
typestringTRACE, DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL
limitinteger50Số lượng kết quả (1-500)
offsetinteger0Offset 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ườngKiểuMô tả
countintegerSố lượng kết quả trả về
offsetintegerOffset hiện tại
limitintegerLimit hiện tại
dataarrayDanh sách log entries

Cấu trúc mỗi log entry:

TrườngKiểuMô tả
idintegerID log
created_fromstringNguồn tạo log
created_bystring | nullWorker ID
typestringMức log
valuestringNội dung log
created_atstringThờ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ểuMô tả
created_bystringLọc theo worker ID
created_fromstringSCHEDULE_WORKER, WEBSOCKET_LISTENER, SYSTEM
typestringTRACE, DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL

Response

{
"deleted": 150
}
TrườngKiểuMô tả
deletedintegerSố 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:

  1. Config riêng worker (worker_id cụ thể) — cao nhất
  2. Config chung (worker_id = null)
  3. Biến môi trường
  4. settings.py — thấp nhất

GET /configs/

Lấy danh sách tất cả config entries.

Query Parameters

Tham sốKiểuMặc địnhMô tả
worker_idstringLọ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ườngKiểuMô tả
idintegerID config
worker_idstring | nullNull = global config
keystringTên config key
valuestringGiá trị
descriptionstring | nullMô tả
created_atstringThời gian tạo
updated_atstringThờ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ểuMô tả
keystringTên config key

Query Parameters

Tham sốKiểuMô tả
worker_idstringNếu có, áp dụng priority chain với worker config

Response

{
"key": "LOG_LEVEL",
"worker_id": null,
"value": "INFO"
}
TrườngKiểuMô tả
keystringTên config key
worker_idstring | nullWorker ID (nếu có)
valuestringGiá trị config
Status CodeĐiều kiện
404Key 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ườngKiểuBắt buộcMô tả
keystringTên config key
valuestringGiá trị
descriptionstringKhôngMô tả config
worker_idstringKhôngNull 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ườngKiểuMô tả
successbooleanKết quả thao tác
keystringConfig key
worker_idstring | nullWorker ID
valuestringGiá trị đã set

DELETE /configs/{key}

Xoá config entry.

Path Parameters

Tham sốKiểuMô tả
keystringTên config key cần xoá

Query Parameters

Tham sốKiểuMô tả
worker_idstringChỉ xoá config riêng worker đó. Không truyền = xoá config chung

Response

{
"success": true,
"key": "LOG_LEVEL",
"worker_id": "test_ws"
}
TrườngKiểuMô tả
successbooleanKết quả thao tác
keystringConfig key đã xoá
worker_idstring | nullWorker ID
Status CodeĐiều kiện
404Key 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ườngKiểuMô tả
successbooleanKết quả thao tác
messagestring"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ườngKiểuMô tả
successbooleanKết quả
seededobject{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ườngKiểuMô tả
successbooleanKết quả
syncedobject{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ườngKiểuMô tả
successbooleanKết quả
seededobject{new_schedules: int, new_websockets: int}
syncedobject{schedules: int, websockets: int}

7. Danh Sách Worker IDs Hiện Có

Schedule Workers

IDTênCronLock
test_scheduleTest Schedule Worker* * * * *No
crawl_funds_fmarket_eodFunds FMarket EOD Crawl0 0 * * *Yes (300s)
crawl_fcafe_news_dailyFCAFE News Daily Crawl0 0 1 * *Yes (300s)

WebSocket Workers

IDTênRestart PolicyMax Attempts
test_wsTest WebSocket Workernone
ws_vcbs_quote_tickVCBs Quote Tickexponential_backoff3

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.

// React Query / TanStack Query
const { data: schedules } = useQuery({
queryKey: ['schedules'],
queryFn: () => fetch('/schedules/').then(r => r.json()),
refetchInterval: 2000, // Cập nhật mỗi 2 giây
});

9. Error Response Format

Status CodeMô tả
200Thành công
400Bad Request — lỗi logic (schedule đang chạy, không có task_id,...)
404Not Found — worker_id hoặc config key không tồn tại
422Validation Error — tham số không hợp lệ (FastAPI tự động)
500Internal Server Error
{
"detail": "Schedule 'unknown_id' not found"
}