pwa-launcher 1.2.3
Cross-platform PWA launcher using Chromium
License: MIT
Requires Python: >=3.8

# py-pwa-launcher

Launch Progressive Web Apps from Python

A Python library for launching Progressive Web Apps (PWAs) using Chromium-based browsers. Automatically detects installed Chromium browsers and launches PWAs in app mode with all necessary flags.

PyPi Stats: 

![Version](https://img.shields.io/pypi/v/pwa-launcher)
![Monthly Downloads](https://img.shields.io/pypi/dm/pwa-launcher)

## Features

- 🚀 **Launch PWAs with a single function call**
- 🔍 **Auto-detect** system Chromium-based browsers (Chrome, Edge, Brave, Vivaldi, Opera, Arc)
- ⚙️ **PWA-optimized flags** for installation and features
- 🔒 **Custom profiles** for isolated PWA data
- ✅ **Check PWA support** before launching
- 🧪 **Fully tested** with comprehensive test suite
- 🌍 **Cross-platform** support (Windows, macOS, Linux)

## Installation

```bash
pip install pwa-launcher
```

**Requirements**: You need a Chromium-based browser installed on your system:
- Google Chrome
- Microsoft Edge
- Brave
- Vivaldi
- Opera
- Arc (macOS)
- Chromium

The library will automatically detect any of these browsers.

## Quick Start

### Launch a PWA

```python
from pwa_launcher import open_pwa

# Launch a PWA - that's it!
open_pwa("https://weatherlite.app")
```

### Check PWA Support

```python
from pwa_launcher import check_pwa_support

# Check if a URL supports PWA
result = check_pwa_support("https://weatherlite.app")

if result.is_pwa_supported:
    print(f"✓ {result.url} is PWA-ready!")
    print(f"  Manifest: {result.manifest_url}")
    print(f"  Service Worker: {result.service_worker_url}")
else:
    print(f"✗ Not a PWA")
    for error in result.errors:
        print(f"  - {error}")
```

### Launch with Custom Options

```python
from pwa_launcher import open_pwa
from pathlib import Path

# Launch with custom profile and flags
process = open_pwa(
    "https://excalidraw.com",
    user_data_dir=Path("./my_pwa_profile"),
    additional_flags=["--start-maximized"]
)

print(f"Launched PWA (PID: {process.pid})")
```

### Keep Process Alive

By default, each PWA runs in an **isolated profile** to keep the process alive:

```python
from pwa_launcher import open_pwa

# Auto-generates isolated profile - process stays alive!
process = open_pwa("https://example.com")
print(f"PID: {process.pid}")  # Process won't exit immediately

# To disable auto-profile (may cause process to exit if Chrome is already running):
process = open_pwa("https://example.com", auto_profile=False)
```

**Why this matters:** When Chrome reuses an existing profile, it hands off to an already-running Chrome instance and the new process exits immediately. With `auto_profile=True` (default), each PWA gets its own isolated profile, keeping the process running.

## API Reference

### `open_pwa(url, **kwargs)`

Launch a PWA using Chromium browser.

**Parameters:**
- `url` (str): URL to open as PWA (required)
- `chromium_path` (Path, optional): Path to Chromium executable (auto-detected if None)
- `user_data_dir` (Path, optional): Custom browser profile directory
- `additional_flags` (List[str], optional): Extra Chromium flags
- `wait` (bool, default=False): Wait for browser to exit
- `auto_profile` (bool, default=False): Auto-generate isolated profile (keeps process alive)

**Returns:** `subprocess.Popen` - Browser process

**Raises:**
- `ChromiumNotFoundError`: No browser found
- `ValueError`: Invalid URL

**Note:** When `auto_profile=True`, each PWA gets its own isolated profile based on the URL hostname. This prevents Chrome from handing off to an existing instance and keeps your process alive.

### `check_pwa_support(url, timeout=10)`

Check if a URL supports PWA features.

**Parameters:**
- `url` (str): URL to check
- `timeout` (int): Request timeout in seconds

**Returns:** `PWACheckResult` with:
- `is_pwa_supported` (bool): Whether PWA is supported
- `has_manifest` (bool): Has web manifest
- `manifest_url` (str): URL of manifest file
- `manifest_data` (dict): Parsed manifest data
- `has_service_worker` (bool): Has service worker
- `service_worker_url` (str): URL of service worker
- `has_https` (bool): Uses HTTPS
- `errors` (list): List of error messages
- `warnings` (list): List of warnings

### `get_chromium_install()`

Get a Chromium browser executable path from system-installed browsers.

**Returns:** `Path` - Path to Chromium executable

**Raises:** `ChromiumNotFoundError` - No browser found

### `get_chromium_installs()`

Get all available Chromium browser executable paths from system.

**Returns:** `List[Path]` - List of paths to Chromium executables

## Examples

See the `examples/` directory for more examples:

- `examples/check_pwa.py` - Check PWA support

## Command Line Usage

### Launch a PWA

```bash
python -m pwa_launcher.open_pwa https://weatherlite.app
```

### Check PWA Support

```bash
python -m pwa_launcher.pwa_support https://weatherlite.app
```

## How It Works

1. **Detect Browser**: Searches for installed Chromium-based browsers on your system
2. **Build Command**: Creates command with `--app={url}` and PWA flags
3. **Launch**: Starts browser in app mode with PWA features enabled

### PWA Flags Included

- `--app={url}`: Launch in app mode (no browser UI)
- `--enable-features=WebAppInstallation`: Enable PWA installation
- `--enable-features=DesktopPWAsTabStrip`: Enable tab strip in PWAs
- `--enable-features=FileSystemAccessAPI`: Enable file system access
- `--enable-features=NotificationTriggers`: Enable notifications
- `--no-default-browser-check`: Skip default browser check
- `--no-first-run`: Skip first run experience
- `--disable-infobars`: Remove automation banners
- **Linux only**: `--no-sandbox`, `--disable-gpu`, `--disable-dev-shm-usage`

## Development

### Setup

```bash
# Clone the repository
git clone https://github.com/yourusername/py-pwa-launcher.git
cd py-pwa-launcher

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements-dev.txt
```

### Run Tests

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=pwa_launcher

# Run specific test file
pytest tests/test_open_pwa.py -v
```

## License

MIT License - see LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.