PyDrive
PyDrive copied to clipboard
Folders
How does this API handle Folders? It seems as tho it only handles files that are stored in the root of the drive.
A folder/directory in Drive is a file with the mimetype 'application/vnd.google-apps.folder' by default it will be assigned an ID and you use this ID as the parent ID when creating subdirectories.
Here's an example:
from pydrive import auth, drive
#authorize however you want
gauth = auth.GoogleAuth().LocalWebserverAuth()
#create and authorize your drive client object
drive_client = drive.GoogleDrive(gauth)
#Create the folder
# If no parent ID is provided this will automatically go to the root or My Drive 'directory'
top_level_folder = drive_client.CreateFile({'title': 'top_level'})
# Upload the file to your drive
top_level_folder.Upload()
# Grab the ID of the folder we just created
parent_id = top_level_folder['id']
# Create a sub-directory
# Make sure to assign it the proper parent ID
child_folder = drive_client.CreateFile({'title': 'level_2', 'parents':[{'id':parent_id}]})
child_folder.Upload()
That's it!
Check out the API documentation it is a huge help in understanding how the metadata for Drive items are used and what you can do with them!
OK this if for only the creation of a folder. When I do the following code
# auth assumed
drive = GoogleDrive(auth)
for f in drive.ListFile().GetList():
if f['mineType'] == 'application/vnd.google-apps.folder':
print f['title']
Nothing prints out. And i do have folders on the drive. Upon further inspection by doing the following.
for f in drive.ListFile().GetList():
print f['title'], f['mineType']
It only prints out titles and mimeTypes for files. Now I may be incorrect here but one would guess that when using the ListFiles it would do exactly that lists the files and not the folders. does your API remove folders or query Google Drive in a manner which causes it to not return folders?
OK so I found out why they are not listed. I do not know how to make then show up.
If I make a folder using the google web interface it does not show up using the API. If i create a folder using the API it shows up in the google web interface as well as in the API.
Did you check the permissions of the two folders? The function file.GetPermissions()
could be useful for the API-created folder, then you can compare it with the permissions displayed in the Google Drive web interface for the other folder.
You can also try whether you can access the folder directly. For this you are going to need the ID of the folder, which you can extract from the share link, which has the following format: https://drive.google.com/drive/folders/<folder ID>?usp=sharing
.
Once you have the ID, you can use it to create a file object:
folder_object = drive.CreateFile({'id': '<folder ID>'})
# Print the permissions.
print(folder_object.GetPermissions())
ok cool. Thanks for the tips. That is going to be helpful in tacking down what is causing this issue. Its very odd why it's not showing up tho. from what i can tell everything in the web UI appears to be identical (except the name of the folders)
I have been looking at how you coded up pydrive and it shouldn't be all that hard to add convince methods for folders. it could be made to mimic a folder structure with GoogleDrive being the base class for a folder and if you use the CreateFile it would make a file in that folder.
Would it be difficult to make a class for each of the various mime types? attach the file location of the file they want to upload to that class, pass the mime type class to the create file and it would do all of the heavy lifting so to speak. Set up the mete data as properties using fset for the things they are allowed to change for that specific mime type.
Also I don't know if this would be of interest to you for possible addition to the library. For the local server auth I wrote up some code that will check to see if the local IP and the WAN IP are the same and if they are not then it would attempt to do a port forward on a router using UPNP all behind the scenes. I have not been able to test this piece of code as of yet because my router has an issue with responding to UPNP SSDP discovery packets. The idea is sound and it should work and it might need some fine tuning.
I know I am hitting you with a bunch of things But this is an extremely useful library. The only thing is you need to read the google API in order to really dive into using it. And google's docs (for lack of better words) really sucks. as an example they do not explain a single thing about how the parents structure works.
I have found that you are able to use the metadata keyword of "q" for doing expression based searching. they have this listed in the "Search for Files and Team Drives" section of the API and it works when querying google for anything really.
@RNabel this is what happens when used your code to check permissions of a folder not created by PyDrive:
pydrive\files.py", line 239, in FetchMetadata
raise ApiRequestError(error)
pydrive.files.ApiRequestError: <HttpError 404 when requesting https://www.googleapis.com/drive/v2/files/1wlAyrKSlcswNG_SRjjPvehexk-1QWJML?fields=permissions&alt=json returned "File not found: 1wlAyrKSlcswNG_SRjjPvehexk-1QWJML">
But the folder exists, indeed. It is view accesible: https://drive.google.com/drive/folders/1wlAyrKSlcswNG_SRjjPvehexk-1QWJML
On the other hand, I have not problem to see all the folders created by PyDrive using the listing code of @kdschlosser above. I can also see their permissions combining it with your code.
So I think this could be related to what I mentioned in [issue #105 ].
Thanks
@kdschlosser have you seen #108 ?
I don't really understand how oAuth works, and I don't know how your script did authenticate. But in my case I was using a settings.yaml file to avoid having to reauthorise the script each time. I followed an example found in StackOverflow, but I took my settings.yaml file from PyDrive documentation. That combination was limiting my script as I described in #105 .
When I browsed closed issues I found #108 and that was the key: my problem was the oauth_scope part of that settings.yaml file. Once I changed it, my problem was gone. I posted my solution also in StackOverflow
By the way, this problem wouldn't happen to me without using that settings.yaml file, since it changed the default oauth_scope field value (which is described just above the linked settings.yaml example file):
oauth_scope (list of str):
OAuth scope to authenticate. Default: [‘https://www.googleapis.com/auth/drive‘]. Required: No.
Maybe this is also the origin of your problem?