4

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'

Community
  • 1
  • 1
MMac11
  • 59
  • 1
  • 1
  • 4

2 Answers2

4

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()
Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193
  • 1
    Hi Vadim - Thanks for the information. I am using Anaconda Prompt to install the package by typing "pip install Office365-REST-Python-Client", but I am getting an error saying "Could not fetch URL https://pypi.org/simple/Office365-REST-Python-Client - I know that the simple should actually be "project"... any suggestions? PS I am completely new to this so anything helps – MMac11 Jul 24 '18 at 19:46
  • @MMac11, just tried myself to install via Anaconda Prompt (Windows 10), no issues.. seems to be the issue is related with pip [details](https://stackoverflow.com/questions/21294997/pip-connection-failure-cannot-fetch-index-base-url-http-pypi-python-org-simpl) – Vadim Gremyachev Jul 25 '18 at 15:00
  • so, the solution would be to update the pip: `python -m pip install --upgrade pip` – Vadim Gremyachev Jul 25 '18 at 15:00
0
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

DerStoffel
  • 2,553
  • 2
  • 15
  • 25
Benito
  • 1
  • 1