Access Microsoft Outlook mail using Python through the Microsoft Graph API

Step-by-step process on how to call the Microsoft Graph API using an access token in Python and retrieve Outlook data

Megan
9 min readMar 29, 2023
An individual on their laptop using Outlook email services
Photo by Adobe Stock

Context

In this fast-paced technology-driven age, automation is at the forefront of many businesses’ data strategies. In order to drive operational excellence and enable future-proof processes, automation of manual and low value activities is essential as it will allow businesses to realise the full value of data and create faster insights through data analytics.

Introduction

As a data consultant, I have worked with many clients who utilise the Microsoft ecosystem with Outlook as their email application. I have built pipelines to automate data ingestion and analysis from external sources such as Outlook.

This article will detail the end-to-end workflow (as well as explain some concepts) from how to connect to the Microsoft Graph API to exploring the content of a specific email, and how this workflow can be automated using a Python script. We will be creating a web application on the Azure portal to obtain an access token.

The steps below are granular and easy to follow. This article requires a good understanding of Python and how APIs work.

Before we dive into the steps, it is useful to understand how the authentication process works holistically.

Diagram source: Microsoft

The Microsoft identity platform as an Authorisation server, is utilised to sign in users with Azure AD accounts, Microsoft accounts, and social accounts like Facebook and Google. It enables protection of web APIs and access to protected APIs like Microsoft Graph to work with your users’ and organisation’s data.

The Client will be the application you will be creating below.

The Resource owner will be the owner of the Outlook email address we will be accessing through the Microsoft Graph API.

The Resource server hosts or provides access to a Resource owner’s data. Most often, the Resource server is a web API fronting a data store.

The Resource server relies on the Authorization server to perform authentication and uses information in Bearer tokens issued by the Authorization server to grant or deny access to resources.

The Bearer token is the access token we will obtain to access the resource owner’s Outlook data in the Resource server.

Note: Steps 1–7 below are a more comprehensive and in-depth version of instructions outlined on learn.microsoft.com. Feel free to follow the high level steps on the website but I have consolidated my learnings and other information across the web in the steps below.

Step 1: Register your application in the Azure portal

In regard to the diagram above, this will be the creation of your Client.

Prerequisites:

  • You have an Azure account with an active subscription. If no, you can create one for free
  • The Azure account must have the appropriate permissions, the following Azure Active Directory (Azure AD) roles will be adequate: application administrator, application developer and cloud application administrator
  • Set up an Azure AD tenant. It’s in the Azure AD tenant that you register and manage your apps, configure access to data in Microsoft 365 and other web APIs
  1. Sign in to the Azure portal
  2. Enter “Azure Active Directory” in the search bar
  3. Under the “Manage”, select “App registrations” > “New registration”

4. Insert a “Name” for your app. Under “Supported account types”, select the option that covers the Microsoft account that you plan to access via the Microsoft Graph API. In my case, I wanted to access a personal Outlook email service hence I could select one of the last 2 options that enables “Personal Microsoft accounts”. Leave “Redirect URI (optional)” blank — we will populate this later. Select “Register”

5. After the application registration, the landing page will be the app overview page. I have named my app “Microsoft Graph test”. You will see the “Application (client) ID” also called client ID, this value uniquely identifies your application in the Microsoft identity platform.

Step 2: Configure platform

This step is required to identify what application you are creating — whether it is a web application, mobile application etc.

Settings for each application type, including redirect URIs, are configured in Platform configurations in the Azure portal. Some platforms, like Web and Single-page applications, require you to manually specify a redirect URI. For other platforms, like mobile and desktop, you can select from redirect URIs generated for you when you configure their other settings.

In our case, we will be creating a web application.

Under “Manage”, select “Authentication” > “Add a platform”

Select “Web”

Enter a Redirect URI for your app https://localhost:5000/getAToken or https://127.0.0.1/getAToken. This is normally your local host and can be updated later depending on your individual local host URL. A redirect URI is the location where the Microsoft identity platform redirects a user’s client and sends security tokens after authentication.

There are some restrictions on the format of the redirect URIs you add to an app registration. Redirect URIs must begin with the scheme https.If you require to add a httpURI, you will need to go into “Manifest” and manually insert the URI there. Find “replyUrlsWithType” in the JSON code, and insert the relevant http URI as shown below. Select “Save” if you have implemented changes.

Step 3: Add a client secret

The web application requires a client secret to prove its identity when requesting an access token.

To create a new client secret value:

  1. Under “Overview”, save the “Application (client) ID” value for later use

2. Under “Manage”, select “Certificates & secrets” > “New client secret”

3. Populate the “Description” for new client secret and leave “Expires” as is or change if desired > “Add”

4. Save the “Value” of the client secret in a safe location as it will be required to populate the code later and it cannot be retrieved later.

Step 4: Add scope

Microsoft Graph has defined permissions that allows a user to implement tasks such as read a user’s Outlook emails or send emails. Third-party apps can be built to request only the permissions that they need to perform their function. Users and administrators can know what data the app can access. These types of permissions or permission sets are called scopes.

  1. Under “Manage”, select “API permissions” > “Add a permission”

2. Under “Microsoft APIs”, select “Microsoft Graph”

3. Select “Delegated permissions”, search for and select “User.ReadBasic.All” and select “Add permissions”

4. Ensure to select “Grant admin consent for <app name>”

Step 5: Download the sample Python app

You can either clone this repository https://github.com/Azure-Samples/ms-identity-python-webapp or download the sample Python app code here

Step 6: Configure the sample Python app

You will need to configure the sample code to align it to the web app we built above — you can do this with your client ID and client secret which was saved earlier.

  1. In the sample code folder, open app_config.py
  2. Populate CLIENT_ID with application (client) ID of your application so that will be “Secret ID” in the reference image below and populate CLIENT_SECRETwith “Value” in the reference image below.

3. Leave AUTHORITYas "https://login.microsoftonline.com/common"

4. For this example, we can call the ENDPOINT, ‘https://graph.microsoft.com/v1.0/me/messages' to obtain messages in the Outlook email.

5. We obtained permission for “User.ReadBasic.All” above and now want to ensure you have all the required permissions to call the Microsoft Graph API and have more functionality. Paste the following for SCOPE [“User.ReadBasic.All”, “User.read”, “Files.Readwrite.All”, “Sites.Readwrite.All”, “Mail.Read”, “Mail.ReadBasic”, “Mail.ReadWrite”, “MailboxSettings.Read”]

Step 7: Run the sample app

  1. If using a MacOS, open up Terminal
  2. Install the requirements using python3 -m pip install -r requirements.txt

3. Navigate to the relevant folder and run the app from the command line:

python3 app.py

You should see something like this in Terminal:

It indicates that the web app is running on my local URL http://127.0.0.1:5000 which corresponds to the URIs I provided in Step 2: Configure platform. If your local URL does not correspond to URIs provided before, you have to revisit Step 2: Configure platform to add in the appropriate URI in order to run your web app.

Step 8: Retrieve Outlook data

  1. If you have done all the steps above correctly, you should view this landing page:

2. Sign in using the Outlook account with appropriate permissions as mentioned in Step 1: Register your application in the Azure portal

3. After successfully signing in, you should see this landing page:

4. Select “Call Microsoft Graph API” and you should see a page which corresponds to the ENDPOINT: ‘https://graph.microsoft.com/v1.0/me/messages' which was stated in app_config.py.

The default page size is 10 messages. If you would like to view more messages you can configure the endpoint to below to obtain the first 100 messages:

https://graph.microsoft.com/v1.0/me/messages?$top=100

The page size is customisable within the range of 1 message and 1000 messages.

For more information on this endpoint, check out https://learn.microsoft.com/en-us/graph/api/user-list-messages?view=graph-rest-1.0&tabs=http

5. You can configure theENDPOINTvalue to obtain whatever Outlook data you desire eg if you want to drill down a single message:

  1. You can obtain the IDof the desired message through https://graph.microsoft.com/v1.0/me/messages provided the desired message is observable through that API call
  2. Update the ENDPOINT: ‘https://graph.microsoft.com/v1.0/me/messages/{id}'
  3. Run app.py

That is how you obtain message details through a Python web app. If you would like to run your own Python program that calls the Microsoft Graph API, continue on to step 8

Step 8: Calling the Microsoft Graph API from your own Python script

You will need to retrieve your access token in order to call the Microsoft API outside of the web app we built above.

  1. In the sample code folder, open app.py
  2. Navigate to def graphcall()and update the code as follows:

This way we will obtain your unique access token to call the Microsoft Graph API from anywhere. FYI if you want your web app to call the ENDPOINT denoted in app_config.py, you will have to return def graphcall()to its original code:

3. Run the app from the command line:

python3 app.py

4. You should be able to see your access code:

"expires_in": 3600 denotes that the access token will expire in one hour from the time the response was generated. You will have to regenerate another access token after an hour (re-visit this step, Step 8: Calling the Microsoft Graph API from your own Python script).

Now that you have your access code you can call the Microsoft Graph API in a Python program.

A sample Python script could be:

import requests

access_token = <insert access token>
# feel free to edit endpoint
endpoint = f'https://graph.microsoft.com/v1.0/me/messages'
headers = {"Authorization": f"Bearer {access_token}"}
response = requests.get(endpoint,headers=headers)
s = response.json()
print(s)

scontains the API JSON response which in this case will be the first 10 messages.

Conclusion

You have learnt 2 ways to access the Microsoft Graph API:

  1. A Python web app using Flask
  2. Any Python program (even Postman to test API) using the access code obtained from #1

There is a plethora of information about Microsoft Graph available on learn.microsoft.com and if you would like to explore more Microsoft Graph endpoints, learn.microsoft.com has great documentation.

--

--

Megan

Statistician 👩🏻‍💻 & Data Jack of all trades - strategy consulting, engineering & science 💡