Создание приложений Python с помощью Microsoft Graph
В этом руководстве описано, как создать консольное приложение Python, которое использует API Microsoft Graph для доступа к данным от имени пользователя.
Примечание.
Сведения о том, как использовать Microsoft Graph для доступа к данным с помощью проверки подлинности только для приложений, см. в этом руководстве по проверке подлинности только для приложений.
В этом руководстве описан порядок выполнения перечисленных ниже задач.
- Получение вошедшего пользователя
- Вывод списка сообщений пользователя в папке "Входящие"
- Отправить сообщение
Совет
В качестве альтернативы этому руководству вы можете скачать готовый код с помощью средства быстрого запуска , которое автоматизирует регистрацию и настройку приложений. Скачанный код работает без каких-либо изменений.
Вы также можете скачать или клонировать репозиторий GitHub и следовать инструкциям в файле README, чтобы зарегистрировать приложение и настроить проект.
Предварительные условия
Перед началом работы с этим руководством на компьютере разработки должны быть установлены Python и pip .
У вас также должна быть рабочая или учебная учетная запись Майкрософт с почтовым ящиком Exchange Online. Если у вас нет клиента Microsoft 365, вы можете претендовать на него в рамках Программы разработчиков Microsoft 365. Дополнительные сведения см. в разделе Вопросы и ответы. Кроме того, вы можете зарегистрироваться для получения бесплатной пробной версии на 1 месяц или приобрести план Microsoft 365.
Примечание.
Это руководство было написано с python версии 3.10.4 и pip версии 20.0.2. Действия, описанные в этом руководстве, могут работать с другими версиями, но не были протестированы.
Регистрация приложения на портале
В этом упражнении вы зарегистрируете новое приложение в Azure Active Directory, чтобы включить проверку подлинности пользователей. Вы можете зарегистрировать приложение в Центре администрирования Microsoft Entra или с помощью пакета SDK Для Microsoft Graph PowerShell.
Регистрация приложения для проверки подлинности пользователей
В этом разделе описано, как зарегистрировать приложение, которое поддерживает проверку подлинности пользователей с помощью потока кода устройства.
Откройте браузер и перейдите в Центр администрирования Microsoft Entra и войдите с помощью учетной записи глобального администратора.
Выберите Идентификатор Microsoft Entra в области навигации слева, разверните узел Удостоверение, Приложения, а затем выберите Регистрация приложений.
Выберите Новая регистрация. Введите имя приложения, например
Graph User Auth Tutorial
.Задайте поддерживаемые типы учетных записей . Доступны следующие варианты:
Вариант Кто может выполнить вход? Учетные записи только в этом каталоге организации Только пользователи в организации Microsoft 365 Учетные записи в любом каталоге организации Пользователи в любой организации Microsoft 365 (рабочие или учебные учетные записи) Учетные записи в любом каталоге организации... и личные учетные записи Майкрософт Пользователи в любой организации Microsoft 365 (рабочие или учебные учетные записи) и личные учетные записи Майкрософт Оставьте поле URI перенаправления пустым.
Нажмите Зарегистрировать. На странице Обзор приложения скопируйте значение идентификатора приложения (клиента) и сохраните его. Оно понадобится на следующем шаге. Если вы выбрали Учетные записи в этом каталоге организации только для поддерживаемых типов учетных записей, скопируйте идентификатор каталога (клиента) и сохраните его.
Выберите пункт Проверка подлинности в разделе Управление. Найдите раздел Дополнительные параметры и установите переключатель Разрешить общедоступные клиентские потоки на Да, а затем нажмите кнопку Сохранить.
Примечание.
Обратите внимание, что вы не настроили разрешения Microsoft Graph для регистрации приложения. Это связано с тем, что в примере используется динамическое согласие для запроса определенных разрешений для проверки подлинности пользователя.
Создание консольного приложения Python
Начните с создания файла Python.
Создайте файл с именем main.py и добавьте следующий код.
print ('Hello world!')
Сохраните файл и выполните следующую команду, чтобы запустить файл.
python3 main.py
Если это работает, приложение должно вывести .
Hello world!
Установка зависимостей
Прежде чем переходить дальше, добавьте некоторые дополнительные зависимости, которые будут использоваться позже.
- Клиентская библиотека удостоверений Azure для Python для проверки подлинности пользователя и получения маркеров доступа.
- Пакет SDK Microsoft Graph для Python (предварительная версия) для выполнения вызовов Microsoft Graph.
Выполните следующие команды в интерфейсе командной строки, чтобы установить зависимости.
python3 -m pip install azure-identity
python3 -m pip install msgraph-sdk
Загрузка параметров приложения
В этом разделе вы добавите в проект сведения о регистрации приложения.
Создайте файл в том же каталоге, что и main.pyс именем config.cfg , и добавьте следующий код.
[azure] clientId = YOUR_CLIENT_ID_HERE tenantId = common graphUserScopes = User.Read Mail.Read Mail.Send
Обновите значения в соответствии со следующей таблицей.
Параметр Значение clientId
Идентификатор клиента для регистрации приложения tenantId
Если вы выбрали параметр, разрешать вход только пользователям в вашей организации, измените это значение на идентификатор клиента. В противном случае оставьте значение common
.Совет
При необходимости эти значения можно задать в отдельном файле с именем config.dev.cfg.
Проектирование приложения
В этом разделе вы создадите простое меню на основе консоли.
Создайте файл с именем graph.py и добавьте в этот файл следующий код.
# Temporary placeholder class Graph: def __init__(self, config): self.settings = config
Этот код является заполнителем. Класс будет реализован
Graph
в следующем разделе.Откройте main.py и замените все его содержимое следующим кодом.
import asyncio import configparser from msgraph.generated.models.o_data_errors.o_data_error import ODataError from graph import Graph async def main(): print('Python Graph Tutorial\n') # Load settings config = configparser.ConfigParser() config.read(['config.cfg', 'config.dev.cfg']) azure_settings = config['azure'] graph: Graph = Graph(azure_settings) await greet_user(graph) choice = -1 while choice != 0: print('Please choose one of the following options:') print('0. Exit') print('1. Display access token') print('2. List my inbox') print('3. Send mail') print('4. Make a Graph call') try: choice = int(input()) except ValueError: choice = -1 try: if choice == 0: print('Goodbye...') elif choice == 1: await display_access_token(graph) elif choice == 2: await list_inbox(graph) elif choice == 3: await send_mail(graph) elif choice == 4: await make_graph_call(graph) else: print('Invalid choice!\n') except ODataError as odata_error: print('Error:') if odata_error.error: print(odata_error.error.code, odata_error.error.message)
Добавьте следующие методы-заполнители в конец файла. Вы будете реализовывать их на последующих шагах.
async def greet_user(graph: Graph): # TODO return async def display_access_token(graph: Graph): # TODO return async def list_inbox(graph: Graph): # TODO return async def send_mail(graph: Graph): # TODO return async def make_graph_call(graph: Graph): # TODO return
Добавьте следующую строку для вызова
main
в конце файла.# Run main asyncio.run(main())
Это реализует базовое меню и считывает выбор пользователя из командной строки.
Добавление проверки подлинности пользователя
В этом разделе описано, как расширить приложение из предыдущего упражнения для поддержки проверки подлинности с помощью Azure AD. Это необходимо для получения необходимого маркера доступа OAuth для вызова Microsoft Graph. На этом шаге вы интегрируете клиентную библиотеку удостоверений Azure для Python в приложение и настроите проверку подлинности для пакета SDK Microsoft Graph для Python (предварительная версия).
Библиотека удостоверений Azure предоставляет ряд классов, которые реализуют потоки маркеров TokenCredential
OAuth2. Пакет SDK для Microsoft Graph использует эти классы для проверки подлинности вызовов Microsoft Graph.
Настройка клиента Graph для проверки подлинности пользователей
В этом разделе вы будете DeviceCodeCredential
использовать класс для запроса маркера доступа с помощью потока кода устройства.
Откройте graph.py и замените все его содержимое следующим кодом.
from configparser import SectionProxy from azure.identity import DeviceCodeCredential from msgraph import GraphServiceClient from msgraph.generated.users.item.user_item_request_builder import UserItemRequestBuilder from msgraph.generated.users.item.mail_folders.item.messages.messages_request_builder import ( MessagesRequestBuilder) from msgraph.generated.users.item.send_mail.send_mail_post_request_body import ( SendMailPostRequestBody) from msgraph.generated.models.message import Message from msgraph.generated.models.item_body import ItemBody from msgraph.generated.models.body_type import BodyType from msgraph.generated.models.recipient import Recipient from msgraph.generated.models.email_address import EmailAddress class Graph: settings: SectionProxy device_code_credential: DeviceCodeCredential user_client: GraphServiceClient def __init__(self, config: SectionProxy): self.settings = config client_id = self.settings['clientId'] tenant_id = self.settings['tenantId'] graph_scopes = self.settings['graphUserScopes'].split(' ') self.device_code_credential = DeviceCodeCredential(client_id, tenant_id = tenant_id) self.user_client = GraphServiceClient(self.device_code_credential, graph_scopes)
Этот код объявляет два частных свойства:
DeviceCodeCredential
объект иGraphServiceClient
объект . Функция__init__
создает новый экземплярDeviceCodeCredential
, а затем использует его для создания нового экземпляраGraphServiceClient
. Каждый раз, когда вызов API выполняется в Microsoft Graph черезuser_client
, он будет использовать предоставленные учетные данные для получения маркера доступа.Добавьте следующую функцию в graph.py.
async def get_user_token(self): graph_scopes = self.settings['graphUserScopes'] access_token = self.device_code_credential.get_token(graph_scopes) return access_token.token
Замените пустую
display_access_token
функцию в main.py на следующую.async def display_access_token(graph: Graph): token = await graph.get_user_token() print('User token:', token, '\n')
Выполните сборку и запуск приложения. Введите
1
при появлении запроса на выбор параметра. Приложение отображает URL-адрес и код устройства.Python Graph Tutorial Please choose one of the following options: 0. Exit 1. Display access token 2. List my inbox 3. Send mail 4. Make a Graph call 1 To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code RB2RUD56D to authenticate.
Откройте браузер и перейдите по url-адресу. Введите предоставленный код и войдите в систему.
Важно!
Помните о всех существующих учетных записях Microsoft 365, которые вошли в браузер при просмотре страницы
https://microsoft.com/devicelogin
. Используйте функции браузера, такие как профили, гостевой режим или частный режим, чтобы проверить подлинность в качестве учетной записи, которую вы планируете использовать для тестирования.После завершения вернитесь к приложению, чтобы увидеть маркер доступа.
Совет
Только для проверки и отладки можно декодировать маркеры доступа пользователей (только для рабочих или учебных учетных записей) с помощью средства синтаксического анализа токенов Майкрософт в сети по адресу https://jwt.ms. Это может быть полезно, если при вызове Microsoft Graph возникают ошибки маркера. Например, убедитесь, что
scp
утверждение в маркере содержит ожидаемые области разрешений Microsoft Graph.
Получение пользователя
В этом разделе описано, как включить Microsoft Graph в приложение. Для этого приложения вы будете использовать пакет SDK Microsoft Graph для Python (предварительная версия) для выполнения вызовов к Microsoft Graph.
Добавьте следующую функцию в graph.py.
async def get_user(self): # Only request specific properties using $select query_params = UserItemRequestBuilder.UserItemRequestBuilderGetQueryParameters( select=['displayName', 'mail', 'userPrincipalName'] ) request_config = UserItemRequestBuilder.UserItemRequestBuilderGetRequestConfiguration( query_parameters=query_params ) user = await self.user_client.me.get(request_configuration=request_config) return user
Замените пустую
greet_user
функцию в main.py на следующую.async def greet_user(graph: Graph): user = await graph.get_user() if user: print('Hello,', user.display_name) # For Work/school accounts, email is in mail property # Personal accounts, email is in userPrincipalName print('Email:', user.mail or user.user_principal_name, '\n')
Если вы запустите приложение сейчас, после входа в приложение будет приветствовать вас по имени.
Hello, Megan Bowen!
Email: MeganB@contoso.com
Описание кода
Рассмотрим код в get_user
функции. Это всего несколько строк, но есть некоторые ключевые детали, которые следует обратить внимание.
Доступ к "мне"
Функция создает запрос к API Get user API. Этот API доступен двумя способами:
GET /me
GET /users/{user-id}
В этом случае код вызывает конечную точку GET /me
API. Это ярлык, который позволяет получить пользователя, прошедшего проверку подлинности, не зная его идентификатора пользователя.
Примечание.
GET /me
Так как конечная точка API получает пользователя, прошедшего проверку подлинности, она доступна только для приложений, использующих проверку подлинности пользователей. Приложения для проверки подлинности только для приложений не могут получить доступ к этой конечной точке.
Запрос определенных свойств
Функция использует параметр запроса $select для указания набора необходимых свойств. Microsoft Graph вернет только запрошенные свойства в ответе. В get_user
это выполняется с помощью select
параметра в объекте MeRequestBuilderGetQueryParameters
.
Перечисление папки "Входящие"
В этом разделе вы добавите возможность выводить список сообщений в папке "Входящие" пользователя.
Добавьте следующую функцию в graph.py.
async def get_inbox(self): query_params = MessagesRequestBuilder.MessagesRequestBuilderGetQueryParameters( # Only request specific properties select=['from', 'isRead', 'receivedDateTime', 'subject'], # Get at most 25 results top=25, # Sort by received time, newest first orderby=['receivedDateTime DESC'] ) request_config = MessagesRequestBuilder.MessagesRequestBuilderGetRequestConfiguration( query_parameters= query_params ) messages = await self.user_client.me.mail_folders.by_mail_folder_id('inbox').messages.get( request_configuration=request_config) return messages
Замените пустую
list_inbox
функцию в main.py на следующую.async def list_inbox(graph: Graph): message_page = await graph.get_inbox() if message_page and message_page.value: # Output each message's details for message in message_page.value: print('Message:', message.subject) if ( message.from_ and message.from_.email_address ): print(' From:', message.from_.email_address.name or 'NONE') else: print(' From: NONE') print(' Status:', 'Read' if message.is_read else 'Unread') print(' Received:', message.received_date_time) # If @odata.nextLink is present more_available = message_page.odata_next_link is not None print('\nMore messages available?', more_available, '\n')
Запустите приложение, войдите в систему и выберите вариант 2, чтобы получить список папки "Входящие".
Please choose one of the following options: 0. Exit 1. Display access token 2. List my inbox 3. Send mail 4. Make a Graph call 2 Message: Updates from Ask HR and other communities From: Contoso Demo on Yammer Status: Read Received: 2022-04-26T19:19:05Z Message: Employee Initiative Thoughts From: Patti Fernandez Status: Read Received: 2022-04-25T19:43:57Z Message: Voice Mail (11 seconds) From: Alex Wilber Status: Unread Received: 2022-04-22T19:43:23Z Message: Our Spring Blog Update From: Alex Wilber Status: Unread Received: 2022-04-19T22:19:02Z Message: Atlanta Flight Reservation From: Alex Wilber Status: Unread Received: 2022-04-19T15:15:56Z Message: Atlanta Trip Itinerary - down time From: Alex Wilber Status: Unread Received: 2022-04-18T14:24:16Z ... More messages available? True
Описание кода
Рассмотрим код в get_inbox
функции.
Доступ к известным почтовым папкам
Функция создает запрос к API списка сообщений . Так как он включает построитель mail_folders.by_mail_folder_id('inbox')
запросов, API будет возвращать только сообщения в папке запрошенной почты. В этом случае, так как папка "Входящие" является хорошо известной папкой по умолчанию в почтовом ящике пользователя, она доступна по известному имени. Доступ к папкам, не используемым по умолчанию, можно получить таким же образом, заменив известное имя свойством идентификатора почтовой папки. Дополнительные сведения о доступных известных именах папок см. в разделе Тип ресурса mailFolder.
Доступ к коллекции
get_user
В отличие от функции из предыдущего раздела, которая возвращает один объект, этот метод возвращает коллекцию сообщений. Большинство API в Microsoft Graph, возвращающих коллекцию, не возвращают все доступные результаты в одном ответе. Вместо этого они используют разбиение на страницы , чтобы вернуть часть результатов, предоставляя метод для клиентов, чтобы запросить следующую "страницу".
Размеры страниц по умолчанию
API, использующие разбиение на страницы, реализуют размер страницы по умолчанию. Для сообщений значение по умолчанию — 10. Клиенты могут запрашивать больше (или меньше) с помощью параметра запроса $top . В get_inbox
это выполняется с помощью top
параметра в объекте MessagesRequestBuilderGetQueryParameters
.
Примечание.
Переданное значение $top
является верхней границей, а не явным числом. API возвращает количество сообщений до указанного значения.
Получение последующих страниц
Если на сервере доступно больше результатов, ответы коллекции содержат @odata.nextLink
свойство с URL-адресом API для доступа к следующей странице. Пакет SDK для Python предоставляет его в odata_next_link
качестве свойства для объектов страницы коллекции. Если это свойство присутствует, доступны дополнительные результаты.
Сортировка коллекций
Функция использует параметр запроса $orderby для запроса результатов, отсортированных по времени получения сообщения (receivedDateTime
свойство). Он включает ключевое DESC
слово, чтобы сообщения, полученные в последнее время, отображались первыми. В get_inbox
это выполняется с помощью orderby
параметра в объекте MessagesRequestBuilderGetQueryParameters
.
Отправка почты
В этом разделе вы добавите возможность отправки сообщения электронной почты в качестве пользователя, прошедшего проверку подлинности.
Добавьте следующую функцию в graph.py.
async def send_mail(self, subject: str, body: str, recipient: str): message = Message() message.subject = subject message.body = ItemBody() message.body.content_type = BodyType.Text message.body.content = body to_recipient = Recipient() to_recipient.email_address = EmailAddress() to_recipient.email_address.address = recipient message.to_recipients = [] message.to_recipients.append(to_recipient) request_body = SendMailPostRequestBody() request_body.message = message await self.user_client.me.send_mail.post(body=request_body)
Замените пустую
send_mail
функцию в main.py на следующую.async def send_mail(graph: Graph): # Send mail to the signed-in user # Get the user for their email address user = await graph.get_user() if user: user_email = user.mail or user.user_principal_name await graph.send_mail('Testing Microsoft Graph', 'Hello world!', user_email or '') print('Mail sent.\n')
Запустите приложение, войдите в систему и выберите вариант 3, чтобы отправить себе сообщение электронной почты.
Please choose one of the following options: 0. Exit 1. Display access token 2. List my inbox 3. Send mail 4. Make a Graph call 3 Mail sent.
Примечание.
Если вы тестируете с помощью клиента разработчика из Программы разработчика Microsoft 365, отправленное сообщение электронной почты может не быть доставлено, и вы можете получить отчет о недоставки. Если это случится с вами, обратитесь в службу поддержки через Центр администрирования Microsoft 365.
Чтобы убедиться, что сообщение получено, выберите вариант 2, чтобы получить список папки "Входящие".
Описание кода
Рассмотрим код в send_mail
функции.
Отправка почты
Функция использует построитель user_client.me.send_mail
запросов, который создает запрос к API отправки почты .
Создание объектов
В отличие от предыдущих вызовов Microsoft Graph, которые считывают только данные, этот вызов создает данные. Для этого с помощью клиентской библиотеки создайте словарь, представляющий полезные данные запроса, задайте нужные свойства, а затем отправьте его в вызове API. Так как вызов отправляет данные, post
вместо используется get
метод .
Необязательно: добавление собственного кода
В этом разделе вы добавите в приложение собственные возможности Microsoft Graph. Это может быть фрагмент кода из документации Microsoft Graph или обозревателя Graph или созданный вами код. Этот раздел является необязательным.
Обновите приложение
Добавьте следующую функцию в graph.py.
async def make_graph_call(self): # INSERT YOUR CODE HERE return
Замените пустую
make_graph_call
функцию в main.py на следующую.async def make_graph_call(graph: Graph): await graph.make_graph_call()
Выбор API
Найдите API в Microsoft Graph, который вы хотите попробовать. Например, API создания событий . Вы можете использовать один из примеров из документации по API или создать собственный запрос API.
Настройка разрешений
Ознакомьтесь с разделом Разрешения справочной документации по выбранному API, чтобы узнать, какие методы проверки подлинности поддерживаются. Некоторые API не поддерживают только приложения или личные учетные записи Майкрософт, например.
- Чтобы вызвать API с проверкой подлинности пользователя (если API поддерживает проверку подлинности пользователя (делегированная), добавьте требуемую область разрешений в config.cfg.
- Чтобы вызвать API с проверкой подлинности только для приложений, ознакомьтесь с руководством по проверке подлинности только для приложений .
Добавление кода
Скопируйте код в функцию make_graph_call
в graph.py. Если вы копируете фрагмент из документации или обозревателя Graph, обязательно переименуйте GraphServiceClient
self.user_client
в .
Поздравляем!
Вы завершили работу с учебником По Microsoft Graph для Python. Теперь, когда у вас есть рабочее приложение, которое вызывает Microsoft Graph, вы можете экспериментировать и добавлять новые функции.
- Узнайте, как использовать проверку подлинности только для приложений с пакетом SDK Microsoft Graph для Python.
- Просмотрите обзор Microsoft Graph , чтобы просмотреть все данные, к которым можно получить доступ с помощью Microsoft Graph.
Примеры Python
Возникла проблема с этим разделом? Если это так, отправьте нам отзыв, чтобы мы исправили этот раздел.