Office365-rest-python-client: How to access remote files on the server with special characters in their names?

Created on 13 Jan 2021  ·  5Comments  ·  Source: vgrem/Office365-REST-Python-Client

I am using your Python client to download files from a SharePoint folder. That basically works, however, some files have uncommon names (with special characters) and with those the download does not work. For example, a typical such file name would be Sequenz%2001.mp4#t=0.033333.jpg - that is not encoded, the file name is exactly that.

When I try to access that file under this name, then I get a "file not found" error. But when I rename the file to test.jpg then the download works. I am following your example to download the files:

FILE = "/Sequenz%2001.mp4#t=0.033333.jpg"  # it does work with "test.jpg" here
# Some more constants for USER, PASS, URL, etc.

ctx_auth = AuthenticationContext(URL)
if ctx_auth.acquire_token_for_user(USER, PASS):
    ctx = ClientContext(URL + SITE, ctx_auth)
    local_file_name = "/tmp" + FILE
    try:
        with open(local_file_name, "wb") as local_file:
            f = ctx.web.get_file_by_server_relative_url(SITE + PATH + FILE)
            f.download(local_file).execute_query()
    except ClientRequestException:
        print("Can't fetch remote file: " + PATH + FILE)

I tried to quote the file name via urllib.parse.quote() and use that, but with the same result.
What do I need to access such a file?

enhancement

All 5 comments

@haimat Have you tried urlencoding the url?

import urllib
FILE = urllib.parse.urlencode("/Sequenz%2001.mp4#t=0.033333.jpg")

Try urllib.parse.quote_plus if that does not work.

@xibriz Thanks, but unfortunately that does not solve it for me.
I tried with quote_plus(), but no luck (the function urlencode() is for key/value pairs, so not for my use case here).

Can anyone reproduce this issue?

@haimat I was able to reproduce the error and fix the issue, but @vgrem should do the honor to come up with a permanent fix.

The following class takes care of special characters:
https://github.com/vgrem/Office365-REST-Python-Client/blob/4bf8ee0b65985980b50fc3b74b32fd2db34561ba/office365/runtime/odata/odata_path_parser.py#L6

The code for downloading files seems correct:
https://github.com/vgrem/Office365-REST-Python-Client/blob/1d7f3d90c17cdbbe9d2b27990e0fe657a2100da9/office365/sharepoint/actions/download_file.py#L30

But for some reason getFileByServerRelativePath is not used when downloading files, but getFileByServerRelativeUrl
https://github.com/vgrem/Office365-REST-Python-Client/blob/1d7f3d90c17cdbbe9d2b27990e0fe657a2100da9/office365/sharepoint/webs/web.py#L202

Changeing line 202 in that file to ResourcePathServiceOperation("getFileByServerRelativePath", [url], self.resource_path)
and making the following changes to odata_path_parser.py resolves the issue, but is not the right fix.

elif method_parameters is not None:
            url += "(decodedurl="

@xibriz
Your fix/workaround indeed solves this issue for me, I can access the files now.
Thanks a lot, you saved my day!

@haimat your welcome 😊

@vgrem You should change the label to bug

Was this page helpful?
0 / 5 - 0 ratings