Account

Multi-user handling

A single Account object can hold more than one user being authenticated. You can authenticate different users and the token backend will hold each authentication. When using the library you can use the account.username property to get or set the current user. If username is not provided, the username will be set automatically to the first authentication found in the token backend. Also, whenever you perform a new call to request_token (manually or through a call to account.authenticate), the username will be set to the user performing the authentication.

account.username = 'user1@domain.com'
#  issue some calls to retrieve data using the auth of the user1
account.username = 'user2@domain.com'
#  now every call will use the auth of the user2

This is only possible in version 2.1. Before 2.1 you had to instantiate one Account for each user. Account class represents a specific account you would like to connect

Setting your Account Instance

Connecting to API Account

from O365 import Account

account = Account(credentials=('my_client_id', 'my_client_secret'))

Setting Proxy

# Option 1
account = Account(credentials=('my_client_id', 'my_client_secret'),
                  proxy_server='myserver.com', proxy_port=8080,
                  proxy_username='username', proxy_password='password)

# Option 2
account = Account(credentials=('my_client_id', 'my_client_secret'))
account.connection.set('myserver.com',8080,'username', 'password')

Using Different Resource

from O365 import Account

account = Account(credentials=('my_client_id', 'my_client_secret'), main_resource='shared_mail@example.com')

Setting Scopes

  • You can set a list of scopes that your like to use, a huge list is available on Microsoft Documentation

  • We have built a custom list make this scopes easier

    Short Scope Name

    Description

    Scopes Included

    basic

    Read User Info

    [‘User.Read’]

    mailbox

    Read your mail

    [‘Mail.Read’]

    mailbox_shared

    Read shared mailbox

    [‘Mail.Read.Shared’]

    message_send

    Send from your mailid

    [‘Mail.Send’]

    message_send_shared

    Send using shared mailbox

    [‘Mail.Send.Shared’]

    message_all

    Full Access to your mailbox

    [‘Mail.ReadWrite’, ‘Mail.Send’]

    message_all_shared

    Full Access to shared mailbox

    [‘Mail.ReadWrite.Shared’, ‘Mail.Send.Shared’]

    address_book

    Read your Contacts

    [‘Contacts.Read’]

    address_book_shared

    Read shared contacts

    [‘Contacts.Read.Shared’]

    address_book_all

    Read/Write your Contacts

    [‘Contacts.ReadWrite’]

    address_book_all_shared

    Read/Write your Contacts

    [‘Contacts.ReadWrite.Shared’]

    calendar

    Full Access to your Calendars

    [‘Calendars.ReadWrite’]

    users

    Read info of all users

    [‘User.ReadBasic.All’]

    onedrive

    Access to OneDrive

    [‘Files.ReadWrite.All’]

    sharepoint_dl

    Access to Sharepoint

    [‘Sites.ReadWrite.All’]

# Full permission to your mail
account = Account(credentials=('my_client_id', 'my_client_secret'),
                  scopes=['message_all'])

# Why change every time, add all at a time :)
account = Account(credentials=('my_client_id', 'my_client_secret'),
                  scopes=['message_all', 'message_all_shared', 'address_book_all',
                          'address_book_all_shared',
                          'calendar', 'users', 'onedrive', 'sharepoint_dl'])

Authenticating your Account

account = Account(credentials=('my_client_id', 'my_client_secret'))
account.authenticate()

Warning

The call to authenticate is only required when you haven’t authenticated before. If you already did the token file would have been saved

The authenticate() method forces an authentication flow, which prints out a url

  1. Open the printed url

  2. Give consent(approve) to the application

  3. You will be redirected out outlook home page, copy the resulting url

    Note

    If the url is simply https://outlook.office.com/owa/?realm=blahblah, and nothing else after that, then you are currently on new Outlook look, revert to old look and try the authentication flow again

  4. Paste the resulting URL into the python console.

  5. That’s it, you don’t need this hassle again unless you want to add more scopes than you approved for

Account Class and Modularity

Usually you will only need to work with the Account Class. This is a wrapper around all functionality.

But you can also work only with the pieces you want.

For example, instead of:

from O365 import Account

account = Account(('client_id', 'client_secret'))
message = account.new_message()
# ...
mailbox = account.mailbox()
# ...

You can work only with the required pieces:

from O365 import Connection, MSGraphProtocol
from O365.message import Message
from O365.mailbox import MailBox

protocol = MSGraphProtocol()
scopes = ['...']
con = Connection(('client_id', 'client_secret'), scopes=scopes)

message = Message(con=con, protocol=protocol)
# ...
mailbox = MailBox(con=con, protocol=protocol)
message2 = Message(parent=mailbox)  # message will inherit the connection and protocol from mailbox when using parent.
# ...

It’s also easy to implement a custom Class. Just Inherit from ApiComponent, define the endpoints, and use the connection to make requests. If needed also inherit from Protocol to handle different communications aspects with the API server.

from O365.utils import ApiComponent

class CustomClass(ApiComponent):
    _endpoints = {'my_url_key': '/customendpoint'}

    def __init__(self, *, parent=None, con=None, **kwargs):
        # connection is only needed if you want to communicate with the api provider
        self.con = parent.con if parent else con
        protocol = parent.protocol if parent else kwargs.get('protocol')
        main_resource = parent.main_resource

        super().__init__(protocol=protocol, main_resource=main_resource)
        # ...

    def do_some_stuff(self):

        # self.build_url just merges the protocol service_url with the endpoint passed as a parameter
        # to change the service_url implement your own protocol inheriting from Protocol Class
        url = self.build_url(self._endpoints.get('my_url_key'))

        my_params = {'param1': 'param1'}

        response = self.con.get(url, params=my_params)  # note the use of the connection here.

        # handle response and return to the user...

# the use it as follows:
from O365 import Connection, MSGraphProtocol

protocol = MSGraphProtocol()  # or maybe a user defined protocol
con = Connection(('client_id', 'client_secret'), scopes=protocol.get_scopes_for(['...']))
custom_class = CustomClass(con=con, protocol=protocol)

custom_class.do_some_stuff()