1
+ from typing import Type , Tuple , Optional , Callable
1
2
from .connection import Connection , Protocol , MSGraphProtocol , MSOffice365Protocol
2
3
from .utils import ME_RESOURCE , consent
3
4
4
5
5
6
class Account :
7
+ connection_constructor : Type = Connection
6
8
7
- connection_constructor = Connection
9
+ def __init__ (self , credentials : Tuple [str , str ], * ,
10
+ protocol : Optional [Protocol ] = None ,
11
+ main_resource : Optional [str ] = None , ** kwargs ):
12
+ """ Creates an object which is used to access resources related to the specified credentials.
8
13
9
- def __init__ (self , credentials , * , protocol = None , main_resource = None , ** kwargs ):
10
- """ Creates an object which is used to access resources related to the
11
- specified credentials
12
-
13
- :param tuple credentials: a tuple containing the client_id
14
- and client_secret
15
- :param Protocol protocol: the protocol to be used in this account
16
- :param str main_resource: the resource to be used by this account
17
- ('me' or 'users', etc.)
14
+ :param credentials: a tuple containing the client_id and client_secret
15
+ :param protocol: the protocol to be used in this account
16
+ :param main_resource: the resource to be used by this account ('me' or 'users', etc.)
18
17
:param kwargs: any extra args to be passed to the Connection instance
19
18
:raises ValueError: if an invalid protocol is passed
20
19
"""
21
20
22
21
protocol = protocol or MSGraphProtocol # Defaults to Graph protocol
23
- self . protocol = protocol ( default_resource = main_resource ,
24
- ** kwargs ) if isinstance ( protocol ,
25
- type ) else protocol
22
+ if isinstance ( protocol , type ):
23
+ protocol = protocol ( default_resource = main_resource , ** kwargs )
24
+ self . protocol : Protocol = protocol
26
25
27
26
if not isinstance (self .protocol , Protocol ):
28
27
raise ValueError ("'protocol' must be a subclass of Protocol" )
@@ -48,7 +47,8 @@ def __init__(self, credentials, *, protocol=None, main_resource=None, **kwargs):
48
47
main_resource = ''
49
48
50
49
elif auth_flow_type == 'password' :
51
- kwargs ['scopes' ] = self .protocol .get_scopes_for (scopes ) if scopes else [self .protocol .prefix_scope ('.default' )]
50
+ kwargs ['scopes' ] = self .protocol .get_scopes_for (scopes ) if scopes else [
51
+ self .protocol .prefix_scope ('.default' )]
52
52
53
53
# set main_resource to blank when it's the 'ME' resource
54
54
if self .protocol .default_resource == ME_RESOURCE :
@@ -60,7 +60,7 @@ def __init__(self, credentials, *, protocol=None, main_resource=None, **kwargs):
60
60
'"public"' )
61
61
62
62
self .con = self .connection_constructor (credentials , ** kwargs )
63
- self .main_resource = main_resource or self .protocol .default_resource
63
+ self .main_resource : str = main_resource or self .protocol .default_resource
64
64
65
65
def __repr__ (self ):
66
66
if self .con .auth :
@@ -69,34 +69,35 @@ def __repr__(self):
69
69
return 'Unidentified Account'
70
70
71
71
@property
72
- def is_authenticated (self ):
72
+ def is_authenticated (self ) -> bool :
73
73
"""
74
- Checks whether the library has the authentication and that is not expired
75
- :return: True if authenticated, False otherwise
74
+ Checks whether the library has the authentication and that is not expired.
75
+ Return True if authenticated, False otherwise.
76
76
"""
77
77
token = self .con .token_backend .token
78
78
if not token :
79
79
token = self .con .token_backend .get_token ()
80
80
81
81
return token is not None and not token .is_expired
82
82
83
- def authenticate (self , * , scopes = None , handle_consent = consent .consent_input_token , ** kwargs ):
83
+ def authenticate (self , * , scopes : Optional [list ] = None ,
84
+ handle_consent : Callable = consent .consent_input_token , ** kwargs ) -> bool :
84
85
""" Performs the oauth authentication flow using the console resulting in a stored token.
85
- It uses the credentials passed on instantiation
86
+ It uses the credentials passed on instantiation.
87
+ Returns True if succeded otherwise False.
86
88
87
- :param list[str] or None scopes: list of protocol user scopes to be converted
89
+ :param scopes: list of protocol user scopes to be converted
88
90
by the protocol or scope helpers
89
91
:param handle_consent: a function to handle the consent process by default just input for the token url
90
92
:param kwargs: other configurations to be passed to the
91
93
Connection.get_authorization_url and Connection.request_token methods
92
- :return: Success / Failure
93
- :rtype: bool
94
94
"""
95
95
96
96
if self .con .auth_flow_type in ('authorization' , 'public' ):
97
97
if scopes is not None :
98
98
if self .con .scopes is not None :
99
- raise RuntimeError ('The scopes must be set either at the Account instantiation or on the account.authenticate method.' )
99
+ raise RuntimeError ('The scopes must be set either at the Account '
100
+ 'instantiation or on the account.authenticate method.' )
100
101
self .con .scopes = self .protocol .get_scopes_for (scopes )
101
102
else :
102
103
if self .con .scopes is None :
@@ -140,7 +141,7 @@ def connection(self):
140
141
"""
141
142
return self .con
142
143
143
- def new_message (self , resource = None ):
144
+ def new_message (self , resource : Optional [ str ] = None ):
144
145
""" Creates a new message to be sent or stored
145
146
146
147
:param str resource: Custom resource to be used in this message
@@ -151,24 +152,24 @@ def new_message(self, resource=None):
151
152
from .message import Message
152
153
return Message (parent = self , main_resource = resource , is_draft = True )
153
154
154
- def mailbox (self , resource = None ):
155
+ def mailbox (self , resource : Optional [ str ] = None ):
155
156
""" Get an instance to the mailbox for the specified account resource
156
157
157
- :param str resource: Custom resource to be used in this mailbox
158
+ :param resource: Custom resource to be used in this mailbox
158
159
(Defaults to parent main_resource)
159
160
:return: a representation of account mailbox
160
161
:rtype: O365.mailbox.MailBox
161
162
"""
162
163
from .mailbox import MailBox
163
164
return MailBox (parent = self , main_resource = resource , name = 'MailBox' )
164
165
165
- def address_book (self , * , resource = None , address_book = 'personal' ):
166
+ def address_book (self , * , resource : Optional [ str ] = None , address_book : str = 'personal' ):
166
167
""" Get an instance to the specified address book for the
167
168
specified account resource
168
169
169
- :param str resource: Custom resource to be used in this address book
170
+ :param resource: Custom resource to be used in this address book
170
171
(Defaults to parent main_resource)
171
- :param str address_book: Choose from 'Personal' or 'Directory'
172
+ :param address_book: Choose from 'Personal' or 'Directory'
172
173
:return: a representation of the specified address book
173
174
:rtype: AddressBook or GlobalAddressList
174
175
:raises RuntimeError: if invalid address_book is specified
@@ -188,29 +189,29 @@ def address_book(self, *, resource=None, address_book='personal'):
188
189
'address_book must be either "Personal" '
189
190
'(resource address book) or "Directory" (Active Directory)' )
190
191
191
- def directory (self , resource = None ):
192
+ def directory (self , resource : Optional [ str ] = None ):
192
193
""" Returns the active directory instance"""
193
194
from .directory import Directory , USERS_RESOURCE
194
195
195
196
return Directory (parent = self , main_resource = resource or USERS_RESOURCE )
196
197
197
- def schedule (self , * , resource = None ):
198
+ def schedule (self , * , resource : Optional [ str ] = None ):
198
199
""" Get an instance to work with calendar events for the
199
200
specified account resource
200
201
201
- :param str resource: Custom resource to be used in this schedule object
202
+ :param resource: Custom resource to be used in this schedule object
202
203
(Defaults to parent main_resource)
203
204
:return: a representation of calendar events
204
205
:rtype: Schedule
205
206
"""
206
207
from .calendar import Schedule
207
208
return Schedule (parent = self , main_resource = resource )
208
209
209
- def storage (self , * , resource = None ):
210
+ def storage (self , * , resource : Optional [ str ] = None ):
210
211
""" Get an instance to handle file storage (OneDrive / Sharepoint)
211
212
for the specified account resource
212
213
213
- :param str resource: Custom resource to be used in this drive object
214
+ :param resource: Custom resource to be used in this drive object
214
215
(Defaults to parent main_resource)
215
216
:return: a representation of OneDrive File Storage
216
217
:rtype: Storage
@@ -223,11 +224,11 @@ def storage(self, *, resource=None):
223
224
from .drive import Storage
224
225
return Storage (parent = self , main_resource = resource )
225
226
226
- def sharepoint (self , * , resource = '' ):
227
+ def sharepoint (self , * , resource : str = '' ):
227
228
""" Get an instance to read information from Sharepoint sites for the
228
229
specified account resource
229
230
230
- :param str resource: Custom resource to be used in this sharepoint
231
+ :param resource: Custom resource to be used in this sharepoint
231
232
object (Defaults to parent main_resource)
232
233
:return: a representation of Sharepoint Sites
233
234
:rtype: Sharepoint
@@ -242,7 +243,7 @@ def sharepoint(self, *, resource=''):
242
243
from .sharepoint import Sharepoint
243
244
return Sharepoint (parent = self , main_resource = resource )
244
245
245
- def planner (self , * , resource = '' ):
246
+ def planner (self , * , resource : str = '' ):
246
247
""" Get an instance to read information from Microsoft planner """
247
248
248
249
if not isinstance (self .protocol , MSGraphProtocol ):
@@ -253,7 +254,7 @@ def planner(self, *, resource=''):
253
254
from .planner import Planner
254
255
return Planner (parent = self , main_resource = resource )
255
256
256
- def tasks (self , * , resource = '' ):
257
+ def tasks (self , * , resource : str = '' ):
257
258
""" Get an instance to read information from Microsoft ToDo """
258
259
259
260
if isinstance (self .protocol , MSOffice365Protocol ):
@@ -262,8 +263,8 @@ def tasks(self, *, resource=''):
262
263
from .tasks_graph import ToDo as ToDo
263
264
264
265
return ToDo (parent = self , main_resource = resource )
265
-
266
- def teams (self , * , resource = '' ):
266
+
267
+ def teams (self , * , resource : str = '' ):
267
268
""" Get an instance to read information from Microsoft Teams """
268
269
269
270
if not isinstance (self .protocol , MSGraphProtocol ):
@@ -273,13 +274,13 @@ def teams(self, *, resource=''):
273
274
from .teams import Teams
274
275
return Teams (parent = self , main_resource = resource )
275
276
276
- def outlook_categories (self , * , resource = '' ):
277
+ def outlook_categories (self , * , resource : str = '' ):
277
278
""" Returns a Categories object to handle the available Outlook Categories """
278
279
from .category import Categories
279
280
280
281
return Categories (parent = self , main_resource = resource )
281
282
282
- def groups (self , * , resource = '' ):
283
+ def groups (self , * , resource : str = '' ):
283
284
""" Get an instance to read information from Microsoft Groups """
284
285
285
286
if not isinstance (self .protocol , MSGraphProtocol ):
0 commit comments