Skip to content

Commit 5487d66

Browse files
Graph client : improvements and error handling for batch request
1 parent 8eca1ff commit 5487d66

15 files changed

+69
-27
lines changed

examples/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
from tests import settings
44

55

6+
test_user_principal_name = settings.get('users', 'test_user1')
7+
8+
69
def acquire_token_by_client_credentials():
710
authority_url = 'https://login.microsoftonline.com/{0}'.format(settings.get('default', 'tenant'))
811
app = msal.ConfidentialClientApplication(

examples/directory/delete_groups.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
client = GraphClient(acquire_token_by_username_password)
55

6-
groups = client.groups.get().top(500).execute_query()
6+
groups = client.groups.get().top(50).execute_query()
77
deletedCount = 0
88
groups_count = len(groups)
99
while len(groups) > 0:

examples/onedrive/upload_file.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import os
22

3-
from examples import acquire_token_by_client_credentials
3+
from examples import acquire_token_by_client_credentials, test_user_principal_name
44
from office365.graph_client import GraphClient
5-
from tests import settings
5+
66

77
client = GraphClient(acquire_token_by_client_credentials)
8-
user_name = settings.get('first_account_name')
9-
target_drive = client.users[user_name].drive
8+
9+
target_drive = client.users[test_user_principal_name].drive
1010

1111
local_path = "../../tests/data/SharePoint User Guide.docx"
1212
with open(local_path, 'rb') as f:

examples/outlook/send_message.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@
2020
},
2121
"SaveToSentItems": "false"
2222
}
23-
target_user = client.users[test_user_principal_name]
24-
target_user.send_mail(message_json).execute_query()
23+
client.users[test_user_principal_name].send_mail(message_json).execute_query()
24+

examples/sharepoint/lists_and_items/create_listitems_batch.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials)
55
list_tasks = ctx.web.lists.get_by_title("Tasks")
66

7-
task_items = [list_tasks.add_item({"Title": create_unique_name("Task")}) for idx in range(0, 25)]
7+
8+
task_items = [list_tasks.add_item({"Title": create_unique_name("Task")}) for idx in range(0, 20)]
89
ctx.execute_batch()
910
print(f" {len(task_items)} task items created")

examples/sharepoint/lists_and_items/data_generator.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@
99

1010

1111
def ensure_list(web, list_properties):
12-
lists = web.lists.filter("Title eq '{0}'".format(list_properties.Title))
13-
ctx.load(lists)
14-
ctx.execute_query()
12+
lists = web.lists.filter("Title eq '{0}'".format(list_properties.Title)).get().execute_query()
1513
if len(lists) == 1:
1614
return lists[0]
17-
target_list = web.lists.add(list_properties)
18-
ctx.execute_query()
19-
return target_list
15+
else:
16+
return web.lists.add(list_properties).execute_query()
2017

2118

2219
def generate_documents(context):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from random import randint
2+
3+
from office365.sharepoint.client_context import ClientContext
4+
from tests import test_team_site_url, test_client_credentials
5+
6+
ctx = ClientContext(test_team_site_url).with_credentials(test_client_credentials)
7+
8+
list_tasks = ctx.web.lists.get_by_title("Tasks")
9+
items = list_tasks.items.get().top(1).execute_query() # 1. Load existing list items
10+
if len(items) > 0:
11+
item_to_update = items[0]
12+
task_prefix = str(randint(0, 10000))
13+
item_to_update.set_property("Title", f"Task {task_prefix}")
14+
item_to_update.update().execute_query()
15+
16+

examples/sharepoint/lists_and_items/update_items_batch.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,5 @@
1111
# 2. Update list items via Batch mode
1212
for task_id, item in enumerate(items):
1313
task_prefix = str(randint(0, 10000))
14-
item.set_property("Title", f"Task {task_prefix}")
15-
item.update()
14+
item.set_property("Title", f"Task {task_prefix}").update()
1615
ctx.execute_batch()

office365/graph_client.py

+8
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ def __init__(self, acquire_token_callback):
4545
self._authority_host_url = "https://login.microsoftonline.com"
4646
self._acquire_token_callback = acquire_token_callback
4747

48+
def build_single_request(self, query):
49+
"""
50+
:type: office365.runtime.queries.client_query.ClientQuery
51+
"""
52+
request = super(GraphClient, self).build_single_request(query)
53+
self._build_specific_query(request)
54+
return request
55+
4856
def execute_batch(self):
4957
"""Construct and submit a batch request"""
5058
batch_request = ODataV4BatchRequest(self)

office365/runtime/odata/odata_v4_batch_request.py

+19-7
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55

66

77
class ODataV4BatchRequest(ClientRequest):
8-
"""
9-
10-
"""
8+
""" JSON batch request """
119

1210
def __init__(self, context):
1311
super().__init__(context)
@@ -33,25 +31,39 @@ def process_response(self, response, query):
3331
"""
3432
json = response.json()
3533
for resp in json["responses"]:
34+
self._validate_response(resp)
3635
sub_qry = query.get(int(resp["id"]))
3736
self.context.pending_request().map_json(resp["body"], sub_qry.return_type)
3837

38+
def _validate_response(self, json):
39+
if int(json['status']) >= 400:
40+
raise ValueError(json['body'])
41+
3942
def _prepare_payload(self, query):
4043
"""Serializes a batch request body.
4144
42-
:type query: office365.runtime.queries.client_query.BatchQuery
45+
:type query: office365.runtime.queries.batch_query.BatchQuery
4346
"""
4447

4548
requests_json = []
4649
for qry in query.queries:
50+
request_id = str(len(requests_json))
4751
request = qry.build_request()
48-
requests_json.append(self._serialize_request(request, len(requests_json)))
52+
requests_json.append(self._normalize_request(request, request_id))
4953

5054
return {"requests": requests_json}
5155

52-
def _serialize_request(self, request, request_no):
56+
def _normalize_request(self, request, _id, depends_on=None):
57+
"""
58+
59+
:type request: RequestOptions
60+
:type _id: str
61+
:type depends_on: list[str] or None
62+
"""
5363
allowed_props = ["id", "method", "headers", "url", "body"]
5464
json = dict((k, v) for k, v in vars(request).items() if v is not None and k in allowed_props)
55-
json["id"] = str(request_no)
65+
json["id"] = _id
66+
if depends_on is not None:
67+
json["dependsOn"] = depends_on
5668
json["url"] = json["url"].replace(self.context.service_root_url(), "/")
5769
return json

office365/runtime/queries/batch_query.py

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ def change_sets(self):
5252

5353
@property
5454
def queries(self):
55+
"""
56+
:rtype: list[ClientQuery]
57+
"""
5558
return self._queries
5659

5760
@property

office365/sharepoint/client_context.py

+3
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ def _prepare_batch_request(request):
112112
batch_request.execute_query(batch_qry)
113113

114114
def build_single_request(self, query):
115+
"""
116+
:type: office365.runtime.queries.client_query.ClientQuery
117+
"""
115118
request = super(ClientContext, self).build_single_request(query)
116119
self._build_modification_query(request)
117120
return request

office365/sharepoint/contenttypes/content_type_collection.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
class ContentTypeCollection(BaseEntityCollection):
99
"""Content Type resource collection"""
1010

11-
def __init__(self, context, resource_path=None):
12-
super(ContentTypeCollection, self).__init__(context, ContentType, resource_path)
11+
def __init__(self, context, resource_path=None, parent=None):
12+
super(ContentTypeCollection, self).__init__(context, ContentType, resource_path, parent)
1313

1414
def get_by_id(self, contentTypeId):
1515
"""

office365/sharepoint/lists/list.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ def content_types(self):
337337
"""Gets the content types that are associated with the list."""
338338
return self.properties.get('ContentTypes',
339339
ContentTypeCollection(self.context,
340-
ResourcePath("ContentTypes", self.resource_path)))
340+
ResourcePath("ContentTypes", self.resource_path), self))
341341

342342
@property
343343
def user_custom_actions(self):

office365/sharepoint/webs/web.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ def content_types(self):
709709
"""Gets the collection of content types for the Web site."""
710710
return self.properties.get('ContentTypes',
711711
ContentTypeCollection(self.context,
712-
ResourcePath("ContentTypes", self.resource_path)))
712+
ResourcePath("ContentTypes", self.resource_path), self))
713713

714714
@property
715715
def role_definitions(self):

0 commit comments

Comments
 (0)