Reputation: 1746
I have seen some older method using onedrive sdk, seems like those are not working now. This is one of the method I got after some research. But it is not working
import msal
import requests
# Azure AD app credentials
client_id = 'xxx9846xxxx'
client_secret = 'xxxTdxxx'
tenant_id = 'xxx-xxxx'
# Authority URL for your tenant
authority = f'https://login.microsoftonline.com/{tenant_id}'
# Scopes needed for OneDrive file operations
scopes = ['https://graph.microsoft.com/.default']
# Initialize the MSAL ConfidentialClientApplication
app = msal.ConfidentialClientApplication(
client_id,
client_credential=client_secret,
authority=authority
)
# Get the access token
token_response = app.acquire_token_for_client(scopes=scopes)
access_token = token_response.get('access_token')
if not access_token:
raise Exception("Could not acquire access token")
# Define the file to upload
file_path = 'C:/test.csv'
# Microsoft Graph API endpoint for OneDrive (using Application Permissions)
upload_url = 'https://graph.microsoft.com/v1.0/me/drive/root:/Documents/' + file_name + ':/content'
# Open the file in binary mode
with open(file_path, 'rb') as file:
file_content = file.read()
# Make the PUT request to upload the file
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/octet-stream'
}
response = requests.put(upload_url, headers=headers, data=file_content)
# Check if the file upload was successful
if response.status_code == 201:
print(f'File uploaded successfully to OneDrive: {file_name}')
else:
print(f'Error uploading file: {response.status_code}, {response.text}')
I am geting below error:
Error uploading file: 400, {"error":{"code":"BadRequest","message":"/me request is only valid with delegated authentication flow.","innerError":{"date":"2025-01-13T17:06:35","request-id":"5959d049-9ad7-4ced-b6fc-00ddddd242","client-request-id":"5959d049-9ad7-4ced-b6fc-0079ddddd"}}}
How to resolve this error ? or any alternative way to upload the files
Update :
I have created a new app registration which support "Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)"
These are the API permissions I have added:
updated code :
import requests
# Replace with your details
client_id = 'xxxxx'
client_secret = 'xxxx'
tenant_id = '052c8b5b-xxxx'
filename = 'C:/test.csv'
onedrive_folder = 'CloudOnly/test'
user_id = 'xxxx-e7d1-44dc-a846-5exxxx'
# Get the access token
url = f'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token'
data = {
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
'scope': 'https://graph.microsoft.com/.default'
}
response = requests.post(url, data=data)
token = response.json().get('access_token')
# Upload the file to OneDrive
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/octet-stream'
}
file_content = open(filename, 'rb').read()
upload_url = f'https://graph.microsoft.com/v1.0/users/{user_id}/drive/root:/{onedrive_folder}/{filename.split("/")[-1]}:/content'
upload_response = requests.put(upload_url, headers=headers, data=file_content)
if upload_response.status_code == 201:
print('File uploaded successfully!')
else:
print('Error uploading file:', upload_response.json())
But this gives me error:
Error uploading file: {'error': {'code': 'BadRequest', 'message': 'Tenant does not have a SPO license.', 'innerError': {'date': '2025-01-14T02:15:47', 'request-id': 'cf70193e-1723-44db-9f5e-xxxxx', 'client-request-id': 'cf70193e-1723-44db-9f5e-xxxx'}}}
Upvotes: 0
Views: 84
Reputation: 848
Initially, I registered Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)" Microsoft Entra ID application:
Error uploading file: 400, {"error":{"code":"BadRequest","message":"/me request is only valid with delegated authentication flow.
I came across same error, When I ran the python code which you provided by using /me
endpoint.
Note: For uploading file to OneDrive-Personal, Must have to use delegated flow where user-interaction is involved and Must use /me
endpoint only; As it not possible with application type API permission and client-credential flow(non-user-interactive).
To resolve the error, Using delegated type, authorization code flow where user-interaction is involved.
Added delegated type Files.ReadWrite.All
API Permission and Granted Admin consent like below:
Configured Authentication tab of application like below:
Use below modified python script with delegated flow using authorization code flow:
import requests
from msal import PublicClientApplication
import os
import time
CLIENT_ID = '<client-id>';
CLIENT_SECRET = '<client-secret>';
file_name= "<file-name to whom you want to upload>";
file_path = "<file-path>";
authority_url = 'https://login.microsoftonline.com/common'
scopes = ['Files.ReadWrite.All']
onedrive_folder ="Documents";
app = PublicClientApplication(CLIENT_ID, authority=authority_url)
# Simplistic approach to illustrate the flow
redirect_uri = 'http://localhost:8000/callback'
url = app.get_authorization_request_url(scopes, redirect_uri=redirect_uri)
print("Please go to this URL and sign-in:", url)
# After sign-in, receive a callback with a code
code = input("Enter the code you received: ")
result = app.acquire_token_by_authorization_code(code, scopes=scopes, redirect_uri=redirect_uri)
if 'access_token' in result:
access_token = result['access_token']
print("Access token acquired.")
else:
print(result.get('error'))
print(result.get('error_description'))
exit(1)
upload_url = f'https://graph.microsoft.com/v1.0/me/drive/root:/{onedrive_folder}/{file_name}:/content'
# Open the file in binary mode
with open(file_path, 'rb') as file:
file_content = file.read()
# Make the PUT request to upload the file
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/octet-stream'
}
response = requests.put(upload_url, headers=headers, data=file_content)
# Check if the file upload was successful
if response.status_code == 201:
print(f'File uploaded successfully to OneDrive: {onedrive_folder}:/{file_name}')
else:
print(f'Error uploading file: {response.status_code}, {response.text}')
Copy the authorization_code from browser and Paste at Enter the code you received:
Response:
I've verified same from OneDrive Portal as well, File TestUploadOnedrive.xlsx
was uploaded successfully.
Error uploading file: {'error': {'code': 'BadRequest', 'message': 'Tenant does not have a SPO license.', '
To resolve this error, User should have active Office 365 E3 license or Office 365 E5 license. Refer this SO Thread by Rukmini.
If still issue persist, Check thisMicrosoft QnA by Carl-Zhao-MSFT
Reference:
Upload the content of Drive Item
Refer this SO thread for Tenant does not have a SPO license. by Dan Kershaw - MSFT.
MsDoc on authorization_code flow
Upvotes: 1