Office365-REST-Python-Client 2.5.5__py3-none-any.whl → 2.5.7__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.
- {Office365_REST_Python_Client-2.5.5.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/METADATA +6 -6
- {Office365_REST_Python_Client-2.5.5.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/RECORD +269 -222
- office365/booking/virtualevents/__init__.py +0 -0
- office365/booking/virtualevents/root.py +5 -0
- office365/communications/calls/participant.py +4 -5
- office365/directory/administrative_unit.py +9 -2
- office365/directory/applications/application.py +3 -3
- office365/directory/applications/roles/assignment_collection.py +1 -1
- office365/directory/applications/roles/collection.py +6 -2
- office365/directory/applications/roles/role.py +1 -1
- office365/directory/audit/provisioning/object_summary.py +30 -1
- office365/directory/authentication/method_configuration.py +9 -0
- office365/directory/authentication/method_mode_detail.py +8 -0
- office365/directory/authentication/method_target.py +5 -0
- office365/directory/authentication/methods/fido.py +8 -0
- office365/directory/authentication/methods/password.py +23 -0
- office365/directory/authentication/strength_root.py +5 -0
- office365/directory/certificates/auth_configuration.py +1 -3
- office365/directory/custom_security_attribute_definition.py +7 -0
- office365/directory/device_local_credential_info.py +6 -0
- office365/directory/directory.py +40 -12
- office365/directory/groups/group.py +2 -6
- office365/directory/identities/conditional_access_root.py +10 -1
- office365/directory/identities/container.py +3 -9
- office365/directory/identities/providers/builtin_identity.py +3 -2
- office365/directory/identities/providers/saml_or_wsfed.py +4 -5
- office365/directory/identitygovernance/appconsent/request_collection.py +1 -1
- office365/directory/identitygovernance/governance.py +14 -3
- office365/directory/identitygovernance/privilegedaccess/__init__.py +0 -0
- office365/directory/identitygovernance/privilegedaccess/root.py +5 -0
- office365/directory/identitygovernance/termsofuse/agreement_acceptance.py +8 -0
- office365/directory/identitygovernance/userconsent/request_collection.py +1 -1
- office365/directory/insights/resource_reference.py +1 -1
- office365/directory/key_credential.py +3 -0
- office365/directory/licenses/assignment_state.py +26 -2
- office365/directory/licenses/details.py +4 -3
- office365/directory/licenses/subscribed_sku.py +8 -10
- office365/directory/object_collection.py +40 -25
- office365/directory/password_credential.py +3 -0
- office365/directory/permissions/default_user_role.py +5 -0
- office365/directory/permissions/grants/condition_set.py +4 -2
- office365/directory/permissions/grants/oauth2.py +7 -10
- office365/directory/policies/authorization.py +50 -3
- office365/directory/policies/device_registration.py +6 -0
- office365/directory/policies/permission_grant.py +2 -0
- office365/directory/policies/root.py +13 -0
- office365/directory/profile_photo.py +6 -6
- office365/directory/protection/riskyusers/risky_user.py +4 -4
- office365/directory/rolemanagement/resource_action.py +10 -0
- office365/directory/rolemanagement/role_permission.py +10 -0
- office365/directory/security/alerts/alert.py +5 -7
- office365/directory/security/attacksimulations/landing_page.py +5 -0
- office365/directory/security/attacksimulations/operation.py +5 -0
- office365/directory/security/attacksimulations/report.py +8 -1
- office365/directory/security/attacksimulations/root.py +33 -0
- office365/directory/security/attacksimulations/users/__init__.py +0 -0
- office365/directory/security/attacksimulations/users/details.py +5 -0
- office365/directory/security/hunting_query_results.py +5 -0
- office365/directory/security/incidents/incident.py +8 -13
- office365/directory/security/security.py +20 -3
- office365/directory/security/threatintelligence/article_indicator.py +7 -0
- office365/directory/serviceprincipals/service_principal.py +6 -12
- office365/directory/synchronization/schema.py +16 -0
- office365/directory/synchronization/synchronization.py +2 -0
- office365/directory/users/activities/history_item.py +3 -2
- office365/directory/users/user.py +60 -10
- office365/entity_collection.py +3 -2
- office365/graph_client.py +58 -30
- office365/intune/audit/event.py +1 -3
- office365/intune/audit/event_collection.py +1 -1
- office365/intune/devices/alternative_security_id.py +4 -0
- office365/intune/devices/collection.py +57 -0
- office365/intune/devices/device.py +38 -10
- office365/intune/devices/management/management.py +12 -0
- office365/intune/organizations/organization.py +1 -0
- office365/onedrive/analytics/item_activity_stat.py +9 -0
- office365/onedrive/analytics/item_analytics.py +1 -0
- office365/onedrive/contenttypes/content_type.py +4 -12
- office365/onedrive/driveitems/driveItem.py +76 -7
- office365/onedrive/files/hashes.py +5 -0
- office365/onedrive/lists/collection.py +2 -2
- office365/onedrive/lists/list.py +1 -1
- office365/onedrive/operations/long_running.py +6 -6
- office365/onedrive/operations/rich_long_running.py +4 -3
- office365/onedrive/permissions/collection.py +1 -14
- office365/onedrive/sharepoint_settings.py +6 -6
- office365/onedrive/sitepages/__init__.py +0 -0
- office365/onedrive/sitepages/base.py +29 -0
- office365/onedrive/sitepages/canvas_layout.py +43 -0
- office365/onedrive/sitepages/collection.py +32 -0
- office365/onedrive/sitepages/horizontal_section.py +23 -0
- office365/onedrive/sitepages/horizontal_section_column.py +27 -0
- office365/onedrive/sitepages/site_page.py +116 -0
- office365/onedrive/sitepages/title_area.py +13 -0
- office365/onedrive/sitepages/vertical_section.py +27 -0
- office365/onedrive/sitepages/web_part.py +5 -0
- office365/onedrive/sites/site.py +10 -0
- office365/onedrive/sites/sites_with_root.py +1 -3
- office365/onedrive/termstore/store.py +2 -4
- office365/onedrive/termstore/terms/collection.py +1 -2
- office365/onedrive/workbooks/charts/data_labels.py +13 -1
- office365/onedrive/workbooks/filter.py +9 -0
- office365/onedrive/workbooks/filter_criteria.py +5 -0
- office365/onedrive/workbooks/functions/functions.py +6 -3
- office365/onedrive/workbooks/functions/result.py +2 -0
- office365/onedrive/workbooks/operations/workbook.py +7 -10
- office365/onedrive/workbooks/tables/pivot_table.py +9 -9
- office365/onedrive/workbooks/tables/sort.py +5 -0
- office365/onedrive/workbooks/tables/table.py +57 -0
- office365/onedrive/workbooks/worksheets/collection.py +0 -6
- office365/onedrive/workbooks/worksheets/protection.py +22 -1
- office365/onedrive/workbooks/worksheets/protection_options.py +7 -0
- office365/outlook/calendar/calendar.py +1 -3
- office365/outlook/calendar/events/event.py +45 -0
- office365/outlook/calendar/permissions/permission.py +7 -7
- office365/outlook/calendar/place.py +5 -3
- office365/outlook/calendar/response_status.py +11 -0
- office365/outlook/calendar/rooms/room.py +14 -0
- office365/outlook/mail/attachments/collection.py +6 -1
- office365/outlook/mail/automatic_replies_mailtips.py +5 -0
- office365/outlook/mail/conversation.py +1 -3
- office365/outlook/mail/folders/folder.py +1 -3
- office365/outlook/mail/messages/message.py +1 -1
- office365/outlook/mail/tips.py +17 -0
- office365/planner/plans/plan.py +11 -1
- office365/reports/root.py +83 -4
- office365/runtime/auth/authentication_context.py +12 -2
- office365/runtime/auth/providers/acs_token_provider.py +10 -7
- office365/runtime/auth/sts_profile.py +0 -1
- office365/runtime/client_object.py +18 -14
- office365/runtime/client_object_collection.py +8 -23
- office365/runtime/client_request_exception.py +1 -3
- office365/runtime/client_result.py +11 -14
- office365/runtime/client_runtime_context.py +11 -21
- office365/runtime/odata/json_format.py +7 -9
- office365/runtime/odata/request.py +12 -2
- office365/runtime/odata/v3/batch_request.py +7 -15
- office365/runtime/odata/v4/batch_request.py +13 -21
- office365/runtime/queries/upload_session.py +5 -0
- office365/runtime/types/event_handler.py +1 -1
- office365/search/entity.py +3 -2
- office365/sharepoint/activities/facets/delete.py +1 -1
- office365/sharepoint/activities/tracked_item_service.py +2 -3
- office365/sharepoint/administration/web_application.py +8 -7
- office365/sharepoint/alerts/collection.py +2 -1
- office365/sharepoint/attachments/attachment.py +3 -9
- office365/sharepoint/audit/audit.py +3 -2
- office365/sharepoint/changes/alert.py +4 -3
- office365/sharepoint/changes/collection.py +7 -10
- office365/sharepoint/changes/content_type.py +4 -4
- office365/sharepoint/changes/field.py +4 -5
- office365/sharepoint/changes/item.py +34 -7
- office365/sharepoint/changes/list.py +4 -4
- office365/sharepoint/changes/user.py +5 -6
- office365/sharepoint/client_context.py +4 -2
- office365/sharepoint/clientsidecomponent/component_context_info.py +4 -3
- office365/sharepoint/contentcenter/machinelearning/enabled.py +4 -3
- office365/sharepoint/contentcenter/machinelearning/hub.py +6 -6
- office365/sharepoint/contentcenter/machinelearning/models/collection.py +1 -1
- office365/sharepoint/contenttypes/content_type.py +13 -1
- office365/sharepoint/contenttypes/fieldlinks/collection.py +5 -7
- office365/sharepoint/contenttypes/fieldlinks/field_link.py +14 -22
- office365/sharepoint/directory/helper.py +2 -0
- office365/sharepoint/entity.py +12 -5
- office365/sharepoint/entity_collection.py +1 -3
- office365/sharepoint/eventreceivers/definition.py +8 -12
- office365/sharepoint/features/collection.py +1 -2
- office365/sharepoint/features/definitions/definition.py +6 -3
- office365/sharepoint/fields/calculated.py +8 -14
- office365/sharepoint/fields/collection.py +46 -13
- office365/sharepoint/fields/computed.py +4 -5
- office365/sharepoint/fields/currency.py +7 -11
- office365/sharepoint/fields/date_time.py +4 -8
- office365/sharepoint/fields/field.py +6 -16
- office365/sharepoint/fields/lookup.py +11 -9
- office365/sharepoint/fields/multi_choice.py +8 -12
- office365/sharepoint/fields/multi_line_text.py +10 -14
- office365/sharepoint/fields/number.py +13 -26
- office365/sharepoint/fields/rating_scale.py +6 -10
- office365/sharepoint/fields/related_field.py +10 -17
- office365/sharepoint/fields/url.py +4 -5
- office365/sharepoint/fields/user.py +10 -9
- office365/sharepoint/files/collection.py +17 -15
- office365/sharepoint/files/file.py +30 -23
- office365/sharepoint/folders/collection.py +22 -5
- office365/sharepoint/folders/coloring.py +11 -9
- office365/sharepoint/folders/coloring_information.py +38 -0
- office365/sharepoint/folders/folder.py +23 -25
- office365/sharepoint/likes/liked_by_information.py +7 -10
- office365/sharepoint/likes/user_entity.py +6 -8
- office365/sharepoint/listitems/form_update_value.py +17 -1
- office365/sharepoint/listitems/listitem.py +2 -2
- office365/sharepoint/lists/bloom_filter.py +5 -7
- office365/sharepoint/lists/creatables_info.py +5 -6
- office365/sharepoint/lists/list.py +24 -9
- office365/sharepoint/lists/template.py +7 -4
- office365/sharepoint/lists/template_collection.py +2 -4
- office365/sharepoint/marketplace/app_metadata.py +14 -23
- office365/sharepoint/marketplace/sitecollection/appcatalog/allowed_item.py +6 -8
- office365/sharepoint/migrationcenter/deploy_status.py +5 -0
- office365/sharepoint/migrationcenter/service/performance/__init__.py +0 -0
- office365/sharepoint/migrationcenter/service/performance/dashboard_data.py +9 -0
- office365/sharepoint/migrationcenter/service/performance/data.py +7 -0
- office365/sharepoint/migrationcenter/service/performance/entity_data.py +5 -0
- office365/sharepoint/navigation/node.py +5 -8
- office365/sharepoint/permissions/irm/effective_settings.py +6 -8
- office365/sharepoint/permissions/irm/file_settings.py +8 -6
- office365/sharepoint/permissions/irm/settings.py +25 -43
- office365/sharepoint/portal/groups/site_manager.py +6 -7
- office365/sharepoint/principal/principal.py +2 -4
- office365/sharepoint/publishing/embed_data_v1.py +8 -15
- office365/sharepoint/publishing/pages/campaign_publication.py +4 -3
- office365/sharepoint/publishing/primary_city_time.py +8 -9
- office365/sharepoint/publishing/video/service_discoverer.py +4 -3
- office365/sharepoint/pushnotifications/subscriber.py +11 -15
- office365/sharepoint/recyclebin/item.py +107 -7
- office365/sharepoint/sharing/information.py +9 -0
- office365/sharepoint/sharing/link_info.py +6 -0
- office365/sharepoint/sharing/object_sharing_settings.py +24 -46
- office365/sharepoint/sharing/permission_collection.py +18 -0
- office365/sharepoint/sharing/permission_information.py +5 -5
- office365/sharepoint/sharing/result.py +1 -0
- office365/sharepoint/sitedesigns/run.py +4 -3
- office365/sharepoint/sites/script_safe_domain.py +5 -0
- office365/sharepoint/sites/site.py +17 -20
- office365/sharepoint/taxonomy/field.py +32 -21
- office365/sharepoint/taxonomy/field_value.py +1 -1
- office365/sharepoint/taxonomy/groups/group.py +12 -1
- office365/sharepoint/taxonomy/sets/set.py +6 -0
- office365/sharepoint/taxonomy/stores/store.py +4 -2
- office365/sharepoint/teams/channel.py +6 -6
- office365/sharepoint/tenant/administration/endpoints.py +4 -3
- office365/sharepoint/tenant/administration/hubsites/properties.py +4 -5
- office365/sharepoint/tenant/administration/powerapps/__init__.py +0 -0
- office365/sharepoint/tenant/administration/powerapps/environment_context.py +8 -0
- office365/sharepoint/tenant/administration/sites/properties.py +0 -1
- office365/sharepoint/tenant/administration/spo_operation.py +4 -4
- office365/sharepoint/tenant/administration/tenant.py +1 -0
- office365/sharepoint/tenant/insights/report.py +11 -0
- office365/sharepoint/tenant/insights/report_manager.py +5 -0
- office365/sharepoint/tenant/insights/report_metadata.py +5 -0
- office365/sharepoint/tenant/settings.py +4 -3
- office365/sharepoint/translation/sync_translator.py +3 -2
- office365/sharepoint/ui/applicationpages/peoplepicker/entity_information.py +4 -4
- office365/sharepoint/usercustomactions/action.py +12 -20
- office365/sharepoint/userprofiles/followed_content.py +6 -10
- office365/sharepoint/userprofiles/people_manager.py +0 -1
- office365/sharepoint/userprofiles/person_properties.py +14 -30
- office365/sharepoint/userprofiles/personal_cache.py +4 -3
- office365/sharepoint/userprofiles/properties_for_user.py +4 -5
- office365/sharepoint/userprofiles/sharedwithme/document.py +12 -21
- office365/sharepoint/utilities/move_copy_util.py +19 -19
- office365/sharepoint/utilities/upload_status.py +7 -10
- office365/sharepoint/views/field_collection.py +9 -14
- office365/sharepoint/views/view.py +43 -64
- office365/sharepoint/webhooks/subscription.py +11 -19
- office365/sharepoint/webparts/webpart.py +3 -1
- office365/sharepoint/webs/information_collection.py +1 -1
- office365/sharepoint/webs/modernize_homepage_result.py +4 -3
- office365/sharepoint/webs/regional_settings.py +79 -16
- office365/sharepoint/webs/template.py +3 -5
- office365/sharepoint/webs/web.py +24 -25
- office365/teams/apps/catalog.py +1 -0
- office365/teams/chats/chat.py +4 -0
- office365/teams/operations/async_operation.py +5 -7
- office365/teams/schedule/schedule.py +6 -2
- office365/runtime/paths/item.py +0 -8
- {Office365_REST_Python_Client-2.5.5.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/LICENSE +0 -0
- {Office365_REST_Python_Client-2.5.5.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/WHEEL +0 -0
- {Office365_REST_Python_Client-2.5.5.dist-info → Office365_REST_Python_Client-2.5.7.dist-info}/top_level.txt +0 -0
office365/planner/plans/plan.py
CHANGED
|
@@ -7,6 +7,7 @@ from office365.planner.buckets.bucket import PlannerBucket
|
|
|
7
7
|
from office365.planner.plans.container import PlannerPlanContainer
|
|
8
8
|
from office365.planner.plans.details import PlannerPlanDetails
|
|
9
9
|
from office365.planner.tasks.task import PlannerTask
|
|
10
|
+
from office365.runtime.http.request_options import RequestOptions
|
|
10
11
|
from office365.runtime.paths.resource_path import ResourcePath
|
|
11
12
|
|
|
12
13
|
|
|
@@ -18,11 +19,20 @@ class PlannerPlan(Entity):
|
|
|
18
19
|
"""
|
|
19
20
|
|
|
20
21
|
def __str__(self):
|
|
21
|
-
return self.title
|
|
22
|
+
return self.title or self.entity_type_name
|
|
22
23
|
|
|
23
24
|
def __repr__(self):
|
|
24
25
|
return self.id or self.entity_type_name
|
|
25
26
|
|
|
27
|
+
def delete_object(self):
|
|
28
|
+
def _construct_request(request):
|
|
29
|
+
# type: (RequestOptions) -> None
|
|
30
|
+
request.set_header("If-Match", self.properties.get("__etag"))
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
super(PlannerPlan, self).delete_object().before_execute(_construct_request)
|
|
34
|
+
)
|
|
35
|
+
|
|
26
36
|
@property
|
|
27
37
|
def container(self):
|
|
28
38
|
"""Identity of the user, device, or application which created the plan."""
|
office365/reports/root.py
CHANGED
|
@@ -11,6 +11,17 @@ from office365.runtime.queries.function import FunctionQuery
|
|
|
11
11
|
class ReportRoot(Entity):
|
|
12
12
|
"""Represents a container for Azure Active Directory (Azure AD) reporting resources."""
|
|
13
13
|
|
|
14
|
+
def device_configuration_device_activity(self):
|
|
15
|
+
"""
|
|
16
|
+
Metadata for the device configuration device activity report
|
|
17
|
+
"""
|
|
18
|
+
return_type = ClientResult(self.context, Report())
|
|
19
|
+
qry = FunctionQuery(
|
|
20
|
+
self, "deviceConfigurationDeviceActivity", None, return_type
|
|
21
|
+
)
|
|
22
|
+
self.context.add_query(qry)
|
|
23
|
+
return return_type
|
|
24
|
+
|
|
14
25
|
def device_configuration_user_activity(self):
|
|
15
26
|
"""
|
|
16
27
|
Metadata for the device configuration user activity report
|
|
@@ -20,6 +31,15 @@ class ReportRoot(Entity):
|
|
|
20
31
|
self.context.add_query(qry)
|
|
21
32
|
return return_type
|
|
22
33
|
|
|
34
|
+
def managed_device_enrollment_failure_details(self):
|
|
35
|
+
""" """
|
|
36
|
+
return_type = ClientResult(self.context, Report())
|
|
37
|
+
qry = FunctionQuery(
|
|
38
|
+
self, "managedDeviceEnrollmentFailureDetails", None, return_type
|
|
39
|
+
)
|
|
40
|
+
self.context.add_query(qry)
|
|
41
|
+
return return_type
|
|
42
|
+
|
|
23
43
|
def managed_device_enrollment_top_failures(self, period=None):
|
|
24
44
|
"""
|
|
25
45
|
Note: The Microsoft Graph API for Intune requires an active Intune license for the tenant.
|
|
@@ -72,6 +92,18 @@ class ReportRoot(Entity):
|
|
|
72
92
|
self.context.add_query(qry)
|
|
73
93
|
return qry.return_type
|
|
74
94
|
|
|
95
|
+
def get_email_app_usage_apps_user_counts(self, period):
|
|
96
|
+
"""
|
|
97
|
+
Get the count of unique users per email app.
|
|
98
|
+
|
|
99
|
+
:param str period: Specifies the length of time over which the report is aggregated.
|
|
100
|
+
The supported values for {period_value} are: D7, D30, D90, and D180. These values follow the format
|
|
101
|
+
Dn where n represents the number of days over which the report is aggregated. Required.
|
|
102
|
+
"""
|
|
103
|
+
qry = create_report_query(self, "getEmailAppUsageAppsUserCounts", period)
|
|
104
|
+
self.context.add_query(qry)
|
|
105
|
+
return qry.return_type
|
|
106
|
+
|
|
75
107
|
def get_m365_app_user_counts(self, period=None):
|
|
76
108
|
"""
|
|
77
109
|
Get a report that provides the trend in the number of active users for each app (Outlook, Word, Excel,
|
|
@@ -85,10 +117,7 @@ class ReportRoot(Entity):
|
|
|
85
117
|
return return_type
|
|
86
118
|
|
|
87
119
|
def get_office365_activations_user_counts(self):
|
|
88
|
-
"""
|
|
89
|
-
Get the count of Microsoft 365 activations on desktops and devices.
|
|
90
|
-
|
|
91
|
-
"""
|
|
120
|
+
"""Get the count of Microsoft 365 activations on desktops and devices."""
|
|
92
121
|
qry = create_report_query(self, "getOffice365ActivationsUserCounts")
|
|
93
122
|
self.context.add_query(qry)
|
|
94
123
|
return qry.return_type
|
|
@@ -166,6 +195,32 @@ class ReportRoot(Entity):
|
|
|
166
195
|
self.context.add_query(qry)
|
|
167
196
|
return qry.return_type
|
|
168
197
|
|
|
198
|
+
def get_mailbox_usage_mailbox_counts(self, period):
|
|
199
|
+
"""
|
|
200
|
+
Get the total number of user mailboxes in your organization and how many are active each day of the reporting
|
|
201
|
+
period. A mailbox is considered active if the user sent or read any email.
|
|
202
|
+
|
|
203
|
+
:param str period: Specifies the length of time over which the report is aggregated.
|
|
204
|
+
The supported values for {period_value} are: D7, D30, D90, and D180. These values follow the format
|
|
205
|
+
Dn where n represents the number of days over which the report is aggregated. Required.
|
|
206
|
+
"""
|
|
207
|
+
qry = create_report_query(self, "getMailboxUsageMailboxCounts", period)
|
|
208
|
+
self.context.add_query(qry)
|
|
209
|
+
return qry.return_type
|
|
210
|
+
|
|
211
|
+
def get_mailbox_usage_quota_status_mailbox_counts(self, period):
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
:param str period: Specifies the length of time over which the report is aggregated.
|
|
215
|
+
The supported values for {period_value} are: D7, D30, D90, and D180. These values follow the format
|
|
216
|
+
Dn where n represents the number of days over which the report is aggregated. Required.
|
|
217
|
+
"""
|
|
218
|
+
qry = create_report_query(
|
|
219
|
+
self, "getMailboxUsageQuotaStatusMailboxCounts", period
|
|
220
|
+
)
|
|
221
|
+
self.context.add_query(qry)
|
|
222
|
+
return qry.return_type
|
|
223
|
+
|
|
169
224
|
def get_sharepoint_activity_pages(self, period):
|
|
170
225
|
"""
|
|
171
226
|
Get the number of unique pages visited by users.
|
|
@@ -203,6 +258,30 @@ class ReportRoot(Entity):
|
|
|
203
258
|
self.context.add_query(qry)
|
|
204
259
|
return qry.return_type
|
|
205
260
|
|
|
261
|
+
def get_sharepoint_site_usage_detail(self, period):
|
|
262
|
+
"""
|
|
263
|
+
Get details about SharePoint site usage.
|
|
264
|
+
|
|
265
|
+
:param str period: Specifies the length of time over which the report is aggregated.
|
|
266
|
+
The supported values for {period_value} are: D7, D30, D90, and D180. These values follow the format
|
|
267
|
+
Dn where n represents the number of days over which the report is aggregated. Required.
|
|
268
|
+
"""
|
|
269
|
+
qry = create_report_query(self, "getSharePointSiteUsageDetail", period)
|
|
270
|
+
self.context.add_query(qry)
|
|
271
|
+
return qry.return_type
|
|
272
|
+
|
|
273
|
+
def get_sharepoint_site_usage_site_counts(self, period):
|
|
274
|
+
"""
|
|
275
|
+
Get the trend of total and active site count during the reporting period.
|
|
276
|
+
|
|
277
|
+
:param str period: Specifies the length of time over which the report is aggregated.
|
|
278
|
+
The supported values for {period_value} are: D7, D30, D90, and D180. These values follow the format
|
|
279
|
+
Dn where n represents the number of days over which the report is aggregated. Required.
|
|
280
|
+
"""
|
|
281
|
+
qry = create_report_query(self, "getSharePointSiteUsageSiteCounts", period)
|
|
282
|
+
self.context.add_query(qry)
|
|
283
|
+
return qry.return_type
|
|
284
|
+
|
|
206
285
|
@property
|
|
207
286
|
def authentication_methods(self):
|
|
208
287
|
"""Container for navigation properties for Azure AD authentication methods resources."""
|
|
@@ -47,6 +47,7 @@ class AuthenticationContext(object):
|
|
|
47
47
|
cert_path=None,
|
|
48
48
|
private_key=None,
|
|
49
49
|
scopes=None,
|
|
50
|
+
passphrase=None,
|
|
50
51
|
):
|
|
51
52
|
"""Initializes a client to acquire a token via certificate credentials
|
|
52
53
|
|
|
@@ -56,6 +57,7 @@ class AuthenticationContext(object):
|
|
|
56
57
|
:param str or None cert_path: Path to A PEM encoded certificate private key.
|
|
57
58
|
:param str or None private_key: A PEM encoded certificate private key.
|
|
58
59
|
:param list[str] or None scopes: Scopes requested to access a protected API (a resource)
|
|
60
|
+
:param str passphrase: Passphrase if the private_key is encrypted
|
|
59
61
|
"""
|
|
60
62
|
if scopes is None:
|
|
61
63
|
resource = get_absolute_url(self.url)
|
|
@@ -70,7 +72,11 @@ class AuthenticationContext(object):
|
|
|
70
72
|
|
|
71
73
|
def _acquire_token():
|
|
72
74
|
authority_url = "https://login.microsoftonline.com/{0}".format(tenant)
|
|
73
|
-
credentials = {
|
|
75
|
+
credentials = {
|
|
76
|
+
"thumbprint": thumbprint,
|
|
77
|
+
"private_key": private_key,
|
|
78
|
+
"passphrase": passphrase,
|
|
79
|
+
}
|
|
74
80
|
import msal
|
|
75
81
|
|
|
76
82
|
app = msal.ConfidentialClientApplication(
|
|
@@ -187,7 +193,11 @@ class AuthenticationContext(object):
|
|
|
187
193
|
browser_mode = kwargs.get("browser_mode", False)
|
|
188
194
|
environment = kwargs.get("environment")
|
|
189
195
|
provider = SamlTokenProvider(
|
|
190
|
-
self.url,
|
|
196
|
+
self.url,
|
|
197
|
+
credentials.userName,
|
|
198
|
+
credentials.password,
|
|
199
|
+
browser_mode,
|
|
200
|
+
environment,
|
|
191
201
|
)
|
|
192
202
|
else:
|
|
193
203
|
raise ValueError("Unknown credential type")
|
|
@@ -10,7 +10,7 @@ from office365.runtime.http.request_options import RequestOptions
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class ACSTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
|
|
13
|
-
def __init__(self, url, client_id, client_secret, environment=
|
|
13
|
+
def __init__(self, url, client_id, client_secret, environment="commercial"):
|
|
14
14
|
"""
|
|
15
15
|
Provider to acquire the access token from a Microsoft Azure Access Control Service (ACS)
|
|
16
16
|
|
|
@@ -65,7 +65,9 @@ class ACSTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
|
|
|
65
65
|
self.SharePointPrincipal, target_host, target_realm
|
|
66
66
|
)
|
|
67
67
|
principal_id = self.get_formatted_principal(self._client_id, None, target_realm)
|
|
68
|
-
sts_url = self.get_security_token_service_url(
|
|
68
|
+
sts_url = self.get_security_token_service_url(
|
|
69
|
+
target_realm, environment=self._environment
|
|
70
|
+
)
|
|
69
71
|
oauth2_request = {
|
|
70
72
|
"grant_type": "client_credentials",
|
|
71
73
|
"client_id": principal_id,
|
|
@@ -105,13 +107,14 @@ class ACSTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
|
|
|
105
107
|
|
|
106
108
|
@staticmethod
|
|
107
109
|
def get_security_token_service_url(realm, environment):
|
|
110
|
+
# type: (str, str) -> str
|
|
108
111
|
if environment == "GCCH":
|
|
109
|
-
return "https://login.microsoftonline.us/{0}/tokens/OAuth/2".format(
|
|
110
|
-
realm
|
|
111
|
-
)
|
|
112
|
+
return "https://login.microsoftonline.us/{0}/tokens/OAuth/2".format(realm)
|
|
112
113
|
else:
|
|
113
|
-
return
|
|
114
|
-
|
|
114
|
+
return (
|
|
115
|
+
"https://accounts.accesscontrol.windows.net/{0}/tokens/OAuth/2".format(
|
|
116
|
+
realm
|
|
117
|
+
)
|
|
115
118
|
)
|
|
116
119
|
|
|
117
120
|
def _get_authorization_header(self):
|
|
@@ -7,6 +7,7 @@ from typing_extensions import Self
|
|
|
7
7
|
|
|
8
8
|
from office365.runtime.client_runtime_context import ClientRuntimeContext
|
|
9
9
|
from office365.runtime.client_value import ClientValue
|
|
10
|
+
from office365.runtime.http.request_options import RequestOptions
|
|
10
11
|
from office365.runtime.odata.json_format import ODataJsonFormat
|
|
11
12
|
from office365.runtime.odata.query_options import QueryOptions
|
|
12
13
|
from office365.runtime.odata.type import ODataType
|
|
@@ -73,12 +74,16 @@ class ClientObject(Generic[T]):
|
|
|
73
74
|
)
|
|
74
75
|
return self
|
|
75
76
|
|
|
76
|
-
def
|
|
77
|
-
# type: (Callable[[
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
def before_execute(self, action):
|
|
78
|
+
# type: (Callable[[RequestOptions], None]) -> Self
|
|
79
|
+
"""Attach an event handler to client object which gets triggered after query is submitted to server"""
|
|
80
|
+
self.context.before_execute(action)
|
|
81
|
+
return self
|
|
82
|
+
|
|
83
|
+
def after_execute(self, action, execute_first=False):
|
|
84
|
+
# type: (Callable[[Self], None], bool) -> Self
|
|
85
|
+
"""Attach an event handler to client object which gets triggered after query is submitted to server"""
|
|
86
|
+
self.context.after_query_execute(action, execute_first)
|
|
82
87
|
return self
|
|
83
88
|
|
|
84
89
|
def get(self):
|
|
@@ -138,13 +143,8 @@ class ClientObject(Generic[T]):
|
|
|
138
143
|
return self._properties.get(name, default_value)
|
|
139
144
|
|
|
140
145
|
def set_property(self, name, value, persist_changes=True):
|
|
141
|
-
# type: (str, P_T, bool) -> Self
|
|
142
|
-
"""Sets property value
|
|
143
|
-
|
|
144
|
-
:param str name: Property name
|
|
145
|
-
:param P_T value: Property value
|
|
146
|
-
:param bool persist_changes: Persist changes
|
|
147
|
-
"""
|
|
146
|
+
# type: (str|int, P_T, bool) -> Self
|
|
147
|
+
"""Sets property value"""
|
|
148
148
|
if persist_changes:
|
|
149
149
|
self._ser_property_names.append(name)
|
|
150
150
|
|
|
@@ -187,7 +187,11 @@ class ClientObject(Generic[T]):
|
|
|
187
187
|
from office365.runtime.queries.read_entity import ReadEntityQuery
|
|
188
188
|
|
|
189
189
|
qry = ReadEntityQuery(self, names_to_include)
|
|
190
|
-
|
|
190
|
+
|
|
191
|
+
def _after_loaded(return_type):
|
|
192
|
+
action(*args, **kwargs)
|
|
193
|
+
|
|
194
|
+
self.context.add_query(qry).after_query_execute(_after_loaded)
|
|
191
195
|
else:
|
|
192
196
|
action(*args, **kwargs)
|
|
193
197
|
return self
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Callable, Generic, Iterator, List, Optional, Type, TypeVar
|
|
2
2
|
|
|
3
3
|
from typing_extensions import Self
|
|
4
4
|
|
|
@@ -147,12 +147,6 @@ class ClientObjectCollection(ClientObject, Generic[T]):
|
|
|
147
147
|
self.top(page_size)
|
|
148
148
|
return self
|
|
149
149
|
|
|
150
|
-
def after_execute(self, action, *args, **kwargs):
|
|
151
|
-
# type: (Callable[[Self, Any, Any], None], Any, Any) -> Self
|
|
152
|
-
super(ClientObjectCollection, self).after_execute(action, *args, **kwargs)
|
|
153
|
-
self._page_loaded += action
|
|
154
|
-
return self
|
|
155
|
-
|
|
156
150
|
def get(self):
|
|
157
151
|
# type: () -> Self
|
|
158
152
|
|
|
@@ -160,39 +154,30 @@ class ClientObjectCollection(ClientObject, Generic[T]):
|
|
|
160
154
|
# type: (Self) -> None
|
|
161
155
|
self._page_loaded.notify(self)
|
|
162
156
|
|
|
163
|
-
self.context.load(self
|
|
157
|
+
self.context.load(self).after_query_execute(_loaded)
|
|
164
158
|
return self
|
|
165
159
|
|
|
166
160
|
def get_all(self, page_size=None, page_loaded=None):
|
|
167
161
|
# type: (int, Callable[[Self], None]) -> Self
|
|
168
162
|
"""Gets all the items in a collection, regardless of the size."""
|
|
169
163
|
|
|
170
|
-
self.paged(page_size, page_loaded)
|
|
171
|
-
|
|
172
164
|
def _page_loaded(col):
|
|
173
165
|
# type: (Self) -> None
|
|
174
|
-
self._page_loaded.notify(col)
|
|
175
166
|
if self.has_next:
|
|
176
|
-
self._get_next(
|
|
167
|
+
self._get_next().after_execute(_page_loaded)
|
|
177
168
|
|
|
178
|
-
self.
|
|
169
|
+
self.paged(page_size, page_loaded).get().after_execute(_page_loaded)
|
|
179
170
|
return self
|
|
180
171
|
|
|
181
|
-
def _get_next(self
|
|
182
|
-
# type: (
|
|
183
|
-
"""
|
|
184
|
-
Submit a request to retrieve next collection of items
|
|
185
|
-
:param (ClientObjectCollection) -> None after_loaded: Page loaded event
|
|
186
|
-
"""
|
|
172
|
+
def _get_next(self):
|
|
173
|
+
# type: () -> Self
|
|
174
|
+
"""Submit a request to retrieve next collection of items"""
|
|
187
175
|
|
|
188
176
|
def _construct_request(request):
|
|
189
177
|
# type: (RequestOptions) -> None
|
|
190
178
|
request.url = self._next_request_url
|
|
191
179
|
|
|
192
|
-
self.
|
|
193
|
-
self, before_loaded=_construct_request, after_loaded=after_loaded
|
|
194
|
-
)
|
|
195
|
-
return self
|
|
180
|
+
return self.get().before_execute(_construct_request)
|
|
196
181
|
|
|
197
182
|
def first(self, expression):
|
|
198
183
|
# type: (str) -> T
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import copy
|
|
2
|
-
from typing import TYPE_CHECKING,
|
|
2
|
+
from typing import TYPE_CHECKING, Callable, Generic, Optional, TypeVar
|
|
3
3
|
|
|
4
4
|
from typing_extensions import Self
|
|
5
5
|
|
|
6
|
+
from office365.runtime.http.request_options import RequestOptions
|
|
7
|
+
|
|
6
8
|
if TYPE_CHECKING:
|
|
7
9
|
from office365.runtime.client_runtime_context import ClientRuntimeContext # noqa
|
|
8
10
|
from office365.runtime.client_value import ClientValue # noqa
|
|
@@ -19,21 +21,16 @@ class ClientResult(Generic[T]):
|
|
|
19
21
|
self._context = context
|
|
20
22
|
self._value = copy.deepcopy(default_value) # type: T
|
|
21
23
|
|
|
22
|
-
def before_execute(self, action
|
|
23
|
-
|
|
24
|
-
Attach an event handler which is triggered before query is submitted to server
|
|
25
|
-
|
|
26
|
-
"""
|
|
27
|
-
self._context.before_query_execute(action, *args, **kwargs)
|
|
24
|
+
def before_execute(self, action):
|
|
25
|
+
# type: (Callable[[RequestOptions], None]) -> Self
|
|
26
|
+
"""Attach an event handler which is triggered before query is submitted to server"""
|
|
27
|
+
self._context.before_query_execute(action)
|
|
28
28
|
return self
|
|
29
29
|
|
|
30
|
-
def after_execute(self, action,
|
|
31
|
-
# type: (Callable[[Self], None],
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
:param (ClientResult) -> None action: Event handler
|
|
35
|
-
"""
|
|
36
|
-
self._context.after_query_execute(action, self, *args, **kwargs)
|
|
30
|
+
def after_execute(self, action, execute_first=False):
|
|
31
|
+
# type: (Callable[[Self], None], bool) -> Self
|
|
32
|
+
"""Attach an event handler which is triggered after query is submitted to server"""
|
|
33
|
+
self._context.after_query_execute(action, execute_first)
|
|
37
34
|
return self
|
|
38
35
|
|
|
39
36
|
def set_property(self, key, value, persist_changes=False):
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
from time import sleep
|
|
3
|
-
from typing import TYPE_CHECKING,
|
|
3
|
+
from typing import TYPE_CHECKING, AnyStr, Callable, List
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
|
+
from requests import Response
|
|
6
7
|
from typing_extensions import Self
|
|
7
8
|
|
|
8
9
|
from office365.runtime.client_request import ClientRequest
|
|
@@ -79,21 +80,11 @@ class ClientRuntimeContext(object):
|
|
|
79
80
|
# type: () -> str
|
|
80
81
|
pass
|
|
81
82
|
|
|
82
|
-
def load(
|
|
83
|
-
|
|
84
|
-
client_object,
|
|
85
|
-
properties_to_retrieve=None,
|
|
86
|
-
before_loaded=None,
|
|
87
|
-
after_loaded=None,
|
|
88
|
-
):
|
|
89
|
-
# type: (T, List[str], Callable[[RequestOptions], None], Callable[[T], None]) -> Self
|
|
83
|
+
def load(self, client_object, properties_to_retrieve=None):
|
|
84
|
+
# type: (T, List[str]) -> Self
|
|
90
85
|
"""Prepare retrieval query"""
|
|
91
86
|
qry = ReadEntityQuery(client_object, properties_to_retrieve)
|
|
92
87
|
self.add_query(qry)
|
|
93
|
-
if callable(before_loaded):
|
|
94
|
-
self.before_query_execute(before_loaded)
|
|
95
|
-
if callable(after_loaded):
|
|
96
|
-
self.after_query_execute(after_loaded, client_object)
|
|
97
88
|
return self
|
|
98
89
|
|
|
99
90
|
def before_query_execute(self, action, once=True):
|
|
@@ -135,34 +126,33 @@ class ClientRuntimeContext(object):
|
|
|
135
126
|
self.pending_request().beforeExecute += _process_request
|
|
136
127
|
return self
|
|
137
128
|
|
|
138
|
-
def after_query_execute(self, action,
|
|
139
|
-
# type: (Callable[
|
|
129
|
+
def after_query_execute(self, action, execute_first=False):
|
|
130
|
+
# type: (Callable[[T], None], bool) -> Self
|
|
140
131
|
"""Attach an event handler which is triggered after query is submitted to server"""
|
|
141
132
|
if len(self._queries) == 0:
|
|
142
133
|
return
|
|
143
134
|
query = self._queries[-1]
|
|
144
135
|
|
|
145
136
|
def _process_response(resp):
|
|
146
|
-
# type: (
|
|
137
|
+
# type: (Response) -> None
|
|
147
138
|
resp.raise_for_status()
|
|
148
139
|
if self.current_query.id == query.id:
|
|
149
140
|
self.pending_request().afterExecute -= _process_response
|
|
150
|
-
action(
|
|
141
|
+
action(query.return_type)
|
|
151
142
|
|
|
152
143
|
self.pending_request().afterExecute += _process_response
|
|
153
144
|
|
|
154
|
-
execute_first = kwargs.pop("execute_first", False)
|
|
155
145
|
if execute_first and len(self._queries) > 1:
|
|
156
146
|
self._queries.insert(0, self._queries.pop())
|
|
157
147
|
|
|
158
148
|
return self
|
|
159
149
|
|
|
160
150
|
def after_execute(self, action, once=True):
|
|
161
|
-
# type: (Callable[[
|
|
151
|
+
# type: (Callable[[Response], None], bool) -> Self
|
|
162
152
|
"""Attach an event handler which is triggered after request is submitted to server"""
|
|
163
153
|
|
|
164
154
|
def _process_response(response):
|
|
165
|
-
# type: (
|
|
155
|
+
# type: (Response) -> None
|
|
166
156
|
if once:
|
|
167
157
|
self.pending_request().afterExecute -= _process_response
|
|
168
158
|
action(response)
|
|
@@ -171,7 +161,7 @@ class ClientRuntimeContext(object):
|
|
|
171
161
|
return self
|
|
172
162
|
|
|
173
163
|
def execute_request_direct(self, path):
|
|
174
|
-
# type: (str) ->
|
|
164
|
+
# type: (str) -> Response
|
|
175
165
|
full_url = "".join([self.service_root_url(), "/", path])
|
|
176
166
|
request = RequestOptions(full_url)
|
|
177
167
|
return self.pending_request().execute_request_direct(request)
|
|
@@ -4,9 +4,10 @@ from abc import ABCMeta
|
|
|
4
4
|
class ODataJsonFormat(object):
|
|
5
5
|
"""OData JSON format"""
|
|
6
6
|
|
|
7
|
-
def __init__(self, metadata_level=None):
|
|
8
|
-
# type: (str) -> None
|
|
7
|
+
def __init__(self, metadata_level=None, etag=None):
|
|
8
|
+
# type: (str, str) -> None
|
|
9
9
|
self.metadata_level = metadata_level
|
|
10
|
+
self.etag = etag
|
|
10
11
|
|
|
11
12
|
__metaclass__ = ABCMeta
|
|
12
13
|
|
|
@@ -24,15 +25,12 @@ class ODataJsonFormat(object):
|
|
|
24
25
|
|
|
25
26
|
@property
|
|
26
27
|
def media_type(self):
|
|
27
|
-
|
|
28
|
-
Gets media type
|
|
29
|
-
:rtype: str
|
|
30
|
-
"""
|
|
28
|
+
# type: () -> str
|
|
29
|
+
"""Gets media type"""
|
|
31
30
|
raise NotImplementedError
|
|
32
31
|
|
|
33
32
|
@property
|
|
34
33
|
def include_control_information(self):
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"""
|
|
34
|
+
# type: () -> bool
|
|
35
|
+
"""Determines whether control information that is represented as annotations should be included in payload"""
|
|
38
36
|
raise NotImplementedError
|
|
@@ -25,7 +25,7 @@ class ODataRequest(ClientRequest):
|
|
|
25
25
|
"""Creates OData request"""
|
|
26
26
|
super(ODataRequest, self).__init__()
|
|
27
27
|
self._default_json_format = json_format
|
|
28
|
-
self.beforeExecute += self.
|
|
28
|
+
self.beforeExecute += self._ensure_http_headers
|
|
29
29
|
|
|
30
30
|
@property
|
|
31
31
|
def json_format(self):
|
|
@@ -111,6 +111,8 @@ class ODataRequest(ClientRequest):
|
|
|
111
111
|
k: v for k, v in self._next_property(value, json_format)
|
|
112
112
|
}
|
|
113
113
|
yield name, value
|
|
114
|
+
elif name == "@odata.etag":
|
|
115
|
+
yield "__etag", value
|
|
114
116
|
else:
|
|
115
117
|
yield "__value", json
|
|
116
118
|
elif json is not None:
|
|
@@ -142,8 +144,16 @@ class ODataRequest(ClientRequest):
|
|
|
142
144
|
json = {query.parameters_name: json}
|
|
143
145
|
return json
|
|
144
146
|
|
|
145
|
-
def
|
|
147
|
+
def _ensure_http_headers(self, request):
|
|
146
148
|
# type: (RequestOptions) -> None
|
|
149
|
+
"""
|
|
150
|
+
Ensures that HTTP Header Fields are specified in the OData request, namely:
|
|
151
|
+
- The Content-Type header
|
|
152
|
+
- Accept request-header field
|
|
153
|
+
- The If-Match request-header field (optional)
|
|
154
|
+
"""
|
|
147
155
|
media_type = self.json_format.media_type
|
|
148
156
|
request.ensure_header("Content-Type", media_type)
|
|
149
157
|
request.ensure_header("Accept", media_type)
|
|
158
|
+
if self.json_format.etag is not None:
|
|
159
|
+
request.ensure_header("If-Match", self.json_format.etag)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import re
|
|
3
3
|
from email.message import Message
|
|
4
|
-
from typing import Iterator, Tuple
|
|
4
|
+
from typing import AnyStr, Iterator, List, Tuple
|
|
5
5
|
|
|
6
6
|
import requests
|
|
7
7
|
from requests import Response
|
|
@@ -40,12 +40,8 @@ class ODataBatchV3Request(ODataRequest):
|
|
|
40
40
|
super(ODataBatchV3Request, self).process_response(sub_resp, sub_qry)
|
|
41
41
|
|
|
42
42
|
def _extract_response(self, response, query):
|
|
43
|
-
# type: (
|
|
44
|
-
"""Parses a multipart/mixed response body from the position defined by the context.
|
|
45
|
-
|
|
46
|
-
:type response: requests.Response
|
|
47
|
-
:type query: office365.runtime.queries.batch.BatchQuery
|
|
48
|
-
"""
|
|
43
|
+
# type: (Response, BatchQuery) -> Iterator[Tuple[ClientQuery, Response]]
|
|
44
|
+
"""Parses a multipart/mixed response body from the position defined by the context."""
|
|
49
45
|
content_type = response.headers["Content-Type"].encode("ascii")
|
|
50
46
|
http_body = b"Content-Type: " + content_type + b"\r\n\r\n" + response.content
|
|
51
47
|
|
|
@@ -59,11 +55,8 @@ class ODataBatchV3Request(ODataRequest):
|
|
|
59
55
|
yield qry, self._deserialize_response(raw_response)
|
|
60
56
|
|
|
61
57
|
def _prepare_payload(self, query):
|
|
62
|
-
|
|
63
|
-
Serializes a batch request body.
|
|
64
|
-
|
|
65
|
-
:type query: office365.runtime.queries.batch.BatchQuery
|
|
66
|
-
"""
|
|
58
|
+
# type: (BatchQuery) -> AnyStr
|
|
59
|
+
"""Serializes a batch request body."""
|
|
67
60
|
main_message = Message()
|
|
68
61
|
main_message.add_header("Content-Type", "multipart/mixed")
|
|
69
62
|
main_message.set_boundary(query.current_boundary)
|
|
@@ -89,9 +82,8 @@ class ODataBatchV3Request(ODataRequest):
|
|
|
89
82
|
|
|
90
83
|
@staticmethod
|
|
91
84
|
def _normalize_headers(headers_raw):
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"""
|
|
85
|
+
# type: (List[str]) -> CaseInsensitiveDict
|
|
86
|
+
""" """
|
|
95
87
|
headers = {}
|
|
96
88
|
for header_line in headers_raw:
|
|
97
89
|
k, v = header_line.split(":", 1)
|