3

My Problem

I have a GDrive folder of which I want to list the users having access to it. Unfortunately the API doesn't return more than 100 users and the documented solutions to paginate don't work.

(!) Maybe this is related to testing on shared drives - currently I cannot reproduce on non-shared drive folders unfortunately.

What I Tried so far:

I tried the pagination solution as described in the google docs, e.g. I tried:

file_id = "12abcde"  # my folder ID
request = service.permissions().list(
  fileId=file_id, fields="permissions(type,emailAddress)", supportsAllDrives=True
)
while request is not None:
    activities_doc = request.execute()
    request = service.permissions().list_next(request, activities_doc)

the request in the loop is always None.

The returned body from the initial request as well doesn't match the one described in the docs.

Does somebody have experience on making this work?

3 Answers 3

4

to get the full list, you need to use the nextPageToken and place it under the pageToken parameter.

You can get the nextPageToken from the response body by adding it to the requested fields.

You can use the following sample code as reference:

    try:

        service = build('drive', 'v3', credentials=creds)
        file_id = "asdfasdfas"  # my folder ID
        permissions_list = []
        first_request = service.permissions().list(
                fileId=file_id, 
                pageSize=100, 
                supportsAllDrives=True, 
                fields="nextPageToken, permissions(type,emailAddress)"
            ).execute()
        
        permissions_list.append(first_request)

        next_Page_Token = first_request.get('nextPageToken')

        

        while next_Page_Token:

            request = service.permissions().list(
                pageToken = next_Page_Token,
                fileId=file_id,
                pageSize=100, 
                supportsAllDrives=True, 
                fields="nextPageToken, permissions(type,emailAddress)"
            ).execute()
            permissions_list.append(request)
            next_Page_Token = request.get('nextPageToken')

            

    except HttpError as error:
        # TODO(developer) - Handle errors from drive API.
        print(f'An error occurred: {error}')

Update:

This one is a sample using list_next() base in the documentation here:

    try:
        service = build('drive', 'v3', credentials=creds)

        permission_list = []
        token = 'test'

        fileID='folderID'

        request_made =  service.permissions().list(
            fileId=fileID,
            pageSize=100, 
            fields="nextPageToken, permissions(type,emailAddress)",
            supportsAllDrives=True
            )

        request = request_made.execute()
        permission_list.append(request)

        while token:
            nextpage = service.permissions().list_next(
                previous_request=request_made, 
                previous_response=request)
            request = nextpage.execute()
            token = request.get('nextPageToken')
            permission_list.append(request)
            request_made = nextpage


    except HttpError as error:
        # TODO(developer) - Handle errors from drive API.
        print(f'An error occurred: {error}')
Sign up to request clarification or add additional context in comments.

4 Comments

Ah okay, one has to explicitly add use the nextPageToken (and retrieve via fields) when using this. Thanks a lot, this helped me a lot!
Cool, glad to here it. And thanks to you, I learnerd about the list_next() method.
Great, happy to hear that :)
This put me on the right track, but the code still looks overcomplicated, TBH. Try this instead?
2

I haven't used the Drive API, but in a fairly modern Python implementation (e.g. 3.11), I'm pretty sure Giselle's code could be simplified like this:

try:
    service = build('drive', 'v3', credentials=creds)
    permissions_api = service.permissions() # permissions in Giselle's code
    permissions = [] # permission_list in Giselle's code

    request = permissions_api.list(
        fileId='folderID',
        fields='nextPageToken, permissions(type,emailAddress)',
        supportsAllDrives=True)
    while request:
        response = request.execute()
        permissions += response
        # permissions += response.get('permissions', []) maybe this, actually?
        request = permissions_api.list_next(request, response)

except HttpError:
    logging.warning('whoopsie!', exc_info=True)  # TODO

pprint.pp(permissions) # Here they all are

You might actually want to append a submapping of response to permission_list, like in the line I commented out (I'm not sure about the structure), but there shouldn't be any need to mess with pagination tokens in your code. The default pageSize should be fine, too.

Comments

1

This is the shortest code:

def get_permissions(file_id) -> Generator[dict, None, None]:
    fields = "nextPageToken, permissions(type,emailAddress)"
    page_token = ""
    resource = SERVICE.permissions()
    while page_token is not None:
        request = resource.list(fileId=file_id, fields=fields, supportsAllDrives=True, pageToken=page_token)
        permission_list = request.execute()
        yield from permission_list.get("permissions", [])
        page_token = permission_list.get("nextPageToken")


file_id = "12abcde"  # my folder ID
for permission in get_permissions(file_id):
    print(permission)

I confirmed that setting empty string "" into page_token works as without it.
We can omit duplicate definition of function calling in code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.