# Google Drive Uploader

This guide demonstrates how to upload files directly to Google Drive using the Google Drive API. This approach allows you to upload files programmatically without installing the Google Drive desktop client.

**Modules Used:**
*   `google-api-python-client`: The official Python client library for Google's discovery based APIs.
*   `google-auth-oauthlib`: Integration with `google-auth` for OAuth 2.0 flows.

## Prerequisites

1.  **Google Cloud Console**: Go to the Google Cloud Console.
2.  **Create Project**: Create a new project.
3.  **Enable API**: Search for "Google Drive API" and enable it.
4.  **Credentials**:
    *   Go to "Credentials" -> "Create Credentials" -> "OAuth client ID".
    *   Configure the Consent Screen (External, Test User = your email).
    *   Application type: Desktop App.
    *   Download the JSON file and rename it to `credentials.json`.
    *   Place `credentials.json` in the same directory as your script.

## Installation

```bash
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
```

## The Code

Save this as `drive_upload.py`.

```python
import os.path
import argparse
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload

# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/drive.file']

def authenticate():
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            if not os.path.exists('credentials.json'):
                print("Error: credentials.json not found.")
                return None
            
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
            
    return creds

def upload_file(file_path, folder_id=None):
    creds = authenticate()
    if not creds:
        return

    try:
        service = build('drive', 'v3', credentials=creds)

        file_metadata = {'name': os.path.basename(file_path)}
        
        if folder_id:
            file_metadata['parents'] = [folder_id]

        media = MediaFileUpload(file_path, resumable=True)
        
        print(f"Uploading {file_path}...")
        file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
        
        print(f"File ID: {file.get('id')}")

    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Google Drive Uploader")
    parser.add_argument("file", help="Path to the file to upload")
    parser.add_argument("--folder", help="ID of the Google Drive folder to upload to (optional)")
    
    args = parser.parse_args()
    
    if os.path.exists(args.file):
        upload_file(args.file, args.folder)
    else:
        print(f"Error: File '{args.file}' not found.")
```

## Usage

1.  **First Run (Authentication)**:
    The first time you run the script, a browser window will open asking you to log in to your Google account and authorize the app.
    ```bash
    python drive_upload.py my_document.pdf
    ```

2.  **Subsequent Runs**:
    It will use the saved `token.json` and upload immediately.

3.  **Upload to Specific Folder**:
    You can find the Folder ID in the URL of the folder in your browser (e.g., `drive.google.com/drive/folders/YOUR_FOLDER_ID`).
    ```bash
    python drive_upload.py image.jpg --folder YOUR_FOLDER_ID
    ```

[[programming/python/python]]