diff --git a/examples/sharepoint/read_resource_no_model.py b/examples/sharepoint/read_resource_no_model.py
index fb5f56542..8c458b898 100644
--- a/examples/sharepoint/read_resource_no_model.py
+++ b/examples/sharepoint/read_resource_no_model.py
@@ -4,13 +4,12 @@
import json
-from office365.sharepoint.client_context import ClientContext
+from office365.sharepoint.request import SharePointRequest
from tests import test_site_url, test_user_credentials
if __name__ == "__main__":
- client = ClientContext(test_site_url).with_credentials(test_user_credentials)
- response = client.execute_request_direct("web")
- response.raise_for_status()
+ request = SharePointRequest(test_site_url).with_credentials(test_user_credentials)
+ response = request.execute_request("web")
json = json.loads(response.content)
web_title = json["d"]["Title"]
print("Web title: {0}".format(web_title))
diff --git a/generator/builders/template_context.py b/generator/builders/template_context.py
index ef0143559..7ab857855 100644
--- a/generator/builders/template_context.py
+++ b/generator/builders/template_context.py
@@ -1,8 +1,6 @@
class TemplateContext:
def __init__(self, template_path):
- """
- :type template_path: str
- """
+ # type: (str) -> None
self._template_path = template_path
def build(self, schema):
diff --git a/generator/import_metadata.py b/generator/import_metadata.py
index 0bb39167f..093a0ba27 100644
--- a/generator/import_metadata.py
+++ b/generator/import_metadata.py
@@ -26,13 +26,13 @@ def export_to_file(path, content):
"--endpoint",
dest="endpoint",
help="Import metadata endpoint",
- default="sharepoint",
+ default="microsoftgraph",
)
parser.add_argument(
"-p",
"--path",
dest="path",
- default="./metadata/SharePoint.xml",
+ default="./metadata/MicrosoftGraph.xml",
help="Import metadata endpoint",
)
diff --git a/generator/metadata/MicrosoftGraph.xml b/generator/metadata/MicrosoftGraph.xml
index 89b83f279..28e0c2924 100644
--- a/generator/metadata/MicrosoftGraph.xml
+++ b/generator/metadata/MicrosoftGraph.xml
@@ -18337,6 +18337,12 @@
+
+
+
+
+
+
@@ -28889,6 +28895,7 @@
+
diff --git a/office365/directory/synchronization/status.py b/office365/directory/synchronization/status.py
index 44acffb04..13e9cfa62 100644
--- a/office365/directory/synchronization/status.py
+++ b/office365/directory/synchronization/status.py
@@ -1,5 +1,6 @@
from office365.directory.synchronization.progress import SynchronizationProgress
from office365.directory.synchronization.quarantine import SynchronizationQuarantine
+from office365.directory.synchronization.task_execution import SynchronizationTaskExecution
from office365.runtime.client_value import ClientValue
from office365.runtime.client_value_collection import ClientValueCollection
@@ -7,10 +8,16 @@
class SynchronizationStatus(ClientValue):
"""Represents the current status of the synchronizationJob."""
- def __init__(self, progress=None, quarantine=SynchronizationQuarantine()):
+ def __init__(self, progress=None, quarantine=SynchronizationQuarantine(),
+ last_execution=SynchronizationTaskExecution(),
+ last_successful_execution=SynchronizationTaskExecution(),
+ last_successful_execution_with_exports=SynchronizationTaskExecution()):
"""
:param list[SynchronizationProgress] progress: Details of the progress of a job toward completion.
:param SynchronizationQuarantine quarantine:
"""
self.progress = ClientValueCollection(SynchronizationProgress, progress)
self.quarantine = quarantine
+ self.lastExecution = last_execution
+ self.lastSuccessfulExecution = last_successful_execution
+ self.lastSuccessfulExecutionWithExports = last_successful_execution_with_exports
diff --git a/office365/directory/synchronization/task_execution.py b/office365/directory/synchronization/task_execution.py
new file mode 100644
index 000000000..7bb629b23
--- /dev/null
+++ b/office365/directory/synchronization/task_execution.py
@@ -0,0 +1,5 @@
+from office365.runtime.client_value import ClientValue
+
+
+class SynchronizationTaskExecution(ClientValue):
+ """Summarizes the results of the synchronization job run."""
diff --git a/office365/onedrive/listitems/list_item.py b/office365/onedrive/listitems/list_item.py
index cac77ab54..15df796b8 100644
--- a/office365/onedrive/listitems/list_item.py
+++ b/office365/onedrive/listitems/list_item.py
@@ -38,6 +38,7 @@ def fields(self):
@property
def versions(self):
+ # type: () -> EntityCollection[ListItemVersion]
"""The list of previous versions of the list item."""
return self.properties.get(
"versions",
diff --git a/office365/runtime/http/request_options.py b/office365/runtime/http/request_options.py
index a239aaedc..65caf3455 100644
--- a/office365/runtime/http/request_options.py
+++ b/office365/runtime/http/request_options.py
@@ -1,20 +1,22 @@
+from typing import Any
+
from office365.runtime.http.http_method import HttpMethod
class RequestOptions(object):
"""Request options"""
- def __init__(self, url):
+ def __init__(self, url, method=HttpMethod.Get, data=None):
"""
Request options
:param str url: URL for the new :class:`requests.Request` object
"""
self.url = url
- self.data = None
+ self.data = data
self.headers = {}
self.auth = None
- self.method = HttpMethod.Get
+ self.method = method
self.verify = True
self.stream = False
self.proxies = None
@@ -28,8 +30,10 @@ def is_bytes(self):
return hasattr(self.data, "decode") and callable(self.data.decode)
def set_header(self, name, value):
+ # type: (str, Any) -> None
self.headers[name] = value
def ensure_header(self, name, value):
+ # type: (str, Any) -> None
if name not in self.headers:
self.headers[name] = value
diff --git a/office365/sharepoint/changes/app_consent_principal.py b/office365/sharepoint/changes/app_consent_principal.py
new file mode 100644
index 000000000..8e54c3ae8
--- /dev/null
+++ b/office365/sharepoint/changes/app_consent_principal.py
@@ -0,0 +1,5 @@
+from office365.sharepoint.changes.change import Change
+
+
+class ChangeAppConsentPrincipal(Change):
+ """"""
diff --git a/office365/sharepoint/request.py b/office365/sharepoint/request.py
index 7f67fdc8e..e64ae73f8 100644
--- a/office365/sharepoint/request.py
+++ b/office365/sharepoint/request.py
@@ -1,7 +1,42 @@
+from typing import Optional
+
+from requests import Response
+from typing_extensions import Self
+
+from office365.runtime.auth.authentication_context import AuthenticationContext
+from office365.runtime.auth.client_credential import ClientCredential
+from office365.runtime.auth.user_credential import UserCredential
+from office365.runtime.http.request_options import RequestOptions
from office365.runtime.odata.request import ODataRequest
from office365.runtime.odata.v3.json_light_format import JsonLightFormat
class SharePointRequest(ODataRequest):
- def __init__(self):
+ def __init__(self, base_url):
super().__init__(JsonLightFormat())
+ self._auth_context = AuthenticationContext(url=base_url)
+ self.beforeExecute += self._authenticate_request
+
+ def execute_request(self, path):
+ # type: (str) -> Response
+ request_url = "{0}/_api/{1}".format(self._auth_context.url, path)
+ return self.execute_request_direct(RequestOptions(request_url))
+
+ def with_credentials(self, credentials, environment="commercial"):
+ # type: (UserCredential|ClientCredential, Optional[str]) -> Self
+ """
+ Initializes a client to acquire a token via user or client credentials
+ :type credentials: UserCredential or ClientCredential
+ :param str environment: The Office 365 Cloud Environment endpoint used for authentication
+ defaults to 'commercial'.
+ """
+ self._auth_context.with_credentials(
+ credentials, environment=environment
+ )
+ return self
+
+ def _authenticate_request(self, request):
+ # type: (RequestOptions) -> None
+ """Authenticate request"""
+ self._auth_context.authenticate_request(request)
+
diff --git a/office365/sharepoint/sharing/information.py b/office365/sharepoint/sharing/information.py
index b0bb9eaed..6bab378d0 100644
--- a/office365/sharepoint/sharing/information.py
+++ b/office365/sharepoint/sharing/information.py
@@ -22,6 +22,11 @@ def access_request_settings(self):
"""
return self.properties.get("accessRequestSettings", AccessRequestSettings())
+ @property
+ def anonymous_link_expiration_restriction_days(self):
+ """Tenant's anonymous link expiration restriction in days."""
+ return self.properties.get("anonymousLinkExpirationRestrictionDays", None)
+
@property
def permissions_information(self):
"""
diff --git a/office365/sharepoint/sharing/permission_collection.py b/office365/sharepoint/sharing/permission_collection.py
index af6290635..b570454aa 100644
--- a/office365/sharepoint/sharing/permission_collection.py
+++ b/office365/sharepoint/sharing/permission_collection.py
@@ -14,25 +14,27 @@ class PermissionCollection(ClientValue):
def __init__(
self,
- hasInheritedLinks=None,
+ app_consent_principals=None,
+ has_inherited_links=None,
links=None,
principals=None,
- siteAdmins=None,
- totalNumberOfPrincipals=None,
+ site_admins=None,
+ total_number_of_principals=None,
):
"""
- :param bool hasInheritedLinks:
+ :param bool has_inherited_links:
:param list[LinkInfo] links: The List of tokenized sharing links with their LinkInfo objects.
:param list[PrincipalInfo] principals: The List of Principals with their roles on this list item.
- :param list[PrincipalInfo] siteAdmins: The List of Principals who are Site Admins. This property is returned
+ :param list[PrincipalInfo] site_admins: The List of Principals who are Site Admins. This property is returned
only if the caller is an Auditor.
- :param int totalNumberOfPrincipals:
+ :param int total_number_of_principals:
"""
- self.hasInheritedLinks = hasInheritedLinks
+ self.appConsentPrincipals = ClientValueCollection(PrincipalInfo, app_consent_principals)
+ self.hasInheritedLinks = has_inherited_links
self.links = ClientValueCollection(LinkInfo, links)
self.principals = ClientValueCollection(PrincipalInfo, principals)
- self.siteAdmins = ClientValueCollection(PrincipalInfo, siteAdmins)
- self.totalNumberOfPrincipals = totalNumberOfPrincipals
+ self.siteAdmins = ClientValueCollection(PrincipalInfo, site_admins)
+ self.totalNumberOfPrincipals = total_number_of_principals
@property
def entity_type_name(self):
diff --git a/office365/sharepoint/sharing/recipient_limits.py b/office365/sharepoint/sharing/recipient_limits.py
new file mode 100644
index 000000000..d54ce1d02
--- /dev/null
+++ b/office365/sharepoint/sharing/recipient_limits.py
@@ -0,0 +1,9 @@
+from office365.runtime.client_value import ClientValue
+
+
+class RecipientLimits(ClientValue):
+ """"""
+
+ @property
+ def entity_type_name(self):
+ return "SP.Sharing.RecipientLimits"
diff --git a/office365/sharepoint/sharing/site_sharing_report_helper.py b/office365/sharepoint/sharing/site_sharing_report_helper.py
index d44e30990..99050c856 100644
--- a/office365/sharepoint/sharing/site_sharing_report_helper.py
+++ b/office365/sharepoint/sharing/site_sharing_report_helper.py
@@ -1,5 +1,6 @@
from office365.runtime.client_result import ClientResult
from office365.runtime.queries.service_operation import ServiceOperationQuery
+from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.entity import Entity
from office365.sharepoint.sharing.reports.site_capabilities import (
SiteSharingReportCapabilities,
@@ -12,9 +13,7 @@
class SiteSharingReportHelper(Entity):
@staticmethod
def cancel_sharing_report_job(context):
- """
- :type context: office365.sharepoint.client_context.ClientContext
- """
+ # type: (ClientContext) -> ClientResult[SiteSharingReportStatus]
return_type = ClientResult(context, SiteSharingReportStatus())
binding_type = SiteSharingReportHelper(context)
qry = ServiceOperationQuery(