vgrem / Office365-REST-Python-Client

Microsoft 365 & Microsoft Graph Library for Python
MIT License
1.3k stars 332 forks source link

404 Client Error, 2130575338, Microsoft.SharePoint.SPException #479

Open simonkjeldgaard opened 2 years ago

simonkjeldgaard commented 2 years ago

Hi all

I have trouble getting access to a file on a Sharepoint site. Can anybody help? Seems like a server relative URL-problem but I've tried almost everything to fix it...

Error message: office365.runtime.client_request_exception.ClientRequestException: ('-2130575338, Microsoft.SharePoint.SPException', 'Filen /sites/{site}/Delte dokumenter/TestFil1.txt findes ikke.', "404 Client Error: Not Found for url: https://{company}.sharepoint.com/sites/{site}/_api/Web/getFileByServerRelativeUrl('%2Fsites%2F{site}%2FDelte%20dokumenter%2FTestFil1.txt')?$select=ServerRelativeUrl")

My code below:

from office365.runtime.auth.authentication_context import AuthenticationContext from office365.sharepoint.client_context import ClientContext from office365.runtime.auth.client_credential import ClientCredential import os

Sharepoint-site URL

url = "https://{company}.sharepoint.com/sites/{site}/"

Client-id and client_secret

app_principal = { 'client_id': '{client_id}', 'client_secret': '{client_secret}' }

Authentication into the Sharepoint-site

ctx_auth = AuthenticationContext(url) if ctx_auth.acquire_token_for_app(client_id=app_principal['client_id'], client_secret=app_principal['client_secret']): ctx = ClientContext(url).with_credentials(ClientCredential(app_principal['client_id'], app_principal['client_secret'])) web = ctx.web ctx.load(web) ctx.execute_query() print('Authenticated into sharepoint app for: ',web.properties['Title']) else: print(ctx_auth.get_last_error()) sys.exit()

Test3 : Download file

file_url = '/sites/{site}/Delte dokumenter/TestFil1.txt' download_path = os.path.join(".", os.path.basename(file_url))

with open(download_path, "wb") as local_file: file = web.get_file_by_server_relative_url(file_url).download(local_file).execute_query()

VdWWouter commented 2 years ago

From the error message(s) it looks like you are able to successfully authenticate. I think your file path is also correctly formed ('/sites/{site}/...')

I'm not sure about the "Delte dokumenter" part. It could be that MS changes it to your local language. In my case, I had to use "Shared Documents".

Could I suggest that you check the relative path per directory(In your case: '/sites/{site}' and '/sites/{site}/Delte dokumenter')? You can make a listing and see what's available in each folder:

folder = ctx.web.get_folder_by_server_relative_url(relative_url)
directory = folder.folders
ctx.load(directory)
ctx.execute_query()

folders = []
folder_props = {}
for d in directory._data:
    folders.append(d.properties["Name"])
print(f'folders in {relative_url = }:')
print(folders)

sub_folders = folder.files
ctx.load(sub_folders)
ctx.execute_query()

files = []
file_props = {}
for s_folder in sub_folders:
    files.append(s_folder.properties["Name"])
print(f'files in {relative_url = }:')
print(files)
simonkjeldgaard commented 2 years ago

Hi VdWWouter

I've tried to use your code and it returns nothing. Actually no matter what I write in 'relative_url' it gives me this:

folders in relative_url = '/sites/Intranet-Organisation-Byggeri/Delte dokumenter': [] files in relative_url = '/sites/Intranet-Organisation-Byggeri/Delte dokumenter': []

:-(

VdWWouter commented 2 years ago

And if you list the contents of relative_url = '/sites/Intranet-Organisation-Byggeri/'? Do you also see 'Delte dokumenter' or something else?

ptoews commented 2 years ago

I have the same issue, even if I use relative_url = '/sites/SITE/' I get empty lists for folders and files.

ptoews commented 2 years ago

In my case I solved it by creating the ClientContext with a base_url with the /sites/SITE prefix, and then still using the same prefix for the relative URLs. E.g.:

ctx = ClientContext("https://xyz.sharepoint.com/sites/mysite/").with_client_certificate("xyz.onmicrosoft.com", **cert_settings)
ctx.web.get_folder_by_server_relative_url("/sites/mysite/Freigegebene Dokumente/General/...")
ameer751 commented 1 year ago

In my case I solved it by creating the ClientContext with a base_url with the /sites/SITE prefix, and then still using the same prefix for the relative URLs. E.g.:

ctx = ClientContext("https://xyz.sharepoint.com/sites/mysite/").with_client_certificate("xyz.onmicrosoft.com", **cert_settings)
ctx.web.get_folder_by_server_relative_url("/sites/mysite/Freigegebene Dokumente/General/...")

Worked for me as well, I was using UserCredentials to auth to SharePoint Online.