Last active
September 26, 2026 06:56
-
-
Save prasathmani/5d78a6126c3e1920ffb6fd591a759edb to your computer and use it in GitHub Desktop.
upload files to google drive using python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import json | |
| import os | |
| import requests | |
| # ============================================================ | |
| # Google Drive configuration | |
| # ============================================================ | |
| CLIENT_ID = "YOUR_CLIENT_ID" | |
| CLIENT_SECRET = "YOUR_CLIENT_SECRET" | |
| REFRESH_TOKEN = "YOUR_REFRESH_TOKEN" | |
| # Google Drive folder ID | |
| FOLDER_ID = "YOUR_GOOGLE_DRIVE_FOLDER_ID" | |
| # Backup file to upload | |
| UPLOAD_FILE = "/path/to/your/backup.zip" | |
| # ============================================================ | |
| # Google OAuth / Drive URLs | |
| # ============================================================ | |
| TOKEN_URL = "https://oauth2.googleapis.com/token" | |
| UPLOAD_URL = ( | |
| "https://www.googleapis.com/upload/drive/v3/files" | |
| "?uploadType=multipart" | |
| ) | |
| # ============================================================ | |
| # Get a new access token using the refresh token | |
| # ============================================================ | |
| def get_access_token(): | |
| data = { | |
| "client_id": CLIENT_ID, | |
| "client_secret": CLIENT_SECRET, | |
| "refresh_token": REFRESH_TOKEN, | |
| "grant_type": "refresh_token", | |
| } | |
| response = requests.post(TOKEN_URL, data=data) | |
| if response.status_code != 200: | |
| raise Exception( | |
| f"Failed to get access token: {response.text}" | |
| ) | |
| token_data = response.json() | |
| access_token = token_data.get("access_token") | |
| if not access_token: | |
| raise Exception( | |
| f"No access token returned: {token_data}" | |
| ) | |
| return access_token | |
| # ============================================================ | |
| # Upload file to Google Drive | |
| # ============================================================ | |
| def upload_to_drive(access_token, file_path, folder_id): | |
| if not os.path.isfile(file_path): | |
| raise FileNotFoundError( | |
| f"Backup file does not exist: {file_path}" | |
| ) | |
| file_name = os.path.basename(file_path) | |
| metadata = { | |
| "name": file_name, | |
| "parents": [folder_id], | |
| } | |
| headers = { | |
| "Authorization": f"Bearer {access_token}", | |
| } | |
| # Keep the file open while requests.post() is running. | |
| # This fixes the "read of closed file" error from the original Gist. | |
| with open(file_path, "rb") as backup_file: | |
| files = { | |
| "data": ( | |
| "metadata", | |
| json.dumps(metadata), | |
| "application/json; charset=UTF-8", | |
| ), | |
| "file": ( | |
| file_name, | |
| backup_file, | |
| "application/zip", | |
| ), | |
| } | |
| response = requests.post( | |
| UPLOAD_URL, | |
| headers=headers, | |
| files=files, | |
| timeout=3600, | |
| ) | |
| if response.status_code not in (200, 201): | |
| raise Exception( | |
| f"Google Drive upload failed " | |
| f"(HTTP {response.status_code}):\n" | |
| f"{response.text}" | |
| ) | |
| result = response.json() | |
| print("Upload successful!") | |
| print(f"File name: {result.get('name')}") | |
| print(f"Google Drive file ID: {result.get('id')}") | |
| # ============================================================ | |
| # Main | |
| # ============================================================ | |
| def main(): | |
| print("Starting Google Drive backup upload...") | |
| try: | |
| print("Getting Google access token...") | |
| access_token = get_access_token() | |
| print(f"Uploading: {UPLOAD_FILE}") | |
| upload_to_drive( | |
| access_token, | |
| UPLOAD_FILE, | |
| FOLDER_ID, | |
| ) | |
| print("Backup upload completed successfully.") | |
| except Exception as e: | |
| print(f"Error: {e}") | |
| raise | |
| # ============================================================ | |
| # Run | |
| # ============================================================ | |
| if __name__ == "__main__": | |
| main() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Google Drive API Setup for Server Backup Script
This guide explains how to create Google Drive API credentials and generate a refresh token for a server-side backup script.
The final setup allows a server to upload a backup to a specific Google Drive folder without requiring you to log in every day.
Overview
The Python script requires these values:
The first three are obtained through Google OAuth 2.0.
The
FOLDER_IDis obtained from the Google Drive folder URL.1. Create a Google Cloud Project
Open:
https://console.cloud.google.com/
Create a new project.
For example:
Select the newly created project.
2. Enable Google Drive API
In Google Cloud Console:
Search for:
Open it and click:
The Drive API must be enabled before the script can access Google Drive.
3. Configure Google Auth Platform
In the Google Cloud Console, go to:
If Google asks you to configure the platform, click:
Configure the application.
Example:
The current Google Cloud interface separates OAuth configuration into areas such as Branding, Audience, and Data Access.
4. Configure the Audience
Go to:
For a personal Google account, you can use:
if Internal is not available.
If you select External, your application can remain in Testing for your own use.
Add your Google account as a test user:
Enter the Google account that owns the Drive folder:
Click:
IMPORTANT:
If your account is not listed as a test user, Google may show:
with a message saying the app can only be accessed by developer-approved testers.
5. Configure the Drive OAuth Scope
Go to:
For the backup script, use:
This gives the application access to Google Drive.
Click:
and then save the configuration.
6. Create an OAuth Client
Because we are using Google's OAuth 2.0 Playground to generate the refresh token, create a:
OAuth client.
Go to:
Select:
Give it a name:
7. Add the OAuth Playground Redirect URI
Under:
add exactly:
Do not add a trailing slash.
It must be:
and not:
Click:
Google will provide:
Keep both values secure.
IMPORTANT:
The Client ID and Client Secret must be used together with the refresh token generated from the same OAuth client.
8. Open Google OAuth 2.0 Playground
Open:
https://developers.google.com/oauthplayground/
Google's OAuth Playground allows you to authorize your Google account and exchange the authorization code for an access token and refresh token.
9. Configure OAuth Playground
Click the gear/settings icon in the upper-right corner.
Enable:
Enter the Client ID and Client Secret created in the previous step.
Example:
Use the exact values from your Google Cloud OAuth client.
10. Configure OAuth Flow
In OAuth Playground settings, use:
The important setting is:
Offline access is required to obtain a refresh token.
11. Select Google Drive Scope
In OAuth Playground, under:
Use the field:
Enter:
Then click:
12. Sign in to Google
Google will open the authorization screen.
Sign in using the same Google account that you added as a test user.
For example:
Review the requested permissions and click:
If Google displays a warning that the application has not been verified, make sure you are using the account that was added as a test user.
13. Exchange Authorization Code for Tokens
After authorization, OAuth Playground will return to the Playground.
Go to:
Click:
OAuth Playground should return something similar to:
The value you need for the server backup script is:
You do NOT need to manually put the access token into the Python script.
The Python script uses the refresh token to obtain a new access token whenever it runs.
14. Create the Google Drive Backup Folder
Open Google Drive:
https://drive.google.com/
Create a folder, for example:
Open the folder.
The browser URL will look similar to:
The folder ID is:
Therefore:
15. Create credentials.env
Put
credentials.envin the same directory asgdrive.py.Example:
Do not put quotes around the values.
16. Install Python Dependencies
Install
requests:Install
python-dotenv:Or:
17. Python Script Configuration
The Python script should load the credentials from
credentials.env.Example:
Using the script directory is recommended because cron may execute the script from a different working directory.
18. Protect credentials.env
On Linux:
This prevents other normal users from reading the file.
If this directory is a Git repository, add this to
.gitignore:Never commit your refresh token or client secret to GitHub.
19. Verify the Configuration
Run:
A successful run should produce output similar to:
20. Common Errors
Error: redirect_uri_mismatch
Example:
Check the OAuth client in Google Cloud.
The Authorized redirect URI must be exactly:
Also make sure you are using a Web application OAuth client for OAuth Playground.
Error: access_denied
Example:
If the OAuth application is External and in Testing mode, add your Google account under:
Then authorize again.
Error: unauthorized_client
Example:
Usually check that:
all belong to the same OAuth client.
Do not generate the refresh token using Client A and then use Client B's Client ID/Secret in the Python script.
Error: read of closed file
Example:
This is caused by closing the backup file before the HTTP upload has finished.
Make sure the upload code keeps the file open while
requests.post()orrequests.patch()is running.Use:
instead of opening the file inside a
withblock and returning the closed file object.21. How OAuth Works
The process is:
The refresh token is then stored securely on your server.
Every day:
You do not need to manually obtain a new access token every day.
The refresh token is used to obtain fresh access tokens automatically.
22. Important Security Warning
Treat these values as secrets:
Do NOT publish them in a GitHub Gist.
Your documentation can contain placeholders:
But never publish the real values.
If a real refresh token or client secret is accidentally published, revoke/rotate the credential immediately.
23. Recommended GitHub Repository Structure
A good structure is:
Create:
with:
Then
.gitignore:The real
credentials.envstays only on your server.Official Google References
Google OAuth 2.0 Playground:
https://developers.google.com/oauthplayground/
Google Drive API Python quickstart:
https://developers.google.com/workspace/drive/api/quickstart/python
Google OAuth consent configuration:
https://developers.google.com/workspace/guides/configure-oauth-consent
Google OAuth Playground documentation:
https://developers.google.com/search-ads/reporting/concepts/oauth-playground
Disclaimer
This guide was generated with the assistance of AI. It is provided for informational purposes only. Google Cloud Console, OAuth, and Google Drive API interfaces and requirements may change over time. Always verify the current Google documentation before configuring authentication or using this setup in production.
Do not share or publish your Google OAuth Client Secret, Refresh Token, or other credentials.