3
votes

I have a Python script that saves a file to a server shared folder for a user to access. Our organization recently moved our server file structure to Sharepoint... including all the folders. (I've read multiple articles that's a bad idea, but there's no changing it right now.)

I have new code that uploads a file to the root folder of the Sharepoint library:

import sharepy s = sharepy.connect("site.sharepoint.com", "username", "password") r = s.post("https://site.sharepoint.com/_api/web/Lists/GetByTitle('Documents')/RootFolder/files\ /add(overwrite=true,url='test.csv')", \ "testing,foo,bar") print(r)

Is there a way to upload the file to a subfolder instead of the root? If so, how?

3
An option that may serve as an interim solution but does not directly upload to SharePoint is to sync a local folder with SharePoint and to have your python script copy the file to the local folder. So long as you are logged in to support the sync, your file will be uploaded to SharePoint and available for others. - BalooRM
That is true. I have several interim solutions available, but am now working on a preferred solution. Thank you! - VMarshall
You're welcome. I'm interested in the solution. Mine is complicated by the use of 2-factor authentication which, once entered, is remembered to allow the sync approach to work. I'll revisit this later when it bumps up in priority. Good luck. - BalooRM
Thankfully I'm not dealing with 2-factor authentication. My solution below. Good luck! - VMarshall

3 Answers

3
votes

I've worked on the same problem some time back. Below is my code.

import requests
from shareplum import Office365

username = "YourUsername"
password = "YourPassword"
site_name = "Sitename"
doc_library = "SubfolderName"
base_path = "https://domainName.sharepoint.com"

file_name = "FileName"

# Obtain auth cookie
authcookie = Office365(base_path, username=username, password=password).GetCookies()
session = requests.Session()
session.cookies = authcookie
session.headers.update({'user-agent': 'python_bite/v1'})
session.headers.update({'accept': 'application/json;odata=verbose'})

# dirty workaround.... I'm getting the X-RequestDigest from the first failed call
session.headers.update({'X-RequestDigest': 'FormDigestValue'})
response = session.post( url=base_path + "/sites/" + site_name + "/_api/web/GetFolderByServerRelativeUrl('" + doc_library + "')/Files/add(url='a.txt',overwrite=true)",
                         data="")
session.headers.update({'X-RequestDigest': response.headers['X-RequestDigest']})

dest =  base_path + "/sites/" + site_name + "/_api/web/GetFolderByServerRelativeUrl('" + doc_library + "')/Files/add(url='a.txt',overwrite=true)" #session.post( url=base_path + "/sites/" + site_name + "/_api/web/GetFolderByServerRelativeUrl('" + doc_library + "')/Files/add(url='a.txt',overwrite=true)",data="")
print('Folder!')
# perform the actual upload
with open( file_name, 'rb') as file_input:
    try:
        print('uploading')
        response = session.post( 
            url=base_path + "/sites/" + site_name + "/_api/web/GetFolderByServerRelativeUrl('" + doc_library + "')/Files/add(url='" 
            + file_name + "',overwrite=true)",
            data=file_input)
    except Exception as err: 
        print("Some error occurred: " + str(err))
print('Uploaded successfully!')
2
votes

In case it helps anybody, here's my final code. It successfully posts a file to a sharepoint site team site library subfolder. Replace the italics with your information.

import sharepy 

s = sharepy.connect("*MySite*.sharepoint.com", "*username*", "*password*") 

r = s.post("https://*MySite*.sharepoint.com/sites/*TeamSiteName*/_api/web/GetFolderByServerRelativeUrl('/sites/*TeamSiteName*/Shared Documents/*FolderName*')/Files/" + "add(overwrite=true,url='test.csv')", "testing,foo,bar")

print r
0
votes

Yes you can upload files to sub-folder via rest api. Please take a reference of following endpoints:

And below are some demos about how to upload files using python (but they might not use the same library as yours).

/////// Update ////// enter image description here