Я хочу загрузить несколько файлов с локального компьютера в свой OneDrive. В этом случае я использую библиотеку MSAL (Библиотека аутентификации Microsoft). В файле ms_graph.py есть небольшая проблема. Поток user_code не отвечает правильно. Как я могу решить эту проблему? В обычном случае код должен напечатать user_code для доступа к учетной записи OneDrive.
мс_граф.py:
import webbrowser
from datetime import datetime
import json
import os
import msal
GRAPH_API_ENDPOINT = 'https://graph.microsoft.com/v1.0'
def generate_access_token(app_id, scopes):
# Save Session Token as a token file
access_token_cache = msal.SerializableTokenCache()
# read the token file
if os.path.exists('ms_graph_api_token.json'):
access_token_cache.deserialize(open("ms_graph_api_token.json", "r").read())
token_detail = json.load(open('ms_graph_api_token.json', ))
token_detail_key = list(token_detail['AccessToken'].keys())[0]
token_expiration = datetime.fromtimestamp(int(token_detail['AccessToken'][token_detail_key]['expires_on']))
if datetime.now() > token_expiration:
os.remove('ms_graph_api_token.json')
access_token_cache = msal.SerializableTokenCache()
# assign a SerializableTokenCache object to the client instance
client = msal.PublicClientApplication(client_id=app_id, token_cache=access_token_cache)
accounts = client.get_accounts()
if accounts:
# load the session
token_response = client.acquire_token_silent(scopes, accounts[0])
else:
# authetnicate your accoutn as usual
flow = client.initiate_device_flow(scopes=scopes)
print('user_code: ' + flow['user_code'])
webbrowser.open('https://microsoft.com/devicelogin')
token_response = client.acquire_token_by_device_flow(flow)
with open('ms_graph_api_token.json', 'w') as _f:
_f.write(access_token_cache.serialize())
return token_response
if __name__ == '__main__':
...
основной.py:
import os
import requests
from ms_graph import generate_access_token, GRAPH_API_ENDPOINT
APP_ID = 'my_client_id'
SCOPES = ['Files.ReadWrite']
access_token = generate_access_token(APP_ID, SCOPES)
headers = {
'Authorization': 'Bearer' + access_token['access_token']
}
file_path = r'C:\Users\user\OneDrive\Desktop\Fiyat-2\example_file.txt'
file_name = os.path.basename(file_path)
with open(file_path, 'rb') as upload:
content = upload.read()
response = requests.put(
GRAPH_API_ENDPOINT + f'me/drive/items/root:/{file_path}:/content',
headers=headers,
data=content
)
print(response.json())
Выход:
C:\Users\user\OneDrive\Desktop\Fiyat-2\venv\Scripts\python.exe C:\Users\user\OneDrive\Desktop\Fiyat-2\main.py
Traceback (most recent call last):
File "C:\Users\user\OneDrive\Desktop\Fiyat-2\main.py", line 8, in <module>
access_token = generate_access_token(APP_ID, SCOPES)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\user\OneDrive\Desktop\Fiyat-2\ms_graph.py", line 34, in generate_access_token
print('user_code: ' + flow['user_code'])
~~~~^^^^^^^^^^^^^
KeyError: 'user_code'
Process finished with exit code 1






Обратите внимание: для потока кода устройства требуется взаимодействие с веб-браузером, пользователь должен ввести код, сгенерированный потоком, и войти в систему с учетной записью пользователя.
Чтобы загрузить файл в OneDrive, вы можете использовать приведенный ниже код:
# Microsoft Graph API endpoint
GRAPH_API_ENDPOINT = 'https://graph.microsoft.com/v1.0/'
# Configuration for Microsoft Authentication
config = {
"client_id": "ClientID",
"authority": "https://login.microsoftonline.com/TenantID",
"scope": ["Files.ReadWrite"],
}
access_token_cache = msal.SerializableTokenCache()
# Load cached token if available
if os.path.exists('ms_graph_api_token.json'):
access_token_cache.deserialize(open("ms_graph_api_token.json", "r").read())
token_detail = json.load(open('ms_graph_api_token.json', ))
token_detail_key = next(iter(token_detail.keys()), None) # Get the first key in the dictionary
if token_detail_key == 'AccessToken':
token_expiration = datetime.fromtimestamp(int(token_detail['AccessToken']['expires_on']))
if datetime.now() > token_expiration:
os.remove('ms_graph_api_token.json')
access_token_cache = msal.SerializableTokenCache()
app = msal.PublicClientApplication(
config["client_id"],
authority=config["authority"],
token_cache=access_token_cache,
)
result = None
# First, try to get a token from the cache.
accounts = app.get_accounts()
if accounts:
# Use the first account to acquire a token silently.
result = app.acquire_token_silent(config["scope"], account=accounts[0])
if not result:
# If a token is not available in the cache, use the device flow to acquire a new token.
flow = app.initiate_device_flow(scopes=config["scope"])
print(flow["message"])
# Open the browser automatically
webbrowser.open(flow["verification_uri"])
result = app.acquire_token_by_device_flow(flow)
# Use the access token to call the Microsoft Graph API.
if "access_token" in result:
access_token = result["access_token"]
headers = {'Authorization': 'Bearer ' + access_token}
# File upload parameters
file_path = r'C:\Users\rukmini\Downloads\RukRoleAssignmentPs.txt'
file_name = os.path.basename(file_path)
with open(file_path, 'rb') as upload:
content = upload.read()
response = requests.put(
GRAPH_API_ENDPOINT + f'me/drive/root:/{file_name}:/content',
headers=headers,
data=content
)
# Output response
print(response.json())
else:
error = result.get("error")
if error == "invalid_client":
print("Invalid client ID. Please check your Azure AD application configuration")
else:
print(error)
Приведенный выше код открывает веб-браузер, и пользователь должен ввести код и войти в систему:


Файл успешно загружен в OneDrive:

Портал OneDrive:

Чтобы решить проблему, измените ms_graph.py, как показано ниже:
if accounts:
# load the session
token_response = client.acquire_token_silent(scopes, accounts[0])
else:
# authetnicate your accoutn as usual
flow = client.initiate_device_flow(scopes=scopes)
webbrowser.open('https://microsoft.com/devicelogin')
token_response = client.acquire_token_by_device_flow(flow)
with open('ms_graph_api_token.json', 'w') as _f:
_f.write(access_token_cache.serialize())
return token_response
if __name__ == '__main__':
...
Могу ли я спросить, после первого запуска я получаю это сообщение: Неверный идентификатор клиента. Проверьте конфигурацию приложения Azure AD. Но все в порядке. Я уверен, что указываю правильный идентификатор клиента.
Возможно, проблема была на секунду, если сейчас все работает нормально, то проблем нет.
Да, с первого раза все получилось. Но примерно через 20 раз я попытался загрузить файл еще раз и получил тот же результат. В сети или cmd ошибок нет. Но печатает неверный идентификатор клиента.
Затем попробуйте удалить оператор печати для недействительного клиента, и я не столкнусь с этой проблемой.
Но файл тоже не загружается в OneDrive. изображение о выпуске
Давайте продолжим обсуждение в чате.
Это сработало! Спасибо за ответ. Я закрепил ваш ответ как решение.