Skip to content

Commit

Permalink
Merge pull request #746 from kellerza/typing
Browse files Browse the repository at this point in the history
Improve typing
  • Loading branch information
vgrem authored Oct 4, 2023
2 parents b00e008 + 1ea302a commit eb3c45e
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 50 deletions.
12 changes: 8 additions & 4 deletions office365/entity_collection.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
from typing import TypeVar

from office365.runtime.client_object_collection import ClientObjectCollection
from office365.runtime.compat import is_string_type
from office365.runtime.paths.item import ItemPath
from office365.runtime.queries.create_entity import CreateEntityQuery
from office365.runtime.paths.resource_path import ResourcePath
from office365.graph_client import GraphClient

T = TypeVar("T")

class EntityCollection(ClientObjectCollection):
class EntityCollection(ClientObjectCollection[T]):
"""A collection container which represents a named collections of entities"""

def __getitem__(self, key):
# type: (int | str) -> T
"""
:param key: key is used to address an entity by either an index or by identifier
:type key: int or str
Expand All @@ -21,6 +26,7 @@ def __getitem__(self, key):
raise ValueError("Invalid key: expected either an entity index [int] or identifier [str]")

def add(self, **kwargs):
# type: (Any) -> T
"""
Creates an entity and prepares the query
"""
Expand All @@ -32,7 +38,5 @@ def add(self, **kwargs):

@property
def context(self):
"""
:rtype: office365.graph_client.GraphClient
"""
# type: () -> GraphClient
return self._context
19 changes: 9 additions & 10 deletions office365/graph_client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Callable

from office365.booking.solutions.root import SolutionsRoot
from office365.communications.cloud_communications import CloudCommunications
from office365.delta_collection import DeltaCollection
Expand Down Expand Up @@ -64,6 +66,7 @@ class GraphClient(ClientRuntimeContext):
"""Graph Service client"""

def __init__(self, acquire_token_callback):
# type: (Callable[None, dict]) -> None
"""
:param () -> dict acquire_token_callback: Acquire token function
"""
Expand All @@ -86,32 +89,28 @@ def execute_batch(self, items_per_batch=100):
return self

def pending_request(self):
# type: () -> ODataRequest
if self._pending_request is None:
self._pending_request = ODataRequest(V4JsonFormat())
self._pending_request.beforeExecute += self._authenticate_request
self._pending_request.beforeExecute += self._build_specific_query
return self._pending_request

def service_root_url(self):
# type: () -> str
return "https://graph.microsoft.com/v1.0"

def _build_specific_query(self, request):
"""
Builds Graph specific HTTP request
:type request: RequestOptions
"""
# type: (RequestOptions) -> None
"""Builds Graph specific HTTP request."""
if isinstance(self.current_query, UpdateEntityQuery):
request.method = HttpMethod.Patch
elif isinstance(self.current_query, DeleteEntityQuery):
request.method = HttpMethod.Delete

def _authenticate_request(self, request):
"""
Authenticate request
:type request: RequestOptions
"""
# type: (RequestOptions) -> None
"""Authenticate request."""
token_json = self._acquire_token_callback()
token = TokenResponse.from_json(token_json)
request.ensure_header('Authorization', 'Bearer {0}'.format(token.accessToken))
Expand Down
1 change: 1 addition & 0 deletions office365/onedrive/drives/drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def owner(self):

@property
def root(self):
# type: () -> DriveItem
"""The root folder of the drive."""
return self.properties.get('root',
DriveItem(self.context, RootPath(self.resource_path, self.items.resource_path)))
Expand Down
24 changes: 22 additions & 2 deletions office365/onedrive/sites/site.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from typing import Optional
from datetime import datetime

from office365.base_item import BaseItem
from office365.entity_collection import EntityCollection
from office365.onedrive.analytics.item_activity_stat import ItemActivityStat
Expand All @@ -22,6 +25,7 @@ class Site(BaseItem):
"""The site resource provides metadata and relationships for a SharePoint site. """

def get_by_path(self, path):
# type: (str) -> Site
"""
Retrieve properties and relationships for a site resource. A site resource represents a team site in SharePoint.
Expand All @@ -34,15 +38,14 @@ def get_by_path(self, path):
/sites/root: The tenant root site.
/groups/{group-id}/sites/root: The group's team site.
:type path: str
"""
return_type = Site(self.context)
qry = ServiceOperationQuery(self, "GetByPath", [path], None, None, return_type)
self.context.add_query(qry)
return return_type

def get_applicable_content_types_for_list(self, list_id):
# type: (str) -> ContentTypeCollection
"""
Get site contentTypes that can be added to a list.
Expand All @@ -57,6 +60,7 @@ def get_applicable_content_types_for_list(self, list_id):
return return_type

def get_activities_by_interval(self, start_dt=None, end_dt=None, interval=None):
# type: (Optional[datetime], Optional[datetime], str) -> EntityCollection[ItemActivityStat]
"""
Get a collection of itemActivityStats resources for the activities that took place on this resource
within the specified time interval.
Expand All @@ -77,29 +81,34 @@ def get_activities_by_interval(self, start_dt=None, end_dt=None, interval=None):

@property
def site_collection(self):
# type: () -> SiteCollection
"""Provides details about the site's site collection. Available only on the root site."""
return self.properties.get("siteCollection", SiteCollection())

@property
def sharepoint_ids(self):
# type: () -> SharePointIds
"""Returns identifiers useful for SharePoint REST compatibility."""
return self.properties.get('sharepointIds', SharePointIds())

@property
def items(self):
# type: () -> EntityCollection[ListItem]
"""Used to address any item contained in this site. This collection cannot be enumerated."""
return self.properties.get('items',
EntityCollection(self.context, ListItem, ResourcePath("items", self.resource_path)))

@property
def columns(self):
# type: () -> ColumnDefinitionCollection
"""The collection of columns under this site."""
return self.properties.get('columns',
ColumnDefinitionCollection(self.context,
ResourcePath("columns", self.resource_path), self))

@property
def external_columns(self):
# type: () -> ColumnDefinitionCollection
"""The collection of columns under this site."""
return self.properties.get('externalColumns',
ColumnDefinitionCollection(self.context,
Expand All @@ -108,68 +117,79 @@ def external_columns(self):

@property
def content_types(self):
# type: () -> ContentTypeCollection
"""The collection of content types under this site."""
return self.properties.get('contentTypes',
ContentTypeCollection(self.context,
ResourcePath("contentTypes", self.resource_path)))

@property
def lists(self):
# type: () -> ListCollection
"""The collection of lists under this site."""
return self.properties.get('lists',
ListCollection(self.context, ResourcePath("lists", self.resource_path)))

@property
def operations(self):
# type: () -> EntityCollection[RichLongRunningOperation]
"""The collection of long-running operations on the site."""
return self.properties.get('operations',
EntityCollection(self.context, RichLongRunningOperation,
ResourcePath("operations", self.resource_path)))

@property
def permissions(self):
# type: () -> PermissionCollection
"""The permissions associated with the site."""
return self.properties.get('permissions',
PermissionCollection(self.context, ResourcePath("permissions", self.resource_path)))

@property
def drive(self):
# type: () -> Drive
"""The default drive (document library) for this site."""
return self.properties.get('drive',
Drive(self.context, ResourcePath("drive", self.resource_path)))

@property
def drives(self):
# type: () -> EntityCollection[Drive]
"""The collection of drives under this site."""
return self.properties.get('drives',
EntityCollection(self.context, Drive, ResourcePath("drives", self.resource_path)))

@property
def sites(self):
# type: () -> EntityCollection[Site]
"""The collection of sites under this site."""
return self.properties.get('sites',
EntityCollection(self.context, Site, ResourcePath("sites", self.resource_path)))

@property
def analytics(self):
# type: () -> ItemAnalytics
"""Analytics about the view activities that took place on this site."""
return self.properties.get('analytics',
ItemAnalytics(self.context, ResourcePath("analytics", self.resource_path)))

@property
def onenote(self):
# type: () -> Onenote
"""Represents the Onenote services available to a site."""
return self.properties.get('onenote',
Onenote(self.context, ResourcePath("onenote", self.resource_path)))

@property
def term_store(self):
# type: () -> Store
"""The default termStore under this site."""
return self.properties.get('termStore',
Store(self.context, ResourcePath("termStore", self.resource_path)))

@property
def term_stores(self):
# type: () -> EntityCollection[Store]
"""The collection of termStores under this site."""
return self.properties.get('termStores',
EntityCollection(self.context, Store,
Expand Down
2 changes: 2 additions & 0 deletions office365/onedrive/sites/sites_with_root.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def remove(self, sites):
return return_type

def search(self, query_text):
# type: (str) -> SitesWithRoot
"""
Search across a SharePoint tenant for sites that match keywords provided.
Expand All @@ -61,4 +62,5 @@ def search(self, query_text):

@property
def root(self):
# type: () -> Site
return self.properties.get('root', Site(self.context, RootPath(self.resource_path, self.resource_path)))
Loading

0 comments on commit eb3c45e

Please sign in to comment.