Office365-REST-Python-Client icon indicating copy to clipboard operation
Office365-REST-Python-Client copied to clipboard

moveto stopped working in 2.4.2

Open GuptaNaman1998 opened this issue 2 years ago • 6 comments

while I was using moveto with v2.4.1 it was working but with 2.4.2 it stopped.

GuptaNaman1998 avatar Jul 03 '23 11:07 GuptaNaman1998

I had the same problem

esgario avatar Jul 07 '23 14:07 esgario

debug on 2.4.2:

2023-07-15 09:55:43,954|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_new_conn       |Starting new HTTPS connection (1): tenant.sharepoint.com:443
2023-07-15 09:55:44,198|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_make_request   |https://tenant.sharepoint.com:443 "GET /sites/zzz/_api/Web/GetFileById('20dbe841-16f4-4c52-8918-de00bb29db44')?$select=Id HTTP/1.1" 200 None
2023-07-15 09:55:44,211|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_new_conn       |Starting new HTTPS connection (1): tenant.sharepoint.com:443
2023-07-15 09:55:44,472|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_make_request   |https://tenant.sharepoint.com:443 "POST /sites/zzz/_api/Web/RootFolder/Folders/Add('sites') HTTP/1.1" 403 None
2023-07-15 09:55:49,499|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_new_conn       |Starting new HTTPS connection (1): tenant.sharepoint.com:443
2023-07-15 09:55:49,777|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_make_request   |https://tenant.sharepoint.com:443 "POST /sites/zzz/_api/Web/RootFolder/Folders('sites')/Folders/Add('yyy') HTTP/1.1" 404 None
2023-07-15 09:55:54,803|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_new_conn       |Starting new HTTPS connection (1): tenant.sharepoint.com:443
2023-07-15 09:55:55,066|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_make_request   |https://tenant.sharepoint.com:443 "POST /sites/zzz/_api/Web/RootFolder/Folders('sites')/Folders('yyy')/Folders/Add('Shared%20Documents') HTTP/1.1" 404 None
2023-07-15 09:56:00,090|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_new_conn       |Starting new HTTPS connection (1): tenant.sharepoint.com:443
2023-07-15 09:56:00,367|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_make_request   |https://tenant.sharepoint.com:443 "POST /sites/zzz/_api/Web/RootFolder/Folders('sites')/Folders('yyy')/Folders('Shared%20Documents')/Folders/Add('ccc') HTTP/1.1" 404 None
2023-07-15 09:56:05,497|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_new_conn       |Starting new HTTPS connection (1): tenant.sharepoint.com:443
2023-07-15 09:56:06,036|P=10751 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_make_request   |https://tenant.sharepoint.com:443 "POST /sites/zzz/_api/Web/RootFolder/Folders('sites')/Folders('yyy')/Folders('Shared%20Documents')/Folders('ccc')/Folders/Add('XXX') HTTP/1.1" 404 None

vs success:

2023-07-15 09:49:34,232|P=10677 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_new_conn       |Starting new HTTPS connection (1): tenant.sharepoint.com:443
2023-07-15 09:49:34,598|P=10677 |T=8572165632      |DEBUG  |urllib3.connectionpool|connectionpool  |_make_request   |https://tenant.sharepoint.com:443 "POST /sites/zzz/_api/Web/GetFileById('00000000-0000-0000-0000-000000000000')/moveto(newurl='%2Fsites%2FTechsupport%2FShared%20Documents%2Fccc%2FXXX%2Ftechsupport-20230713-081000-6.2.2%2B1.tar',flags=1) HTTP/1.1" 200 None

There is a new logic handling path. IMO the problem lies with ensuring the path. It starts with fetching the site, which fails. Permission issue?

More info on what we were trying to achieve. While uploading the file to SharePoint, we have random filename, and on SharePoint, we were using the move command to rename the uploaded file also. Using rename command is a no-go, as it refuses to change the extension even through API. Right now, the move command expects the target folder - known to us, we can pass the object, but the file does not get renamed as it is only moved.

kinocz avatar Jul 15 '23 08:07 kinocz

Hey,

thank you for catching this bug and @kinocz for providing the detailed analysis! Indeed, the way how destination folder is verified (i.e. all child foldes gets enumerated to ensure the folder(s) exist), lies the root of cause of this problem

Perhaps, better off abandon destination folder verification.. Meanwhile (before it gets resolved in next version) propose to switch to those methods:

MoveCopyUtil.move_folder(context, src_url, dest_url, options) or MoveCopyUtil.move_folder_by_path(context, src_path, dest_path, options)

they behave pretty much the same way as Folder.move_to() in prev version:

ctx = ClientContext(site_url).with_credentials(credentials)

folder_from_url = "/sites/{my site}/{my-in-folder}" 
folder_to_url = "/sites/{my site}/{my-out-folder}" 

opt = MoveCopyOptions()
MoveCopyUtil.move_folder(ctx, folder_from_url, folder_to_url, opt).execute_query()

vgrem avatar Jul 15 '23 10:07 vgrem

I'm moving just a file, so the trick is to create the API command directly as the moveto method did.

            uploaded_file.context.add_query(
                ServiceOperationQuery(uploaded_file,
                                      "moveto",
                                      {
                                          "newurl": server_filename,
                                          "flags": 1
                                      },
                                      None)
            ).execute_query_retry()

kinocz avatar Jul 15 '23 14:07 kinocz

Hey,

thank you for catching this bug and @kinocz for providing the detailed analysis! Indeed, the way how destination folder is verified (i.e. all child foldes gets enumerated to ensure the folder(s) exist), lies the root of cause of this problem

Perhaps, better off abandon destination folder verification.. Meanwhile (before it gets resolved in next version) propose to switch to those methods:

MoveCopyUtil.move_folder(context, src_url, dest_url, options) or MoveCopyUtil.move_folder_by_path(context, src_path, dest_path, options)

they behave pretty much the same way as Folder.move_to() in prev version:

ctx = ClientContext(site_url).with_credentials(credentials)

folder_from_url = "/sites/{my site}/{my-in-folder}" 
folder_to_url = "/sites/{my site}/{my-out-folder}" 

opt = MoveCopyOptions()
MoveCopyUtil.move_folder(ctx, folder_from_url, folder_to_url, opt).execute_query()

thank you @vgrem & @kinocz both your comments help a lot! For now I've resorted to using v2.4.1

GuptaNaman1998 avatar Jul 16 '23 10:07 GuptaNaman1998

Thank you @kinocz ! Your solution with ServiceOperationQuery above worked for me. I am using version 2.4.3

I used this import to gain access to the function:

from office365.runtime.queries.service_operation import ServiceOperationQuery

Thank you again @kinocz and @vgrem !!

JimPfening avatar Aug 02 '23 23:08 JimPfening

Nowadays it is recomended to utilize standard File.move_to_using_path(destination, flag) and File.moveto(destination, flag) methods to move the file to the specified destination path:

where:

  • destination : Specifies the existing folder (Folder type) or folder site relative url (str)
  • flag : Specifies the kind of move operation.

Example:

file_from = ctx.web.get_file_by_server_relative_path(
    "Shared Documents/Financial Sample.xlsx"
)

# folder_to = ctx.web.get_folder_by_server_relative_url("Shared Documents")
folder_to = "Shared Documents/Archive"

file_to = file_from.move_to_using_path(
    folder_to, MoveOperations.overwrite
).execute_query()

vgrem avatar Jun 26 '24 08:06 vgrem

I have the same problem right now

truski22 avatar Jul 16 '24 07:07 truski22