iterative / PyDrive2

Google Drive API Python wrapper library. Maintained fork of PyDrive.
https://docs.iterative.ai/PyDrive2
Other
570 stars 70 forks source link

Cant copy the file... using service account #299

Closed meet1919 closed 8 months ago

meet1919 commented 1 year ago

@shcheklein

I am using the code as below:


from oauth2client.service_account import ServiceAccountCredentials
from pydrive2.auth import GoogleAuth
from pydrive2.drive import GoogleDrive

scope = ["https://www.googleapis.com/auth/drive"]
gauth = GoogleAuth()
gauth.auth_method = 'service'
gauth.credentials = ServiceAccountCredentials.from_json_keyfile_name('client_secrets_service.json', scope).create_delegated('xyz@gmail.com')
drive = GoogleDrive(gauth)

body = {
    "parents": [{"kind": "drive#fileLink", "id": new_target_id}],
    'title': 'new.jpeg'
}
drive.auth.service.files().copy(fileId=source_file_id, supportsAllDrives=True, body=body).execute() 

But I am getting the error as below:

Traceback (most recent call last):
  File "C:\python\Work\upwork\payup\test.py", line 92, in <module>
    drive.auth.service.files().copy(fileId=source_file_id, supportsAllDrives=True, body=body).execute()
AttributeError: 'NoneType' object has no attribute 'files

Well I can see this in the API reference:

class pydrive2.files.GoogleDriveFile(auth=None, metadata=None, uploaded=False)
Copy(target_folder=None, new_title=None, param=None)
      Creates a copy of this file. Folders cannot be copied.

      PARAMETERS:
      target_folder ([GoogleDriveFile](https://docs.iterative.ai/PyDrive2/pydrive2/#pydrive2.files.GoogleDriveFile), optional) – Folder where the file will be copied.

      new_title (str, optional) – Name of the new file.

      param (dict, optional) – addition parameters to pass.

      RAISES:
      ApiRequestError

      RETURNS:
      the copied file

      RETURN TYPE:
      [GoogleDriveFile](https://docs.iterative.ai/PyDrive2/pydrive2/#pydrive2.files.GoogleDriveFile)

But I am not sure how to use it

shcheklein commented 1 year ago

Yes, PyDrive2 API is quite "specific". Sorry, about that it's a legacy that we are replacing gradually with fsspec compatible implementation here.

I would give it a try, I think this spec should be enough to try along with the link above.

For the native PyDrive2 api, to make it work you need to create instance of the file object to manipulate with it.

file_id = "id" # you need to know this ID, can be taken in UI, or using other PyDrive2 helpers, something like this:
file_to_copy = drive.CreateFile({"id": file_id})
directory_to_copy_to = drive.CreateFile({"id": directory_id}) # optional
file_to_copy.Copy(target_folder=directory_to_copy_to, new_title="if you need this")
shcheklein commented 1 year ago

May be tests in https://github.com/iterative/PyDrive2/pull/188/files , could also help you get a better idea on how this API works.

meet1919 commented 1 year ago

I see, I can use this cp(["source/file1", "source/file2", "source/subdir/subfile1"], "target/") for copying multiple files to target folder. Just wondering (might be a little silly), what will be the file path here in reference to the drive?

Should it be like cp(["file1_id", "file2_id"], "target_folder_id") ?