Is there a way to upload a file on sharepoint site using python script? I tried installing haufe.sharepoint, but it seems like it failed to fetch ntlm while it was installing, and I can't even use the connector module without having ntlm installed.
I've also tried just saving the excel file to the server location (so save it to directory like \server\sharepointsite\files instead of connecting via the URL) using openpyxl, but it looks like the file remains checked out after the file is saved..
I would appreciate any help. Thanks!!
I'll start by saying this example is adapted from the example for Office365-REST-Python-Client. It works with Sharepoint online using the REST API.
https://github.com/vgrem/Office365-REST-Python-Client/blob/master/examples/sharepoint/files/upload_file.py
Example URL you might want to upload to [baseurl][site][folder][file].
https://your_company.sharepoint.com/path/to/site/Shared Documents/file.txt
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
baseurl = 'https://your_company.sharepoint.com'
basesite = '/path/to/site' # every share point has a home.
siteurl = baseurl + basesite
localpath = ./file.txt
remotepath = Shared Documents/file.txt # existing folder path under sharepoint site.
ctx_auth = AuthenticationContext(siteurl) # should also be the siteurl
ctx_auth.acquire_token_for_user(username, password)
ctx = ClientContext(siteurl, ctx_auth) # make sure you auth to the siteurl.
with open(localpath, 'rb') as content_file:
file_content = content_file.read()
dir, name = os.path.split(remotepath)
file = ctx.web.get_folder_by_server_relative_url(dir).upload_file(name, file_content).execute_query()
haufe.sharepoint only works for sharepoint lists, but you probably need access to document libraries.
You should use Python Requests with the help of Sharepoint's REST API.
If your sharepoint site doesn't support BasicAuth I recommend the requests_ntlm package.
It didn't work for me due to other reasons, but maybe it helps you out a bit.
You could upload files with SharePlum
install SharePlum: pip install SharePlum and try the code below
import requests
from shareplum import Office365
# Set Login Info
username = '<username>'
password = '<password>'
site_name = '<site_name>'
base_path = 'https://<domain_name>.sharepoint.com'
doc_library = 'Shared%20Documents'
nested_folder = 'Shared%20Documents/<folder1>/<folder2>' #if you want to upload in nested folders else nested_folder = doc_library
file_name = "my_file.zip" #when your file in the same directory
# 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'})
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']})
# Upload file
with open(file_name, 'rb') as file_input:
try:
response = session.post(
url=base_path + "/sites/" + site_name + f"/_api/web/GetFolderByServerRelativeUrl('" + nested_folder + "')/Files/add(url='"
+ file_name + "',overwrite=true)",
data=file_input)
print("response: ", response.status_code) #it returns 200
if response.status_code == '200':
print("File uploaded successfully")
except Exception as err:
print("Something went wrong: " + str(err))
print('File Uploaded Successfully')
I think I might be a bit late in answering this question.
The following solution worked for me-
In the Sharepoint webpage, Go to Library Tools>> Library>> Open with Explorer Command( Its the tiny icon in the bottom right beside Connect to Office command.
The address bar gives us the address that we need to upload the file to. Remember to remove "http:" or "https:" from the address This address is your destination to upload the file.
Subsequently you can use shutil package to upload the file.
import shutil as sl
sl.copy(source,destination)
This should help you upload files to Sharepoint
Disclaimer- This works quite well in Python 3.6
The answers above didn't work for me.
I have found a simple and nice way by just mapping a drive to my sharepoint folder and then I used a copy to that drive.
import subprocess
import shutil
subprocess.call(r'net use Y: http://sharepoint/link/to/your/folder', shell=True)
shutil.copy("link_to_local_file","Y:\\")
Instead of copy, You can also delete files or do anything like a normal folder.
I have created a file in SharePoint site in python via rest api calls. Please find my code below.
def CreateHomePage():
server_relative_url = base_url+ '/_api/web/webinfos'
r1 = requests.get(server_relative_url, auth=HttpNtlmAuth(username, password), headers = headers, verify=True)
value = json.loads(r1.text)
for row in value['d']['results']:
if(row['Title'] == myvars['Site Name'].strip(' \t\n\r')):
Id= row['ServerRelativeUrl']
#Add Template and create file simultaneously
title = myvars['Site Name'].strip(' \t\n\r')
post_url = root_url +'GetFolderByServerRelativeUrl(\'/'+Id+'/Pages\')/Files/add(url=\'Home.aspx\',overwrite=true)'
r2 = requests.post(post_url, auth=HttpNtlmAuth(username, password), headers = headers, verify=True)
logger.debug("Creation of home page %d", r2.status_code)
I have created a script to upload attachment into a SharePoint list
let me know if it works
import requests
from shareplum import Office365
# Obtain auth cookie
authcookie = Office365('https://YOUR-NAME.sharepoint.com', username='YOUR-USERNAME',password='YOUR-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="https://YOUR-NAME.sharepoint.com/sites/YOU-SITE/_api/web/GetFolderByServerRelativeUrl('YOUR-FOLDER')/Files/add(url='a.txt',overwrite=true)",data="")
session.headers.update({'X-RequestDigest': response.headers['X-RequestDigest']})
# perform the upload
fileName = 'picture.png'
file_name = 'images.png'
with open(file_name, 'rb') as file_input:
response = session.post(
url="https://YOUR-NAME.sharepoint.com/sites/YOUR-SITE/_api/web/lists/getbytitle('ID-ROW-INTO-SHAREPOINT')/items(4)/AttachmentFiles/add(FileName='" + fileName + "')",data=file_input)
print(response.text)
Related
Getting an error when connecting to SharePoint
'Error authenticating against Office 365. Error from Office 365:', "AADSTS50053: The account is locked, you've tried to sign in too many times with an incorrect user ID or password.")
Here is my code, I think I've everything set up right, but the URLs might be wrong, here is the complete URL to the Testing Folder I want to upload too
https://abc.sharepoint.com/teams/TestUpload/Shared%20Documents/Forms/AllItems.aspx?id=%2Fteams%2FTestupload%2FShared%20Documents%2FTesting%20Folder&viewid=e0db9acc%2Dfe4d%2D4acf%2Dbd25%2D66384f546239
from shareplum import Office365
from shareplum import Site
from shareplum.site import Version
#Logging info
server_url = "https://abc.sharepoint.com/"
site_url = server_url + "Teams/Testupload"
Username = 'johnDoe.abc.com'
Password = 'fakepass!'
Sharepoint_folder = 'Shared Documents'
fileName = r'C:\Users\co123abc\OneDrive - abc\Desktop\Files\test\aaa.docx'
def file_upload_to_sharepoint(**context):
authcookie = Office365(server_url, username = Username, password=Password).GetCookies()
site = Site(site_url, version=Version.v365, authcookie=authcookie)
folder = site.Folder(Sharepoint_folder)
with open(fileName, mode='rb') as file:
fileContent = file.read()
folder.upload_file(fileContent, "filename.bin")
file_upload_to_sharepoint()
I am able to upload file to Documents in SharePoint. But I want to upload it to a specific Folder. I am not sure how can I do that. Any help will be welcomed. I am using the code below to upload files.
def upload_file(ctx, listTitle, path):
list_obj = ctx.web.lists.get_by_title(listTitle)
folder = list_obj.root_folder
ctx.load(folder)
ctx.execute_query()
files = folder.files
ctx.load(files)
ctx.execute_query()
with open(path, 'rb') as f:
content = f.read()
file_creation_information = FileCreationInformation()
file_creation_information.overwrite = True
file_creation_information.url = os.path.basename(path)
file_creation_information.content = content
file_new = files.add(file_creation_information)
ctx.load(files)
ctx.execute_query()
upload_file(ctx,'/Documents/reports/',path)
The code above works fine for upload_file(ctx,'Documents',report)
but doesn't work for upload_file(ctx,'Documents/reports',report) folder. It doesn't work.
Error:
office365.runtime.client_request_exception.ClientRequestException: ('-1, System.ArgumentException', "List 'reports' does not exist at site with URL 'https://sharepoint.com/sites/my_page'.", "404 Client Error: Not Found for url: https://sharepoint.com/sites/my_page/_api/Web/lists/GetByTitle('reports')/RootFolder")
The error you're getting is suggesting that you somehow look for a list called reports. But you want to get a folder-object.
It's not clear which package you're using to connect to sharepoint but the docs say that you need to make an api-call like this:
POST https://{site_url}/_api/web/GetFolderByServerRelativeUrl('/Folder Name')/Files/add(url='a.txt',overwrite=true)
Authorization: "Bearer " + accessToken
Content-Length: {length of request body as integer}
X-RequestDigest: "{form_digest_value}"
"Contents of file"
Uploading a file to the Document directory is working because it's a folder inside the the default directory Shared Documents. You can only access folders inside root with the .root_foldercalls.
Edit 2: As I don't know which package you're using (probably Office365-REST) you can upload a file using the endpoint above in a normal requests.post-function.
Should look like this:
import requests
url = f'https://{site_url}/_api/web/GetFolderByServerRelativeUrl('{specific Folder URL}')/Files/add(url='a.txt',overwrite=true)'
headers = {Authorization: "Bearer " + accessToken,
Content-Length: content-length
}
payload = your_byte_string
response = requests.post(url = url, headers=headers, data = payload}
I'm writing an automation script to transfer files & subdirectory in a directory to SharePoint from ubuntu. And I'm able to transfer the files from in a directory but failed when uploading the subdirectories.
For reference my code
#importing required packages
import sys
import requests
from requests_ntlm import HttpNtlmAuth
from config import config
import os
#Reading the configuration variables
username=config['sp_user'].split("#")[0]
password=config['sp_password']
sharepoint_url=config['sp_base_path']
sp_folder_url=config['folderUrl']
path=config['path']
domain=config['domain']
domain_username=domain+'\\'+username
#Reading the files from Linux
files = next(os.walk(path))[2]
for i in range(0, len(files)):
filename = files[i]
requestUrl = sharepoint_url + '/_api/web/getfolderbyserverrelativeurl(\'' + sp_folder_url + '\')/Files/add(url=\'' + filename + '\',overwrite=true)'
with open( filename, 'rb') as file_input:
try:
headers = {'Content-Type': 'application/json; odata=verbose', 'accept': 'application/json;odata=verbose'}
r = requests.post(sharepoint_url + "/_api/contextinfo",auth=HttpNtlmAuth(domain_username,password), headers=headers)
formDigestValue = r.json()['d']['GetContextWebInformation']['FormDigestValue']
headers = {'Content-Type': 'application/json; odata=verbose', 'accept': 'application/json;odata=verbose', 'x-requestdigest' : formDigestValue}
uploadResult = requests.post(requestUrl,auth=HttpNtlmAuth(domain_username,'password'), headers=headers, data=file_input.read())
except Exception as err:
print("Some error occurred: " + str(err))
May I know what should I need to achieve that and please help me to bridge the gap between my requirement. Could you please try to produce my code. Thanks in advance
UPDATE
I'm getting following error when uploading the files now.
{"error":{"code":"-2147024891, System.UnauthorizedAccessException","message":{"lang":"en-US","value":"Access denied. You do not have permission to perform this action or access this resource."}}}
The error shows the request has not got authenticated. I suggest you take advantage of below python library for SharePoint :
https://shareplum.readthedocs.io/en/latest/tutorial.html
And there is a similar thread you may take a reference:
upload files from Linux to share point using Python
I am trying to upload my excel spreadsheet to a document library on my SharePoint Online site. The Sharepoint URL and the folder location on the SharePoint site are listed in the excel Spreadsheet.
Here is the code that I have right now:
import numpy as np
import pandas as pd
import xlwings as xw
from xlwings.constants import Direction
import sys
import requests
from requests_ntlm import HttpNtlmAuth
pd.options.mode.chained_assignment = None
def Upload():
wb = xw.Book.caller()
ws = wb.sheets['Sheet1']
#Read filename from excel
fileName = sys.argv[1]
#Enter SharePoint ONline site and target library
SP_URL = ws.range('C7').value
folder_URL = ws.range('C8').value
#Set up the url for requesting file upload
request_URL = SP_URL + '/_api/web/getfolderbyserverrelativeurl(\'' +
folder_URL + '\')/Files/asdd(url=\'' + fileName + '\',overwrite=true)'
#read in the file that we are going to upload
file = open(fileName, 'rb')
headers = {'Content-Type': 'application/json; odata=verbose', 'accept':
'application/json;odata=verbose'}
r = requests.post(SP_URL +
"/_api/contextinfo",auth=HttpNtlmAuth('Domain\\username','password'),
headers=headers)
formDigestValue = r.json()['d']['GetContextWebInformation']
['FormDigestValue']
headers = {'Content-Type': 'application/json; odata=verbose', 'accept':
'application/json;odata=verbose', 'x-requestdigest' : formDigestValue}
uploadResult =
requests.post(request_URL,auth=HttpNtlmAuth('Domain\\username','password'),
headers=headers, data=file.read())
I am receiving the following error:
formDigestValue = r.json()['d']['GetContextWebInformation']['FormDigestValue']
KeyError: 'd'
requests_ntlm package
allows for HTTP NTLM authentication using the requests library
but NTLM is not supported for SharePoint Online.
Instead of requests_ntlm i would suggest to utilize Office365-REST-Python-Client (it supports to specify user credentials and consumes SharePoint REST API) package to upload file into SharePoint Online, for example:
ctx_auth = AuthenticationContext(url=settings['url'])
if ctx_auth.acquire_token_for_user(username=settings['user_credentials']['username'],
password=settings['user_credentials']['password']):
ctx = ClientContext(settings['url'], ctx_auth)
target_list = ctx.web.lists.get_by_title("Documents")
info = FileCreationInformation()
file_name = "Book.xlsx"
path = "{0}/data/{1}".format(os.path.dirname(__file__), file_name)
with open(path, 'rb') as content_file:
info.content = content = content_file.read()
info.url = file_name
info.overwrite = True
upload_file = target_list.root_folder.files.add(info)
ctx.execute_query()
formDigestValue = r.json()['d']['GetContextWebInformation']['FormDigestValue']
KeyError: 'd'
All this means is that the response content doesn't have 'd' as a key. Try looking at the json code
print(r.content) or something, there could be an error message indicating what is wrong with your post request
I have a download link on one of my webpage in django.
When i download a audio file of 75mb it downloads but nothing in the audio, its 0bytes.
this is my code:
from django.core.servers.basehttp import FileWrapper
import mimetypes
rec_file = settings.WEB_PATH + "/media/recording/" + filename
wrapper = FileWrapper( open(rec_file, "r"))
contentType = mimetypes.guess_type(rec_file)[0]
response = HttpResponse(wrapper, mimetype = "application/force-download")
response['Content-Length'] = os.path.getsize(rec_file)
response['Content-Disposition'] = "attachment; filename=" + filename
return response
i use apache server. can anyone tell me the solution ?
Couldn't say what's wrong with your code, but you shouldn't be doing that anyways. You should serve static files directly from Apache or use X-Sendfile.