9.6 KiB
CEFPython Implementation Guide (Revised)
Author: Matthew Raymer
Date: 2025-07-12
Status: ✨ PLANNING - Ready for Implementation
Overview
This guide outlines the implementation of CEFPython to deliver the TimeSafari Vue.js application as a native desktop experience. It details the integration of Chromium Embedded Framework (CEF) with a Python backend for desktop-specific operations.
Architecture
High-Level Diagram
TimeSafari CEFPython Architecture
├── Python Backend (CEFPython)
│ ├── CEF Browser Window
│ ├── SQLite Database Access
│ ├── File System Operations
│ └── Native OS Integration
├── Vue.js Frontend (Unchanged)
│ ├── Existing Components
│ ├── Platform Service Integration
│ └── Database Operations
└── Platform Service Bridge
├── CEFPython Platform Service
├── IPC Communication
└── Native API Exposure
Platform Service
A TypeScript class will act as the interface between the Vue frontend and the Python backend:
export class CEFPythonPlatformService implements PlatformService {
async dbQuery(sql: string, params?: any[]): Promise<any[]> {
// Call Python backend via IPC
}
async exportData(fileName: string, data: string): Promise<ExportResult> {
// Call file export via IPC
}
async getPlatformInfo(): Promise<PlatformInfo> {
return {
platform: 'cefpython',
capabilities: ['sqlite', 'filesystem', 'native-ui']
};
}
}
Implementation Plan
Phase 1: Foundation Setup (Week 1)
- Install CEFPython dependencies
- Create Python virtual environment
- Set up development and build tools
- Create and test minimal CEFPython app
- Create IPC and platform service skeleton
Phase 2: SQLite Database (Week 2)
- Implement Python SQLite wrapper
- Setup schema initialization
- Bridge database ops over IPC
- Test queries and data integrity
Phase 3: Native OS Integration (Week 3)
- Implement file import/export
- Add system tray and notifications
- Test native menu hooks and permissions
Phase 4: Build & Packaging (Week 4)
- Create packaging and build scripts
- Integrate with existing npm build
- Automate cross-platform distribution
Backend Implementation
Main Entry
# main.py
import cefpython3.cefpython as cef
from platform_service import CEFPythonPlatformService
from ipc_bridge import IPCBridge
class TimeSafariApp:
def __init__(self):
self.platform_service = CEFPythonPlatformService()
self.cef_settings = {
"debug": False,
"log_severity": cef.LOGSEVERITY_ERROR,
"log_file": "cef.log",
"multi_threaded_message_loop": True,
}
def initialize(self):
cef.Initialize(settings=self.cef_settings)
self.browser = cef.CreateBrowserSync(
url=f"file://{os.path.abspath('dist/index.html')}"
)
self.ipc = IPCBridge(self.browser, self.platform_service)
def run(self):
cef.MessageLoop()
cef.Shutdown()
Platform Service (Python)
Handles local database and file system access:
class CEFPythonPlatformService:
def __init__(self):
self.db_path = self._get_db_path()
self._init_schema()
def db_query(self, sql, params=None):
with sqlite3.connect(self.db_path, check_same_thread=False) as conn:
conn.row_factory = sqlite3.Row
return [dict(row) for row in conn.execute(sql, params or [])]
def db_exec(self, sql, params=None):
with sqlite3.connect(self.db_path, check_same_thread=False) as conn:
cur = conn.execute(sql, params or [])
conn.commit()
return {"changes": cur.rowcount, "lastId": cur.lastrowid}
def export_data(self, file_name, data):
try:
path = os.path.join(self._get_downloads(), file_name)
with open(path, 'w') as f:
f.write(data)
return {"success": True, "path": path}
except Exception as e:
return {"success": False, "error": str(e)}
IPC Bridge
Handles communication from JavaScript:
class IPCBridge:
def __init__(self, browser, platform_service):
self.browser = browser
self.platform_service = platform_service
bindings = cef.JavascriptBindings()
bindings.SetFunction("callPython", self.call)
self.browser.SetJavascriptBindings(bindings)
def call(self, name, args):
handlers = {
"dbQuery": self.platform_service.db_query,
"dbExec": self.platform_service.db_exec,
"exportData": self.platform_service.export_data
}
try:
return {"success": True, "data": handlers[name](*args)}
except Exception as e:
return {"success": False, "error": str(e)}
Build & Packaging
Shell script with build modes:
npm run build:web:dev
./scripts/build-cefpython.sh --dev
Includes PyInstaller packaging:
pyinstaller --onefile --windowed --name TimeSafari main.py
Package.json Integration
CEFPython Build Scripts
{
"scripts": {
// CEFPython builds
"build:cefpython": "./scripts/build-cefpython.sh",
"build:cefpython:dev": "./scripts/build-cefpython.sh --dev",
"build:cefpython:test": "./scripts/build-cefpython.sh --test",
"build:cefpython:prod": "./scripts/build-cefpython.sh --prod",
"build:cefpython:package": "./scripts/build-cefpython.sh --prod --package",
// Legacy aliases
"build:desktop:cef": "npm run build:cefpython",
"build:desktop:cef:dev": "npm run build:cefpython:dev",
"build:desktop:cef:prod": "npm run build:cefpython:prod"
}
}
Platform Service Factory Integration
Update PlatformServiceFactory
// src/services/PlatformServiceFactory.ts
export class PlatformServiceFactory {
private static instance: PlatformService | null = null;
public static getInstance(): PlatformService {
if (!PlatformServiceFactory.instance) {
const platform = process.env.VITE_PLATFORM || "web";
switch (platform) {
case "cefpython":
PlatformServiceFactory.instance = new CEFPythonPlatformService();
break;
case "electron":
PlatformServiceFactory.instance = new ElectronPlatformService();
break;
case "capacitor":
PlatformServiceFactory.instance = new CapacitorPlatformService();
break;
default:
PlatformServiceFactory.instance = new WebPlatformService();
}
}
return PlatformServiceFactory.instance;
}
}
Development Workflow
cd cefpython
pip install -r requirements.txt
npm run build:cefpython:dev
Platform Considerations
Windows
- VC++ Redistributable
- Registry for settings
macOS
- macOS 10.14+
- Handle App Sandbox
Linux
- GTK dependencies
- Provide
.desktop
launcher
Security Considerations
- CEF sandboxing
- File and IPC validation
- Data encryption & key management
- Code signing & integrity checks
Performance Optimization
1. Memory Management
- Implement proper cleanup
- Monitor memory usage
- Optimize database queries
- Handle large datasets
2. Startup Time
- Optimize application startup
- Implement lazy loading
- Cache frequently used data
- Minimize initialization overhead
3. Resource Usage
- Monitor CPU usage
- Optimize rendering
- Handle background tasks
- Implement resource limits
Testing
- Unit tests for each service
- Integration for IPC and file access
- End-to-end for user workflows
Issues & Suggestions for Improvement
1. IPC Registration Missing in Initial Version
You must explicitly bind Python functions to JS:
bindings.SetFunction("callPython", self.call)
2. Incorrect IPCBridge
Constructor in Early Draft
Original:
def __init__(self, browser):
Fixed:
def __init__(self, browser, platform_service):
3. SQLite Threading Caveat
Add check_same_thread=False
or use a threading queue to avoid crashes from multi-threaded access.
4. No Vue IPC Access Description
Specify the frontend JS API for calling Python:
window.callPython('dbQuery', ['SELECT * FROM accounts'])
5. Missing Cleanup in Unit Tests
Add teardown for exported files to avoid clutter and permissions issues.
6. Logging
Add logging
or structlog
to the Python service and bridge for auditability.
Troubleshooting
Common Issues
1. CEF Initialization Failures
# Check CEF installation
python -c "import cefpython3; print('CEF installed')"
# Verify dependencies
pip list | grep cefpython3
2. Database Access Issues
# Check database permissions
ls -la ~/.local/share/timesafari/
# Verify SQLite installation
python -c "import sqlite3; print('SQLite available')"
3. Build Failures
# Clean and rebuild
rm -rf cefpython/dist/
rm -rf cefpython/build/
npm run build:cefpython:dev
Debug Mode
# Enable debug logging
cef_settings = {
"debug": True,
"log_severity": cef.LOGSEVERITY_VERBOSE,
"log_file": "cef_debug.log",
}
Conclusion
This guide offers a clear and technically complete roadmap for integrating CEFPython with TimeSafari. By implementing the suggestions above, the solution will be production-ready with complete platform service integration, desktop capability, and a stable build process.
Effort: 4 weeks
Priority: Medium
Dependencies: Python 3.8+, CEFPython
Stakeholders: Desktop development team, users