This fork incorporates a couple of fixes:
- The "Consent is required to transfer ownership of a file to another user." error, fixed by @svaponi in his fork (which this is based on).
- The "Error 400: invalid_request", "The out-of-band (OOB) flow has been blocked in order to keep users secure." error, fixed by @wildintellect in his fork. This change has been pulled in.
Still, you may encounter the following error after confirming in your browser:
Traceback (most recent call last):
File "/home/koopa/code/python/google-drive-recursive-ownership/transfer.py", line 197, in <module>
main()
~~~~^^
File "/home/koopa/code/python/google-drive-recursive-ownership/transfer.py", line 181, in main
service = get_drive_service()
File "/home/koopa/code/python/google-drive-recursive-ownership/transfer.py", line 20, in get_drive_service
credentials = flow.run_local_server()
File "/home/koopa/code/python/google-drive-recursive-ownership/.venv/lib/python3.13/site-packages/google_auth_oauthlib/flow.py", line 464, in run_local_server
authorization_response = wsgi_app.last_request_uri.replace("http", "https")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'replace'
This appears to be a race condition within google_auth_oauthlib. I worked around this with a pretty silly change to .venv/lib/python3.13/site-packages/google_auth_oauthlib/flow.py (yes, you should use a virtualenv!):
- local_server.handle_request()
+ try:
+ local_server.serve_forever()
+ except KeyboardInterrupt:
+ passWith this applied, once you go through the flow in your browser, you can tab back to your terminal and issue an interrupt with Ctrl+C. This gives enough time for the callback to run.
G Suite for Government and G Suite for Education accounts can change ownership of any file owned by the current user, including uploaded/synced files suchs as PDFs.
Other Google Accounts such as G Suite for Business or Personal Google Accounts can only transfer ownership of Google files (Docs, Sheets, Sildes, Forms, Drawings, My Maps, and folders).
NOTE: Ownership can only be transferred to members of the same G Suite or Google domain. Ex. @gmail.com can only transfer to other @gmail.com addresses.
NOTE: The Google Drive API does not allow suppressing notifications for change of ownership if the if the new owner does not already have access to the file. However, if the new owner already has access to the file, upgrading their permissions to ownership will not generate a notification.
git clone https://github.com/svaponi/google-drive-recursive-ownership
cd google-drive-recursive-ownership
pip install -r requirements.txtAlternatively, if you have poetry installed, run:
git clone https://github.com/svaponi/google-drive-recursive-ownership
cd google-drive-recursive-ownership
poetry installTo update the requirements.txt, run:
poetry export -f requirements.txt --output requirements.txt --without-hashes
First, replace the sample client_secrets.json with your own client secrets. Otherwise, authorizations you create will be usable by anyone with access to the sample key (the entire internet).
Next, if transfer.py is contained in a folder listed in your system's PATH this can be run from anywhere. Otherwise it needs to be run from the directory where transfer.py is located.
python transfer.py PATH-PREFIX NEW-OWNER-EMAIL SHOW-ALREADY-OWNER
-
PATH-PREFIXassumes use of "/" or "" as appropriate for your operating system.- The
PATH-PREFIXfolder must be in My Drive section. For shared folders right click and select Add to My Drive.
- The
-
SHOW-ALREADY-OWNER"true"|"false" (defaulttrue) to hide feedback for files already set correctly.
Windows Example:
python transfer.py "Folder 1\Folder 2\Folder 3" new_owner@example.com true
Mac/Linux Example:
python transfer.py "Folder 1/Folder 2/Folder 3" new_owner@example.com false