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()
Related
I have a SP online folder and would like to read all the excel files in that folder. here's my codes. The codes below only able to direct me to the path. But I am stuck on the codes that want to combine all the data inside those files in the folder and read them.
url = 'https://abc.sharepoint.com/sites/GlobalMaterials'
username = 'user'
password = 'password'
folder_url = '/sites/GlobalMaterialss/Shared Documents/abc folder'
ctx_auth = AuthenticationContext(url)
if ctx_auth.acquire_token_for_user(username, password):
ctx = ClientContext(url, 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())
I need to access a list on my SharePoint account that the MFA is already activated using python but i keep getting this error message :
Failed to connect to SP site: ('Error authenticating against Office 365. Error from Office 365:', "AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access ''.")
import sys
from shareplum.site import Version
from shareplum import Site, Office365
AUTHOR_PAGE_URL = 'Page URL'
SHAREPOINT_URL = 'SharePoint URL'
SHAREPOINT_SITE = 'SharePoint Site'
SHAREPOINT_LIST = 'List name'
USERNAME = 'username'
PASSWORD = 'password'
def authenticate(sp_url, sp_site, user_name, password):
site = None
try:
authcookie = Office365(SHAREPOINT_URL, username=USERNAME,
password=PASSWORD).GetCookies()
site = Site(SHAREPOINT_SITE, version=Version.v365, authcookie=authcookie)
except:
# We should log the specific type of error occurred.
print('Failed to connect to SP site: {}'.format(sys.exc_info()[1]))
return site
# Test the function
sp_site = authenticate(SHAREPOINT_URL,SHAREPOINT_SITE,USERNAME,PASSWORD)
I am trying to access share point site as api using python to download files.
So far I have tried "shareplum" , "office365", and "sharepy" modules in python.
Every time I am getting authentication error due to invalid username or password.
But I can logon to that share point site from web browser using same username and password.
What approach should I follow or what sort of authentication should I use ?
Regards
Santanu
shareplum:
from shareplum import Site, Office365
from shareplum.site import Version
import json
import os
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
config_path = '\\'.join([ROOT_DIR, 'config_1.json'])
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_DOC = config['doc_library']
def auth():
authcookie = Office365(SHAREPOINT_URL, username=USERNAME, password=PASSWORD).GetCookies()
print(f"authcookie: {authcookie}")
site = Site(SHAREPOINT_SITE, version=Version.v365, authcookie=authcookie)
print(f"site: {site}")
return site
def connect_folder(folder_name):
auth_site = auth()
print(f"auth_site: {auth_site}")
sharepoint_dir = '/'.join([SHAREPOINT_DOC, folder_name])
print(f"sharepoint_dir: {sharepoint_dir}")
folder = auth_site.Folder(sharepoint_dir)
print(f"folder: {folder}")
return folder
def download_file(file_name, folder_name):
_folder = connect_folder(folder_name)
print(f"_folder: {_folder}")
return _folder.get_file(file_name)
def run():
# set file name
file_name = 'Hardy_ServiceReporting_Aug2021.csv'
# set the folder name
folder_name = 'Problem Management'
# get file
file = download_file(file_name, folder_name)
print(file)
if __name__ == "__main__":
run()
Error: Error from Office 365:', 'AADSTS50126: Error validating credentials due to invalid username or password.'
office365:
from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.files.file import File
import json
import os
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
config_path = '\\'.join([ROOT_DIR, 'config_1.json'])
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_DOC = config['doc_library']
FOLDER = "Problem Management"
url = SHAREPOINT_SITE + "/_api/web/GetFolderByServerRelativeUrl('{}/{}')/Files".format(SHAREPOINT_DOC, FOLDER)
print(f"url: {url}")
ctx_auth = AuthenticationContext(url)
print(f"ctx_auth: {ctx_auth}")
ctx_auth.acquire_token_for_user(USERNAME, PASSWORD)
ctx = ClientContext(url, ctx_auth)
print(f"ctx: {ctx}")
Error: An error occurred while retrieving token from XML response: AADSTS53003: Access has been blocked by Conditional Access policies. The access policy does not allow token issuance.
New programmer who has been coding scripts to automate work responsibilities.
Scope of Problem:
I get bi-monthly excel reports from an outside vendor sent via email. This vendor uses ZixMail for encryption in which my company does not leverage. As a result, I have to access these emails via a Secure Mail Center with my username and password to log on this Mail Center website. I am trying to establish a connection to this server and download the attachment files.
What I have tried:
Tried a IMAP connection into the "server" (I am not sure if the website is a mail server)
Struck out many times, as I could never get a connection (If there are suggestions to try please share)
Accessing the site via HTTP using sessions.
I am able to connect to the site but when I go to .get and .write the file my excel file returns blank and corrupted.
On the Mail Center/website when I click the link/url it automatically downloads the file. I am not sure why this has to be so challenging?
The source code from the website where you download the file looks like:
a rel="external" href="/s/attachment?name=Random Letters and Numbers=emdeon" title="File Title.xlsx"
the href looks nothing like a normal URL and does not end in a .xlsx or any other type of file like most of the examples I have seen.
I guess I am just really looking for any ideas, thoughts, helps solutions.
Here is my HTTP connection code
import requests
import urllib.request
import shutil
import os
#Fill in your details here to be posted to the login form.
payload = {
'em': 'Username',
'passphrase': 'Password',
'validationKey': 'Key'
}
#This reads your URL and returns if the file is downloadable
def is_downloadable(URL_D):
h = requests.head(URL_D, allow_redirects=True)
header = h.headers
content_type = header.get('content-type')
if 'text' in content_type.lower():
return False
if 'html' in content_type.lower():
return False
return True
def download_file(URL_D):
with requests.get(URL_D, stream=True) as r:
r.raise_for_status()
with open(FileName, 'wb') as f:
for chunk in r.iter_content(chunk_size=None):
if chunk:
f.write(chunk)
f.close()
return FileName
def Main():
with requests.Session() as s:
p = s.post(URL, data=payload, allow_redirects=True )
print(is_downloadable(URL_D))
download_file(URL_D)
if __name__ == '__main__':
Path = "<path>"
FileName = os.path.join(Path,"Testing File.xlsx")
URL = 'login URL'
URL_D = 'Attachment URL"
Main()
is_downloadable(URL_D) returns as false and the excel file is empty and corrupted
Here is my code for the IMAP attempt:
import email
import imaplib
import os
class FetchEmail():
connection = None
error = None
def __init__(self, mail_server, username, password):
self.connection = imaplib.IMAP4_SSL(mail_server,port=993)
self.connection.login(username, password)
self.connection.select('inbox',readonly=False) # so we can mark mails as read
def close_connection(self):
"""
Close the connection to the IMAP server
"""
self.connection.close()
def save_attachment(self, msg, download_folder):
att_path = "No attachment found."
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
att_path = os.path.join(download_folder, filename)
if not os.path.isfile(att_path):
fp = open(att_path, 'wb')
fp.write(part.get_payload(decode=True))
fp.close()
return att_path
def fetch_messages(self):
emails = []
(result, messages) = self.connection.search(None, "(ON 20-Nov-2020)")
if result == "OK":
for message in messages[0].split(' '):
try:
ret, data = self.connection.fetch(message,'(RFC822)')
except:
print ("No emails to read for date.")
self.close_connection()
exit()
msg = email.message_from_bytes(data[0][1])
if isinstance(msg, str) == False:
emails.append(msg)
response, data = self.connection.store(message, '+FLAGS','\\Seen')
return emails
self.error = "Failed to retreive emails."
return emails
def Main():
p = FetchEmail(mail_server,username,password)
msg = p.fetch_messages()
p.save_attachment(msg, download_folder)
p.close_connection()
if __name__ == "__main__":
mail_server = "Server"
username = "username"
password = "password"
download_folder= Path
Main()
Error Message: TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Even if I wrote the IMAP script wrong, I tried to IMAP connect via cmd prompt and same results.
To recap all I am looking for is some pointers and ideas to solve this problem. Thank You!
For anyone who stumbled upon this because of a similar issue. Probably not since I have a really weird habit of making everything simple, complicated. But
I was able to solve problem by using selenium webdriver to login to the website, and navigate through using the "click" mechanism. This was the only way I'd be able to successfully download the reports.
import time
import os
import re
import datetime
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
today = datetime.date.today()
first = today.replace(day=1)
year = today.strftime('%Y')
month = today.strftime('%B')
lastMonth = (first - datetime.timedelta(days=1)).strftime('%b')
def Main():
chrome_options = Options()
chrome_options.add_experimental_option("detach", True)
s = Chrome(executable_path=path to chrome extension)
s.get("Website login page")
s.find_element_by_id("loginname").send_keys('username')
s.find_element_by_id("password").send_keys('password')
s.find_element_by_class_name("button").click()
for i in range(50):
s.get("landing page post login")
n = str(i)
subject = ("mailsubject"+n)
sent = ("mailsent"+n)
title = s.find_element_by_id(subject).text
date = s.find_element_by_id(sent).text
regex = "Bi Monthly"
regex_pr = "PR"
match = re.search(regex,title)
match_pr = re.search(regex_pr,title)
if match and not match_pr:
match_m = re.search(r"(\D{3})",date)
match_d = re.search(r"(\d{1,2})",date)
day = int(match_d.group())
m = (match_m.group(1))
if (day <= 15) and (m == lastMonth):
print("All up to date files have been dowloaded")
break
else:
name = ("messageItem"+n)
s.find_element_by_id(name).click()
s.find_element_by_partial_link_text("xlsx").click() #This should be under the else but its not formatting right on here
else:
continue
time.sleep(45)
if __name__ == "__main__":
Main()
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)