Add Demo Mode via Service Layer with FastAPI Dependency Injection#25
Draft
Add Demo Mode via Service Layer with FastAPI Dependency Injection#25
Conversation
…d demo mode via env var Co-authored-by: 1PingSun <38580658+1PingSun@users.noreply.github.com>
Co-authored-by: 1PingSun <38580658+1PingSun@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add Demo mode for WebUI with FastAPI
Add Demo Mode via Service Layer with FastAPI Dependency Injection
Feb 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduces a service abstraction layer so the WebUI can run against simulated data without Raspberry Pi hardware, toggled via
HACKMASTER_DEMO_MODE=true. Uses FastAPI'sdependency_overrides— no router code changes needed to switch modes.Architecture
app/services/wifi_service.py,ble_service.py,ir_service.py,rfid_service.py) — define the contract each module must fulfillapp/services/real/) — hardware logic migrated from routers; module-level globals preserve state across requests (same semantics as before)app/services/mock/) — return schema-compatible fake data (e.g. 3 fake APs, captured handshake, cracked password, EVIL_TWIN defense issue)Router changes
All four routers (
WiFi.py,BLE.py,IR.py,RFID.py) now expose aget_*_service()factory and inject it viaDepends. HTML page routes are untouched.Demo mode wiring (
main.py)Singleton mock instances are used so stateful operations (e.g. IR recording state machine) behave consistently across requests.
Bug fixes (incidental)
BLE.py: duplicate function nameread_airpods_emulator(lines 29 and 117) — second renamed toread_airpods_emulator_pageIR.py:randomwas used inenumerate_ir_codewithout being imported — moved toir_real.pywith the implementationwifi_real.py: operator precedence bug in adapter name filtering conditionir_real.py: potentialIndexErrorwhenfunctionis an empty string ingenerate_ir_codeNew files
app/.env.example— documentsHACKMASTER_DEMO_MODE__pycache__/and*.pycadded to.gitignoreOriginal prompt
目標
為 WebUI 建立一個可以回應模擬資料的 Demo 模式,同時確保未來 API 介面變動時 Mock 與真實實作不會出現不一致。利用 FastAPI 原生 Dependency Injection (
Depends+dependency_overrides) 機制實現,透過環境變數HACKMASTER_DEMO_MODE=true一鍵切換,完全不需要修改 router 程式碼。需要做的事
1. 新增 Service 抽象層(ABC Interface)
建立
app/services/目錄,為四個模組各建立 ABC interface,所有 method 必須與現有 router 的實際邏輯吻合:app/services/__init__.py空白或只有
__all__的 init 檔。app/services/wifi_service.pyapp/services/ble_service.pyapp/services/ir_service.pyapp/services/rfid_service.py2. 新增 Real Service 實作
將現有 router 裡的硬體邏輯搬移到 real service,router 只呼叫 service。
app/services/real/__init__.py空白。
app/services/real/wifi_real.py把
app/api/WiFi.py中所有非 HTML page route 的邏輯搬到這裡實作WiFiService。原本 WiFi.py 裡的全域狀態變數 (ap_running,capture_active,capture_process,network_adapters等) 也移至此 class 的 instance 變數。helper function (extract_adapter_names,parse_aircrack_output,run_capture_process) 也搬到這裡。重要:
start_capture的 background task 在 real service 中需要特別處理。可以保留BackgroundTasks的使用,在 router 層傳入,或改用asyncio.create_task。建議在 router 層傳遞background_tasks,real service 的start_capture接收background_tasks: BackgroundTasks參數。`app/services/real/ble_real.py...
This pull request was created from Copilot chat.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.