[Python] How to get authorization token through OAuth2 and read Outlook emails through http...

Discussão em 'Python' iniciado por Stack, Maio 8, 2025.

  1. Stack

    Stack Membro Participativo

    I've been retrieving my emails in Outlook by only using python requests to GET the endpoint https://outlook.office365.com/api/v1.0/me/messages

    Example code:

    import requests

    requests.get('https://outlook.office365.com/api/v1.0/me/messages', auth=(email, pwd))


    I would get a json object back, parse through it, and get the contents of my email. But now Microsoft has deprecated it and I have been trying to migrate over to using Microsoft Graph. My question is, how do I get an OAuth2 token without having to launch a browser using http requests?

    So far I've been reading through the docs and registered my "app" (just a regular python script) in the Application Registration Portal. Every example that I come across, I always have to go visit an authorization url where I have to manually log in through a front end UI which looks like this: [​IMG] I want to be able to do this through http requests/without a frontend UI but I can't seem to find any answers on how to do this.

    This is the code I have so far:

    outlook_test.py


    import requests

    authorize_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize'
    token_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token'

    payload = {
    'client_id': app_client_id, # Variable exists but not exposed in this question
    'response_type': 'code',
    'redirect_uri': 'https://login.microsoftonline.com/common/oauth2/nativeclient',
    'response_mode': 'form_post',
    'scope': 'mail.read',
    'state': '12345'
    }

    r = requests.get(authorize_url, params=payload)
    print(r.status_code)
    print(r.text)


    This is what I get back:

    200
    <!DOCTYPE html>
    <html dir="ltr" class="" lang="en">
    <head>
    <title>Sign in to your account</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scal able=yes">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Expires" content="-1">
    <meta name="PageID" content="ConvergedSignIn" />
    <meta name="SiteID" content="" />
    <meta name="ReqLC" content="1033" />
    <meta name="LocLC" content="en-US" />

    <noscript>
    <meta http-equiv="Refresh" content="0; URL=https://login.microsoftonline.com/jsdisabled" />
    </noscript>


    <link rel="shortcut icon" href="https://secure.aadcdn.microsoftonline-p.com/ests/2.1.8502.8/co ntent/images/favicon_a_eupayfgghqiai7k9sol6lg2.ico" />

    <meta name="robots" content="none" />
    ...


    This is what I have in my platform settings when I registered my app if it helps: [​IMG]

    Is there any way I can get the authorization code programatically? I tried passing in the auth parameter as well but that didn't work.

    New Findings


    I recently found out that python requests handles OAuth2 but now I am getting a different error when trying to follow their examples. This is the error that I'm getting:

    File "outlook_test.py", line 31, in <module>
    token = oauth.fetch_token(token_url=token_url, auth=auth)
    File "C:\Users\ryee\Documents\gitLabQA\QA_BDD\outlook_env\lib\site-packages\requests_oauthlib\oauth2_session.py", line 307, in fetch_token
    self._client.parse_request_body_response(r.text, scope=self.scope)
    File "C:\Users\ryee\Documents\gitLabQA\QA_BDD\outlook_env\lib\site-packages\oauthlib\oauth2\rfc6749\clients\base.py", line 415, in parse_request_body_response
    self.token = parse_token_response(body, scope=scope)
    File "C:\Users\ryee\Documents\gitLabQA\QA_BDD\outlook_env\lib\site-packages\oauthlib\oauth2\rfc6749\parameters.py", line 425, in parse_token_response
    validate_token_parameters(params)
    File "C:\Users\ryee\Documents\gitLabQA\QA_BDD\outlook_env\lib\site-packages\oauthlib\oauth2\rfc6749\parameters.py", line 432, in validate_token_parameters
    raise_from_error(params.get('error'), params)
    File "C:\Users\ryee\Documents\gitLabQA\QA_BDD\outlook_env\lib\site-packages\oauthlib\oauth2\rfc6749\errors.py", line 405, in raise_from_error
    raise cls(**kwargs)
    oauthlib.oauth2.rfc6749.errors.InvalidClientIdError: (invalid_request) AADSTS90014: The required field 'scope' is missing.
    Trace ID: 2359d8a6-0140-43c1-8ff5-8103045d2f00
    Correlation ID: dff39a1f-ffe1-493e-aea3-1536974b777d


    I tried '[Mail.Read]' as a scope but I'm getting an "Invalid Scope parameter".

    My new python script:

    outlook_test.py


    from oauthlib.oauth2 import BackendApplicationClient
    from requests.auth import HTTPBasicAuth
    from requests_oauthlib import OAuth2Session
    auth = HTTPBasicAuth(client_app_id, app_secret)
    client = BackendApplicationClient(client_id=client_app_id)
    oauth = OAuth2Session(client=client)
    token = oauth.fetch_token(token_url=token_url, auth=auth)

    Continue reading...

Compartilhe esta Página