Office365-REST-Python-Client 2.5.2__py3-none-any.whl → 2.5.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. {Office365_REST_Python_Client-2.5.2.dist-info → Office365_REST_Python_Client-2.5.4.dist-info}/METADATA +18 -5
  2. {Office365_REST_Python_Client-2.5.2.dist-info → Office365_REST_Python_Client-2.5.4.dist-info}/RECORD +135 -131
  3. office365/base_item.py +12 -20
  4. office365/communications/presences/presence.py +18 -7
  5. office365/delta_path.py +1 -1
  6. office365/directory/administrative_unit.py +6 -7
  7. office365/directory/applications/application.py +15 -13
  8. office365/directory/applications/template.py +5 -8
  9. office365/directory/audit/signins/signin.py +8 -12
  10. office365/directory/authentication/methods/details.py +8 -6
  11. office365/directory/authentication/methods/email.py +4 -4
  12. office365/directory/groups/lifecycle_policy.py +8 -7
  13. office365/directory/identities/provider.py +5 -6
  14. office365/directory/internal/paths/me.py +1 -1
  15. office365/directory/permissions/email_identity.py +7 -0
  16. office365/directory/protection/riskyusers/history_item.py +4 -3
  17. office365/directory/rolemanagement/role.py +5 -4
  18. office365/directory/rolemanagement/template.py +2 -6
  19. office365/directory/rolemanagement/unified_role_assignment.py +5 -4
  20. office365/directory/rolemanagement/unified_role_definition.py +6 -4
  21. office365/directory/serviceprincipals/service_principal.py +11 -6
  22. office365/directory/users/user.py +8 -11
  23. office365/entity.py +2 -2
  24. office365/entity_collection.py +11 -4
  25. office365/intune/devices/enrollment/configuration.py +6 -4
  26. office365/intune/devices/managed.py +9 -12
  27. office365/onedrive/analytics/item_activity_stat.py +4 -3
  28. office365/onedrive/columns/definition.py +9 -9
  29. office365/onedrive/documentsets/version.py +1 -3
  30. office365/onedrive/driveitems/driveItem.py +36 -29
  31. office365/onedrive/internal/paths/children.py +2 -2
  32. office365/onedrive/internal/paths/root.py +1 -1
  33. office365/onedrive/internal/paths/shared.py +11 -6
  34. office365/onedrive/internal/paths/site.py +3 -3
  35. office365/onedrive/internal/paths/url.py +2 -2
  36. office365/onedrive/listitems/list_item.py +2 -0
  37. office365/onedrive/lists/list.py +7 -4
  38. office365/onedrive/permissions/collection.py +26 -6
  39. office365/onedrive/sharepoint.py +1 -0
  40. office365/onedrive/shares/collection.py +2 -5
  41. office365/onedrive/shares/drive_item.py +5 -1
  42. office365/onedrive/termstore/groups/collection.py +3 -8
  43. office365/onedrive/termstore/groups/group.py +8 -0
  44. office365/onedrive/termstore/sets/collection.py +2 -6
  45. office365/onedrive/termstore/sets/name.py +5 -0
  46. office365/onedrive/termstore/sets/set.py +7 -0
  47. office365/onedrive/termstore/store.py +10 -13
  48. office365/onedrive/versions/drive_item.py +6 -8
  49. office365/onedrive/workbooks/functions/result.py +1 -1
  50. office365/onedrive/workbooks/names/collection.py +26 -0
  51. office365/onedrive/workbooks/names/named_item.py +23 -6
  52. office365/onedrive/workbooks/ranges/range.py +61 -14
  53. office365/onedrive/workbooks/ranges/view.py +1 -0
  54. office365/onedrive/workbooks/tables/table.py +11 -8
  55. office365/onedrive/workbooks/workbook.py +7 -11
  56. office365/onedrive/workbooks/worksheets/worksheet.py +5 -3
  57. office365/onenote/pages/collection.py +3 -2
  58. office365/onenote/resources/resource.py +5 -4
  59. office365/onenote/sectiongroups/section_group.py +10 -7
  60. office365/outlook/calendar/calendar.py +1 -1
  61. office365/outlook/calendar/schedule/information.py +0 -1
  62. office365/outlook/contacts/contact.py +3 -9
  63. office365/outlook/contacts/folder.py +3 -0
  64. office365/outlook/item.py +3 -4
  65. office365/outlook/mail/messages/message.py +25 -18
  66. office365/outlook/mail/recipient.py +3 -1
  67. office365/runtime/auth/authentication_context.py +6 -4
  68. office365/runtime/auth/providers/acs_token_provider.py +21 -15
  69. office365/runtime/auth/providers/saml_token_provider.py +5 -2
  70. office365/runtime/auth/sts_profile.py +5 -2
  71. office365/runtime/client_object.py +3 -11
  72. office365/runtime/client_object_collection.py +22 -20
  73. office365/runtime/client_result.py +1 -3
  74. office365/runtime/client_value_collection.py +2 -6
  75. office365/runtime/odata/json_format.py +1 -5
  76. office365/runtime/odata/query_options.py +1 -3
  77. office365/runtime/odata/request.py +8 -13
  78. office365/runtime/odata/type.py +2 -0
  79. office365/runtime/paths/appid.py +1 -1
  80. office365/runtime/{odata/url_builder.py → paths/builder.py} +24 -9
  81. office365/runtime/paths/item.py +1 -1
  82. office365/runtime/paths/resource_path.py +12 -16
  83. office365/runtime/paths/service_operation.py +8 -7
  84. office365/runtime/paths/v3/__init__.py +0 -0
  85. office365/runtime/paths/{key.py → v3/entity.py} +5 -5
  86. office365/runtime/paths/v4/__init__.py +0 -0
  87. office365/runtime/paths/v4/entity.py +35 -0
  88. office365/sharepoint/client_context.py +17 -10
  89. office365/sharepoint/contenttypes/content_type.py +6 -0
  90. office365/sharepoint/documentmanagement/document_set.py +4 -6
  91. office365/sharepoint/entity_collection.py +9 -0
  92. office365/sharepoint/features/feature.py +6 -8
  93. office365/sharepoint/files/checked_out_file.py +4 -2
  94. office365/sharepoint/files/checked_out_file_collection.py +1 -1
  95. office365/sharepoint/files/collection.py +35 -3
  96. office365/sharepoint/files/file.py +35 -11
  97. office365/sharepoint/files/versions/collection.py +4 -0
  98. office365/sharepoint/files/versions/event.py +6 -3
  99. office365/sharepoint/files/versions/version.py +6 -4
  100. office365/sharepoint/folders/collection.py +2 -2
  101. office365/sharepoint/folders/folder.py +5 -11
  102. office365/sharepoint/internal/paths/static_operation.py +9 -0
  103. office365/sharepoint/internal/paths/web.py +20 -0
  104. office365/sharepoint/listitems/collection.py +4 -0
  105. office365/sharepoint/listitems/listitem.py +19 -30
  106. office365/sharepoint/lists/list.py +44 -60
  107. office365/sharepoint/portal/groups/service.py +12 -16
  108. office365/sharepoint/portal/groups/site_manager.py +0 -1
  109. office365/sharepoint/publishing/pages/metadata.py +7 -2
  110. office365/sharepoint/publishing/pages/metadata_collection.py +0 -1
  111. office365/sharepoint/publishing/pages/page.py +3 -6
  112. office365/sharepoint/publishing/pages/reposts/repost.py +5 -9
  113. office365/sharepoint/recyclebin/item.py +11 -9
  114. office365/sharepoint/sharing/links/share_response.py +3 -0
  115. office365/sharepoint/sharing/result.py +18 -41
  116. office365/sharepoint/sites/site.py +46 -68
  117. office365/sharepoint/taxonomy/item.py +4 -2
  118. office365/sharepoint/taxonomy/stores/store.py +2 -6
  119. office365/sharepoint/tenant/administration/internal/permission_grant.py +7 -0
  120. office365/sharepoint/tenant/administration/sites/properties.py +55 -44
  121. office365/sharepoint/tenant/administration/tenant.py +25 -40
  122. office365/sharepoint/usercustomactions/collection.py +0 -1
  123. office365/sharepoint/webs/collection.py +8 -0
  124. office365/sharepoint/webs/template_collection.py +2 -4
  125. office365/sharepoint/webs/web.py +27 -24
  126. office365/teams/apps/app.py +1 -0
  127. office365/teams/collection.py +12 -16
  128. office365/teams/members/conversation_collection.py +1 -3
  129. office365/teams/operations/async_operation.py +3 -5
  130. office365/teams/schedule/groups/group.py +3 -0
  131. office365/teams/team.py +1 -1
  132. office365/todo/attachments/base.py +7 -9
  133. office365/runtime/odata/path_builder.py +0 -23
  134. office365/runtime/paths/entity.py +0 -34
  135. office365/sharepoint/internal/key_value.py +0 -28
  136. {Office365_REST_Python_Client-2.5.2.dist-info → Office365_REST_Python_Client-2.5.4.dist-info}/LICENSE +0 -0
  137. {Office365_REST_Python_Client-2.5.2.dist-info → Office365_REST_Python_Client-2.5.4.dist-info}/WHEEL +0 -0
  138. {Office365_REST_Python_Client-2.5.2.dist-info → Office365_REST_Python_Client-2.5.4.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- from typing import Callable, Generic, Iterator, List, Optional, Type, TypeVar
1
+ from typing import Any, Callable, Generic, Iterator, List, Optional, Type, TypeVar
2
2
 
3
3
  from typing_extensions import Self
4
4
 
@@ -40,6 +40,8 @@ class ClientObjectCollection(ClientObject, Generic[T]):
40
40
  raise AttributeError(
41
41
  "No class model for entity type '{0}' was found".format(self._item_type)
42
42
  )
43
+ if resource_path is None:
44
+ resource_path = ResourcePath(None, self.resource_path)
43
45
  client_object = self._item_type(
44
46
  context=self.context, resource_path=resource_path
45
47
  ) # type: T
@@ -66,9 +68,7 @@ class ClientObjectCollection(ClientObject, Generic[T]):
66
68
 
67
69
  def add_child(self, client_object):
68
70
  # type: (T) -> Self
69
- """
70
- Adds client object into collection
71
- """
71
+ """Adds client object into collection"""
72
72
  client_object._parent_collection = self
73
73
  self._data.append(client_object)
74
74
  return self
@@ -110,7 +110,6 @@ class ClientObjectCollection(ClientObject, Generic[T]):
110
110
  # type: (str) -> Self
111
111
  """
112
112
  Allows clients to filter a collection of resources that are addressed by a request URL
113
-
114
113
  :param str expression: Filter expression, for example: 'Id eq 123'
115
114
  """
116
115
  self.query_options.filter = expression
@@ -134,17 +133,13 @@ class ClientObjectCollection(ClientObject, Generic[T]):
134
133
 
135
134
  def top(self, value):
136
135
  # type: (int) -> Self
137
- """
138
- Specifies the number of items in the queried collection to be included in the result
139
- """
136
+ """Specifies the number of items in the queried collection to be included in the result"""
140
137
  self.query_options.top = value
141
138
  return self
142
139
 
143
140
  def paged(self, page_size=None, page_loaded=None):
144
141
  # type: (int, Callable[[Self], None]) -> Self
145
- """
146
- Retrieves via server-driven paging mode
147
- """
142
+ """Retrieves via server-driven paging mode"""
148
143
  self._paged_mode = True
149
144
  if callable(page_loaded):
150
145
  self._page_loaded += page_loaded
@@ -152,6 +147,12 @@ class ClientObjectCollection(ClientObject, Generic[T]):
152
147
  self.top(page_size)
153
148
  return self
154
149
 
150
+ def after_execute(self, action, *args, **kwargs):
151
+ # type: (Callable[[Self, Any, Any], None], Any, Any) -> Self
152
+ super(ClientObjectCollection, self).after_execute(action, *args, **kwargs)
153
+ self._page_loaded += action
154
+ return self
155
+
155
156
  def get(self):
156
157
  # type: () -> Self
157
158
 
@@ -196,22 +197,22 @@ class ClientObjectCollection(ClientObject, Generic[T]):
196
197
  def first(self, expression):
197
198
  # type: (str) -> T
198
199
  """Return the first Entity instance that matches current query
199
-
200
200
  :param str expression: Filter expression
201
201
  """
202
202
  return_type = self.create_typed_object()
203
203
  self.add_child(return_type)
204
- key = return_type.property_ref_name
205
204
 
206
205
  def _after_loaded(col):
207
206
  # type: (ClientObjectCollection) -> None
208
207
  if len(col) < 1:
209
208
  message = "Not found for filter: {0}".format(self.query_options.filter)
210
209
  raise ValueError(message)
211
- return_type.set_property(key, col[0].get_property(key))
210
+ [
211
+ return_type.set_property(k, v, False)
212
+ for k, v in col[0].properties.items()
213
+ ]
212
214
 
213
- self.filter(expression).top(1)
214
- self.context.load(self, [key], after_loaded=_after_loaded)
215
+ self.get().filter(expression).top(1).after_execute(_after_loaded)
215
216
  return return_type
216
217
 
217
218
  def single(self, expression):
@@ -223,7 +224,6 @@ class ClientObjectCollection(ClientObject, Generic[T]):
223
224
  """
224
225
  return_type = self.create_typed_object()
225
226
  self.add_child(return_type)
226
- key = return_type.property_ref_name
227
227
 
228
228
  def _after_loaded(col):
229
229
  # type: (ClientObjectCollection) -> None
@@ -233,10 +233,12 @@ class ClientObjectCollection(ClientObject, Generic[T]):
233
233
  elif len(col) > 1:
234
234
  message = "Ambiguous match found for filter: {0}".format(expression)
235
235
  raise ValueError(message)
236
- return_type.set_property(key, col[0].get_property(key), False)
236
+ [
237
+ return_type.set_property(k, v, False)
238
+ for k, v in col[0].properties.items()
239
+ ]
237
240
 
238
- self.filter(expression).top(2)
239
- self.context.load(self, after_loaded=_after_loaded)
241
+ self.get().filter(expression).top(2).after_execute(_after_loaded)
240
242
  return return_type
241
243
 
242
244
  @property
@@ -59,9 +59,7 @@ class ClientResult(Generic[T]):
59
59
  def execute_query_retry(
60
60
  self, max_retry=5, timeout_secs=5, success_callback=None, failure_callback=None
61
61
  ):
62
- """
63
- Executes the current set of data retrieval queries and method invocations and retries it if needed.
64
- """
62
+ """Executes the current set of data retrieval queries and method invocations and retries it if needed."""
65
63
  self._context.execute_query_retry(
66
64
  max_retry=max_retry,
67
65
  timeout_secs=timeout_secs,
@@ -41,9 +41,7 @@ class ClientValueCollection(ClientValue, Generic[T]):
41
41
 
42
42
  def to_json(self, json_format=None):
43
43
  # type: (ODataJsonFormat) -> list
44
- """
45
- Serializes a client value's collection
46
- """
44
+ """Serializes a client value's collection"""
47
45
  json = [v for v in self]
48
46
  for i, v in enumerate(json):
49
47
  if isinstance(v, ClientValue):
@@ -81,7 +79,5 @@ class ClientValueCollection(ClientValue, Generic[T]):
81
79
 
82
80
  @property
83
81
  def entity_type_name(self):
84
- """
85
- Returns server type name of value's collection
86
- """
82
+ """Returns server type name of value's collection"""
87
83
  return "Collection({0})".format(ODataType.resolve_type(self._item_type))
@@ -5,9 +5,7 @@ class ODataJsonFormat(object):
5
5
  """OData JSON format"""
6
6
 
7
7
  def __init__(self, metadata_level=None):
8
- """
9
- :type metadata_level: str
10
- """
8
+ # type: (str) -> None
11
9
  self.metadata_level = metadata_level
12
10
 
13
11
  __metaclass__ = ABCMeta
@@ -28,7 +26,6 @@ class ODataJsonFormat(object):
28
26
  def media_type(self):
29
27
  """
30
28
  Gets media type
31
-
32
29
  :rtype: str
33
30
  """
34
31
  raise NotImplementedError
@@ -36,7 +33,6 @@ class ODataJsonFormat(object):
36
33
  @property
37
34
  def include_control_information(self):
38
35
  """Determines whether control information that is represented as annotations should be included in payload
39
-
40
36
  :rtype: bool
41
37
  """
42
38
  raise NotImplementedError
@@ -90,9 +90,7 @@ class QueryOptions(object):
90
90
  self.custom = {}
91
91
 
92
92
  def to_url(self):
93
- """Convert query options to url
94
- :return: str
95
- """
93
+ """Convert query options to url"""
96
94
  return "&".join(["$%s=%s" % (key, value) for (key, value) in self])
97
95
 
98
96
  def __iter__(self):
@@ -1,4 +1,5 @@
1
1
  import copy
2
+ from typing import Any, Optional
2
3
 
3
4
  import requests
4
5
 
@@ -69,11 +70,7 @@ class ODataRequest(ClientRequest):
69
70
  self.map_json(response.json(), return_type, json_format)
70
71
 
71
72
  def map_json(self, json, return_type, json_format=None):
72
- """
73
- :type json: any
74
- :type return_type: ClientValue or ClientResult or ClientObject
75
- :type json_format: office365.runtime.odata.json_format.ODataJsonFormat
76
- """
73
+ # type: (Any, ClientValue | ClientResult | ClientObject, Optional[ODataJsonFormat]) -> None
77
74
  if json_format is None:
78
75
  json_format = self.json_format
79
76
 
@@ -82,19 +79,17 @@ class ODataRequest(ClientRequest):
82
79
  return_type.set_property(k, v, False)
83
80
 
84
81
  def _next_property(self, json, json_format):
85
- """
86
- :type json: Any
87
- :type json_format: office365.runtime.odata.json_format.ODataJsonFormat
88
- """
82
+ # type: (Any, ODataJsonFormat) -> None
89
83
  if isinstance(json_format, JsonLightFormat):
90
84
  json = json.get(json_format.security, json)
91
85
  json = json.get(json_format.function, json)
92
86
 
93
87
  if isinstance(json, dict):
94
- next_link_url = json.get(json_format.collection_next, None)
95
- json = json.get(json_format.collection, json)
96
- if next_link_url:
97
- yield "__nextLinkUrl", next_link_url
88
+ if isinstance(json.get(json_format.collection, None), list):
89
+ next_link_url = json.get(json_format.collection_next, None)
90
+ json = json.get(json_format.collection, json)
91
+ if next_link_url:
92
+ yield "__nextLinkUrl", next_link_url
98
93
 
99
94
  if isinstance(json, list):
100
95
  for index, item in enumerate(json):
@@ -64,6 +64,8 @@ class ODataType(object):
64
64
  """
65
65
  if value is None:
66
66
  return None
67
+ elif isinstance(value, datetime.datetime):
68
+ return value
67
69
 
68
70
  known_formats = [
69
71
  "%Y-%m-%dT%H:%M:%SZ",
@@ -7,7 +7,7 @@ class AppIdPath(ResourcePath):
7
7
 
8
8
  @property
9
9
  def segment(self):
10
- return "(appId='{0}')".format(self.key)
10
+ return "(appId='{0}')".format(self._key)
11
11
 
12
12
  @property
13
13
  def delimiter(self):
@@ -1,18 +1,33 @@
1
1
  import json
2
+ import re
3
+ from typing import TYPE_CHECKING
2
4
 
3
5
  from office365.runtime.client_value import ClientValue
4
6
  from office365.runtime.compat import is_string_type
7
+ from office365.runtime.paths.resource_path import ResourcePath
5
8
 
9
+ if TYPE_CHECKING:
10
+ from office365.runtime.paths.service_operation import ServiceOperationPath
6
11
 
7
- class ODataUrlBuilder(object):
12
+
13
+ class ODataPathBuilder(object):
8
14
  @staticmethod
9
- def build_segment(path):
10
- """
11
- Constructs url for path segment
15
+ def parse_url(path_str):
16
+ # type: (str) -> ResourcePath
17
+ """Parses path from a string"""
18
+ segments = [n for n in re.split(r"[('')]|/", path_str) if n]
19
+ if not segments:
20
+ raise TypeError("Invalid path")
21
+ path = None
22
+ for segment in segments:
23
+ path = ResourcePath(segment, path)
24
+ return path
12
25
 
13
- :type path: office365.runtime.paths.service_operation.ServiceOperationPath
14
- """
15
- url = path.key or ""
26
+ @staticmethod
27
+ def build_segment(path):
28
+ # type: (ServiceOperationPath) -> str
29
+ """Constructs url for path segment"""
30
+ url = path.name or ""
16
31
  if isinstance(path.parameters, ClientValue):
17
32
  url += "(@v)?@v={0}".format(json.dumps(path.parameters.to_json()))
18
33
  elif path.parameters is not None:
@@ -20,7 +35,7 @@ class ODataUrlBuilder(object):
20
35
  if isinstance(path.parameters, dict):
21
36
  url += ",".join(
22
37
  [
23
- "%s=%s" % (key, ODataUrlBuilder._encode_method_value(value))
38
+ "%s=%s" % (key, ODataPathBuilder._encode_method_value(value))
24
39
  for (key, value) in path.parameters.items()
25
40
  if value is not None
26
41
  ]
@@ -28,7 +43,7 @@ class ODataUrlBuilder(object):
28
43
  else:
29
44
  url += ",".join(
30
45
  [
31
- "%s" % (ODataUrlBuilder._encode_method_value(value))
46
+ "%s" % (ODataPathBuilder._encode_method_value(value))
32
47
  for (i, value) in enumerate(path.parameters)
33
48
  if value is not None
34
49
  ]
@@ -1,4 +1,4 @@
1
- from office365.runtime.paths.entity import EntityPath
1
+ from office365.runtime.paths.v4.entity import EntityPath
2
2
 
3
3
 
4
4
  class ItemPath(EntityPath):
@@ -1,18 +1,21 @@
1
+ from typing import Iterator
2
+
3
+
1
4
  class ResourcePath(object):
2
5
  """OData resource path"""
3
6
 
4
- def __init__(self, key, parent=None):
5
- """
6
- :type key: int or str
7
- :type parent: ResourcePath or None
8
- """
7
+ def __init__(self, key=None, parent=None):
8
+ # type: (int|str, "ResourcePath") -> None
9
9
  self._key = key
10
10
  self._parent = parent
11
11
 
12
- def patch(self, key, inplace=False):
12
+ def patch(self, key):
13
+ if self._key is None:
14
+ self._key = key
13
15
  return self
14
16
 
15
17
  def __iter__(self):
18
+ # type: () -> Iterator["ResourcePath"]
16
19
  current = self
17
20
  while current:
18
21
  yield current
@@ -25,11 +28,8 @@ class ResourcePath(object):
25
28
  return self.to_url()
26
29
 
27
30
  def to_url(self):
28
- """
29
- Builds url
30
-
31
- :rtype: str
32
- """
31
+ # type: () -> str
32
+ """Builds url"""
33
33
  segments = []
34
34
  for path in self:
35
35
  segments.insert(0, path.segment)
@@ -43,11 +43,7 @@ class ResourcePath(object):
43
43
 
44
44
  @property
45
45
  def segment(self):
46
- return str(self.key)
47
-
48
- @property
49
- def key(self):
50
- return self._key
46
+ return str(self._key)
51
47
 
52
48
  @property
53
49
  def delimiter(self):
@@ -1,4 +1,5 @@
1
- from office365.runtime.odata.url_builder import ODataUrlBuilder
1
+ from office365.runtime.client_value import ClientValue
2
+ from office365.runtime.paths.builder import ODataPathBuilder
2
3
  from office365.runtime.paths.resource_path import ResourcePath
3
4
 
4
5
 
@@ -6,17 +7,17 @@ class ServiceOperationPath(ResourcePath):
6
7
  """Path to address Service Operations which represents simple functions exposed by an OData service"""
7
8
 
8
9
  def __init__(self, name, parameters=None, parent=None):
9
- """
10
- :type parameters: list or dict or office365.runtime.client_value.ClientValue or None
11
- :type name: str
12
- :type parent: office365.runtime.paths.resource_path.ResourcePath
13
- """
10
+ # type: (str, list|dict|ClientValue, ResourcePath) -> None
14
11
  super(ServiceOperationPath, self).__init__(name, parent)
15
12
  self._parameters = parameters
16
13
 
17
14
  @property
18
15
  def segment(self):
19
- return ODataUrlBuilder.build_segment(self)
16
+ return ODataPathBuilder.build_segment(self)
17
+
18
+ @property
19
+ def name(self):
20
+ return self._key
20
21
 
21
22
  @property
22
23
  def parameters(self):
File without changes
@@ -1,16 +1,16 @@
1
1
  from office365.runtime.paths.resource_path import ResourcePath
2
2
 
3
3
 
4
- class KeyPath(ResourcePath):
4
+ class EntityPath(ResourcePath):
5
5
  """Path for addressing a single entity by key"""
6
6
 
7
7
  @property
8
8
  def segment(self):
9
- if self.key is None:
9
+ if self._key is None:
10
10
  return "(<key>)"
11
- elif isinstance(self.key, int):
12
- return "({0})".format(self.key)
13
- return "('{0}')".format(self.key)
11
+ elif isinstance(self._key, int):
12
+ return "({0})".format(self._key)
13
+ return "('{0}')".format(self._key)
14
14
 
15
15
  @property
16
16
  def delimiter(self):
File without changes
@@ -0,0 +1,35 @@
1
+ from typing import Optional
2
+
3
+ from typing_extensions import Self
4
+
5
+ from office365.runtime.paths.resource_path import ResourcePath
6
+
7
+
8
+ class EntityPath(ResourcePath):
9
+ def __init__(self, key=None, parent=None, collection=None):
10
+ # type: (Optional[str], Optional[ResourcePath], Optional[ResourcePath]) -> None
11
+ super(EntityPath, self).__init__(key, parent)
12
+ self._collection = collection
13
+
14
+ @property
15
+ def collection(self):
16
+ from office365.onedrive.internal.paths.children import ChildrenPath
17
+
18
+ if self._collection is None:
19
+ if isinstance(self.parent, ChildrenPath):
20
+ self._collection = self.parent.collection
21
+ else:
22
+ self._collection = self.parent
23
+ return self._collection
24
+
25
+ @property
26
+ def segment(self):
27
+ return str(self._key or "<key>")
28
+
29
+ def patch(self, key):
30
+ # type: (str) -> Self
31
+ """Patches the path"""
32
+ self._key = key
33
+ self._parent = self.collection
34
+ self.__class__ = EntityPath
35
+ return self
@@ -81,7 +81,7 @@ class ClientContext(ClientRuntimeContext):
81
81
  thumbprint,
82
82
  cert_path=None,
83
83
  private_key=None,
84
- scopes=None,
84
+ scopes=None
85
85
  ):
86
86
  # type: (str, str, str, Optional[str], Optional[str], Optional[List[str]]) -> Self
87
87
  """
@@ -93,7 +93,6 @@ class ClientContext(ClientRuntimeContext):
93
93
  :param str thumbprint: Hex encoded thumbprint of the certificate.
94
94
  :param str client_id: The OAuth client id of the calling application.
95
95
  :param list[str] or None scopes: Scopes requested to access a protected API (a resource)
96
-
97
96
  """
98
97
  self.authentication_context.with_client_certificate(
99
98
  tenant, client_id, thumbprint, cert_path, private_key, scopes
@@ -137,25 +136,28 @@ class ClientContext(ClientRuntimeContext):
137
136
  return self
138
137
 
139
138
  def with_user_credentials(
140
- self, username, password, allow_ntlm=False, browser_mode=False
139
+ self, username, password, allow_ntlm=False, browser_mode=False, environment='commercial'
141
140
  ):
142
- # type: (str, str, bool, bool) -> Self
141
+ # type: (str, str, bool, bool, Optional[str]) -> Self
143
142
  """
144
143
  Initializes a client to acquire a token via user credentials.
145
144
  :param str username: Typically, a UPN in the form of an email address
146
145
  :param str password: The password
147
146
  :param bool allow_ntlm: Flag indicates whether NTLM scheme is enabled. Disabled by default
148
147
  :param bool browser_mode:
148
+ :param str environment: The Office 365 Cloud Environment endpoint used for authentication
149
+ defaults to 'commercial'.
149
150
  """
150
151
  self.authentication_context.with_credentials(
151
152
  UserCredential(username, password),
152
153
  allow_ntlm=allow_ntlm,
153
154
  browser_mode=browser_mode,
155
+ environment=environment
154
156
  )
155
157
  return self
156
158
 
157
- def with_client_credentials(self, client_id, client_secret):
158
- # type: (str, str) -> Self
159
+ def with_client_credentials(self, client_id, client_secret, environment='commercial'):
160
+ # type: (str, str, Optional[str]) -> Self
159
161
  """
160
162
  Initializes a client to acquire a token via client credentials (SharePoint App-Only)
161
163
 
@@ -164,19 +166,24 @@ class ClientContext(ClientRuntimeContext):
164
166
 
165
167
  :param str client_id: The OAuth client id of the calling application
166
168
  :param str client_secret: Secret string that the application uses to prove its identity when requesting a token
169
+ :param str environment: The Office 365 Cloud Environment endpoint used for authentication
170
+ defaults to 'commercial'.
167
171
  """
168
172
  self.authentication_context.with_credentials(
169
- ClientCredential(client_id, client_secret)
173
+ ClientCredential(client_id, client_secret),
174
+ environment=environment
170
175
  )
171
176
  return self
172
177
 
173
- def with_credentials(self, credentials):
174
- # type: (UserCredential|ClientCredential) -> Self
178
+ def with_credentials(self, credentials, environment='commercial'):
179
+ # type: (UserCredential|ClientCredential, Optional[str]) -> Self
175
180
  """
176
181
  Initializes a client to acquire a token via user or client credentials
177
182
  :type credentials: UserCredential or ClientCredential
183
+ :param str environment: The Office 365 Cloud Environment endpoint used for authentication
184
+ defaults to 'commercial'.
178
185
  """
179
- self.authentication_context.with_credentials(credentials)
186
+ self.authentication_context.with_credentials(credentials, environment=environment)
180
187
  return self
181
188
 
182
189
  def execute_batch(self, items_per_batch=100, success_callback=None):
@@ -19,6 +19,12 @@ class ContentType(Entity):
19
19
  to items of those types
20
20
  """
21
21
 
22
+ def __str__(self):
23
+ return self.name
24
+
25
+ def __repr__(self):
26
+ return self.string_id or str(self.id) or self.entity_type_name
27
+
22
28
  def reorder_fields(self, field_names):
23
29
  """
24
30
  The ReorderFields method is called to change the order in which fields appear in a content type.
@@ -1,6 +1,8 @@
1
1
  from office365.runtime.http.http_method import HttpMethod
2
+ from office365.runtime.http.request_options import RequestOptions
2
3
  from office365.runtime.queries.client_query import ClientQuery
3
4
  from office365.sharepoint.folders.folder import Folder
5
+ from office365.sharepoint.lists.list import List
4
6
 
5
7
 
6
8
  class DocumentSet(Folder):
@@ -26,18 +28,14 @@ class DocumentSet(Folder):
26
28
  target_list.ensure_property("Title", _create, target_list=target_list)
27
29
 
28
30
  def _create(target_list):
29
- """
30
- :type target_list: office365.sharepoint.lists.list.List
31
- """
31
+ # type: (List) -> None
32
32
  qry = ClientQuery(context, return_type=return_type)
33
33
  context.add_query(qry)
34
34
  folder_url = parent_folder.serverRelativeUrl + "/" + name
35
35
  return_type.set_property("ServerRelativeUrl", folder_url)
36
36
 
37
37
  def _construct_request(request):
38
- """
39
- :type request: office365.runtime.http.request_options.RequestOptions
40
- """
38
+ # type: (RequestOptions) -> None
41
39
  list_name = target_list.title.replace(" ", "")
42
40
  request.url = r"{0}/_vti_bin/listdata.svc/{1}".format(
43
41
  context.base_url, list_name
@@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Optional, Type, TypeVar
2
2
 
3
3
  from office365.runtime.client_object_collection import ClientObjectCollection
4
4
  from office365.runtime.paths.resource_path import ResourcePath
5
+ from office365.runtime.paths.v3.entity import EntityPath
5
6
  from office365.sharepoint.entity import Entity
6
7
 
7
8
  if TYPE_CHECKING:
@@ -21,6 +22,14 @@ class EntityCollection(ClientObjectCollection[T]):
21
22
  context, item_type, resource_path, parent
22
23
  )
23
24
 
25
+ def create_typed_object(self, initial_properties=None, resource_path=None):
26
+ # type: (Optional[dict], Optional[ResourcePath]) -> T
27
+ if resource_path is None:
28
+ resource_path = EntityPath(None, self.resource_path)
29
+ return super(EntityCollection, self).create_typed_object(
30
+ initial_properties, resource_path
31
+ )
32
+
24
33
  @property
25
34
  def context(self):
26
35
  # type: () -> ClientContext
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.sharepoint.entity import Entity
2
4
 
3
5
 
@@ -6,16 +8,12 @@ class Feature(Entity):
6
8
 
7
9
  @property
8
10
  def definition_id(self):
9
- """
10
- Gets the GUID that identifies this feature.
11
- :rtype: str or None
12
- """
11
+ # type: () -> Optional[str]
12
+ """Gets the GUID that identifies this feature."""
13
13
  return self.properties.get("DefinitionId", None)
14
14
 
15
15
  @property
16
16
  def display_name(self):
17
- """
18
- Gets the GUID that identifies this feature.
19
- :rtype: str or None
20
- """
17
+ # type: () -> Optional[str]
18
+ """Gets the GUID that identifies this feature."""
21
19
  return self.properties.get("DisplayName", None)
@@ -1,5 +1,5 @@
1
- from office365.runtime.paths.key import KeyPath
2
1
  from office365.runtime.paths.resource_path import ResourcePath
2
+ from office365.runtime.paths.v3.entity import EntityPath
3
3
  from office365.runtime.queries.service_operation import ServiceOperationQuery
4
4
  from office365.sharepoint.entity import Entity
5
5
  from office365.sharepoint.principal.users.user import User
@@ -43,5 +43,7 @@ class CheckedOutFile(Entity):
43
43
  super(CheckedOutFile, self).set_property(name, value, persist_changes)
44
44
  # fallback: create a new resource path
45
45
  if name == "CheckedOutById":
46
- self._resource_path = KeyPath(value, self.parent_collection.resource_path)
46
+ self._resource_path = EntityPath(
47
+ value, self.parent_collection.resource_path
48
+ )
47
49
  return self