title: OneDrive API Python request.post to upload file produces 401 error
body: <p>I am trying to use OneDrive API, ADAL and Python request.post to upload file to Sharepoint folder but am getting 401 error.</p>
  
  <p>The ADAL authorization is working as gets correct token response and produces a viable <code>access_token</code>. </p>
  
  <p>I can use the <code>access_token</code> to download a file from the same Sharepoint folder.</p>
  
  <p>Although this only works when I manually copy <code>print file_url</code> url created by code into browser. However <code>urllib.urlretrieve(file_url, local_file_name)</code> only creates an file named <code>myfilename.csv</code> with contents <code>403 Forbidden</code>.</p>
  
  <p>My authorization uses hard coded username and password, and I am saving refresh token in clear text, and always retrieving it when retrieving token response:</p>
  
  <pre><code>import adal
  import urllib
  import requests
  
  ## set variables
  username = 'username@mydomain.onmicrosoft.com'
  password = 'mypassword'
  authorization_url = 'https://login.windows.net/mydomain.onmicrosoft.com' # Authority
  redirect_uri = 'https://login.microsoftonline.com/login.srf'
  client_id = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx' # Client id
  
  ## use ADAL to create token response
  token_response = adal.acquire_token_with_username_password(
          authorization_url,
          username,
          password
      )
  
  ## create refresh token and save it to use later 
  refresh_token = token_response['refreshToken']
  refresh_token_file = open('refresh_token.txt', 'w')
  refresh_token_file.write(refresh_token)
  refresh_token_file.close()
  
  ## get saved refresh token and use it to get new token response
  refresh_token = open('refresh_token.txt', 'r').read()
  token_response = adal.acquire_token_with_refresh_token(authorization_url, str(refresh_token))
  
  ## get access_token from token response
  access_token = token_response.get('accessToken') 
  </code></pre>
  
  <p>The token response is correct and using the access token from it the following code produces a  <code>file_url</code> url that I can manually copy and paste into browser that downloads a file successfullly. However <code>urllib.urlretrieve(file_url, local_file_name)</code> only creates an file named <code>myfilename.csv</code> with contents <code>403 Forbidden</code>:</p>
  
  <pre><code>## download file
  file_url = 'https://mydomain.sharepoint.com/Shared%20Documents/myfoldername/myfilename.csv?token_response=' + str(access_token)
  local_file_name = 'myfilename.csv'
  urllib.urlretrieve(file_url, local_file_name)
  </code></pre>
  
  <p>However I have not yet been able to successfully upload to this Sharepoint folder. Currently I have the following:</p>
  
  <pre><code># upload file
  site_url = 'https://mydomain.sharepoint.com/'
  headers = {'Authorization':'BEARER ' + str(access_token)}
  r = requests.post(site_url, files={'Shared%20Documents/myfoldername/myfilename.csv': open('myfilename.csv', 'rb')}, headers=headers)
  
  print r.text
  </code></pre>
  
  <p>which produces response</p>
  
  <pre><code>401 UNAUTHORIZED 
  </code></pre>
  
  <p>My Azure AD app has permissions:</p>
  
  <pre><code>Read and write all user files 
  Read and write items and lists in all site collections
  (not sure both are needed to upload files)
  </code></pre>
  
  <p>Does my request.post look ok?  Pretty sure I am sending header, folder and file correctly.</p>
  
  <p>EDIT TO ADD:</p>
  
  <p>Given fact that both download code returns <code>403 Forbidden</code> and upload code returns <code>401 Unauthorized</code> I suspect the issue is with how <code>urllib</code> and <code>requests</code> are sending the urls. </p>
  
  <p>EDIT TO ADD:</p>
  
  <p>Trying to build the file url to use in GET and PUT. After I am authenticated, I can manually enter this url into browser:</p>
  
  <pre><code>https://mydomain.sharepoint.com/_api/v1.0/files/root
  </code></pre>
  
  <p>which returns following XML:</p>
  
  <pre><code>{"@odata.context":"https://mydomain.sharepoint.com/_api/v1.0/$metadata#files/$entity"
  ,"@odata.type":"#Microsoft.FileServices.Folder"
  ,"@odata.id":"https://mydomain.sharepoint.com/_api/v1.0/files/01QEW7725BZO3N6Y2GOV54373IPWSELRRZ"
  ,"@odata.editLink":"files/01QEW7725BZO3N6Y2GOV54373IPWSELRRZ"
  ,"createdBy":null
  ,"eTag":null
  ,"id":"01QEW7725BZO3N6Y2GOV54373IPWSELRRZ"
  ,"lastModifiedBy":null
  ,"name":"/"
  ,"parentReference":null
  ,"size":0
  ,"dateTimeCreated":"2013-07-31T02:35:57Z"
  ,"dateTimeLastModified":"2016-05-23T03:55:46Z"
  ,"type":"Folder"
  ,"webUrl":"https://mydomain.sharepoint.com/Shared%20Documents"
  ,"childCount":1}
  </code></pre>
  
  <p>However haven't found the correct syntax for the reference to the file. For example this isn't working:</p>
  
  <pre><code>https://mydomain.sharepoint.com/_api/v1.0/files/root:/myfoldername/myfilename.csv:/content
  </code></pre>
  
  <p>This is returning error:</p>
  
  <pre><code>    {"error":"invalid_client","error_description":"Invalid audience Uri 'https:\/\/m
  anagement.core.windows.net\/'."}
  </code></pre>
  
  <p>I think that getting this specific reference to file is what I need to to make it work. </p>