Office365-REST-Python-Client 2.5.10__py3-none-any.whl → 2.5.12__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 (85) hide show
  1. {Office365_REST_Python_Client-2.5.10.dist-info → Office365_REST_Python_Client-2.5.12.dist-info}/METADATA +14 -10
  2. {Office365_REST_Python_Client-2.5.10.dist-info → Office365_REST_Python_Client-2.5.12.dist-info}/RECORD +85 -69
  3. {Office365_REST_Python_Client-2.5.10.dist-info → Office365_REST_Python_Client-2.5.12.dist-info}/WHEEL +1 -1
  4. office365/directory/authentication/conditions/__init__.py +0 -0
  5. office365/directory/authentication/conditions/application.py +5 -0
  6. office365/directory/authentication/conditions/applications.py +5 -0
  7. office365/directory/authentication/conditions/conditions.py +11 -0
  8. office365/directory/identitygovernance/appconsent/request.py +32 -0
  9. office365/directory/identitygovernance/appconsent/request_scope.py +5 -0
  10. office365/directory/identitygovernance/privilegedaccess/group.py +5 -0
  11. office365/directory/identitygovernance/privilegedaccess/root.py +14 -0
  12. office365/directory/identitygovernance/privilegedaccess/schedule_instance.py +6 -0
  13. office365/directory/policies/admin_consent_request.py +10 -0
  14. office365/directory/policies/root.py +15 -0
  15. office365/directory/synchronization/status.py +14 -1
  16. office365/directory/synchronization/task_execution.py +5 -0
  17. office365/directory/users/user.py +4 -2
  18. office365/graph_client.py +11 -25
  19. office365/graph_request.py +24 -1
  20. office365/onedrive/driveitems/driveItem.py +41 -38
  21. office365/onedrive/idle_session_signout.py +15 -0
  22. office365/onedrive/listitems/list_item.py +1 -0
  23. office365/onedrive/lists/collection.py +6 -0
  24. office365/onedrive/sharepoint_ids.py +18 -1
  25. office365/onedrive/sharepoint_settings.py +13 -0
  26. office365/onedrive/shares/drive_item.py +1 -2
  27. office365/onedrive/sitepages/title_area.py +15 -5
  28. office365/onedrive/storage/__init__.py +0 -0
  29. office365/onedrive/storage/storage.py +5 -0
  30. office365/onedrive/workbooks/filter.py +7 -0
  31. office365/onedrive/workbooks/filter_criteria.py +9 -2
  32. office365/onedrive/workbooks/tables/rows/collection.py +20 -0
  33. office365/onedrive/workbooks/tables/rows/row.py +2 -1
  34. office365/onedrive/workbooks/workbook.py +7 -5
  35. office365/onenote/internal/multipart_page_query.py +2 -3
  36. office365/outlook/calendar/sharing/__init__.py +0 -0
  37. office365/outlook/calendar/sharing/message_action.py +5 -0
  38. office365/outlook/calendar/sharing_message.py +19 -0
  39. office365/outlook/calendar/timezones/custom.py +9 -0
  40. office365/outlook/category.py +7 -0
  41. office365/outlook/mail/automatic_replies_setting.py +7 -0
  42. office365/outlook/mail/item_body.py +10 -1
  43. office365/outlook/mail/messages/collection.py +3 -0
  44. office365/outlook/mail/messages/message.py +3 -4
  45. office365/outlook/mail/messages/rules/predicates.py +5 -0
  46. office365/outlook/mail/messages/rules/rule.py +4 -3
  47. office365/runtime/auth/providers/saml_token_provider.py +4 -4
  48. office365/runtime/http/request_options.py +7 -3
  49. office365/runtime/odata/query_options.py +3 -0
  50. office365/runtime/queries/batch.py +4 -0
  51. office365/runtime/queries/create_entity.py +6 -8
  52. office365/runtime/queries/update_entity.py +3 -5
  53. office365/sharepoint/appprincipal/identity_provider.py +7 -1
  54. office365/sharepoint/attachments/attachment.py +14 -2
  55. office365/sharepoint/attachments/collection.py +27 -4
  56. office365/sharepoint/changes/app_consent_principal.py +5 -0
  57. office365/sharepoint/changes/file.py +4 -0
  58. office365/sharepoint/client_context.py +4 -3
  59. office365/sharepoint/directory/group.py +9 -9
  60. office365/sharepoint/directory/helper.py +6 -4
  61. office365/sharepoint/documentmanagement/document_set.py +7 -8
  62. office365/sharepoint/entity.py +4 -3
  63. office365/sharepoint/fields/builtin_field_id.py +19 -0
  64. office365/sharepoint/fields/choice.py +2 -2
  65. office365/sharepoint/fields/collection.py +1 -3
  66. office365/sharepoint/fields/field.py +5 -2
  67. office365/sharepoint/files/file.py +1 -1
  68. office365/sharepoint/internal/queries/upload_file.py +12 -8
  69. office365/sharepoint/navigation/node.py +4 -2
  70. office365/sharepoint/packaging/app_details.py +34 -0
  71. office365/sharepoint/policy/dlp_policy_tip.py +9 -1
  72. office365/sharepoint/portal/sites/manager.py +1 -1
  73. office365/sharepoint/principal/principal.py +10 -1
  74. office365/sharepoint/principal/users/collection.py +1 -3
  75. office365/sharepoint/publishing/pages/collection.py +1 -1
  76. office365/sharepoint/publishing/sites/communication/site.py +4 -3
  77. office365/sharepoint/request.py +33 -1
  78. office365/sharepoint/sharing/information.py +5 -0
  79. office365/sharepoint/sharing/permission_collection.py +13 -9
  80. office365/sharepoint/sharing/recipient_limits.py +9 -0
  81. office365/sharepoint/sharing/site_sharing_report_helper.py +2 -3
  82. office365/sharepoint/tenant/administration/recent_admin_action_report.py +2 -2
  83. office365/sharepoint/tenant/administration/tenant.py +50 -4
  84. {Office365_REST_Python_Client-2.5.10.dist-info → Office365_REST_Python_Client-2.5.12.dist-info}/LICENSE +0 -0
  85. {Office365_REST_Python_Client-2.5.10.dist-info → Office365_REST_Python_Client-2.5.12.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,14 @@ from office365.runtime.client_value import ClientValue
4
4
  class WorkbookFilterCriteria(ClientValue):
5
5
  """Represents the filtering criteria applied to a column."""
6
6
 
7
- def __init__(self, operator=None, values=None):
8
- """ """
7
+ def __init__(self, color=None, dynamicCriteria=None, operator=None, values=None):
8
+ """
9
+ :param str color: The color applied to the cell.
10
+ :param str dynamicCriteria: A dynamic formula specified in a custom filter.
11
+ :param str operator: An operator in a cell; for example, =, >, <, <=, or <>.
12
+ :param list values: The values that appear in the cell.
13
+ """
14
+ self.color = color
15
+ self.dynamicCriteria = dynamicCriteria
9
16
  self.operator = operator
10
17
  self.values = values
@@ -1,5 +1,7 @@
1
1
  from office365.entity_collection import EntityCollection
2
2
  from office365.onedrive.workbooks.tables.rows.row import WorkbookTableRow
3
+ from office365.runtime.client_result import ClientResult
4
+ from office365.runtime.queries.function import FunctionQuery
3
5
 
4
6
 
5
7
  class WorkbookTableRowCollection(EntityCollection[WorkbookTableRow]):
@@ -25,3 +27,21 @@ class WorkbookTableRowCollection(EntityCollection[WorkbookTableRow]):
25
27
  Any rows below the inserted row are shifted downwards. Zero-indexed.
26
28
  """
27
29
  return super(WorkbookTableRowCollection, self).add(values=values, index=index)
30
+
31
+ def count(self):
32
+ """"""
33
+ return_type = ClientResult(self.context, int())
34
+ qry = FunctionQuery(self, "count", None, return_type)
35
+ self.context.add_query(qry)
36
+ return return_type
37
+
38
+ def item_at(self, index):
39
+ # type: (int) -> WorkbookTableRow
40
+ """Gets a row based on its position in the collection.
41
+ :param int index: Index value of the object to be retrieved. Zero-indexed.
42
+ """
43
+ return_type = WorkbookTableRow(self.context)
44
+ self.add_child(return_type)
45
+ qry = FunctionQuery(self, "itemAt", [index], return_type)
46
+ self.context.add_query(qry)
47
+ return return_type
@@ -1,4 +1,4 @@
1
- from typing import Optional
1
+ from typing import List, Optional
2
2
 
3
3
  from office365.entity import Entity
4
4
 
@@ -14,6 +14,7 @@ class WorkbookTableRow(Entity):
14
14
 
15
15
  @property
16
16
  def values(self):
17
+ # type: () -> Optional[List]
17
18
  """
18
19
  Represents the raw values of the specified range. The data returned could be of type string, number,
19
20
  or a boolean. Cell that contain an error will return the error string.
@@ -1,3 +1,5 @@
1
+ from typing_extensions import Self
2
+
1
3
  from office365.entity import Entity
2
4
  from office365.entity_collection import EntityCollection
3
5
  from office365.onedrive.workbooks.applications.application import WorkbookApplication
@@ -50,20 +52,21 @@ class Workbook(Entity):
50
52
  return return_type
51
53
 
52
54
  def refresh_session(self, session_id):
55
+ # type: (str) -> Self
53
56
  """Use this API to refresh an existing workbook session.
54
57
  :param str session_id: Identifier of the workbook session
55
58
  """
56
- qry = ServiceOperationQuery(self, "refreshSession")
57
- self.context.add_query(qry)
58
59
 
59
60
  def _construct_request(request):
60
61
  # type: (RequestOptions) -> None
61
62
  request.set_header("workbook-session-id", session_id)
62
63
 
63
- self.context.before_execute(_construct_request)
64
+ qry = ServiceOperationQuery(self, "refreshSession")
65
+ self.context.add_query(qry).before_query_execute(_construct_request)
64
66
  return self
65
67
 
66
68
  def close_session(self, session_id):
69
+ # type: (str) -> Self
67
70
  """Use this API to close an existing workbook session.
68
71
  :param str session_id: Identifier of the workbook session
69
72
  """
@@ -73,8 +76,7 @@ class Workbook(Entity):
73
76
  # type: (RequestOptions) -> None
74
77
  request.set_header("workbook-session-id", session_id)
75
78
 
76
- self.context.before_execute(_construct_request)
77
- self.context.add_query(qry)
79
+ self.context.add_query(qry).before_query_execute(_construct_request)
78
80
  return self
79
81
 
80
82
  @property
@@ -3,6 +3,7 @@ from typing import AnyStr
3
3
 
4
4
  from office365.runtime.compat import get_mime_type, message_as_bytes_or_string
5
5
  from office365.runtime.http.http_method import HttpMethod
6
+ from office365.runtime.http.request_options import RequestOptions
6
7
  from office365.runtime.queries.batch import create_boundary
7
8
  from office365.runtime.queries.client_query import ClientQuery
8
9
 
@@ -32,9 +33,7 @@ class OneNotePageCreateQuery(ClientQuery):
32
33
  self._files = attachment_files
33
34
 
34
35
  def _construct_multipart_request(self, request):
35
- """
36
- :type request: office365.runtime.http.request_options.RequestOptions
37
- """
36
+ # type: (RequestOptions) -> None
38
37
  request.method = HttpMethod.Post
39
38
  boundary = create_boundary("PageBoundary", True)
40
39
  request.set_header(
File without changes
@@ -0,0 +1,5 @@
1
+ from office365.runtime.client_value import ClientValue
2
+
3
+
4
+ class CalendarSharingMessageAction(ClientValue):
5
+ """"""
@@ -1,5 +1,24 @@
1
+ from office365.outlook.calendar.sharing.message_action import (
2
+ CalendarSharingMessageAction,
3
+ )
1
4
  from office365.outlook.mail.messages.message import Message
2
5
 
3
6
 
4
7
  class CalendarSharingMessage(Message):
5
8
  """"""
9
+
10
+ @property
11
+ def sharing_message_action(self):
12
+ """"""
13
+ return self.properties.setdefault(
14
+ "sharingMessageAction", CalendarSharingMessageAction()
15
+ )
16
+
17
+ def get_property(self, name, default_value=None):
18
+ if default_value is None:
19
+ property_type_mapping = {
20
+ "sharingMessageAction": self.sharing_message_action,
21
+ }
22
+ default_value = property_type_mapping.get(name, None)
23
+
24
+ return super(CalendarSharingMessage, self).get_property(name, default_value)
@@ -5,3 +5,12 @@ class CustomTimeZone(TimeZoneBase):
5
5
  """
6
6
  Represents a time zone where the transition from standard to daylight saving time, or vice versa is not standard.
7
7
  """
8
+
9
+ def __init__(self, bias=None):
10
+ """
11
+ :param int bias: The time offset of the time zone from Coordinated Universal Time (UTC). This value is in
12
+ minutes. Time zones that are ahead of UTC have a positive offset; time zones that are behind UTC have
13
+ a negative offset.
14
+ """
15
+ super(CustomTimeZone, self).__init__()
16
+ self.bias = bias
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.entity import Entity
2
4
 
3
5
 
@@ -6,13 +8,18 @@ class OutlookCategory(Entity):
6
8
  The user defines categories in a master list, and can apply one or more
7
9
  of these user-defined categories to an item."""
8
10
 
11
+ def __str__(self):
12
+ return self.display_name or self.entity_type_name
13
+
9
14
  @property
10
15
  def color(self):
16
+ # type: () -> Optional[str]
11
17
  """A pre-set color constant that characterizes a category, and that is mapped to one of 25 predefined colors"""
12
18
  return self.properties.get("color", None)
13
19
 
14
20
  @property
15
21
  def display_name(self):
22
+ # type: () -> Optional[str]
16
23
  """A unique name that identifies a category in the user's mailbox.
17
24
  After a category is created, the name cannot be changed"""
18
25
  return self.properties.get("displayName", None)
@@ -1,3 +1,4 @@
1
+ from office365.outlook.calendar.dateTimeTimeZone import DateTimeTimeZone
1
2
  from office365.runtime.client_value import ClientValue
2
3
 
3
4
 
@@ -12,6 +13,9 @@ class AutomaticRepliesSetting(ClientValue):
12
13
  external_audience=None,
13
14
  external_reply_message=None,
14
15
  internal_reply_message=None,
16
+ scheduled_end_datetime=DateTimeTimeZone(),
17
+ scheduled_start_datetime=DateTimeTimeZone(),
18
+ status=None,
15
19
  ):
16
20
  """
17
21
  :param str external_audience: The set of audience external to the signed-in user's organization who will
@@ -25,3 +29,6 @@ class AutomaticRepliesSetting(ClientValue):
25
29
  self.externalAudience = external_audience
26
30
  self.externalReplyMessage = external_reply_message
27
31
  self.internalReplyMessage = internal_reply_message
32
+ self.scheduledEndDateTime = scheduled_end_datetime
33
+ self.scheduledStartDateTime = scheduled_start_datetime
34
+ self.status = status
@@ -6,7 +6,6 @@ class ItemBody(ClientValue):
6
6
 
7
7
  def __init__(self, content=None, content_type="Text"):
8
8
  """
9
-
10
9
  :param str content: The content of the item.
11
10
  :param str content_type: The type of the content. Possible values are text and html.
12
11
  """
@@ -14,5 +13,15 @@ class ItemBody(ClientValue):
14
13
  self.content = content
15
14
  self.contentType = content_type
16
15
 
16
+ @staticmethod
17
+ def text(content):
18
+ # type: (str) -> "ItemBody"
19
+ return ItemBody(content)
20
+
21
+ @staticmethod
22
+ def html(content):
23
+ # type: (str) -> "ItemBody"
24
+ return ItemBody(content, "html")
25
+
17
26
  def __repr__(self):
18
27
  return self.content
@@ -1,3 +1,5 @@
1
+ from typing import List
2
+
1
3
  from office365.delta_collection import DeltaCollection
2
4
  from office365.outlook.mail.item_body import ItemBody
3
5
  from office365.outlook.mail.messages.message import Message
@@ -10,6 +12,7 @@ class MessageCollection(DeltaCollection[Message]):
10
12
  super(MessageCollection, self).__init__(context, Message, resource_path)
11
13
 
12
14
  def add(self, subject=None, body=None, to_recipients=None, **kwargs):
15
+ # type: (str, str|ItemBody, List[str], ...) -> Message
13
16
  """
14
17
  Create a draft of a new message in either JSON or MIME format.
15
18
 
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  import uuid
3
3
  from datetime import datetime
4
- from typing import IO, AnyStr, Optional
4
+ from typing import IO, AnyStr, List, Optional
5
5
 
6
6
  from typing_extensions import Self
7
7
 
@@ -42,6 +42,7 @@ class Message(OutlookItem):
42
42
  return self
43
43
 
44
44
  def create_forward(self, to_recipients=None, message=None, comment=None):
45
+ # type: (List[Recipient], "Message", str) -> Message
45
46
  """
46
47
  Create a draft to forward an existing message, in either JSON or MIME format.
47
48
 
@@ -373,9 +374,7 @@ class Message(OutlookItem):
373
374
  @property
374
375
  def subject(self):
375
376
  # type: () -> Optional[str]
376
- """
377
- The subject of the message.
378
- """
377
+ """The subject of the message."""
379
378
  return self.properties.get("subject", None)
380
379
 
381
380
  @subject.setter
@@ -15,6 +15,8 @@ class MessageRulePredicates(ClientValue):
15
15
  from_addresses=None,
16
16
  has_attachments=None,
17
17
  header_contains=None,
18
+ importance=None,
19
+ is_approval_request=None,
18
20
  ):
19
21
  """
20
22
  :param list[str] body_contains: Represents the strings that should appear in the body of an incoming message
@@ -28,6 +30,7 @@ class MessageRulePredicates(ClientValue):
28
30
  :param bool has_attachments: Indicates whether an incoming message must have attachments in order for the
29
31
  condition or exception to apply.
30
32
  :param list[str] header_contains:
33
+ :param bool is_approval_request:
31
34
  """
32
35
  self.bodyContains = StringCollection(body_contains)
33
36
  self.bodyOrSubjectContains = StringCollection(body_or_subject_contains)
@@ -35,3 +38,5 @@ class MessageRulePredicates(ClientValue):
35
38
  self.fromAddresses = ClientValueCollection(Recipient, from_addresses)
36
39
  self.hasAttachments = has_attachments
37
40
  self.headerContains = StringCollection(header_contains)
41
+ self.importance = importance
42
+ self.isApprovalRequest = is_approval_request
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.entity import Entity
2
4
  from office365.outlook.mail.messages.rules.actions import MessageRuleActions
3
5
  from office365.outlook.mail.messages.rules.predicates import MessageRulePredicates
@@ -26,7 +28,6 @@ class MessageRule(Entity):
26
28
 
27
29
  @property
28
30
  def is_read_only(self):
29
- """
30
- Indicates if the rule is read-only and cannot be modified or deleted by the rules REST API.
31
- """
31
+ # type: () -> Optional[bool]
32
+ """Indicates if the rule is read-only and cannot be modified or deleted by the rules REST API."""
32
33
  return self.properties.get("isReadOnly", None)
@@ -40,7 +40,7 @@ def is_valid_auth_cookies(values):
40
40
 
41
41
 
42
42
  class SamlTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
43
- def __init__(self, url, username, password, browser_mode, environment='commercial'):
43
+ def __init__(self, url, username, password, browser_mode, environment="commercial"):
44
44
  """
45
45
  SAML Security Token Service provider (claims-based authentication)
46
46
 
@@ -281,9 +281,9 @@ class SamlTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
281
281
  if not federated or self._browser_mode:
282
282
  headers = {"Content-Type": "application/x-www-form-urlencoded"}
283
283
  if self._browser_mode:
284
- headers[
285
- "User-Agent"
286
- ] = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"
284
+ headers["User-Agent"] = (
285
+ "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"
286
+ )
287
287
  session.post(
288
288
  self._sts_profile.signin_page_url, data=security_token, headers=headers
289
289
  )
@@ -1,20 +1,22 @@
1
+ from typing import Any
2
+
1
3
  from office365.runtime.http.http_method import HttpMethod
2
4
 
3
5
 
4
6
  class RequestOptions(object):
5
7
  """Request options"""
6
8
 
7
- def __init__(self, url):
9
+ def __init__(self, url, method=HttpMethod.Get, data=None):
8
10
  """
9
11
  Request options
10
12
 
11
13
  :param str url: URL for the new :class:`requests.Request` object
12
14
  """
13
15
  self.url = url
14
- self.data = None
16
+ self.data = data
15
17
  self.headers = {}
16
18
  self.auth = None
17
- self.method = HttpMethod.Get
19
+ self.method = method
18
20
  self.verify = True
19
21
  self.stream = False
20
22
  self.proxies = None
@@ -28,8 +30,10 @@ class RequestOptions(object):
28
30
  return hasattr(self.data, "decode") and callable(self.data.decode)
29
31
 
30
32
  def set_header(self, name, value):
33
+ # type: (str, Any) -> None
31
34
  self.headers[name] = value
32
35
 
33
36
  def ensure_header(self, name, value):
37
+ # type: (str, Any) -> None
34
38
  if name not in self.headers:
35
39
  self.headers[name] = value
@@ -59,6 +59,9 @@ class QueryOptions(object):
59
59
  ClientObjectCollection,
60
60
  )
61
61
 
62
+ if name in query_options.select:
63
+ continue
64
+
62
65
  if isinstance(client_object, ClientObjectCollection):
63
66
  prop = client_object.create_typed_object().get_property(name)
64
67
  else:
@@ -61,3 +61,7 @@ class BatchQuery(ClientQuery):
61
61
  @property
62
62
  def url(self):
63
63
  return "{0}/$batch".format(self.context.service_root_url())
64
+
65
+ @property
66
+ def return_type(self):
67
+ return [q.return_type for q in self._queries]
@@ -1,16 +1,14 @@
1
+ from typing import Dict
2
+
3
+ from office365.runtime.client_object import ClientObject
4
+ from office365.runtime.client_value import ClientValue
1
5
  from office365.runtime.queries.client_query import ClientQuery
2
6
 
3
7
 
4
8
  class CreateEntityQuery(ClientQuery):
5
9
  def __init__(self, parent_entity, parameters, return_type=None):
6
- """
7
- Create entity query
8
-
9
- :type return_type: office365.runtime.client_object.ClientObject
10
- :type parameters: office365.runtime.client_object.ClientObject or office365.runtime.client_value.ClientValue
11
- or dict
12
- :type parent_entity: office365.runtime.client_object.ClientObject
13
- """
10
+ # type: (ClientObject, ClientObject|ClientValue|Dict, ClientObject) -> None
11
+ """Create entity query"""
14
12
  super(CreateEntityQuery, self).__init__(
15
13
  parent_entity.context, parent_entity, parameters, None, return_type
16
14
  )
@@ -1,13 +1,11 @@
1
+ from office365.runtime.client_object import ClientObject
1
2
  from office365.runtime.queries.client_query import ClientQuery
2
3
 
3
4
 
4
5
  class UpdateEntityQuery(ClientQuery):
5
6
  def __init__(self, update_type):
6
- """
7
- Update client object query
8
-
9
- :type update_type: office365.runtime.client_object.ClientObject
10
- """
7
+ # type: (ClientObject) -> None
8
+ """Update client object query"""
11
9
  super(UpdateEntityQuery, self).__init__(
12
10
  update_type.context, update_type, update_type
13
11
  )
@@ -1,3 +1,4 @@
1
+ from office365.runtime.queries.service_operation import ServiceOperationQuery
1
2
  from office365.sharepoint.entity import Entity
2
3
 
3
4
 
@@ -6,4 +7,9 @@ class AppPrincipalIdentityProvider(Entity):
6
7
 
7
8
  @staticmethod
8
9
  def external(context):
9
- pass
10
+ return_type = AppPrincipalIdentityProvider(context)
11
+ qry = ServiceOperationQuery(
12
+ return_type, "External", None, None, None, return_type, True
13
+ )
14
+ context.add_query(qry)
15
+ return return_type
@@ -1,6 +1,9 @@
1
- from typing import AnyStr, Optional
1
+ from typing import IO, AnyStr, Optional
2
+
3
+ from typing_extensions import Self
2
4
 
3
5
  from office365.runtime.client_result import ClientResult
6
+ from office365.runtime.queries.function import FunctionQuery
4
7
  from office365.runtime.queries.service_operation import ServiceOperationQuery
5
8
  from office365.sharepoint.entity import Entity
6
9
  from office365.sharepoint.internal.queries.upload_file import create_upload_file_query
@@ -42,6 +45,14 @@ class Attachment(Entity):
42
45
  self.ensure_property("ServerRelativeUrl", _download_file_by_url)
43
46
  return self
44
47
 
48
+ def get_content(self):
49
+ # type: () -> ClientResult[AnyStr]
50
+ """Gets the raw contents of attachment"""
51
+ return_type = ClientResult(self.context)
52
+ qry = FunctionQuery(self, "$value", None, return_type)
53
+ self.context.add_query(qry)
54
+ return return_type
55
+
45
56
  def recycle_object(self):
46
57
  """Move this attachment to site recycle bin."""
47
58
  qry = ServiceOperationQuery(self, "RecycleObject")
@@ -49,6 +60,7 @@ class Attachment(Entity):
49
60
  return self
50
61
 
51
62
  def upload(self, file_object, use_path=True):
63
+ # type: (IO, bool) -> Self
52
64
  """
53
65
  Upload attachment into list item
54
66
 
@@ -90,7 +102,7 @@ class Attachment(Entity):
90
102
  @property
91
103
  def server_relative_url(self):
92
104
  # type: () -> Optional[str]
93
- """ """
105
+ """The server-relative-url of the attachment"""
94
106
  return self.properties.get("ServerRelativeUrl", None)
95
107
 
96
108
  @property
@@ -1,6 +1,10 @@
1
1
  import os
2
- from typing import IO, AnyStr
2
+ from functools import partial
3
+ from typing import IO, AnyStr, Callable, Optional
3
4
 
5
+ from typing_extensions import Self
6
+
7
+ from office365.runtime.client_result import ClientResult
4
8
  from office365.runtime.paths.service_operation import ServiceOperationPath
5
9
  from office365.runtime.queries.service_operation import ServiceOperationQuery
6
10
  from office365.sharepoint.attachments.attachment import Attachment
@@ -74,11 +78,30 @@ class AttachmentCollection(EntityCollection[Attachment]):
74
78
  self.get().after_execute(_delete_all)
75
79
  return self
76
80
 
81
+ def download(self, download_file, file_downloaded=None):
82
+ # type: (IO, Optional[Callable[[Attachment], None]]) -> Self
83
+ """Downloads attachments as a zip file"""
84
+ import zipfile
85
+
86
+ def _file_downloaded(attachment_file, result):
87
+ # type: (Attachment, ClientResult[AnyStr]) -> None
88
+ with zipfile.ZipFile(download_file.name, "a", zipfile.ZIP_DEFLATED) as zf:
89
+ zf.writestr(attachment_file.file_name, result.value)
90
+ if callable(file_downloaded):
91
+ file_downloaded(attachment_file)
92
+
93
+ def _download(return_type):
94
+ for attachment_file in return_type:
95
+ attachment_file.get_content().after_execute(
96
+ partial(_file_downloaded, attachment_file)
97
+ )
98
+
99
+ self.get().after_execute(_download)
100
+ return self
101
+
77
102
  def upload(self, file, use_path=True):
78
103
  # type: (IO, bool) -> Attachment
79
- """
80
- Uploads the attachment
81
- """
104
+ """Uploads the attachment"""
82
105
  info = AttachmentCreationInformation(os.path.basename(file.name), file.read())
83
106
  if use_path:
84
107
  return self.add_using_path(info.filename, info.content)
@@ -0,0 +1,5 @@
1
+ from office365.sharepoint.changes.change import Change
2
+
3
+
4
+ class ChangeAppConsentPrincipal(Change):
5
+ """"""
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from office365.sharepoint.changes.change import Change
2
4
 
3
5
 
@@ -6,10 +8,12 @@ class ChangeFile(Change):
6
8
 
7
9
  @property
8
10
  def unique_id(self):
11
+ # type: () -> Optional[str]
9
12
  """Identifies the file that changed."""
10
13
  return self.properties.get("UniqueId", None)
11
14
 
12
15
  @property
13
16
  def web_id(self):
17
+ # type: () -> Optional[str]
14
18
  """Identifies the site that contains the changed file."""
15
19
  return self.properties.get("WebId", None)
@@ -8,6 +8,7 @@ from office365.runtime.auth.authentication_context import AuthenticationContext
8
8
  from office365.runtime.auth.client_credential import ClientCredential
9
9
  from office365.runtime.auth.token_response import TokenResponse
10
10
  from office365.runtime.auth.user_credential import UserCredential
11
+ from office365.runtime.client_object import ClientObject
11
12
  from office365.runtime.client_result import ClientResult
12
13
  from office365.runtime.client_runtime_context import ClientRuntimeContext
13
14
  from office365.runtime.compat import get_absolute_url, urlparse
@@ -197,11 +198,11 @@ class ClientContext(ClientRuntimeContext):
197
198
  return self
198
199
 
199
200
  def execute_batch(self, items_per_batch=100, success_callback=None):
200
- # type: (int, Callable[[int], None]) -> Self
201
+ # type: (int, Callable[[List[ClientObject|ClientResult]], None]) -> Self
201
202
  """
202
203
  Construct and submit to a server a batch request
203
204
  :param int items_per_batch: Maximum to be selected for bulk operation
204
- :param (int)-> None success_callback: A callback
205
+ :param (List[ClientObject|ClientResult])-> None success_callback: A success callback
205
206
  """
206
207
  batch_request = ODataBatchV3Request(JsonLightFormat())
207
208
  batch_request.beforeExecute += self._authenticate_request
@@ -210,7 +211,7 @@ class ClientContext(ClientRuntimeContext):
210
211
  qry = self._get_next_query(items_per_batch)
211
212
  batch_request.execute_query(qry)
212
213
  if callable(success_callback):
213
- success_callback(items_per_batch)
214
+ success_callback(qry.return_type)
214
215
  return self
215
216
 
216
217
  def pending_request(self):
@@ -7,41 +7,41 @@ from office365.sharepoint.entity_collection import EntityCollection
7
7
  class Group(Entity):
8
8
  def get_members_info(self, row_limit):
9
9
  """"""
10
- result = MembersInfo(self.context)
10
+ return_type = MembersInfo(self.context)
11
11
 
12
12
  def _user_loaded():
13
13
  from office365.sharepoint.directory.helper import SPHelper
14
14
 
15
15
  SPHelper.get_members_info(
16
- self.context, self.properties["Id"], row_limit, result
16
+ self.context, self.properties["Id"], row_limit, return_type
17
17
  )
18
18
 
19
19
  self.ensure_property("Id", _user_loaded)
20
- return result
20
+ return return_type
21
21
 
22
22
  def get_members(self):
23
23
  """"""
24
24
  from office365.directory.users.user import User
25
25
 
26
- members = EntityCollection(self.context, User)
26
+ return_type = EntityCollection(self.context, User)
27
27
 
28
28
  def _group_loaded():
29
- SPHelper.get_members(self.context, self.properties["Id"], members)
29
+ SPHelper.get_members(self.context, self.properties["Id"], return_type)
30
30
 
31
31
  self.ensure_property("Id", _group_loaded)
32
- return members
32
+ return return_type
33
33
 
34
34
  def get_owners(self):
35
35
  """"""
36
36
  from office365.directory.users.user import User
37
37
 
38
- owners = EntityCollection(self.context, User)
38
+ return_type = EntityCollection(self.context, User)
39
39
 
40
40
  def _group_loaded():
41
- SPHelper.get_owners(self.context, self.properties["Id"], owners)
41
+ SPHelper.get_owners(self.context, self.properties["Id"], return_type)
42
42
 
43
43
  self.ensure_property("Id", _group_loaded)
44
- return owners
44
+ return return_type
45
45
 
46
46
  @property
47
47
  def entity_type_name(self):