본문 바로가기
Tech Notes

Python OnPromise Structure 비교 Electron + Python vs PyWebView + PyInstaller

by miracle-tech 2025. 12. 8.
320x100
반응형

frontend 는 react, backend 는 fastapi(python)으로 만들었는데 이걸 saas로 시도하다가 실패 ❌

(성능 좋은 CPU 필요- 영상 생성 시간, Storage 비용 등으로)

Local 설치형으로 만들어보고자 방향을 바꿨다.

사실 올 여름에도 Electron + Python 조합으로 시도 했었으나 실패 ❌

 

하지만, 다시 한번 도전 

목표는 "사용자가 exe 만 더블 클릭하면 사용할 수 있도록" 하는 것

 

이번엔 PyWebView + PyInstaller 를 추천해줘서 이 방법으로 해보려한다.

 

아키텍처 비교

 

 

┌─────────────────────────────────────────────────────────────────┐
│                    Electron + Python                            │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐         ┌─────────────────┐               │
│  │   Electron      │   IPC   │   Python        │               │
│  │   (Node.js)     │◀───────▶│   (subprocess)  │               │
│  │                 │  통신    │                 │               │
│  │  ┌───────────┐  │         │  FastAPI 서버   │               │
│  │  │ Chromium  │  │         │  또는 직접 호출  │               │
│  │  │ (React)   │  │         │                 │               │
│  │  └───────────┘  │         └─────────────────┘               │
│  └─────────────────┘                                           │
│                                                                 │
│  프로세스: 2~3개 (Electron + Node + Python)                     │
│  메모리: ~300MB+                                                │
│  앱 크기: ~250-400MB                                            │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                   PyWebView + PyInstaller                       │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────┐                   │
│  │              Python 프로세스             │                   │
│  │  ┌─────────────────┐  ┌──────────────┐  │                   │
│  │  │   PyWebView     │  │   FastAPI    │  │                   │
│  │  │   (시스템 WebView)│  │   (스레드)   │  │                   │
│  │  │                 │  │              │  │                   │
│  │  │  ┌───────────┐  │  │              │  │                   │
│  │  │  │ React UI  │◀─┼──┼─localhost────│  │                   │
│  │  │  └───────────┘  │  │              │  │                   │
│  │  └─────────────────┘  └──────────────┘  │                   │
│  └─────────────────────────────────────────┘                   │
│                                                                 │
│  프로세스: 1개 (Python만)                                        │
│  메모리: ~150MB                                                  │
│  앱 크기: ~100-150MB                                             │
└─────────────────────────────────────────────────────────────────┘

상세 비교표

항목Electron + PythonPyWebView + PyInstaller

앱 크기 250~400MB 100~150MB
메모리 사용 300MB+ 150MB
프로세스 수 2~3개 1개
브라우저 엔진 Chromium (내장) 시스템 WebView (Edge/WebKit)
Python 연동 subprocess / IPC 같은 프로세스
개발 복잡도 ⭐⭐⭐ (Node + Python) ⭐⭐ (Python만)
빌드 도구 electron-builder PyInstaller
크로스 플랫폼 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
웹 호환성 100% (Chromium) 95% (시스템 의존)
DevTools 항상 사용 가능 개발 모드만

핵심 차이점

1. 브라우저 엔진

 
 
Electron:
- Chromium을 앱에 내장 (모든 PC에서 동일)
- 앱 크기 증가 (~150MB가 Chromium)
- 최신 웹 기능 100% 지원

PyWebView:
- Windows: Edge WebView2 (대부분 설치됨)
- Mac: WebKit (기본 포함)
- Linux: WebKitGTK
- 앱에 브라우저 미포함 → 크기 절약

2. Python 연동 방식

 
 
python
# ═══════════════════════════════════════════
# Electron + Python: IPC 통신 필요
# ═══════════════════════════════════════════

# main.js (Electron)
const { spawn } = require('child_process');
const python = spawn('python', ['backend/server.py']);

// React에서 API 호출
fetch('http://localhost:8000/api/generate')

# ───────────────────────────────────────────

# ═══════════════════════════════════════════
# PyWebView: 같은 프로세스, 직접 호출 가능
# ═══════════════════════════════════════════

# main.py
import webview
from backend.video_generator import generate_video

class Api:
    def generate(self, script):
        # Python 함수 직접 호출 (IPC 불필요)
        return generate_video(script)

window = webview.create_window('App', 'index.html', js_api=Api())
webview.start()

# JavaScript에서 직접 호출
window.pywebview.api.generate(script)

3. 빌드 과정

 
 
bash
# ═══════════════════════════════════════════
# Electron + Python
# ═══════════════════════════════════════════

# 1. Python 백엔드를 exe로 (PyInstaller)
pyinstaller backend/server.py

# 2. Electron 앱 빌드 (electron-builder)
npm run build

# 3. 두 개를 합쳐서 배포
#    → 복잡한 빌드 파이프라인

# ───────────────────────────────────────────

# ═══════════════════════════════════════════
# PyWebView + PyInstaller
# ═══════════════════════════════════════════

# 1. 전부 Python이므로 한 번에 빌드
pyinstaller main.py

# 끝! 단일 exe 생성
```

### 장단점 정리

#### Electron + Python

**장점:**
- 웹 호환성 완벽 (Chromium 내장)
- 프론트엔드 개발자 친화적 (Node.js 생태계)
- DevTools 항상 사용 가능
- 크로스 플랫폼 완벽 지원

**단점:**
- 앱 크기 큼 (250MB+)
- 메모리 많이 사용
- 두 개의 런타임 관리 (Node + Python)
- 빌드 복잡 (두 단계)
- Python 연동에 IPC 오버헤드

#### PyWebView + PyInstaller

**장점:**
- 앱 크기 작음 (100~150MB)
- 메모리 효율적
- Python 단일 코드베이스
- 빌드 단순 (한 번에)
- Python 함수 직접 호출 가능
- 기존 FastAPI 코드 그대로 사용

**단점:**
- 시스템 WebView 의존 (드물게 호환성 이슈)
- DevTools 제한적
- Node.js 생태계 활용 불가

### 당신의 상황에서 추천

기존에 **FastAPI + React**로 구현되어 있으니까:
```
┌─────────────────────────────────────────────────────────────┐
│  PyWebView + PyInstaller 추천 이유                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 기존 FastAPI 코드 100% 재사용                           │
│     → Electron이면 IPC 통신 레이어 추가 필요                │
│                                                             │
│  2. Python만 다루면 됨                                      │
│     → Node.js + Python 두 개 관리 불필요                    │
│                                                             │
│  3. 앱 크기 절반                                            │
│     → 150MB vs 300MB                                        │
│                                                             │
│  4. 빌드 단순                                               │
│     → pyinstaller 한 번이면 끝                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

### 그래도 Electron이 나은 경우
```
- 복잡한 프론트엔드 기능 (웹 API 많이 사용)
- 팀에 Node.js 개발자가 있음
- 여러 OS에서 완벽히 동일한 UI 필요
- 이미 Electron 경험이 있어서 편함
320x100