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
Quick Start (5 Steps)
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
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
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.
Start the Server
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
Access the Application
Open your web browser and navigate to: You should see the Platzi Viewer home page with your course categories.
Alternative: Docker Installation
For containerized deployment:
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/
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/.
Start Docker container
docker compose up --build -d
Check logs:
Alternative: Windows Executable
Build a portable Windows executable:
Build executable
# Activate virtual environment
.venv\Scripts\activate
# Install PyInstaller
pip install pyinstaller
# Build portable executable
powershell - ExecutionPolicy Bypass - File .\build_portable_exe.ps1
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)
Run the executable
Double-click PlatziViewer.exe or run from command line: 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:
# 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:
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:
Go to http://localhost:8080
You should see course categories on the home page
Click a category to see routes and courses
Click a course to see modules and classes
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:
Endpoint Method Description /api/healthGET Server health and diagnostics /api/coursesGET Full courses cache (JSON) /api/refreshGET Reload cache from disk (localhost only) /api/progressGET User progress data /api/progressPOST Save user progress /drive/files/{fileId}GET Proxy to Google Drive (streaming) /api/video-compatible/{fileId}GET FFmpeg 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 < PI D > /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:
No Drive access : Check /api/health shows drive.available: true
Wrong file ID : Verify file exists in Drive
Codec issues : Try a different browser (Chrome/Edge recommended)
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:
localStorage disabled : Check browser settings
Private/Incognito mode : Use normal browsing mode
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:
Check the Troubleshooting page
Review server logs for error messages
Verify your setup against this quickstart guide
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