File Download from Sharepoint using Python - python

I am trying to download an excel file from Sharepoint with the office365 module. Here's my code.
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.file import File
app_settings = {
'url': 'https://xxxxx/sites/DownloadFiles',
'client_id': 'xxxxxx',
'client_secret': 'xxxxxx',
}
if name == 'main':
ctx_auth = AuthenticationContext(url=app_settings['url'])
ctx_auth.acquire_token_for_app(client_id=app_settings['client_id'],
client_secret=app_settings['client_secret'])
ctx = ClientContext(app_settings['url'], ctx_auth)
path = "F:\myexcel.xlsx"
response = File.open_binary(ctx, "/Shared%20Documents/myexcel.xlsx")
response.raise_for_status()
with open(path, "wb") as local_file:
local_file.write(response.content)
When I run that code, I get the following error:
400 Client Error: Bad Request for url: https://xxx/DownloadFiles/_api/web/getfilebyserverrelativeurl('/Shared%20Documents/myexcel.xlsx')/%5C$value

I am able to reproduce the same issue on my SPO.
Please modify the code as below to fix it:
response = File.open_binary(ctx, "/sites/{abc}/Shared%20Documents/source.txt")
Such as i want to download file from a site collection like "https://xxxx.sharepoint.com/sites/abc", the serverrelativeurl is "/sites/abc"
You can get the serverrelativeurl via '_spPageContextInfo' object:
And there is another SharePoint library 'shareplum' that provided some easy ways to operate files, you may have a try.
Best Regards,
Baker Kong

Related

How to download a file from Sharepoint with python

I need to download a file from sharepoint using user credentials (rather that client credentials).
I've tried this:
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.files.file import File
root_url = "https://company-my.sharepoint.com"
full_url = "https://company-my.sharepoint.com/personal/Documents/AB.csv"
ctx = ClientContext(root_url)
ctx.with_user_credentials(<my_email>,
<my_password)
response = File.open_binary(ctx, full_url)
print(response.content)
The response I am getting is
*b'{"error":{"code":"-2147024809, System.ArgumentException","message":{"lang":"en-US","value":"serverRelativePath\\r\\nParameter
name: Specified value is not supported for the serverRelativePath
parameter."}}}'*

Error 400 when trying to extract data from sharepoint

I am trying to extract xml data from a SharePoint site.
I always get error 400. Here is my Python code.
import requests
from office365.sharepoint.client_context import ClientContext
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.runtime.http.request_options import RequestOptions
from office365.runtime.client_request import ClientRequest
from office365.graph.graph_client import GraphClient
app_settings = {
'url': 'https://xxxxxxxx.sharepoint.com/sites/xxxxxxx',
'client_id': 'xxxxxxx',
'client_secret': 'xxxxxxxx',
}
context_auth = AuthenticationContext(url=app_settings['url'])
context_auth.acquire_token_for_app(client_id=app_settings['client_id'], client_secret=app_settings['client_secret'])
ctx = ClientContext(app_settings['url'], context_auth)
token = context_auth.provider.token.accessToken
headers = {"Authorization": "Bearer " + token, "Content-type": "application/xml"}
request = requests.get("https://xxxxxxx.sharepoint.com/sites/xxxxxxx/_api/xxxxxx/xxxxx/xxxxx", headers=headers)
I don't understand what I am missing because my url seems to be correct, I can get a token, which seems to be valid and not expired. Moreover, the application I have created on the SharePoint site seems also to be correct. I have entered this code in the permission request XML:
<AppPermissionRequests AllowAppOnlyPolicy="true">
<AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
</AppPermissionRequests>
The strange thing is that I can access the lists and subsites data that is available on the SharePoint site, but not this background odata.
Can someone help me please?

office365 sharepoint open binary gives missing schema error

I am trying to read a file from sharepoint using the office 365 package. My code looks like this:
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.file import File
app_settings = {
'url': 'https://xxxx.sharepoint.com/sites/mysite/',
'client_id': 'id',
'client_secret': 'secret'}
context_auth = AuthenticationContext(url=app_settings['url'])
context_auth.acquire_token_for_app(client_id=app_settings['client_id'],
client_secret=app_settings['client_secret'])
ctx = ClientContext(app_settings['url'], context_auth)
File.open_binary(ctx, '/sites/mysite/Documents/Dictionary.csv')
I've tried several variations of the server relative url and get the error every time:
MissingSchema: Invalid URL "<bound method ClientContext.service_root_url of
<office365.sharepoint.client_context.ClientContext object at
0x00019D2CCED68>>web/getfilebyserverrelativeurl
('/sites/mysite/Documents/Dictionary.csv')/\\$value": No schema supplied.
Perhaps you meant http://<bound method ClientContext.service_root_url of
<office365.sharepoint.client_context.ClientContext object at
0x00019D2CCED68>>web/getfilebyserverrelativeurl('/sites/mysite/Documents/Dictionary.csv')/\$value?
Is there a simple way to read and download files from sharepoint online using the office365 library?

no_file_data error when upload file name contains japanese to slack using slack upload api

I'm trying to upload a file with name contains Japanese charaters to slack like: /tmp/結果.xlsx
The request response with no_file_data error and no file is sended to slack.
But when I change file name to /tmp/result.xlsx, every thing is fine.
I have no idea that what went wrong.
job.py
from botocore.vendored import requests
import urllib.request
def execute():
params = {'token': 'my-slack-token',
'channels': 'test-channel', 'initial_comment': 'test-comment'}
file_name = "/tmp/結果.xlsx"
urllib.request.urlretrieve(
'http://download-url', file_name)
file = {'file': open(file_name, 'rb')}
res = requests.post(url="https://slack.com/api/files.upload", params=params, files=file)
print(res.text)
and main.py
import job
def execute(event, context):
job.execute()
return {
'statusCode': 200,
'body': "Done!"
}
When this lambda is triggered I got a result <Response [200]> {"ok":false,"error":"no_file_data"} but if I change file name to result.xlsx, every thing will be fine
Thanks for any help!

How to upload a file to sharepoint site using python script

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)

Categories

Resources