Upload File to Windows Sharepoint using Python 3? - python

I have a test.txt on my Desktop and now I want to upload it to a Sharepoint Directory via Python3. How can I do that?

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(url)
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()```

Related

Collecting activities(Like comments) in a Sharepoint list

I am trying to collect activity histories in a Sharepoint list such as comments and dates created, etc. but I wasn't able to find the way to achieve it.
Would there be a way to collect those data?
Below is the code that I am using.
import json
import os
import urllib.parse
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
config_path = '\\'.join([ROOT_DIR, 'config.json'])
#read jason config file
with open(config_path) as config_file:
config = json.load(config_file)
config = config['share_point']
USERNAME = config[ 'user']
PASSWORD = config[ 'password' ]
sharepoint_url = config['url']
sharepoint_site = config['site']
sharepoint_list = config[ 'list']
from office365.runtime.auth.user_credential import UserCredential
from office365.sharepoint.client_context import ClientContext
ctx = ClientContext(sharepoint_site).with_credentials(UserCredential(USERNAME, PASSWORD))
web = ctx.web.lists.get_by_title('Test')
items = web.items.paged(True).top(200)
ctx.load(items)
ctx.execute_query()
contents = items.properties
print(contents)
The attached image shows the items that I would like to collect.
Sharepoint List Activities

Sharepoint API list directory not working

I am trying to use the sharepoint api to download files within folders at the location "folder_in_sp" below. I've seem similar questions asked on here before but none are working for me. I am using the following code.
from office365.runtime.auth.client_credential import ClientCredential
from office365.runtime.client_request_exception import ClientRequestException
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.files.file import File
import io
import datetime
import pandas as pd
import keyring
from office365.runtime.auth.user_credential import UserCredential
from office365.sharepoint.files.file_system_object_type import FileSystemObjectType
username = 'MY USERNAME'
site_url = "https://ORG_NAME.sharepoint.com/"
folder_in_sp = "/a very long/folder path/with lots of spaces/and numbers/Leading to/A Final/folder"
ctx = ClientContext(site_url).with_credentials(UserCredential(username, keyring.get_password("Sharepoint API", username))) # Use keyring to access your password for user credentials
web = ctx.web
ctx.load(web)
ctx.execute_query()
print("You're in! Web title: {0}".format(web.properties['Title']))
def folder_details(ctx, folder_in_sharepoint):
folder = ctx.web.get_folder_by_server_relative_url(folder_in_sharepoint)
fold_names = []
sub_folders = folder.files
ctx.load(sub_folders)
ctx.execute_query()
for s_folder in sub_folders:
fold_names.append(s_folder.properties["Name"])
return fold_names
file_list = folder_details(ctx, folder_in_sp)
I am trying to access the folders within the final folder at that location. Sometimes there will be multiple folders I need to access to download a single file within each of them. I have tried replacing spaces the folder_in_sp path with "%20" as they are formatted online but that has not worked either.
Any help would be appreciated!
Thanks in advance.

Python SharePoint connection gives 400 Client Error

I am using the following code to connect to my sharepoint site and try to access the files on the site:
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.files.file import File
####inputs########
# This will be the URL that points to your sharepoint site.
# Make sure you change only the parts of the link that start with "Your"
url_shrpt = 'https://YourOrganisation.sharepoint.com/sites/YourSharepointSiteName'
username_shrpt = 'YourUsername'
password_shrpt = 'YourPassword'
folder_url_shrpt = '/sites/YourSharepointSiteName/Shared%20Documents/YourSharepointFolderName/'
#######################
###Authentication###For authenticating into your sharepoint site###
ctx_auth = AuthenticationContext(url_shrpt)
if ctx_auth.acquire_token_for_user(username_shrpt, password_shrpt):
ctx = ClientContext(url_shrpt, ctx_auth)
web = ctx.web
ctx.load(web)
ctx.execute_query()
print('Authenticated into sharepoint as: ',web.properties['Title'])
else:
print(ctx_auth.get_last_error())
############################
####Function for extracting the file names of a folder in sharepoint###
###If you want to extract the folder names instead of file names, you have to change "sub_folders = folder.files" to "sub_folders = folder.folders" in the below function
global print_folder_contents
def print_folder_contents(ctx, folder_url):
try:
folder = ctx.web.get_folder_by_server_relative_url(folder_url)
fold_names = []
sub_folders = folder.files #Replace files with folders for getting list of folders
ctx.load(sub_folders)
ctx.execute_query()
for s_folder in sub_folders:
fold_names.append(s_folder.properties["Name"])
return fold_names
except Exception as e:
print('Problem printing out library contents: ', e)
######################################################
# Call the function by giving your folder URL as input
filelist_shrpt=print_folder_contents(ctx,folder_url_shrpt)
#Print the list of files present in the folder
print(filelist_shrpt)
However I get the message:
Authenticated into sharepoint as: My Team
Problem printing out library contents: (None, None, "400 Client Error: Bad Request for url: /sites/YourSharepointSiteName/Shared%20Documents/YourSharepointFolderName/")
Why am I able to access the site but cannot access the folder or files in it? I would really appreciate some insight on this

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?
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!')
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
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)
Yes you can upload files to sub-folder via rest api. Please take a reference of following endpoints:
Add method to create a file
create a file and add it to a folder
And below are some demos about how to upload files using python (but they might not use the same library as yours).
SharePlum
Office365-REST-Python-Client
/////// Update //////
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')

Download files from a Box location using API

How to download files from a Box location programmatically?
I have a shared box location URL(Not the exact path of the box location).
I want to download all the files under the location.
I checked below sdk to connect to box but unable to find methods/library to download files from a shared link.
https://github.com/box/box-python-sdk
from boxsdk import Client
from boxsdk import OAuth2
oauth = OAuth2(
client_id='XXX',
client_secret='XXX',
store_tokens='XXX',
)
data = client.make_request(
'GET',
'<Shared BOX URL>',
)
Please help
Get metadata of shared Box link:
shared_folder = client.get_shared_item("https://app.box.com/s/0123456789abcdef0123456789abcdef")
Loop through each item inside the folder and download each file using boxsdk.object.file.File.content or boxsdk.object.file.File.download_to:
for item in shared_folder.get_items(limit=1000):
if item.type == 'file':
# Get file contents into memory
file_contents = client.file(file_id=item.id).content()
# Or download to file
client.file(file_id=item.id).download_to(item.name)
You can use the method that gives you the direct URL:
download_url = client.file(file_id='SOME_FILE_ID').get_shared_link_download_url()
And then you can use urlib to download it to your local computer:
import urllib
urllib.urlretrieve (download_url , your_local_file_name)
Could it solve your problem?
Pre-requisite:
oauth = OAuth2(
client_id = 'strBoxClientID',
client_secret = 'strBoxClientSecret',
access_token = access_token,
)
client = Client(oauth)
Initial attempt (failed, it produces an empty file):
with open(Box_File.name, 'wb') as open_file:
client.file(Box_File.id).download_to(open_file)
open_file.close()
Final solution:
output_file = open('strFilePath' + str(Box_File.name), 'wb')
Box_File.download_to(output_file)

Categories

Resources