How to use PyDrive2 to upload a file to google drive folder

Uploading file to google drive requires the following steps:

  1. Authenticate with google drive

  2. Uploading a file to a specific folder by the name of the folder

  3. If the folder does not exist, we need to create the folder first

  4. Finally, upload the file.

To authenticate, we will use PyDrive2, which is a new library that is actively maintained.

Step 1: Authentication

We will use a service account instead of using Google OAuth so that it integrates nicely with our development workflow. In case you want to use google OAuth you will find documentation here https://docs.iterative.ai/PyDrive2/quickstart/#authentication

  1. Create a new service account https://cloud.google.com/iam/docs/creating-managing-service-accounts
    No
    need to give any permissions to the account.

  2. Create and JSON Key https://cloud.google.com/iam/docs/creating-managing-service-account-keys

  3. Create the folder on google drive and give Editor rights to the service account email which might look like xxxxxxx@xxxxxxx.iam.gserviceaccount.com
    You can find this in the JSON key you downloaded in client_email property

gauth = GoogleAuth()
# NOTE: if you are getting storage quota exceeded error, create a new service account, and give that service account permission to access the folder and replace the google_credentials.
gauth.credentials = ServiceAccountCredentials.from_json_keyfile_name(
    pkg_resources.resource_filename(__name__, "google_credentials.json"), scopes=['https://www.googleapis.com/auth/drive'])

drive = GoogleDrive(gauth)

Remember, the service account does not have a lot of space like your actual google account. So, in case you have issues, it’s better to use google oauth. Or you can write a script to delete all the files owned by the service account. I will write a blog post on how to do that soon.

Step 2: Folder Creation

Let’s decide the name of the folder that we would want to create inside the parent directory we created in Step 1 (remember you gave editor rights to the service account to the parent folder)

folder_name = "my_new_folder"
parent_directory_id = "x-xxxxxxxxxxxxxxxxxxxxx" 
folder_meta = {
    'title':  folder_name,
    'parents': [{'id': parent_directory_id}],
    'mimeType': 'application/vnd.google-apps.folder'
}

# check if folder already exist or not
folder_id = None
foldered_list = drive.ListFile(
    {'q':  "'"+parent_directory_id+"' in parents and trashed=false"}).GetList()
for file in foldered_list:
    if (file['title'] == folder_name):
        folder_id = file['id']
if folder_id == None:
    folder = drive.CreateFile(folder_meta)
    folder.Upload()
    folder_id = folder.get("id")

Step 3: Upload the file in the folder

Now that we have the folder_id, we can upload our new file to this newly created folder.

file1 = drive.CreateFile(
    {'parents': [{"id": folder_id}], 'title': file_name})

file1.SetContentFile(file_path)

file1.Upload()

Full Code Example

from pydrive2.auth import GoogleAuth
from pydrive2.drive import GoogleDrive
from oauth2client.service_account import ServiceAccountCredentials
import pkg_resources
from datetime import date
import sys
import os


def upload_file_to_gdrive(file_path, file_name):
    gauth = GoogleAuth()
    # NOTE: if you are getting storage quota exceeded error, create a new service account, and give that service account permission to access the folder and replace the google_credentials.
    gauth.credentials = ServiceAccountCredentials.from_json_keyfile_name(
        pkg_resources.resource_filename(__name__, "google_credentials.json"), scopes=['https://www.googleapis.com/auth/drive'])

    drive = GoogleDrive(gauth)
    today = date.today().strftime("%m/%d/%y")

    folder_name = today + "-" + "manual_upload"
    parent_directory_id = 'x-xxxxxxxxxxxxxxxxxxxxxxxxxxx'

    folder_meta = {
        "title":  folder_name,
        "parents": [{'id': parent_directory_id}],
        'mimeType': 'application/vnd.google-apps.folder'
    }

    # check if folder already exist or not
    folder_id = None
    foldered_list = drive.ListFile(
        {'q':  "'"+parent_directory_id+"' in parents and trashed=false"}).GetList()

    for file in foldered_list:
        if (file['title'] == folder_name):
            folder_id = file['id']

    if folder_id == None:
        folder = drive.CreateFile(folder_meta)
        folder.Upload()
        folder_id = folder.get("id")

    file1 = drive.CreateFile(
        {'parents': [{"id": folder_id}], 'title': file_name})

    file1.SetContentFile(file_path)

    file1.Upload()


file_path = sys.argv[1]

if not os.path.isfile(file_path):
    print('file does not exist ----------')
else:
    file_name = os.path.basename(file_path)
    print('file exist and uploading ----------')
    upload_file_to_gdrive(file_path, file_name)