Skip to content

Commit 043e66d

Browse files
committed
Bug fixes (#28), introduced a simplified way of initializing a client, improvements
1 parent 4b32bf0 commit 043e66d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+607
-421
lines changed

examples/sharepoint/file_operations.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import os
22

3+
from office365.runtime.auth.UserCredential import UserCredential
34
from settings import settings
45

5-
from office365.runtime.auth.authentication_context import AuthenticationContext
66
from office365.sharepoint.caml_query import CamlQuery
77
from office365.sharepoint.client_context import ClientContext
88
from office365.sharepoint.file import File
@@ -41,8 +41,7 @@ def read_folder_and_files(context, list_title):
4141

4242

4343
def upload_file(context):
44-
45-
path = "../tests/data/SharePoint User Guide.docx"
44+
path = "../../tests/data/SharePoint User Guide.docx"
4645
with open(path, 'rb') as content_file:
4746
file_content = content_file.read()
4847

@@ -58,25 +57,25 @@ def upload_file(context):
5857

5958

6059
def download_file(context):
61-
response = File.open_binary(context, "/Shared Documents/SharePoint User Guide.docx")
62-
with open("./data/SharePoint User Guide.docx", "wb") as local_file:
60+
path = "../../tests/data/SharePoint User Guide.docx"
61+
response = File.open_binary(context, "/teams/DemoSite/Shared Documents/SharePoint User Guide.docx")
62+
response.raise_for_status()
63+
with open(path, "wb") as local_file:
6364
local_file.write(response.content)
6465

6566

6667
if __name__ == '__main__':
6768
site_url = 'https://mediadev8.sharepoint.com/teams/DemoSite/'
6869

69-
ctx_auth = AuthenticationContext(url=site_url)
70-
if ctx_auth.acquire_token_for_user(username=settings['user_credentials']['username'],
71-
password=settings['user_credentials']['password']):
72-
# if ctx_auth.acquire_token_for_app(client_id=settings['client_credentials']['client_id'],
73-
# client_secret=settings['client_credentials']['client_secret']):
74-
ctx = ClientContext(site_url, ctx_auth)
75-
# get a source file located in library 'Shared Documents'
76-
source_file = ctx.web.get_file_by_server_relative_url("/teams/DemoSite/Shared Documents/Guide.docx")
77-
# move a file into sub folder called 'Archive'
78-
source_file.moveto("/teams/DemoSite/Shared Documents/Archive/Guide.docx", 1)
79-
# execute a query
80-
ctx.execute_query()
81-
else:
82-
print(ctx_auth.get_last_error())
70+
ctx = ClientContext.connect_with_credentials(site_url, UserCredential(settings['user_credentials']['username'],
71+
settings['user_credentials']['password']))
72+
73+
# upload_file(ctx)
74+
download_file(ctx)
75+
76+
# get a source file located in library 'Shared Documents'
77+
# source_file = ctx.web.get_file_by_server_relative_url("/teams/DemoSite/Shared Documents/Guide.docx")
78+
# move a file into sub folder called 'Archive'
79+
# source_file.moveto("/teams/DemoSite/Shared Documents/Archive/Guide.docx", 1)
80+
# execute a query
81+
# ctx.execute_query()

office365/directory/directoryObjectCollection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def __getitem__(self, key):
1414

1515
def getByIds(self, ids):
1616
"""Returns the directory objects specified in a list of IDs."""
17-
qry = ServiceOperationQuery(self, "getByIds")
1817
result = ClientResult(None)
19-
self.context.add_query(qry, result)
18+
qry = ServiceOperationQuery(self, "getByIds", None, None, None, result)
19+
self.context.add_query(qry)
2020
return result

office365/directory/groupCollection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def add(self, group_properties):
1414
Office 365 group (unified group)
1515
Security group"""
1616
grp = Group(self.context)
17-
qry = CreateEntityQuery(self, group_properties)
18-
self.context.add_query(qry, grp)
1917
self.add_child(grp)
18+
qry = CreateEntityQuery(self, group_properties, grp)
19+
self.context.add_query(qry)
2020
return grp

office365/directory/userCollection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def __init__(self, context, resource_path=None):
1212
def add(self, user_properties):
1313
"""Create a new user."""
1414
usr = User(self.context)
15-
qry = CreateEntityQuery(self, user_properties)
16-
self.context.add_query(qry, usr)
15+
qry = CreateEntityQuery(self, user_properties, usr)
16+
self.context.add_query(qry)
1717
self.add_child(usr)
1818
return usr

office365/graphClient.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import adal
22
from office365.directory.directoryObjectCollection import DirectoryObjectCollection
3+
from office365.onedrive.driveItem import DriveItem
34
from office365.onedrive.siteCollection import SiteCollection
45
from office365.runtime.client_query import UpdateEntityQuery, DeleteEntityQuery, ServiceOperationQuery
6+
from office365.runtime.client_result import ClientResult
57
from office365.runtime.client_runtime_context import ClientRuntimeContext
8+
from office365.runtime.odata.odata_request import ODataRequest
69
from office365.runtime.odata.v4_json_format import V4JsonFormat
710
from office365.runtime.resource_path import ResourcePath
811
from office365.runtime.http.http_method import HttpMethod
@@ -12,28 +15,31 @@
1215
from office365.directory.userCollection import UserCollection
1316
from office365.onedrive.driveCollection import DriveCollection
1417
from office365.onedrive.sharedDriveItemCollection import SharedDriveItemCollection
18+
from office365.runtime.resource_path_url import ResourcePathUrl
1519

1620

1721
class DownloadContentQuery(ServiceOperationQuery):
1822
def __init__(self, entity_type, format_name=None):
23+
return_type = ClientResult(None)
1924
action_name = "content"
2025
if format_name is not None:
2126
action_name = action_name + r"?format={0}".format(format_name)
22-
super(DownloadContentQuery, self).__init__(entity_type, action_name, None, None)
27+
super(DownloadContentQuery, self).__init__(entity_type, action_name, None, None, None, return_type)
2328

2429

2530
class ReplaceMethodQuery(ServiceOperationQuery):
2631
pass
2732

2833

2934
class UploadContentQuery(ServiceOperationQuery):
30-
def __init__(self, entity_type, content=None):
31-
super(UploadContentQuery, self).__init__(entity_type, "content", None, content)
35+
def __init__(self, parent_entity, name, content):
36+
return_type = DriveItem(parent_entity.context, ResourcePathUrl(name, parent_entity.resourcePath))
37+
super(UploadContentQuery, self).__init__(return_type, "content", None, content, None, return_type)
3238

3339

3440
class SearchQuery(ServiceOperationQuery):
35-
def __init__(self, entity_type, query_text):
36-
super(SearchQuery, self).__init__(entity_type, "search", {"q": query_text}, None)
41+
def __init__(self, entity_type, query_text, return_type):
42+
super(SearchQuery, self).__init__(entity_type, "search", {"q": query_text}, None, None, return_type)
3743

3844

3945
class GraphClient(ClientRuntimeContext):
@@ -42,15 +48,15 @@ class GraphClient(ClientRuntimeContext):
4248
def __init__(self, tenant, acquire_token_callback):
4349
self.__service_root_url = "https://graph.microsoft.com/v1.0/"
4450
super(GraphClient, self).__init__(self.__service_root_url, None)
45-
self.json_format = V4JsonFormat("minimal")
51+
self._pending_request = ODataRequest(self, V4JsonFormat("minimal"))
52+
self._pending_request.beforeExecute += self._build_specific_query
4653
self._resource = "https://graph.microsoft.com"
4754
self._authority_host_url = "https://login.microsoftonline.com"
4855
self._tenant = tenant
4956
self._acquire_token_callback = acquire_token_callback
5057

51-
def execute_query(self):
52-
self.pending_request.before_execute_request(self._build_specific_query)
53-
super(GraphClient, self).execute_query()
58+
def get_pending_request(self):
59+
return self._pending_request
5460

5561
@staticmethod
5662
def _build_specific_query(request, query):

office365/onedrive/driveItem.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from office365.runtime.resource_path import ResourcePath
77
from office365.onedrive.baseItem import BaseItem
88
from office365.onedrive.listItem import ListItem
9-
from office365.runtime.resource_path_url import ResourcePathUrl
9+
1010

1111

1212
class DriveItem(BaseItem):
@@ -16,34 +16,34 @@ class DriveItem(BaseItem):
1616
def create_upload_session(self, item):
1717
"""Creates a temporary storage location where the bytes of the file will be saved until the complete file is
1818
uploaded. """
19+
result = ClientResult(UploadSession())
1920
qry = ServiceOperationQuery(self,
2021
"createUploadSession",
2122
None,
2223
{
2324
"item": item
24-
}
25+
},
26+
None,
27+
result
2528
)
26-
result = ClientResult(UploadSession())
27-
self.context.add_query(qry, result)
29+
self.context.add_query(qry)
2830
return result
2931

3032
def upload(self, name, content):
3133
"""The simple upload API allows you to provide the contents of a new file or update the contents of an
3234
existing file in a single API call. This method only supports files up to 4MB in size. """
33-
drive_item = DriveItem(self.context, ResourcePathUrl(self.context, self.resourcePath, name))
3435
from office365.graphClient import UploadContentQuery
35-
qry = UploadContentQuery(drive_item, content)
36-
self.context.add_query(qry, drive_item)
37-
return drive_item
36+
qry = UploadContentQuery(self, name, content)
37+
self.context.add_query(qry)
38+
return qry.returnType
3839

3940
def download(self):
4041
"""Download the contents of the primary stream (file) of a DriveItem. Only driveItems with the file property
4142
can be downloaded. """
4243
from office365.graphClient import DownloadContentQuery
4344
qry = DownloadContentQuery(self)
44-
result = ClientResult(None)
45-
self.context.add_query(qry, result)
46-
return result
45+
self.context.add_query(qry)
46+
return qry.returnType
4747

4848
def create_folder(self, name):
4949
"""Create a new folder or DriveItem in a Drive with a specified parent item or path."""
@@ -54,56 +54,59 @@ def create_folder(self, name):
5454
"folder": {},
5555
"@microsoft.graph.conflictBehavior": ConflictBehavior.Rename
5656
}
57-
qry = CreateEntityQuery(self.children, payload)
58-
self.context.add_query(qry, drive_item)
57+
qry = CreateEntityQuery(self.children, payload, drive_item)
58+
self.context.add_query(qry)
5959
return drive_item
6060

6161
def convert(self, format_name):
6262
"""Converts the contents of an item in a specific format"""
6363
from office365.graphClient import DownloadContentQuery
6464
qry = DownloadContentQuery(self, format_name)
65-
result = ClientResult(None)
66-
self.context.add_query(qry, result)
67-
return result
65+
self.context.add_query(qry)
66+
return qry.returnType
6867

6968
def copy(self, name, parent_reference=None):
7069
"""Asynchronously creates a copy of an driveItem (including any children), under a new parent item or with a
7170
new name. """
71+
result = ClientResult(None)
7272
qry = ServiceOperationQuery(self,
7373
"copy",
7474
None,
7575
{
7676
"name": name,
7777
"parentReference": parent_reference
78-
}
78+
},
79+
None,
80+
result
7981
)
80-
result = ClientResult(None)
81-
self.context.add_query(qry, result)
82+
self.context.add_query(qry)
8283
return result
8384

8485
def move(self, name, parent_reference=None):
8586
"""To move a DriveItem to a new parent item, your app requests to update the parentReference of the DriveItem
8687
to move. """
8788
from office365.graphClient import ReplaceMethodQuery
89+
result = ClientResult(None)
8890
qry = ReplaceMethodQuery(self,
8991
"move",
9092
None,
9193
{
9294
"name": name,
9395
"parentReference": parent_reference
94-
}
96+
},
97+
None,
98+
result
9599
)
96-
result = ClientResult(None)
97-
self.context.add_query(qry, result)
100+
self.context.add_query(qry)
98101
return result
99102

100103
def search(self, query_text):
101104
"""Search the hierarchy of items for items matching a query. You can search within a folder hierarchy,
102105
a whole drive, or files shared with the current user. """
103106
from office365.graphClient import SearchQuery
104-
qry = SearchQuery(self, query_text)
105107
result = ClientResult(None)
106-
self.context.add_query(qry, result)
108+
qry = SearchQuery(self, query_text, result)
109+
self.context.add_query(qry)
107110
return result
108111

109112
@property

office365/onedrive/driveItemCollection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ def get_by_id(self, _id):
1818
def get_by_url(self, url):
1919
"""Retrieve DriveItem by url"""
2020
return DriveItem(self.context,
21-
ResourcePathUrl(self.context, self.resourcePath, url))
21+
ResourcePathUrl(url, self.resourcePath))

office365/onedrive/listCollection.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ def __init__(self, context, resource_path=None):
1111

1212
def add(self, list_creation_information):
1313
"""Creates a Drive list resource"""
14-
new_list = List(self.context)
15-
qry = CreateEntityQuery(self, list_creation_information)
16-
self.context.add_query(qry, new_list)
17-
self.add_child(new_list)
18-
return new_list
14+
target_list = List(self.context)
15+
self.add_child(target_list)
16+
qry = CreateEntityQuery(self, list_creation_information, target_list)
17+
self.context.add_query(qry)
18+
return target_list

office365/outlookservices/contact_collection.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ def __init__(self, context, resource_path=None):
1313
def add_from_json(self, contact_creation_information):
1414
"""Creates a Contact resource from JSON"""
1515
contact = Contact(self.context)
16-
qry = CreateEntityQuery(self, contact_creation_information)
17-
self.context.add_query(qry, contact)
1816
self.add_child(contact)
17+
qry = CreateEntityQuery(self, contact_creation_information, contact)
18+
self.context.add_query(qry)
1919
return contact
2020

2121
def add(self):
2222
"""Creates a Contact resource"""
2323
contact = Contact(self.context)
24-
qry = CreateEntityQuery(self, contact)
25-
self.context.add_query(qry, contact)
2624
self.add_child(contact)
25+
qry = CreateEntityQuery(self, contact, contact)
26+
self.context.add_query(qry)
2727
return contact
2828

2929
def get_by_id(self, contact_id):

office365/outlookservices/event_collection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def __init__(self, context, resource_path=None):
1111
def add_from_json(self, event_creation_information):
1212
"""Creates a Event resource from JSON"""
1313
event = Event(self.context)
14-
qry = CreateEntityQuery(self, event_creation_information)
15-
self.context.add_query(qry, event)
1614
self.add_child(event)
15+
qry = CreateEntityQuery(self, event_creation_information, event)
16+
self.context.add_query(qry)
1717
return event

office365/outlookservices/messageCollection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def __init__(self, context, resource_path=None):
1111
def add_from_json(self, message_creation_information):
1212
"""Create a draft of a new message from JSON"""
1313
contact = Message(self.context)
14-
qry = CreateEntityQuery(self, message_creation_information)
15-
self.context.add_query(qry, contact)
1614
self.add_child(contact)
15+
qry = CreateEntityQuery(self, message_creation_information, contact)
16+
self.context.add_query(qry)
1717
return contact

office365/outlookservices/outlook_client.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from office365.runtime.client_query import UpdateEntityQuery, DeleteEntityQuery
22
from office365.runtime.client_runtime_context import ClientRuntimeContext
3+
from office365.runtime.odata.odata_request import ODataRequest
34
from office365.runtime.odata.v4_json_format import V4JsonFormat
45
from office365.runtime.resource_path import ResourcePath
56
from office365.runtime.http.http_method import HttpMethod
@@ -12,11 +13,11 @@ class OutlookClient(ClientRuntimeContext):
1213
def __init__(self, ctx_auth):
1314
self.__service_root_url = "https://outlook.office365.com/api/v1.0/"
1415
super(OutlookClient, self).__init__(self.__service_root_url, ctx_auth)
15-
self.json_format = V4JsonFormat("minimal")
16+
self._pendingRequest = ODataRequest(self, V4JsonFormat("minimal"))
17+
self._pendingRequest.beforeExecute += self._build_specific_query
1618

17-
def execute_query(self):
18-
self.pending_request.before_execute_request(self._build_specific_query)
19-
super(OutlookClient, self).execute_query()
19+
def get_pending_request(self):
20+
return self._pendingRequest
2021

2122
@staticmethod
2223
def _build_specific_query(request, query):
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class ClientCredential(object):
2+
3+
def __init__(self, client_id, client_secret):
4+
self.clientId = client_id
5+
self.clientSecret = client_secret
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class UserCredential(object):
2+
3+
def __init__(self, user_name, password):
4+
self.userName = user_name
5+
self.password = password

0 commit comments

Comments
 (0)