Skip to main content
This guide will walk you through the complete setup process from clone to running application. Follow these steps to start viewing your Platzi courses from Google Drive.

Prerequisites Checklist

Before starting, ensure you have:
  • Python 3.7+ installed
  • Git for cloning the repository
  • Google Cloud service account with Drive API enabled
  • service_account.json credentials file
  • Google Drive folder with course content, shared with service account
  • Drive folder ID from the URL
If you haven’t completed the Google Drive setup, see Google Drive Setup first.

Quick Start (5 Steps)

1

Clone and Install

# Clone repository
git clone https://github.com/your-username/platzi-viewer.git
cd platzi-viewer

# Create virtual environment
python -m venv .venv

# Activate virtual environment
# Windows:
.venv\Scripts\activate
# Linux/Mac:
source .venv/bin/activate

# Install dependencies
pip install -r requirements.txt
2

Configure Credentials

# Copy your service account file to project root
cp /path/to/your/service_account.json .

# Or set environment variable
export GOOGLE_SERVICE_ACCOUNT_FILE=/path/to/service_account.json
Never commit service_account.json to Git. Add it to .gitignore:
echo "service_account.json" >> .gitignore
3

Build Course Cache

# Edit rebuild_cache_drive.py to set your Drive folder ID
# Line 18: DRIVE_ROOT_ID = "your-folder-id-here"

# Run cache builder (takes 15-30 minutes)
python rebuild_cache_drive.py
You’ll see progress updates as courses are scanned:
📦 Rebuilding courses_cache.json from Google Drive
📖 Parsing PlatziRoutes.md...
   8 categories, 120 routes, 500 course entries
📁 Listing Drive root folder...
   487 course folders found in Drive
🔗 Matching courses to Drive folders and scanning content...
  🌐 Desarrollo Web...
     ✓ 85 courses matched to Drive
...
✅ Cache rebuilt! Total classes: 19,847
The script saves progress every 10 courses. If interrupted, run it again to resume.
4

Start the Server

python server.py
You should see:
[INFO] Drive credentials loaded from: service_account.json
[INFO] Cache loaded from: ./courses_cache.json (18.7 MB, 19847 classes)
[INFO] Server starting on http://127.0.0.1:8080
[INFO] Press Ctrl+C to stop
5

Access the Application

Open your web browser and navigate to:
http://localhost:8080
You should see the Platzi Viewer home page with your course categories.

Alternative: Docker Installation

For containerized deployment:
1

Prepare directories

# Clone repository
git clone https://github.com/your-username/platzi-viewer.git
cd platzi-viewer

# Create directories
mkdir secrets runtime-data

# Copy service account credentials
cp /path/to/service_account.json secrets/
2

Build cache (one-time)

You need to build the cache before running Docker:
# Install Python dependencies locally (temporary)
pip install requests google-api-python-client google-auth google-auth-httplib2

# Update Drive folder ID in rebuild_cache_drive.py
# Run cache builder
python rebuild_cache_drive.py

# Move cache to runtime-data
mv courses_cache.json runtime-data/
You only need to do this once. Docker will use the cache from runtime-data/.
3

Start Docker container

docker compose up --build -d
Check logs:
docker compose logs -f
4

Access the application

Open your browser to:
http://localhost:8080

Alternative: Windows Executable

Build a portable Windows executable:
1

Build executable

# Activate virtual environment
.venv\Scripts\activate

# Install PyInstaller
pip install pyinstaller

# Build portable executable
powershell -ExecutionPolicy Bypass -File .\build_portable_exe.ps1
2

Prepare distribution

cd dist/PlatziViewer

# Contents:
# - PlatziViewer.exe (main executable)
# - All DLL dependencies
# - index.html, css/, js/ (frontend files)
# - service_account.json (if present in source)
# - courses_cache.json (if present in source)
3

Run the executable

Double-click PlatziViewer.exe or run from command line:
.\PlatziViewer.exe
The server starts automatically and opens in your default browser.
For a desktop application with embedded browser (no browser tabs), use:
powershell -ExecutionPolicy Bypass -File .\build_desktop_exe.ps1
This creates PlatziViewerDesktop.exe with a native window.

Configuration Options

Environment Variables

Create a .env file for custom configuration:
.env
# Server settings
PORT=8080
HOST=127.0.0.1
PUBLIC_HOST=127.0.0.1

# Google Drive credentials
GOOGLE_SERVICE_ACCOUNT_FILE=./service_account.json
# Or inline JSON:
# GOOGLE_SERVICE_ACCOUNT_JSON={"type":"service_account",...}

# Optional paths
PLATZI_VIEWER_PATH=/path/to/platzi-viewer
PLATZI_DATA_PATH=/path/to/data

# Progress file size limit (2MB default)
MAX_PROGRESS_BYTES=2097152

Port Configuration

Change the default port (8080):
# Linux/Mac
export PORT=3000
python server.py

# Windows
set PORT=3000
python server.py
Access at http://localhost:3000

Network Access

Allow access from other devices on your network:
.env
HOST=0.0.0.0
PORT=8080
PUBLIC_HOST=192.168.1.100  # Your machine's IP
Security Considerations:
  • Only bind to 0.0.0.0 on trusted networks
  • Consider firewall rules to restrict access
  • The application has no built-in authentication
  • Anyone with network access can view content

Verifying Installation

Health Check

Check server status:
curl http://localhost:8080/api/health
Response:
{
  "status": "ok",
  "cache": {
    "loaded": true,
    "source": "viewer",
    "path": "./courses_cache.json",
    "sizeBytes": 19584323,
    "totalClasses": 19847,
    "lastModified": "2026-03-07T10:30:45Z",
    "driveOnlyCheck": {
      "ok": true,
      "message": "drive_only_ok",
      "validDriveRefs": 98735,
      "localRefs": 0,
      "invalidRefs": 0
    }
  },
  "drive": {
    "available": true,
    "serviceAccountSource": "./service_account.json"
  },
  "ffmpeg": {
    "available": false,
    "path": null
  }
}
ffmpeg.available: false is normal. FFmpeg is only needed for video compatibility mode (advanced feature).

Test Drive Access

Load courses in the browser:
  1. Go to http://localhost:8080
  2. You should see course categories on the home page
  3. Click a category to see routes and courses
  4. Click a course to see modules and classes
  5. Click a class to open the video player
If videos stream successfully, your setup is complete!

API Endpoints Reference

The server exposes these API endpoints:
EndpointMethodDescription
/api/healthGETServer health and diagnostics
/api/coursesGETFull courses cache (JSON)
/api/refreshGETReload cache from disk (localhost only)
/api/progressGETUser progress data
/api/progressPOSTSave user progress
/drive/files/{fileId}GETProxy to Google Drive (streaming)
/api/video-compatible/{fileId}GETFFmpeg compatibility mode (optional)

Example: Fetch Courses

curl http://localhost:8080/api/courses > courses.json

Example: Stream Video

# Get a file ID from courses.json
curl http://localhost:8080/drive/files/1OOJ5lrsLfFEnp6AKVKZKYZH5A-NasCjl \
  --output video.mp4

Usage Tips

Keyboard Shortcuts

Once in the player:
  • Space: Play/Pause
  • ←/→: Previous/Next class
  • F: Fullscreen
  • Escape: Close player

Progress Tracking

Progress is automatically saved:
  • localStorage: Client-side (immediate)
  • progress.json: Server-side (backup)
Progress syncs every time you mark a class complete or reach 90% of a video.

Search and Filters

Use the search bar to find courses and classes:
  • Search by course name
  • Search by class name
  • Filter by type (video, reading, HTML)

Next Steps

User Guide

Learn how to navigate and use all features

Architecture

Understand how Platzi Viewer works

API Reference

Explore server API endpoints

Troubleshooting

Solve common issues and errors

Troubleshooting

”ModuleNotFoundError: No module named ‘google’”

Problem: Missing dependencies Solution:
# Ensure virtual environment is activated
source .venv/bin/activate  # Linux/Mac
.venv\Scripts\activate     # Windows

# Reinstall dependencies
pip install -r requirements.txt

“Drive service not available”

Problem: Cannot connect to Google Drive Solution:
# Check service account file exists
ls service_account.json

# Verify file is valid JSON
cat service_account.json | python -m json.tool

# Check environment variable
echo $GOOGLE_SERVICE_ACCOUNT_FILE
See Google Drive Setup.

”Cache file not found”

Problem: courses_cache.json doesn’t exist Solution:
# Build the cache first
python rebuild_cache_drive.py

# Verify file was created
ls -lh courses_cache.json
See Building Cache.

”Port already in use”

Problem: Port 8080 is occupied by another process Solution:
# Use a different port
export PORT=3000
python server.py

# Or kill the process using port 8080 (Linux/Mac)
lsof -ti:8080 | xargs kill -9

# Windows
netstat -ano | findstr :8080
taskkill /PID <PID> /F

“Cannot access from other device”

Problem: Server only accessible from localhost Solution:
# Bind to all interfaces
export HOST=0.0.0.0
python server.py

# Find your local IP
ifconfig  # Linux/Mac
ipconfig  # Windows

# Access from other device
# http://192.168.1.100:8080

“Videos won’t play”

Problem: Video player shows error or black screen Possible causes:
  1. No Drive access: Check /api/health shows drive.available: true
  2. Wrong file ID: Verify file exists in Drive
  3. Codec issues: Try a different browser (Chrome/Edge recommended)
  4. Network: Check internet connection to Google Drive
Solution:
# Test direct file access
curl -I http://localhost:8080/drive/files/1OOJ5lrsLfFEnp6AKVKZKYZH5A-NasCjl

# Should return HTTP 200 or 206 (partial content)

“Progress not saving”

Problem: Progress resets after refresh Possible causes:
  1. localStorage disabled: Check browser settings
  2. Private/Incognito mode: Use normal browsing mode
  3. Server error: Check progress.json file permissions
Solution:
# Check progress file exists
ls -l progress.json

# Test save endpoint
curl -X POST http://localhost:8080/api/progress \
  -H "Content-Type: application/json" \
  -d '{"test": true}'

Getting Help

If you encounter issues not covered here:
  1. Check the Troubleshooting page
  2. Review server logs for error messages
  3. Verify your setup against this quickstart guide
  4. Check GitHub issues for similar problems
When reporting issues, include:
  • Python version (python --version)
  • Operating system
  • Output from /api/health endpoint
  • Relevant error messages from server logs

Build docs developers (and LLMs) love