Skip to content

Commit 686039c

Browse files
committed
Teams API: new types, type hints improvements
1 parent fc53e8d commit 686039c

File tree

39 files changed

+505
-92
lines changed

39 files changed

+505
-92
lines changed

examples/onedrive/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Working with OneDrive and SharePoint API v2 APIs

examples/outlook/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Working with Outlook API
2+
3+
The list of supported APIs:
4+
- [Outlook Contacts REST API](https://msdn.microsoft.com/en-us/office/office365/api/contacts-rest-operations)
5+
- [Outlook Calendar REST API](https://msdn.microsoft.com/en-us/office/office365/api/calendar-rest-operations)
6+
- [Outlook Mail REST API](https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations)

examples/sharepoint/README.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,26 @@
33
This directory contains examples for SharePoint REST API v1
44

55

6-
### [Working with folders and files](./files/)
7-
- **Download** a file: [`download.py`](./files/download.py)
8-
- **Upload** a file: [`upload.py`](./files/upload.py)
9-
- **Create** a folder: [`create.py`](./folders/create.py)
10-
11-
### [Working with lists](./lists/)
12-
- **Create** a list item: [`create_item.py`](./lists/create_item.py)
13-
- **Read** list items (paged): [`read_items.py`](./lists/read_items.py)
14-
15-
### [Working with list items](./listitems/)
16-
- **Update** items in batch: [`update_batch.py`](./listitems/update_batch.py)
17-
- **Delete** an item: [`delete.py`](./listitems/delete.py)
18-
19-
6+
### Working with folders and files
7+
- **Download** a file: [`./files/download.py`](./files/download.py)
8+
- **Upload** a file: [`./files/upload.py`](./files/upload.py)
9+
- **Create** a folder: [`./folders/create.py`](./folders/create.py)
10+
- **Upload** large file: [`./files/upload_large.py`](./files/upload_large.py)
11+
- **List** file version history: [`./versions/list.py`](./files/versions/list.py)
12+
13+
### Working with lists and list items
14+
- **Create** a list item: [`/lists/create_item.py`](./lists/create_item.py)
15+
- **Read** list items (paged): [`/lists/read_items.py`](./lists/read_items.py)
16+
- **Update** items in batch: [`./listitems/update_batch.py`](./listitems/update_batch.py)
17+
- **Delete** an list item: [`./listitems/delete.py`](./listitems/delete.py)
18+
19+
### Working with fields and field values
20+
- **Create** lookup field: [`create_lookup.py`](./fields/create_lookup.py)
21+
22+
### Working with taxonomy
23+
- **Get** field value : [`get_field_value.py`](./taxonomy/get_field_value.py)
24+
25+
### Working with site
2026

2127
---
2228

generator/metadata/Graph.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41874,6 +41874,7 @@ within the time frame of their original request."/>
4187441874
<Member Name="microsoftDefenderThreatIntelligenceAnalytics" Value="1073741846"/>
4187541875
<Member Name="builtInMl" Value="1073741847"/>
4187641876
<Member Name="microsoftInsiderRiskManagement" Value="1073741848"/>
41877+
<Member Name="microsoftThreatIntelligence" Value="1073741849"/>
4187741878
<Member Name="microsoftSentinel" Value="268435456"/>
4187841879
</EnumType>
4187941880
<EnumType Name="detectionStatus">
@@ -42025,6 +42026,7 @@ within the time frame of their original request."/>
4202542026
<Member Name="microsoftDefenderForCloud" Value="256"/>
4202642027
<Member Name="microsoftSentinel" Value="512"/>
4202742028
<Member Name="microsoftInsiderRiskManagement" Value="1024"/>
42029+
<Member Name="microsoftThreatIntelligence" Value="2048"/>
4202842030
</EnumType>
4202942031
<EnumType Name="teamsDeliveryLocation">
4203042032
<Member Name="unknown" Value="0"/>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
11
from office365.directory.authentication.method_configuration import (
22
AuthenticationMethodConfiguration,
33
)
4+
from office365.directory.authentication.methods.sms_target import (
5+
SmsAuthenticationMethodTarget,
6+
)
7+
from office365.entity_collection import EntityCollection
8+
from office365.runtime.paths.resource_path import ResourcePath
49

510

611
class SmsAuthenticationMethodConfiguration(AuthenticationMethodConfiguration):
712
"""Represents a text message authentication methods policy. Authentication methods policies define
813
configuration settings and users or groups that are enabled to use the authentication method.
914
"""
15+
16+
@property
17+
def include_targets(self):
18+
"""Groups of users that are excluded from the policy."""
19+
return self.properties.get(
20+
"includeTargets",
21+
EntityCollection(
22+
self.context,
23+
SmsAuthenticationMethodTarget,
24+
ResourcePath("includeTargets", self.resource_path),
25+
),
26+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from office365.sharepoint.entity import Entity
2+
3+
4+
class SmsAuthenticationMethodTarget(Entity):
5+
"""Represents the users or groups of users that are excluded from a policy."""

office365/directory/security/alerts/history_state.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,9 @@
33

44
class AlertHistoryState(ClientValue):
55
"""Stores changes made to alerts."""
6+
7+
def __init__(self, app_id=None, assigned_to=None, comments=None):
8+
# type: (str, str, list[str]) -> None
9+
self.appId = app_id
10+
self.assignedTo = assigned_to
11+
self.comments = comments
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
from office365.directory.security.hunting_row_result import HuntingRowResult
12
from office365.runtime.client_value import ClientValue
3+
from office365.runtime.client_value_collection import ClientValueCollection
24

35

46
class HuntingQueryResults(ClientValue):
57
"""The results of running a query for advanced hunting."""
8+
9+
def __init__(self, results=None):
10+
self.results = ClientValueCollection(HuntingRowResult, results)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class HuntingRowResult(ClientValue):
5+
"""Represents a row of the results from running an advanced hunting query.
6+
7+
The content of the results is depended on the submitted KQL query, see KQL quick reference.
8+
"""

office365/directory/security/security.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
from office365.directory.security.incidents.incident import Incident
77
from office365.directory.security.labels.root import LabelsRoot
88
from office365.directory.security.scorecontrol.profile import SecureScoreControlProfile
9+
from office365.directory.security.subjectrightsrequests.request import (
10+
SubjectRightsRequest,
11+
)
912
from office365.directory.security.threatintelligence.threat_intelligence import (
1013
ThreatIntelligence,
1114
)
@@ -93,6 +96,19 @@ def labels(self):
9396
LabelsRoot(self.context, ResourcePath("labels", self.resource_path)),
9497
)
9598

99+
@property
100+
def subject_rights_requests(self):
101+
# type: () -> EntityCollection[SubjectRightsRequest]
102+
"""Get a list of the subjectRightsRequest objects and their properties."""
103+
return self.properties.get(
104+
"subjectRightsRequests",
105+
EntityCollection(
106+
self.context,
107+
SubjectRightsRequest,
108+
ResourcePath("subjectRightsRequests", self.resource_path),
109+
),
110+
)
111+
96112
@property
97113
def secure_score_control_profiles(self):
98114
""""""
@@ -128,6 +144,7 @@ def get_property(self, name, default_value=None):
128144
property_mapping = {
129145
"alerts_v2": self.alerts_v2,
130146
"attackSimulation": self.attack_simulation,
147+
"subjectRightsRequests": self.subject_rights_requests,
131148
"secureScoreControlProfiles": self.secure_score_control_profiles,
132149
"threatIntelligence": self.threat_intelligence,
133150
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from office365.entity import Entity
2+
3+
4+
class SubjectRightsRequest(Entity):
5+
"""Represents the properties of a subject rights request, which is a formal request by a data subject to
6+
a controller to take an action on their personal data."""
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from office365.runtime.client_value import ClientValue
2+
3+
4+
class SubjectRightsRequestStageDetail(ClientValue):
5+
"""Represents the properties of the stages of a subject rights request."""
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from office365.entity import Entity
2+
3+
4+
class AttributeMappingFunctionSchema(Entity):
5+
"""Describes a function that can be used in an attribute mapping to transform values during synchronization."""

office365/directory/synchronization/schema.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
from office365.directory.synchronization.attribute_mapping_function_schema import (
2+
AttributeMappingFunctionSchema,
3+
)
14
from office365.directory.synchronization.directory_definition import DirectoryDefinition
25
from office365.entity import Entity
36
from office365.entity_collection import EntityCollection
47
from office365.runtime.paths.resource_path import ResourcePath
8+
from office365.runtime.queries.function import FunctionQuery
59

610

711
class SynchronizationSchema(Entity):
@@ -13,6 +17,13 @@ class SynchronizationSchema(Entity):
1317
The following sections describe the high-level components of the synchronization schema.
1418
"""
1519

20+
def functions(self):
21+
"""List all the functions currently supported in the attributeMappingSource."""
22+
return_type = EntityCollection(self.context, AttributeMappingFunctionSchema)
23+
qry = FunctionQuery(self, "functions", None, return_type)
24+
self.context.add_query(qry)
25+
return return_type
26+
1627
@property
1728
def directories(self):
1829
# type: () -> EntityCollection[DirectoryDefinition]

office365/entity_collection.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import TYPE_CHECKING, Any, Optional, Type, TypeVar
1+
from typing import TYPE_CHECKING, Any, Optional, Type
22

33
from typing_extensions import Self
44

@@ -12,7 +12,7 @@
1212
if TYPE_CHECKING:
1313
from office365.graph_client import GraphClient
1414

15-
T = TypeVar("T")
15+
from office365.runtime.client_object import T
1616

1717

1818
class EntityCollection(ClientObjectCollection[T]):
@@ -26,6 +26,7 @@ def __init__(self, context, item_type, resource_path=None, parent=None):
2626
self._delta_request_url = None
2727

2828
def token(self, value):
29+
# type: (str) -> T
2930
"""
3031
Apply delta query
3132

office365/onedrive/driveitems/driveItem.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from datetime import datetime
55
from functools import partial
66
from os.path import isfile, join
7-
from typing import IO, AnyStr, Callable, Optional, TypeVar
7+
from typing import IO, AnyStr, Callable, Optional
88

99
import requests
1010
from typing_extensions import Self
@@ -58,8 +58,6 @@
5858
from office365.runtime.queries.upload_session import UploadSessionQuery
5959
from office365.subscriptions.collection import SubscriptionCollection
6060

61-
P_T = TypeVar("P_T")
62-
6361

6462
class DriveItem(BaseItem):
6563
"""The driveItem resource represents a file, folder, or other item stored in a drive. All file system objects in
@@ -931,7 +929,6 @@ def set_property(self, name, value, persist_changes=True):
931929
return self
932930

933931
def get_property(self, name, default_value=None):
934-
# type: (str, P_T) -> P_T
935932
if default_value is None:
936933
property_mapping = {
937934
"fileSystemInfo": self.file_system_info,

office365/outlook/mail/messages/message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from office365.outlook.mail.messages.followup_flag import FollowupFlag
1818
from office365.outlook.mail.messages.internet_header import InternetMessageHeader
1919
from office365.outlook.mail.recipient import Recipient
20-
from office365.runtime.client_object import persist_property
20+
from office365.runtime.client_object_meta import persist_property
2121
from office365.runtime.client_result import ClientResult
2222
from office365.runtime.client_value_collection import ClientValueCollection
2323
from office365.runtime.paths.resource_path import ResourcePath

office365/outlook/mail/messages/rules/rule.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from office365.entity import Entity
44
from office365.outlook.mail.messages.rules.actions import MessageRuleActions
55
from office365.outlook.mail.messages.rules.predicates import MessageRulePredicates
6-
from office365.runtime.client_object import persist_property
6+
from office365.runtime.client_object_meta import persist_property
77

88

99
class MessageRule(Entity):

office365/runtime/client_object.py

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
from __future__ import annotations
22

33
import datetime
4-
from typing import TYPE_CHECKING, Any, Callable, Generic, List, Optional, TypeVar
4+
from typing import (
5+
TYPE_CHECKING,
6+
Any,
7+
Callable,
8+
Generic,
9+
List,
10+
Optional,
11+
TypeVar,
12+
Union,
13+
)
514

615
from requests import Response
716
from typing_extensions import Self
@@ -20,27 +29,8 @@
2029
from office365.runtime.client_object_collection import ClientObjectCollection
2130

2231

23-
T = TypeVar("T")
24-
P_T = TypeVar("P_T")
25-
"""Property Type."""
26-
27-
28-
def persist_property(property_name=None):
29-
# type: (Optional[str]) -> Callable[[Callable[..., P_T]], Callable[..., P_T]]
30-
"""Decorator to automatically track property access for persistence"""
31-
32-
def decorator(method):
33-
# type: (Callable[..., P_T]) -> Callable[..., P_T]
34-
def wrapper(self, *args, **kwargs):
35-
# type: (ClientObject, *Any, **Any) -> P_T
36-
name = property_name if property_name is not None else method.__name__
37-
if name not in self._properties_to_persist:
38-
self._properties_to_persist.append(name)
39-
return method(self, *args, **kwargs)
40-
41-
return wrapper
42-
43-
return decorator
32+
T = TypeVar("T", bound="ClientObject")
33+
PropertyT = Union[bool, int, float, str, bytes, ClientValue]
4434

4535

4636
class ClientObject(Generic[T]):
@@ -67,6 +57,9 @@ def clear_state(self):
6757
self._query_options = QueryOptions()
6858
return self
6959

60+
# @overload
61+
# def execute_query(self: T) -> T: ...
62+
7063
def execute_query(self):
7164
# type: () -> Self
7265
"""Submit request(s) to the server."""
@@ -113,6 +106,9 @@ def after_execute(self, action, execute_first=False, include_response=False):
113106
self.context.after_query_execute(action, execute_first, include_response)
114107
return self
115108

109+
# @overload
110+
# def get(self: T) -> T: ...
111+
116112
def get(self):
117113
# type: () -> Self
118114
"""Retrieves a client object from the server."""
@@ -162,15 +158,15 @@ def _persist_changes(self, name):
162158
return self
163159

164160
def get_property(self, name, default_value=None):
165-
# type: (str, P_T) -> P_T
161+
# type: (str, PropertyT) -> PropertyT
166162
"""Gets property value."""
167163
if default_value is None:
168164
normalized_name = name[0].lower() + name[1:]
169165
default_value = getattr(self, normalized_name, None)
170166
return self._properties.get(name, default_value)
171167

172168
def set_property(self, name, value, persist_changes=True):
173-
# type: (str|int, P_T, bool) -> Self
169+
# type: (str|int, PropertyT, bool) -> Self
174170
"""Sets property value"""
175171
if persist_changes:
176172
self._properties_to_persist.append(name)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from __future__ import annotations
2+
3+
from typing import Any, Callable, Optional
4+
5+
from office365.runtime.client_object import ClientObject, PropertyT
6+
7+
8+
def persist_property(property_name=None):
9+
# type: (Optional[str]) -> Callable[[Callable[..., PropertyT]], Callable[..., PropertyT]]
10+
"""Decorator to automatically track property access for persistence"""
11+
12+
def decorator(method):
13+
# type: (Callable[..., PropertyT]) -> Callable[..., PropertyT]
14+
def wrapper(self, *args, **kwargs):
15+
# type: (ClientObject, *Any, **Any) -> PropertyT
16+
name = property_name if property_name is not None else method.__name__
17+
if name not in self._properties_to_persist:
18+
self._properties_to_persist.append(name)
19+
return method(self, *args, **kwargs)
20+
21+
return wrapper
22+
23+
return decorator

0 commit comments

Comments
 (0)