Skip to main content
Platzi Viewer uses a Google Cloud service account to access course content stored in Google Drive. This guide walks you through creating the necessary credentials.

Overview

The application authenticates with Google Drive using a service account, which:
  • Provides read-only access to shared Drive folders (drive.readonly scope)
  • Requires no user OAuth flow - authentication is automatic with the JSON key file
  • Allows programmatic access to Drive content without browser interaction
  • Must be granted access to the specific Drive folder containing course content

Prerequisites

  • A Google account (personal or workspace)
  • Access to Google Cloud Console
  • A Google Drive folder containing your Platzi course content

Step 1: Create a Google Cloud Project

1

Navigate to Google Cloud Console

Go to Google Cloud Console and sign in with your Google account.
2

Create a new project

  1. Click on the project dropdown in the top navigation bar
  2. Click “New Project”
  3. Enter a project name (e.g., “Platzi Viewer”)
  4. Click “Create”
  5. Wait for the project to be created (this may take a few seconds)
3

Select your project

Ensure your newly created project is selected in the project dropdown.

Step 2: Enable the Google Drive API

1

Navigate to API Library

In the Google Cloud Console, go to “APIs & Services” → “Library” from the left sidebar menu.
2

Search for Google Drive API

Use the search bar to find “Google Drive API”.
3

Enable the API

  1. Click on “Google Drive API” in the search results
  2. Click the “Enable” button
  3. Wait for the API to be enabled
You only need to enable the Drive API once per project. The API provides access to file metadata and content streaming.

Step 3: Create a Service Account

1

Navigate to Service Accounts

Go to “APIs & Services” → “Credentials” from the left sidebar, then click the “Credentials” tab.
2

Create service account

  1. Click ”+ CREATE CREDENTIALS” at the top
  2. Select “Service account” from the dropdown
3

Configure service account details

  1. Service account name: Enter a descriptive name (e.g., “platzi-viewer-service”)
  2. Service account ID: Auto-generated based on the name
  3. Description: Optional (e.g., “Read-only access to Platzi courses”)
  4. Click “Create and Continue”
4

Grant access (Optional)

You can skip the role assignment step by clicking “Continue” - we only need the service account key, not specific GCP roles.
5

Complete creation

Click “Done” to finish creating the service account.

Step 4: Generate Service Account Key

1

Find your service account

On the Credentials page, scroll down to the “Service Accounts” section. You should see your newly created service account listed.
2

Access Keys

  1. Click on the email address of your service account (e.g., [email protected])
  2. Go to the “Keys” tab
3

Create a new key

  1. Click “ADD KEY” → “Create new key”
  2. Select “JSON” as the key type
  3. Click “Create”
4

Download and secure the key

  • The JSON key file will download automatically to your computer
  • This file contains sensitive credentials - store it securely
  • Rename it to service_account.json for convenience
Security Best Practices:
  • Never commit service_account.json to version control (Git)
  • Add it to your .gitignore file
  • Store it outside your project directory if sharing code
  • Treat it like a password - anyone with this file can access your Drive
  • Delete keys from Google Cloud Console if they’re compromised

Step 5: Share Drive Folder with Service Account

The service account needs explicit permission to access your Drive folder.
1

Copy service account email

Open your downloaded service_account.json file and copy the client_email value.It looks like:
{
  "type": "service_account",
  "project_id": "your-project-id",
  "client_email": "[email protected]",
  ...
}
2

Open Google Drive

Navigate to Google Drive and locate the folder containing your Platzi course content.
3

Share with service account

  1. Right-click on the folder
  2. Select “Share”
  3. Paste the service account email (from Step 1)
  4. Set permission to “Viewer” (read-only)
  5. Click “Send”
4

Verify access

The service account now has read-only access to this folder and all its subfolders.
The Drive folder should be organized with this structure:
Platzi Courses/
├── Curso de Python/
│   ├── 1. Introducción/
│   │   ├── 1. Bienvenida.mp4
│   │   ├── 1. Bienvenida_summary.html
│   │   └── 1. Bienvenida.vtt
│   └── 2. Fundamentos/
│       └── ...
└── Curso de JavaScript/
    └── ...
See Building Cache for details on folder structure requirements.

Step 6: Configure Platzi Viewer

Place your service account key in the project directory:
platzi-viewer/
├── service_account.json  # Your credentials file
├── server.py
├── requirements.txt
└── ...
Alternatively, use environment variables:
GOOGLE_SERVICE_ACCOUNT_FILE=/secure/path/to/service_account.json

Verification

Test your service account configuration:
test_drive_access.py
import json
import os
from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build

# Load credentials
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']
creds = Credentials.from_service_account_file(
    'service_account.json',
    scopes=SCOPES
)

# Build Drive service
service = build('drive', 'v3', credentials=creds)

# Test: List files in shared folder
# Replace with your Drive folder ID
FOLDER_ID = '17kPqqPSheDtQ5S1HM6Qvvh2qJ7O3YADm'

results = service.files().list(
    q=f"'{FOLDER_ID}' in parents and trashed=false",
    fields='files(id, name, mimeType)',
    pageSize=10
).execute()

files = results.get('files', [])

if files:
    print(f"✓ Successfully accessed Drive folder ({len(files)} items found)")
    for file in files:
        print(f"  - {file['name']} ({file['mimeType']})")
else:
    print("✗ No files found. Check folder sharing permissions.")
Run the test:
python test_drive_access.py
Replace FOLDER_ID with your actual Google Drive folder ID. You can find this in the URL when viewing the folder in Drive:https://drive.google.com/drive/folders/17kPqqPSheDtQ5S1HM6Qvvh2qJ7O3YADmThe ID is the string after /folders/.

Authentication Scopes

Platzi Viewer uses the drive.readonly scope:
drive_service.py
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']

credentials = Credentials.from_service_account_file(
    'service_account.json',
    scopes=SCOPES
)
This scope provides:
  • ✅ Read file metadata (name, size, MIME type)
  • ✅ Download/stream file content
  • ✅ List folder contents
  • ❌ No write, delete, or modify permissions
  • ❌ No access to files not explicitly shared with the service account

Troubleshooting

”Service account file not found”

Problem: Application cannot locate service_account.json Solution:
# Check file exists
ls service_account.json

# Verify file path in environment
echo $GOOGLE_SERVICE_ACCOUNT_FILE

# Set explicit path
export GOOGLE_SERVICE_ACCOUNT_FILE=/absolute/path/to/service_account.json

“Invalid grant: account not found”

Problem: Service account credentials are invalid or expired Solution:
  1. Verify the JSON file is valid JSON (use cat service_account.json | python -m json.tool)
  2. Regenerate the service account key from Google Cloud Console
  3. Ensure you downloaded the correct key (not an OAuth client ID)

“User Rate Limit Exceeded”

Problem: Too many API requests in a short time Solution: The application includes automatic rate limiting and retry logic. If you still encounter this:
  1. Wait a few minutes before retrying
  2. Check your Google Cloud Console quota usage
  3. Request quota increase if needed (rarely necessary)
The rebuild_cache_drive.py script throttles requests to ~100 calls/second to stay within limits:
rebuild_cache_drive.py:26
def api_call_throttle():
    """Simple rate limiter to avoid hitting Drive API quotas."""
    global API_CALL_COUNT, API_CALL_START
    API_CALL_COUNT += 1
    elapsed = time.time() - API_CALL_START
    # Google Drive API: 12,000 queries per minute for service accounts
    # Be conservative: max ~100 calls per second
    if API_CALL_COUNT % 50 == 0 and elapsed < 1.0:
        wait = 1.0 - elapsed
        time.sleep(wait)
        API_CALL_START = time.time()
        API_CALL_COUNT = 0

“Folder not accessible”

Problem: Service account cannot access the Drive folder Solution:
  1. Verify the folder is shared with the service account email
  2. Check the service account has “Viewer” or “Reader” permission
  3. Ensure the folder ID in your code/config is correct
  4. Test with a simple folder first before using production data

”Drive service not available (503)”

Problem: Application shows Drive unavailable in health check Solution:
# Check health endpoint
curl http://localhost:8080/api/health

# Look for drive.available: false
# Common causes:
# - Missing service_account.json
# - Invalid credentials
# - Wrong file path in environment variables
Check the server logs for specific error messages from drive_service.py.

Next Steps

1

Build the Course Cache

With Drive access configured, scan your folder structure to generate the courses cache.Go to Building Cache →
2

Start Using Platzi Viewer

Complete the setup by starting the server and accessing the application.Go to Quickstart →

Build docs developers (and LLMs) love