Skip to content

Commit

Permalink
#612: introduced SharePointRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
vgrem committed Jun 9, 2024
1 parent f6db7c5 commit b2d4802
Show file tree
Hide file tree
Showing 14 changed files with 102 additions and 26 deletions.
7 changes: 3 additions & 4 deletions examples/sharepoint/read_resource_no_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
4 changes: 1 addition & 3 deletions generator/builders/template_context.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down
4 changes: 2 additions & 2 deletions generator/import_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
)

Expand Down
7 changes: 7 additions & 0 deletions generator/metadata/MicrosoftGraph.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18337,6 +18337,12 @@
<Member Name="serviceProvider" Value="32"/>
<Member Name="unknownFutureValue" Value="64"/>
</EnumType>
<EnumType Name="conditionalAccessInsiderRiskLevels" IsFlags="true">
<Member Name="minor" Value="1"/>
<Member Name="moderate" Value="2"/>
<Member Name="elevated" Value="4"/>
<Member Name="unknownFutureValue" Value="8"/>
</EnumType>
<EnumType Name="conditionalAccessPolicyState">
<Member Name="enabled" Value="0"/>
<Member Name="disabled" Value="1"/>
Expand Down Expand Up @@ -28889,6 +28895,7 @@
<Property Name="clientApplications" Type="graph.conditionalAccessClientApplications"/>
<Property Name="clientAppTypes" Type="Collection(graph.conditionalAccessClientApp)" Nullable="false"/>
<Property Name="devices" Type="graph.conditionalAccessDevices"/>
<Property Name="insiderRiskLevels" Type="graph.conditionalAccessInsiderRiskLevels"/>
<Property Name="locations" Type="graph.conditionalAccessLocations"/>
<Property Name="platforms" Type="graph.conditionalAccessPlatforms"/>
<Property Name="servicePrincipalRiskLevels" Type="Collection(graph.riskLevel)" Nullable="false"/>
Expand Down
9 changes: 8 additions & 1 deletion office365/directory/synchronization/status.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
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


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
5 changes: 5 additions & 0 deletions office365/directory/synchronization/task_execution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from office365.runtime.client_value import ClientValue


class SynchronizationTaskExecution(ClientValue):
"""Summarizes the results of the synchronization job run."""
1 change: 1 addition & 0 deletions office365/onedrive/listitems/list_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 7 additions & 3 deletions office365/runtime/http/request_options.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
5 changes: 5 additions & 0 deletions office365/sharepoint/changes/app_consent_principal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from office365.sharepoint.changes.change import Change


class ChangeAppConsentPrincipal(Change):
""""""
37 changes: 36 additions & 1 deletion office365/sharepoint/request.py
Original file line number Diff line number Diff line change
@@ -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)

5 changes: 5 additions & 0 deletions office365/sharepoint/sharing/information.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down
20 changes: 11 additions & 9 deletions office365/sharepoint/sharing/permission_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
9 changes: 9 additions & 0 deletions office365/sharepoint/sharing/recipient_limits.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from office365.runtime.client_value import ClientValue


class RecipientLimits(ClientValue):
""""""

@property
def entity_type_name(self):
return "SP.Sharing.RecipientLimits"
5 changes: 2 additions & 3 deletions office365/sharepoint/sharing/site_sharing_report_helper.py
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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(
Expand Down

0 comments on commit b2d4802

Please sign in to comment.