├── AutomatedOneDriveAPIUploadFiles-public.py ├── LICENSE ├── README.md └── generateOneDriveAPIConsentURL-public.py /AutomatedOneDriveAPIUploadFiles-public.py: -------------------------------------------------------------------------------- 1 | import os 2 | import requests 3 | import json 4 | import msal 5 | 6 | #Configuration 7 | CLIENT_ID = 'xxxxxxxx-xxxxxxx-xxxxxx-xxxxxxx-xxxxxxxxxx' 8 | TENANT_ID = 'xxxxxxxx-xxxxxxx-xxxxxx-xxxxxxx-xxxxxxxxxx' 9 | AUTHORITY_URL = 'https://login.microsoftonline.com/{}'.format(TENANT_ID) 10 | RESOURCE_URL = 'https://graph.microsoft.com/' 11 | API_VERSION = 'v1.0' 12 | USERNAME = 'xxxxxxxxx@xxxxxx.xxx' #Office365 user's account username 13 | PASSWORD = 'xxxxxxxxxxxxxxx' 14 | SCOPES = ['Sites.ReadWrite.All','Files.ReadWrite.All'] # Add other scopes/permissions as needed. 15 | 16 | #Creating a public client app, Aquire a access token for the user and set the header for API calls 17 | cognos_to_onedrive = msal.PublicClientApplication(CLIENT_ID, authority=AUTHORITY_URL) 18 | token = cognos_to_onedrive.acquire_token_by_username_password(USERNAME,PASSWORD,SCOPES) 19 | headers = {'Authorization': 'Bearer {}'.format(token['access_token'])} 20 | onedrive_destination = '{}/{}/me/drive/root:/cognos'.format(RESOURCE_URL,API_VERSION) 21 | cognos_reports_source = r"C:\Users\jsnmtr\Desktop\filesToUpload" 22 | 23 | #Looping through the files inside the source directory 24 | for root, dirs, files in os.walk(cognos_reports_source): 25 | for file_name in files: 26 | file_path = os.path.join(root,file_name) 27 | file_size = os.stat(file_path).st_size 28 | file_data = open(file_path, 'rb') 29 | 30 | if file_size < 4100000: 31 | #Perform is simple upload to the API 32 | r = requests.put(onedrive_destination+"/"+file_name+":/content", data=file_data, headers=headers) 33 | else: 34 | #Creating an upload session 35 | upload_session = requests.post(onedrive_destination+"/"+file_name+":/createUploadSession", headers=headers).json() 36 | 37 | with open(file_path, 'rb') as f: 38 | total_file_size = os.path.getsize(file_path) 39 | chunk_size = 327680 40 | chunk_number = total_file_size//chunk_size 41 | chunk_leftover = total_file_size - chunk_size * chunk_number 42 | i = 0 43 | while True: 44 | chunk_data = f.read(chunk_size) 45 | start_index = i*chunk_size 46 | end_index = start_index + chunk_size 47 | #If end of file, break 48 | if not chunk_data: 49 | break 50 | if i == chunk_number: 51 | end_index = start_index + chunk_leftover 52 | #Setting the header with the appropriate chunk data location in the file 53 | headers = {'Content-Length':'{}'.format(chunk_size),'Content-Range':'bytes {}-{}/{}'.format(start_index, end_index-1, total_file_size)} 54 | #Upload one chunk at a time 55 | chunk_data_upload = requests.put(upload_session['uploadUrl'], data=chunk_data, headers=headers) 56 | print(chunk_data_upload) 57 | print(chunk_data_upload.json()) 58 | i = i + 1 59 | 60 | file_data.close() -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jason 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-OneDriveAPI-FileUpload 2 | Uploading files to OneDrive account using Python, Microsoft Graph and OneDrive API 3 | 4 | PS: Before runnig this script, the API has to be created, set up and correctly configured. 5 | A step by step guide is available in the wiki https://github.com/jsnm-repo/Python-OneDriveAPI-FileUpload/wiki 6 | 7 | A tutorial with screenshots on how to create the API will be comming soon to my dev page on https://dev.to/jsnmtr 8 | 9 | 10 | *** 11 | ## Let me know your thoughts! 12 | 13 | ## Find me on [LinkedIn](https://www.linkedin.com/in/jasonmatar/) | [Twitter](https://twitter.com/Jsnmtr) | [Dev.to](https://dev.to/jsnmtr) | [StackOverflow](https://stackoverflow.com/users/8206322/jason-m) 14 | 15 | -------------------------------------------------------------------------------- /generateOneDriveAPIConsentURL-public.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | from requests_oauthlib import OAuth2Session 4 | from oauthlib.oauth2 import MobileApplicationClient 5 | 6 | client_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" 7 | scopes = ['Sites.ReadWrite.All','Files.ReadWrite.All'] 8 | auth_url = 'https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/oauth2/v2.0/authorize' 9 | 10 | #OAuth2Session is an extension to requests.Session 11 | #used to create an authorization url using the requests.Session interface 12 | #MobileApplicationClient is used to get the Implicit Grant 13 | oauth = OAuth2Session(client=MobileApplicationClient(client_id=client_id), scope=scopes) 14 | authorization_url, state = oauth.authorization_url(auth_url) 15 | 16 | consent_link = oauth.get(authorization_url) 17 | print(consent_link.url) 18 | 19 | 20 | --------------------------------------------------------------------------------