Uploading a file to onedrive for business with Python

For a Raspberry Pi project that’ll take a number of pictures of my house for an as of yet unknown period of time I’m sharing my very first Python script with you.

All it has to do is upload all files from a given folder to a given Onedrive for Business path, as obviously the Pi can’t store much data on its tiny SD card. You’ll need to register an azure ad app and give it the appropriate permissions. You’ll have to consent to the application once (url format = https://login.microsoftonline.com/common/adminconsent?client_id={client-id}).

Then schedule below Python script on your Pi, it will retrieve an Azure token without the need for external libraries, parse the directory and upload everything in it to the given onedrive for business URL, simple as that! It can also be used for Sharepoint or Teams by adjusting the path.

import requests 
import json
directory = r"c:\temp\uploads"
data = {'grant_type':"client_credentials", 
        'resource':"https://graph.microsoft.com", 
        'client_id':'XXXXX', 
        'client_secret':'XXXXX'} 
URL = "https://login.windows.net/YOURTENANTDOMAINNAME/oauth2/token?api-version=1.0"
r = requests.post(url = URL, data = data) 
j = json.loads(r.text)
TOKEN = j["access_token"]
URL = "https://graph.microsoft.com/v1.0/users/YOURONEDRIVEUSERNAME/drive/root:/fotos/HouseHistory"
headers={'Authorization': "Bearer " + TOKEN}
r = requests.get(URL, headers=headers)
j = json.loads(r.text)
print("Uploading file(s) to "+URL)
for root, dirs, files in os.walk(directory):
    for filename in files:
        filepath = os.path.join(root,filename)
        print("Uploading "+filename+"....")
        fileHandle = open(filepath, 'rb')
        r = requests.put(URL+"/"+filename+":/content", data=fileHandle, headers=headers)
        fileHandle.close()
        if r.status_code == 200 or r.status_code == 201:
            #remove folder contents
            print("succeeded, removing original file...")
            os.remove(os.path.join(root, filename)) 
print("Script completed")
raise SystemExit
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

41 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Roger
Roger
3 years ago

Hi, thanks for sharing your script. I’m a beginner and I am not sure if I register my app correctly in Azure.

Could you please help me with this questions:

  • What Redirect_Uri do I need for this?
  • App Registration as “Desktop” and not as “Web” correct?
  • Is there an easy way to test only my app, if I set it correctly?

I really tried to find it out by myself (googling for long time), but I don’t get it 🙁

Thank you very much

TRH
TRH
1 year ago

So, you’re permitting this script with a secret stored in plaintext to Read & Write to all OneDrive user locations in order to be able to write to one? Application scoped permissions should not even be considered for this usage in an Enterprise environment.

akash
akash
1 year ago

{“error”:{“code”:”accessDenied”,”message”:”Access denied”,”innerError”:{“date”:”2022-05-10T18:07:57″,”request-id”:”6ac100ae-42b1-4566-9fb2-b4c41c032f57″,”client-request-id”:”6ac100ae-42b1-4566-9fb2-b4c41c032f57″}}}

unable to execute line number 14 n 15
token able to generate

Vipin
Vipin
2 years ago

Hi,

How can I upload a excel file from my local folder to a OneDrive location location. I am new to Python and I am trying to download files from JIRA and upload to a folder under OneDrive . I was able to download the files to my local drive, but I could not uplaod it the OneDrive location

Hope you can help.
Thanks.

klav
klav
2 years ago

Hi Jos
I get an error in line 11:

TOKEN = j["access_token"]
KeyError: 'access_token'

Do you know what to do?

Roger
Roger
3 years ago

Hi Jos

You can ingore my last comment 🙂
It works now, in see I don’t need a redirect URI, I also had a mistake in the URL.

Thanks again for your super script

varun
varun
3 years ago

{‘error’: {‘code’: ‘AccessDenied’, ‘message’: ‘Either scp or roles claim need to be present in the token.’, ‘innerError’: {‘date’: ‘2020-10-21T13:25:42’, ‘request-id
‘: ’23f377cd-f650-4d06-a0bd-759d65xxxx’, ‘client-request-id’: ’23f377cd-f650-4d06-a0bd-759d6588xxxx’}}}
I get this error can anyone please help me out.
I have successfully received the access token.

christy
christy
3 years ago

Hi, Im trying to execute the code but getting Internal server error in get request.

url used: URL = “https://graph.microsoft.com/v1.0/users/Christyece13@gmail.com/drive/root:/test_file_uploads”

Kindly help me to sort it out.I’m not sure if the URL im using is correct or not.

marcus
marcus
3 years ago

Hi, I tried to use this code to upload a single excel file to my onedrive, but the request status code was 400 and the file did not successfully upload. The excel file is in the same directory as the python file. I replaced the loop with this code: filename = ‘testfile.xlsx’ print(“Uploading….”) fileHandle = open(filename, ‘rb’) r = requests.put(URL+”/”+filename+”:/content”, data=fileHandle, headers=headers) fileHandle.close() print(r.status_code) if r.status_code == 200 or r.status_code == 201:    #remove folder contents    print(“succeeded”) Is it possible I used an incorrect URL? I used my email for YOURONEDRIVEUSERNAME and used the part of my email after the @… Read more »

lesec
lesec
3 years ago

I’m trying to use your script but I’m not uploading pictures, instead a simple plain/text file on OneDrive. The only minor change to the code I’ve made is adding this in the for loop(in the 23th line) for debugging purposes: h = json.loads(r.text) Now I get the following error triggered by the upload line(23): {'error': {'code': 'BadRequest', 'message': 'Write requests (excluding DELETE) must contain the Content-Type header declaration.', 'innerError': {'request-id': '7a12885b-d4c8-43ff-84af-11412d45676d', 'date': '2020-05-29T08:28:44'}}} I’ve tried to add an header (line 13) to specify the Content-Type of file but none of the following bring a succesfull upload: # headers={'Authorization': "Bearer " + TOKEN, 'Content-Type': 'multipart/form-data'} headers={'Authorization': "Bearer " + TOKEN, 'Content-Type': 'text/plain'} and they both trigger… Read more »

Last edited 3 years ago by lesec
Rajeev
Rajeev
3 years ago

Hi,
I am using registered email id, but getting user not found, while calling upload api.
Please help, what i am i missing

Geoffroy Givry
Geoffroy Givry
4 years ago

Hi There, Many thanks for this tutorial!
I have one tiny (and stupid!) question. How to I get the
YOURONEDRIVEUSERNAME please? it sounds very silly but I’ve tried my login name from my email account geoff.gi@mycompanyname.onmicrosoft,com: geoff.gi
And it didn’t work. Did I miss anything?
Thanks a lot for your help!

Geoff

Joris
Joris
4 years ago

Good stuff! The script completed successfully (status code 200) for my test files. Unfortunately the files are nowhere to be found in OneDrive for Business. Any idea what I am doing wrong? (Trying to upload to the root folder). Also, would you have pointers on how to limit the App’s access to only one specific folder (write only)? Thanks for sharing your script!

Thierry
4 years ago

Short and sweet… Perfect

Gajendra Patidar
Gajendra Patidar
4 years ago

I’m not able to send big file like 25MB

Wa Wa
Wa Wa
4 years ago

Great script ! Thanks a lot