VMarshall
VMarshall

Reputation: 131

Upload a file to a Sharepoint folder using Python

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?

Upvotes: 7

Views: 33255

Answers (5)

Anand Maurya
Anand Maurya

Reputation: 101

Below is the code I used to upload files from Azure Blob storage to a new sub folder on Sharepoint using python in Databricks.

def upload_sharepoint(sp_filepath,blob_file_path):
  from office365.runtime.auth.authentication_context import AuthenticationContext
  from office365.sharepoint.client_context import ClientContext
  from office365.sharepoint.files.file import File
  import os
  
  url='https://<domain>.sharepoint.com/sites/<site1>/<subsite1>'
  username = 'user'
  pwd = 'password'

  ctx_auth = AuthenticationContext(url)
  ctx_auth.acquire_token_for_user(username, pwd)   
  ctx = ClientContext(url, ctx_auth)

  blobpath = '/dbfs' + blob_file_path
  filename=os.path.basename(blob_file_path)
  
  #read content of file
  with open(blobpath, 'rb') as content_file:
    file_content = content_file.read()
  
  target_url = sp_filepath  # sharepoint url to upload a file 
  target_folder=ctx.web.get_folder_by_server_relative_url(target_url)
  try:
    folder_exist=ctx.load(target_folder).execute_query().properties['Exists']
  except Exception as e:
    folder_exist=False
    print('Folder Not Found,Creating Folder')
    
  if !folder_exist:
    try:
      target_folder = ctx.web.folders.add(target_url).execute_query()    #Create the folder, can create folder upto 1 level only
    except Exception as e:
      print('Parent folder Not Found',e)
  target_folder.upload_file(filename, file_content).execute_query()    # upload the file
  print('Uploaded '+filename+' to '+target_url)

The above code can be used to create a 1 level sub-folder within a folder that already exist.

For Ex, here we will create a folder name 'NewFolder' inside 'Pay file' folder that exist on Sharepoint:

sharepoint_fp='/sites/<site1>/<subsite1>/Document%20upload/Pay%20file/NewFolder' 
blob_path='/mnt/PayFile/'  
files=spark.createDataFrame(dbutils.fs.ls(blob_path))
files=files.select('name').collect()
for f in files:
  upload_sharepoint(sharepoint_fp,blob_path+f.name)

Upvotes: 1

Alessandro Paiva
Alessandro Paiva

Reputation: 1

After so many tries, I finally made this work with less line coding than I expected.

I was having some issues with the some urls and folder paths that's why I put the "r" to get the raw path.

from shareplum import Site from shareplum import Office365 from shareplum.site import Version

Normal authentication

authcookie = Office365(r'https://.sharepoint.com', username='@', password='***').GetCookies()

Here you fill the info from your site

site = Site(r'https://*******.sharepoint.com/sites/sitename/',version=Version.v365, authcookie=authcookie)

And here you just fill the info of your folder

folder = site.Folder('Shared Documents/Your Folder')

Source: https://shareplum.readthedocs.io/en/latest/files.html#folders

Encoding and Errors are optional

with open(r'C:/Users/Alessandro.paiva/Desktop/file.xlsx', encoding = 'latin-1', errors = 'ignore') as file: fileContent = file.read()

Name of the file

folder.upload_file(fileContent, r'file.xlsx')

Upvotes: 0

VMarshall
VMarshall

Reputation: 131

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

Upvotes: 6

Anusha Prabhu
Anusha Prabhu

Reputation: 53

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!')

Upvotes: 3

Baker_Kong
Baker_Kong

Reputation: 1889

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

Upvotes: 0

Related Questions