Skip to content

Commit 874b911

Browse files
committed
Improves docstrings and type hinting. Renames method names for APIs. Adds throttling property.
1 parent 45e945f commit 874b911

File tree

15 files changed

+839
-390
lines changed

15 files changed

+839
-390
lines changed

microsoftgraph/calendar.py

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,112 @@
11
from microsoftgraph.decorators import token_required
22
from microsoftgraph.response import Response
3+
from datetime import datetime
34

45

56
class Calendar(object):
6-
def __init__(self, client):
7+
def __init__(self, client) -> None:
8+
"""Working with Outlook Calendar.
9+
10+
https://docs.microsoft.com/en-us/graph/api/resources/calendar?view=graph-rest-1.0
11+
12+
Args:
13+
client (Client): Library Client.
14+
"""
715
self._client = client
816

917
@token_required
10-
def get_me_events(self) -> Response:
11-
"""Get a list of event objects in the user's mailbox. The list contains single instance meetings and
12-
series masters.
18+
def list_events(self) -> Response:
19+
"""Get a list of event objects in the user's mailbox. The list contains single instance meetings and series
20+
masters.
1321
14-
Currently, this operation returns event bodies in only HTML format.
22+
https://docs.microsoft.com/en-us/graph/api/user-list-events?view=graph-rest-1.0&tabs=http
1523
1624
Returns:
17-
A dict.
18-
25+
Response: Microsoft Graph Response.
1926
"""
2027
return self._client._get(self._client.base_url + "me/events")
2128

2229
@token_required
23-
def create_calendar_event(
30+
def create_event(
2431
self,
2532
subject: str,
2633
content: str,
27-
start_datetime: str,
34+
start_datetime: datetime,
2835
start_timezone: str,
29-
end_datetime: str,
36+
end_datetime: datetime,
3037
end_timezone: str,
3138
location: str,
3239
calendar: str = None,
40+
content_type: str = "HTML",
3341
**kwargs,
3442
) -> Response:
35-
"""
36-
Create a new calendar event.
43+
"""Create an event in the user's default calendar or specified calendar.
44+
45+
https://docs.microsoft.com/en-us/graph/api/user-post-events?view=graph-rest-1.0&tabs=http
46+
47+
Additional time zones: https://docs.microsoft.com/en-us/graph/api/resources/datetimetimezone?view=graph-rest-1.0
3748
3849
Args:
39-
subject: subject of event, string
40-
content: content of event, string
41-
start_datetime: in the format of 2017-09-04T11:00:00, dateTimeTimeZone string
42-
start_timezone: in the format of Pacific Standard Time, string
43-
end_datetime: in the format of 2017-09-04T11:00:00, dateTimeTimeZone string
44-
end_timezone: in the format of Pacific Standard Time, string
45-
location: string
46-
attendees: list of dicts of the form:
47-
{"emailAddress": {"address": a['attendees_email'],"name": a['attendees_name']}
48-
calendar:
50+
subject (str): The text of the event's subject line.
51+
content (str): The body of the message associated with the event.
52+
start_datetime (datetime): A single point of time in a combined date and time representation ({date}T{time};
53+
start_timezone (datetime): Represents a time zone, for example, "Pacific Standard Time".
54+
end_datetime (str): A single point of time in a combined date and time representation ({date}T{time}; for
55+
end_timezone (str): Represents a time zone, for example, "Pacific Standard Time".
56+
location (str): The location of the event.
57+
calendar (str, optional): Calendar ID. Defaults to None.
58+
content_type (str, optional): It can be in HTML or text format. Defaults to HTML.
4959
5060
Returns:
51-
A dict.
52-
61+
Response: Microsoft Graph Response.
5362
"""
54-
# TODO: attendees
55-
# attendees_list = [{
56-
# "emailAddress": {
57-
# "address": a['attendees_email'],
58-
# "name": a['attendees_name']
59-
# },
60-
# "type": a['attendees_type']
61-
# } for a in kwargs['attendees']]
63+
if isinstance(start_datetime, datetime):
64+
start_datetime = start_datetime.strftime("%Y-%m-%dT%H:%M:%S.%f")
65+
if isinstance(end_datetime, datetime):
66+
start_datetime = start_datetime.strftime("%Y-%m-%dT%H:%M:%S.%f")
67+
6268
body = {
6369
"subject": subject,
64-
"body": {"contentType": "HTML", "content": content},
65-
"start": {"dateTime": start_datetime, "timeZone": start_timezone},
66-
"end": {"dateTime": end_datetime, "timeZone": end_timezone},
70+
"body": {
71+
"contentType": content_type,
72+
"content": content,
73+
},
74+
"start": {
75+
"dateTime": start_datetime,
76+
"timeZone": start_timezone,
77+
},
78+
"end": {
79+
"dateTime": end_datetime,
80+
"timeZone": end_timezone,
81+
},
6782
"location": {"displayName": location},
68-
# "attendees": attendees_list
6983
}
7084
url = "me/calendars/{}/events".format(calendar) if calendar is not None else "me/events"
7185
return self._client._post(self._client.base_url + url, json=body)
7286

7387
@token_required
74-
def create_calendar(self, name: str) -> Response:
75-
"""Create an event in the user's default calendar or specified calendar.
76-
77-
You can specify the time zone for each of the start and end times of the event as part of these values,
78-
as the start and end properties are of dateTimeTimeZone type.
88+
def list_calendars(self) -> Response:
89+
"""Get all the user's calendars (/calendars navigation property), get the calendars from the default calendar
90+
group or from a specific calendar group.
7991
80-
When an event is sent, the server sends invitations to all the attendees.
81-
82-
Args:
83-
name:
92+
https://docs.microsoft.com/en-us/graph/api/user-list-calendars?view=graph-rest-1.0&tabs=http
8493
8594
Returns:
86-
A dict.
87-
95+
Response: Microsoft Graph Response.
8896
"""
89-
body = {"name": "{}".format(name)}
90-
return self._client._post(self._client.base_url + "me/calendars", json=body)
97+
return self._client._get(self._client.base_url + "me/calendars")
9198

9299
@token_required
93-
def get_me_calendars(self) -> Response:
94-
"""Get all the user's calendars (/calendars navigation property), get the calendars from the default
95-
calendar group or from a specific calendar group.
100+
def create_calendar(self, name: str) -> Response:
101+
"""Create a new calendar for a user.
96102
97-
Returns:
98-
A dict.
103+
https://docs.microsoft.com/en-us/graph/api/user-post-calendars?view=graph-rest-1.0&tabs=http
104+
105+
Args:
106+
name (str): The calendar name.
99107
108+
Returns:
109+
Response: Microsoft Graph Response.
100110
"""
101-
return self._client._get(self._client.base_url + "me/calendars")
111+
body = {"name": "{}".format(name)}
112+
return self._client._post(self._client.base_url + "me/calendars", json=body)

microsoftgraph/client.py

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
from microsoftgraph import exceptions
66
from microsoftgraph.calendar import Calendar
7-
from microsoftgraph.excel import Excel
7+
from microsoftgraph.contacts import Contacts
8+
from microsoftgraph.files import Files
89
from microsoftgraph.mail import Mail
9-
from microsoftgraph.onedrive import Onedrive
10-
from microsoftgraph.onenote import Onenote
11-
from microsoftgraph.outlook import Outlook
10+
from microsoftgraph.notes import Notes
1211
from microsoftgraph.response import Response
13-
from microsoftgraph.users import User
12+
from microsoftgraph.users import Users
1413
from microsoftgraph.webhooks import Webhooks
14+
from microsoftgraph.workbooks import Workbooks
1515

1616

1717
class Client(object):
@@ -21,8 +21,25 @@ class Client(object):
2121
RESOURCE = "https://graph.microsoft.com/"
2222

2323
def __init__(
24-
self, client_id: str, client_secret: str, api_version: str = "v1.0", account_type: str = "common"
24+
self,
25+
client_id: str,
26+
client_secret: str,
27+
api_version: str = "v1.0",
28+
account_type: str = "common",
29+
requests_hooks: dict = None,
2530
) -> None:
31+
"""Instantiates library.
32+
33+
Args:
34+
client_id (str): Application client id.
35+
client_secret (str): Application client secret.
36+
api_version (str, optional): v1.0 or beta. Defaults to "v1.0".
37+
account_type (str, optional): common, organizations or consumers. Defaults to "common".
38+
requests_hooks (dict, optional): Requests library event hooks. Defaults to None.
39+
40+
Raises:
41+
Exception: requests_hooks is not a dict.
42+
"""
2643
self.client_id = client_id
2744
self.client_secret = client_secret
2845
self.api_version = api_version
@@ -32,13 +49,19 @@ def __init__(
3249
self.token = None
3350

3451
self.calendar = Calendar(self)
35-
self.excel = Excel(self)
52+
self.contacts = Contacts(self)
53+
self.files = Files(self)
3654
self.mail = Mail(self)
37-
self.onedrive = Onedrive(self)
38-
self.onenote = Onenote(self)
39-
self.outlook = Outlook(self)
40-
self.user = User(self)
55+
self.notes = Notes(self)
56+
self.users = Users(self)
4157
self.webhooks = Webhooks(self)
58+
self.workbooks = Workbooks(self)
59+
60+
if requests_hooks and not isinstance(requests_hooks, dict):
61+
raise Exception(
62+
'requests_hooks must be a dict. e.g. {"response": func}. http://docs.python-requests.org/en/master/user/advanced/#event-hooks'
63+
)
64+
self.requests_hooks = requests_hooks
4265

4366
def authorization_url(self, redirect_uri: str, scope: list, state: str = None) -> str:
4467
"""Generates an Authorization URL.
@@ -163,6 +186,8 @@ def _request(self, method, url, headers=None, **kwargs):
163186
_headers["Authorization"] = "Bearer " + self.token["access_token"]
164187
if headers:
165188
_headers.update(headers)
189+
if self.requests_hooks:
190+
kwargs.update({"hooks": self.requests_hooks})
166191
if "files" not in kwargs:
167192
# If you use the 'files' keyword, the library will set the Content-Type to multipart/form-data
168193
# and will generate a boundary.

microsoftgraph/contacts.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from microsoftgraph.decorators import token_required
2+
from microsoftgraph.response import Response
3+
4+
5+
class Contacts(object):
6+
def __init__(self, client) -> None:
7+
"""Working with Outlook Contacts.
8+
9+
https://docs.microsoft.com/en-us/graph/api/resources/contact?view=graph-rest-1.0
10+
11+
Args:
12+
client (Client): Library Client.
13+
"""
14+
self._client = client
15+
16+
@token_required
17+
def get_contact(self, contact_id: str, params: dict = None) -> Response:
18+
"""Retrieve the properties and relationships of a contact object.
19+
20+
https://docs.microsoft.com/en-us/graph/api/contact-get?view=graph-rest-1.0&tabs=http
21+
22+
Args:
23+
contact_id (str): The contact's unique identifier.
24+
params (dict, optional): Query. Defaults to None.
25+
26+
Returns:
27+
Response: Microsoft Graph Response.
28+
"""
29+
url = "{0}me/contacts/{1}".format(self._client.base_url, contact_id)
30+
return self._client._get(url, params=params)
31+
32+
@token_required
33+
def list_contacts(self, params: dict = None) -> Response:
34+
"""Get a contact collection from the default contacts folder of the signed-in user.
35+
36+
https://docs.microsoft.com/en-us/graph/api/user-list-contacts?view=graph-rest-1.0&tabs=http
37+
38+
Args:
39+
params (dict, optional): Query. Defaults to None.
40+
41+
Returns:
42+
Response: Microsoft Graph Response.
43+
"""
44+
url = "{0}me/contacts".format(self._client.base_url)
45+
return self._client._get(url, params=params)
46+
47+
@token_required
48+
def create_contact(self, **kwargs) -> Response:
49+
"""Add a contact to the root Contacts folder.
50+
51+
https://docs.microsoft.com/en-us/graph/api/user-post-contacts?view=graph-rest-1.0&tabs=http
52+
53+
Returns:
54+
Response: Microsoft Graph Response.
55+
"""
56+
url = "{0}me/contacts".format(self._client.base_url)
57+
return self._client._post(url, **kwargs)
58+
59+
@token_required
60+
def create_contact_in_folder(self, folder_id: str, **kwargs) -> Response:
61+
"""Add a contact to another contact folder.
62+
63+
https://docs.microsoft.com/en-us/graph/api/user-post-contacts?view=graph-rest-1.0&tabs=http
64+
65+
Args:
66+
folder_id (str): Unique identifier of the contact folder.
67+
68+
Returns:
69+
Response: Microsoft Graph Response.
70+
"""
71+
url = "{0}me/contactFolders/{1}/contacts".format(self._client.base_url, folder_id)
72+
return self._client._post(url, **kwargs)
73+
74+
@token_required
75+
def list_contact_folders(self, params: dict = None) -> Response:
76+
"""Get the contact folder collection in the default Contacts folder of the signed-in user.
77+
78+
https://docs.microsoft.com/en-us/graph/api/user-list-contactfolders?view=graph-rest-1.0&tabs=http
79+
80+
Args:
81+
params (dict, optional): Query. Defaults to None.
82+
83+
Returns:
84+
Response: Microsoft Graph Response.
85+
"""
86+
url = "{0}me/contactFolders".format(self._client.base_url)
87+
return self._client._get(url, params=params)
88+
89+
@token_required
90+
def create_contact_folder(self, **kwargs) -> Response:
91+
"""Create a new contactFolder under the user's default contacts folder.
92+
93+
https://docs.microsoft.com/en-us/graph/api/user-post-contactfolders?view=graph-rest-1.0&tabs=http
94+
95+
Returns:
96+
Response: Microsoft Graph Response.
97+
"""
98+
url = "{0}me/contactFolders".format(self._client.base_url)
99+
return self._client._post(url, **kwargs)

0 commit comments

Comments
 (0)