You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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