Office365-REST-Python-Client 3.1.0__py3-none-any.whl → 3.2.0__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.
Files changed (245) hide show
  1. office365/communications/callrecords/call_record.py +18 -0
  2. office365/communications/calls/call.py +3 -0
  3. office365/communications/presences/presence.py +3 -0
  4. office365/communications/quotas.py +66 -0
  5. office365/communications/virtualevents/virtual_event.py +3 -0
  6. office365/directory/domains/domain.py +3 -0
  7. office365/directory/licenses/subscribed_sku.py +3 -0
  8. office365/directory/objects/object.py +3 -0
  9. office365/directory/quotas.py +34 -0
  10. office365/entity_collection.py +2 -2
  11. office365/graph_client.py +46 -2
  12. office365/limits.py +66 -0
  13. office365/migration/__init__.py +6 -1
  14. office365/migration/adapters/__init__.py +14 -4
  15. office365/migration/adapters/filesystem.py +4 -1
  16. office365/migration/assessment/export.py +5 -5
  17. office365/migration/assessment/issue.py +19 -0
  18. office365/migration/assessment/report.py +11 -0
  19. office365/migration/assessment/scanners/base.py +37 -49
  20. office365/migration/base.py +33 -8
  21. office365/migration/checkpoint.py +1 -1
  22. office365/migration/outlook/assessor.py +4 -4
  23. office365/migration/package/__init__.py +82 -0
  24. office365/migration/package/builder.py +603 -0
  25. office365/migration/package/crypto.py +54 -0
  26. office365/migration/package/manifest_xml.py +495 -0
  27. office365/migration/package/staging.py +180 -0
  28. office365/migration/report.py +7 -2
  29. office365/migration/report_io.py +79 -0
  30. office365/migration/runner.py +117 -10
  31. office365/migration/server_job.py +126 -14
  32. office365/migration/session.py +132 -49
  33. office365/migration/settings.py +67 -0
  34. office365/migration/sharepoint/__init__.py +2 -0
  35. office365/migration/sharepoint/adapters.py +207 -41
  36. office365/migration/sharepoint/assessor.py +45 -9
  37. office365/migration/sharepoint/options.py +57 -0
  38. office365/migration/sharepoint/package_target.py +209 -0
  39. office365/migration/sharepoint/registry.py +22 -0
  40. office365/migration/sharepoint/resolvers.py +96 -0
  41. office365/migration/sharepoint/scanners/__init__.py +29 -0
  42. office365/migration/sharepoint/scanners/browser_file_handling.py +55 -0
  43. office365/migration/sharepoint/scanners/checked_out_files.py +57 -0
  44. office365/migration/sharepoint/scanners/file_versions.py +56 -0
  45. office365/migration/sharepoint/scanners/files.py +5 -2
  46. office365/migration/sharepoint/scanners/large_excel_files.py +56 -0
  47. office365/migration/sharepoint/scanners/large_lists.py +58 -0
  48. office365/migration/sharepoint/scanners/large_sites.py +4 -3
  49. office365/migration/sharepoint/scanners/long_onedrive_urls.py +52 -0
  50. office365/migration/sharepoint/scanners/lookup.py +38 -0
  51. office365/migration/sharepoint/scanners/paths.py +9 -4
  52. office365/migration/sharepoint/scanners/permissions.py +20 -2
  53. office365/migration/sharepoint/scanners/smat.py +51 -0
  54. office365/migration/sharepoint/scanners/summary.py +1 -0
  55. office365/migration/sharepoint/scanners/thicket_folders.py +38 -0
  56. office365/migration/sharepoint/scanners/unsupported_site_templates.py +90 -0
  57. office365/migration/sharepoint/tenant_assessor.py +5 -3
  58. office365/migration/sharepoint/transfer.py +4 -2
  59. office365/migration/tasks.py +121 -0
  60. office365/migration/validators.py +2 -19
  61. office365/onedrive/driveitems/driveItem.py +116 -12
  62. office365/onedrive/termstore/groups/collection.py +2 -9
  63. office365/onedrive/termstore/sets/collection.py +2 -9
  64. office365/onedrive/termstore/terms/collection.py +3 -10
  65. office365/onedrive/workbooks/workbook.py +7 -0
  66. office365/outlook/contacts/folders/collection.py +4 -13
  67. office365/runtime/auth/authentication_context.py +5 -0
  68. office365/runtime/client_object.py +18 -0
  69. office365/runtime/client_object_collection.py +75 -245
  70. office365/runtime/client_request.py +77 -1
  71. office365/runtime/client_request_exception.py +127 -39
  72. office365/runtime/client_runtime_context.py +79 -8
  73. office365/runtime/converters/csv_writer.py +10 -4
  74. office365/runtime/converters/dataframe.py +84 -4
  75. office365/runtime/converters/json_file.py +12 -3
  76. office365/runtime/converters/parquet.py +67 -0
  77. office365/runtime/converters/records.py +31 -12
  78. office365/runtime/converters/registry.py +185 -0
  79. office365/runtime/converters/scalars.py +31 -0
  80. office365/runtime/converters/sql.py +69 -0
  81. office365/runtime/converters/streamers.py +105 -0
  82. office365/runtime/converters/streams.py +42 -0
  83. office365/runtime/converters/upsert.py +101 -0
  84. office365/runtime/exceptions.py +105 -0
  85. office365/runtime/http/prefer.py +26 -0
  86. office365/runtime/http/throttling.py +258 -56
  87. office365/runtime/imports.py +571 -0
  88. office365/runtime/limits.py +455 -0
  89. office365/runtime/odata/request.py +11 -2
  90. office365/runtime/odata/type.py +1 -0
  91. office365/runtime/odata/v3/batch_request.py +4 -2
  92. office365/runtime/odata/v4/batch_request.py +22 -7
  93. office365/runtime/operations.py +29 -0
  94. office365/runtime/parallel.py +12 -14
  95. office365/runtime/paths/v4/entity.py +2 -2
  96. office365/runtime/queries/batch.py +18 -1
  97. office365/runtime/queries/get_or_create.py +109 -0
  98. office365/runtime/record_collection.py +443 -0
  99. office365/runtime/retry.py +92 -26
  100. office365/runtime/transport/base.py +6 -1
  101. office365/runtime/transport/requests_transport.py +4 -0
  102. office365/runtime/transport/throttled_transport.py +67 -0
  103. office365/runtime/verification.py +40 -0
  104. office365/sharepoint/activities/logger.py +118 -8
  105. office365/sharepoint/administration/analytics/usage_service.py +15 -7
  106. office365/sharepoint/administration/sitemove/service.py +791 -8
  107. office365/sharepoint/alerts/alert.py +79 -0
  108. office365/sharepoint/apps/app_collection.py +25 -0
  109. office365/sharepoint/apps/launcher.py +16 -0
  110. office365/sharepoint/authpolicy/tenant/compliancereport.py +5 -0
  111. office365/sharepoint/businessdata/app_bdc_catalog.py +135 -0
  112. office365/sharepoint/businessdata/entityfieldvaluedictionary.py +65 -0
  113. office365/sharepoint/businessdata/entityidentifier.py +23 -0
  114. office365/sharepoint/businessdata/entityinstance.py +52 -0
  115. office365/sharepoint/businessdata/entityview.py +31 -0
  116. office365/sharepoint/businessdata/externalsubscriptionstore.py +9 -0
  117. office365/sharepoint/businessdata/typedescriptor.py +37 -0
  118. office365/sharepoint/client_context.py +40 -23
  119. office365/sharepoint/clientsidecomponent/hostedapps/app.py +21 -0
  120. office365/sharepoint/clientsidecomponent/hostedapps/manager.py +16 -0
  121. office365/sharepoint/comments/comment.py +84 -2
  122. office365/sharepoint/contentcenter/machinelearning/models/model.py +0 -23
  123. office365/sharepoint/contentcenter/machinelearning/publications/publication.py +0 -9
  124. office365/sharepoint/contentcenter/machinelearning/samples/sample.py +0 -14
  125. office365/sharepoint/contentcenter/machinelearning/workitems/item.py +0 -80
  126. office365/sharepoint/contentsolution/template_api.py +148 -0
  127. office365/sharepoint/contenttypes/collection.py +32 -10
  128. office365/sharepoint/convergence/addnoliveblobsinodcservicestateapi.py +9 -0
  129. office365/sharepoint/convergence/consumer_permissions.py +15 -0
  130. office365/sharepoint/convergence/migration_complete_state_api.py +25 -0
  131. office365/sharepoint/convergence/odcmetadatacleanedupapi.py +9 -0
  132. office365/sharepoint/documentmanagement/document_id.py +12 -0
  133. office365/sharepoint/entity.py +11 -2
  134. office365/sharepoint/entity_collection.py +2 -2
  135. office365/sharepoint/exceptions.py +194 -0
  136. office365/sharepoint/fields/builtin_field_id.py +45 -34
  137. office365/sharepoint/fields/builtin_field_name.py +123 -0
  138. office365/sharepoint/fields/coercion.py +131 -0
  139. office365/sharepoint/fields/collection.py +54 -37
  140. office365/sharepoint/fields/field.py +17 -0
  141. office365/sharepoint/fields/name.py +46 -2
  142. office365/sharepoint/files/collection.py +7 -1
  143. office365/sharepoint/files/file.py +54 -8
  144. office365/sharepoint/files/versions/version.py +38 -13
  145. office365/sharepoint/folders/collection.py +4 -0
  146. office365/sharepoint/folders/folder.py +91 -21
  147. office365/sharepoint/htmlpages/html_page.py +16 -0
  148. office365/sharepoint/htmlpages/html_page_service.py +19 -0
  149. office365/sharepoint/ir/migration.py +9 -0
  150. office365/sharepoint/listitems/caml/__init__.py +31 -0
  151. office365/sharepoint/listitems/caml/builder.py +129 -0
  152. office365/sharepoint/listitems/caml/expressions.py +424 -0
  153. office365/sharepoint/listitems/caml/fields.py +68 -0
  154. office365/sharepoint/listitems/caml/guard.py +63 -0
  155. office365/sharepoint/listitems/caml/query.py +71 -2
  156. office365/sharepoint/listitems/caml/values.py +113 -0
  157. office365/sharepoint/listitems/collection.py +21 -20
  158. office365/sharepoint/listitems/upsert.py +75 -0
  159. office365/sharepoint/lists/collection.py +29 -22
  160. office365/sharepoint/lists/exporter.py +4 -3
  161. office365/sharepoint/lists/list.py +397 -39
  162. office365/sharepoint/lists/smart_wiki_library_utility.py +58 -0
  163. office365/sharepoint/logger/export.py +12 -0
  164. office365/sharepoint/marketplace/app_metadata.py +97 -1
  165. office365/sharepoint/marketplace/appstatequeryjobdefinition.py +9 -0
  166. office365/sharepoint/marketplace/corporatecuratedgallery/carddesigns/card_designs.py +35 -0
  167. office365/sharepoint/marketplace/sitecollection/appcatalog/allowed_item.py +5 -0
  168. office365/sharepoint/marketplace/tenant/appcatalog/accessor.py +107 -30
  169. office365/sharepoint/microfeed/data.py +0 -6
  170. office365/sharepoint/microservice/manager.py +61 -0
  171. office365/sharepoint/migrationcenter/common/task.py +193 -4
  172. office365/sharepoint/migrationcenter/common/task_entity_data.py +1 -1
  173. office365/sharepoint/migrationcenter/deploy_status.py +13 -0
  174. office365/sharepoint/migrationcenter/service/properties.py +20 -0
  175. office365/sharepoint/migrationcenter/service/storage.py +34 -0
  176. office365/sharepoint/migrationcenter/spflight.py +13 -0
  177. office365/sharepoint/migrationcenter/urlparseresult.py +77 -0
  178. office365/sharepoint/multigeo/service/spmultigeoproxy.py +13 -0
  179. office365/sharepoint/navigation/servicerest.py +127 -0
  180. office365/sharepoint/oauth/authentication.py +13 -0
  181. office365/sharepoint/portal/theme_manager.py +120 -8
  182. office365/sharepoint/principal/users/user.py +10 -0
  183. office365/sharepoint/publishing/campaign/campaign.py +36 -1
  184. office365/sharepoint/publishing/feedvideopage.py +0 -7
  185. office365/sharepoint/publishing/pages/3d/page.py +0 -6
  186. office365/sharepoint/publishing/pages/page.py +0 -117
  187. office365/sharepoint/publishing/pages/reposts/repost.py +0 -7
  188. office365/sharepoint/publishing/pages/topics/topic.py +0 -7
  189. office365/sharepoint/publishing/subtitlefile.py +0 -40
  190. office365/sharepoint/quotamanagement/consumer/consumer_quota_info_api.py +14 -0
  191. office365/sharepoint/quotamanagement/consumer/non_quota_backfill_api.py +23 -0
  192. office365/sharepoint/quotamanagement/consumer/nonquotamigrationapi.py +9 -0
  193. office365/sharepoint/quotamanagement/consumer/quotamigrationapi.py +13 -0
  194. office365/sharepoint/request.py +57 -16
  195. office365/sharepoint/search/administration/document_crawl_log.py +24 -7
  196. office365/sharepoint/search/administration/providers/crawl_versions_info.py +29 -0
  197. office365/sharepoint/search/administration/providers/recycle_bin_info.py +23 -0
  198. office365/sharepoint/search/administration/providers/site_content_processing_info.py +67 -0
  199. office365/sharepoint/sites/site.py +976 -65
  200. office365/sharepoint/sites/siteprovisioninginfoprovider.py +13 -0
  201. office365/sharepoint/tenant/administration/datagovernance/insight_client.py +292 -23
  202. office365/sharepoint/tenant/administration/ddiadapter.py +97 -0
  203. office365/sharepoint/tenant/administration/internal/aad/collection.py +20 -0
  204. office365/sharepoint/tenant/administration/internal/aad/permission_grant.py +0 -19
  205. office365/sharepoint/tenant/administration/internal/appservice/permission_request.py +72 -1
  206. office365/sharepoint/tenant/administration/internal/appservice/principal.py +1 -3
  207. office365/sharepoint/tenant/administration/odb_license_enforcement_service.py +26 -0
  208. office365/sharepoint/tenant/administration/sites/properties.py +564 -6
  209. office365/sharepoint/tenant/administration/spdatagovernancesarrestapiclient.py +60 -1
  210. office365/sharepoint/tenant/insights/reports/manager.py +24 -12
  211. office365/sharepoint/tenant/management/office365_tenant.py +451 -2
  212. office365/sharepoint/tenantadministration/catalog_management_collection.py +69 -0
  213. office365/sharepoint/tenantadministration/catalog_management_custom_properties_collection.py +237 -0
  214. office365/sharepoint/tenantadministration/catalog_management_restricted_content_discovery_collection.py +56 -0
  215. office365/sharepoint/tenantadministration/sp_data_governance_client_exception.py +7 -0
  216. office365/sharepoint/thresholds.py +529 -0
  217. office365/sharepoint/translation/jobs/job.py +72 -2
  218. office365/sharepoint/translation/jobs/status.py +47 -9
  219. office365/sharepoint/translation/sync_translator.py +15 -2
  220. office365/sharepoint/utilities/move_copy_util.py +2 -1
  221. office365/sharepoint/viva/connections/page.py +27 -0
  222. office365/sharepoint/viva/home.py +38 -0
  223. office365/sharepoint/viva/learningmanager.py +9 -0
  224. office365/sharepoint/viva/vivaresources.py +60 -0
  225. office365/sharepoint/webhooks/subscription.py +0 -11
  226. office365/sharepoint/webparts/definitions/definition.py +13 -0
  227. office365/sharepoint/webparts/limited_manager.py +29 -7
  228. office365/sharepoint/webs/context_web_information.py +14 -9
  229. office365/sharepoint/webs/templates/__init__.py +11 -0
  230. office365/sharepoint/webs/templates/type.py +74 -15
  231. office365/sharepoint/workflow/definition.py +6 -0
  232. office365/sharepoint/workflow/deployment_service.py +155 -0
  233. office365/sharepoint/workflow/instances/service.py +33 -0
  234. office365/sharepoint/workflow/interopservice.py +68 -0
  235. office365/sharepoint/workflow/messagingservice.py +24 -0
  236. office365/sharepoint/workflow/servicesmanager.py +41 -2
  237. office365/sharepoint/workflow/subscriptions/service.py +67 -0
  238. office365/sharepoint/workflow/subscriptions/subscription.py +31 -0
  239. office365/sharepoint/workflow/task.py +425 -0
  240. office365_rest_python_client-3.2.0.dist-info/METADATA +605 -0
  241. {office365_rest_python_client-3.1.0.dist-info → office365_rest_python_client-3.2.0.dist-info}/RECORD +242 -185
  242. office365/migration/_util.py +0 -73
  243. office365/sharepoint/listitems/caml/types.py +0 -70
  244. office365_rest_python_client-3.1.0.dist-info/METADATA +0 -475
  245. {office365_rest_python_client-3.1.0.dist-info → office365_rest_python_client-3.2.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,605 @@
1
+ Metadata-Version: 2.3
2
+ Name: office365-rest-python-client
3
+ Version: 3.2.0
4
+ Summary: Microsoft 365 & Microsoft Graph Library for Python
5
+ Author: Vadim Gremyachev
6
+ Author-email: Vadim Gremyachev <vvgrem@gmail.com>
7
+ License: The MIT License (MIT)
8
+
9
+ Copyright (c) 2016 Vadim Gremyachev
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+ Classifier: Development Status :: 4 - Beta
29
+ Classifier: Intended Audience :: Developers
30
+ Classifier: License :: OSI Approved :: MIT License
31
+ Classifier: Programming Language :: Python
32
+ Classifier: Programming Language :: Python :: 3 :: Only
33
+ Classifier: Programming Language :: Python :: 3.8
34
+ Classifier: Programming Language :: Python :: 3.9
35
+ Classifier: Programming Language :: Python :: 3.10
36
+ Classifier: Programming Language :: Python :: 3.11
37
+ Classifier: Programming Language :: Python :: 3.12
38
+ Classifier: Programming Language :: Python :: 3.13
39
+ Classifier: Programming Language :: Python :: 3.14
40
+ Classifier: Topic :: Internet :: WWW/HTTP
41
+ Classifier: Topic :: Software Development :: Libraries
42
+ Requires-Dist: msal>=1.28,<2
43
+ Requires-Dist: pytz>=2021.1
44
+ Requires-Dist: requests>=2.32.4,<3
45
+ Requires-Dist: typing-extensions>=4.5
46
+ Requires-Dist: azure-storage-blob>=12.19 ; extra == 'azure'
47
+ Requires-Dist: cryptography>=42 ; extra == 'azure'
48
+ Requires-Dist: duckdb>=1.0 ; extra == 'duckdb'
49
+ Requires-Dist: faker ; extra == 'examples'
50
+ Requires-Dist: openpyxl>=3.1 ; extra == 'excel'
51
+ Requires-Dist: pandas>=1.3.0 ; extra == 'notebooks'
52
+ Requires-Dist: jupyter ; extra == 'notebooks'
53
+ Requires-Dist: nbformat ; extra == 'notebooks'
54
+ Requires-Dist: jinja2 ; extra == 'notebooks'
55
+ Requires-Dist: requests-ntlm ; extra == 'ntlm'
56
+ Requires-Dist: pandas>=1.5 ; extra == 'pandas'
57
+ Requires-Dist: pyarrow>=14 ; extra == 'parquet'
58
+ Requires-Dist: sqlalchemy>=2.0 ; extra == 'sql'
59
+ Maintainer: Domenico Di Nicola
60
+ Maintainer-email: Domenico Di Nicola <dom.dinicola@gmail.com>
61
+ Requires-Python: >=3.8.0
62
+ Project-URL: funding, https://ko-fi.com/vgrem
63
+ Project-URL: repository, https://github.com/vgrem/office365-rest-python-client
64
+ Provides-Extra: azure
65
+ Provides-Extra: duckdb
66
+ Provides-Extra: examples
67
+ Provides-Extra: excel
68
+ Provides-Extra: notebooks
69
+ Provides-Extra: ntlm
70
+ Provides-Extra: pandas
71
+ Provides-Extra: parquet
72
+ Provides-Extra: sql
73
+ Description-Content-Type: text/markdown
74
+
75
+ # office365-rest-python-client
76
+
77
+ **A Python client library for Microsoft 365, the SharePoint REST API and Microsoft Graph.**
78
+
79
+ [![Downloads](https://pepy.tech/badge/office365-rest-python-client/month)](https://pepy.tech/project/office365-rest-python-client)
80
+ [![PyPI](https://img.shields.io/pypi/v/office365-rest-python-client.svg)](https://pypi.python.org/pypi/office365-rest-python-client)
81
+ [![PyPI pyversions](https://img.shields.io/pypi/pyversions/office365-rest-python-client.svg)](https://pypi.python.org/pypi/office365-rest-python-client/)
82
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/vgrem/office365-rest-python-client/blob/master/LICENSE)
83
+ [![Sponsor](https://img.shields.io/badge/sponsor-vgrem-ea4aaa.svg?logo=github-sponsors)](https://github.com/sponsors/vgrem)
84
+
85
+ **Python 3.8+** · typed models · fluent queries · deferred execution · 700+ runnable examples
86
+
87
+ - **Two clients, one library** — `ClientContext` speaks the SharePoint REST API; `GraphClient` speaks Microsoft Graph.
88
+ - **Fluent and deferred** — chain `.select()`, `.filter()`, `.expand()`, `.top()`, `.order_by()` and only hit the wire when you call `execute_query()`.
89
+ - **Typed models** — every entity is a real Python class (`List`, `File`, `Team`, `Message`, …), not a dictionary.
90
+ - **Copy-paste examples** — a runnable script for every service and scenario under [`examples/`](https://github.com/vgrem/office365-rest-python-client/tree/master/examples).
91
+
92
+ > **New here?** Pick a client in [Choose your client](#choose-your-client), then jump straight to a runnable snippet in [Examples by product](#examples-by-product).
93
+
94
+ ## Table of contents
95
+
96
+ - [Choose your client](#choose-your-client)
97
+ - [Installation](#installation)
98
+ - [Authentication](#authentication)
99
+ - [Quick start](#quick-start)
100
+ - [Examples by product](#examples-by-product)
101
+ - [Common patterns](#common-patterns)
102
+ - [Dependencies](#dependencies)
103
+ - [Contributing](#contributing)
104
+ - [Support](#support)
105
+
106
+ ## Choose your client
107
+
108
+ The library ships two clients. Pick the one that matches the API you need.
109
+
110
+ | | `ClientContext` | `GraphClient` |
111
+ |---|---|---|
112
+ | **Talks to** | SharePoint REST API (`/_api`) | Microsoft Graph (`graph.microsoft.com`) |
113
+ | **Entry point** | `ClientContext("https://contoso.sharepoint.com/sites/team")` | `GraphClient(tenant="contoso.onmicrosoft.com")` |
114
+ | **Best for** | SharePoint lists, items, files, folders, search, permissions, site and tenant administration, taxonomy, webhooks | Outlook, OneDrive, Teams, OneNote, Planner, To Do, Entra ID, Intune, Purview, Bookings, reports, security… |
115
+ | **SharePoint** | Full fidelity | Partial — prefer `ClientContext` for SharePoint-only work |
116
+ | **Typed models** | `List`, `ListItem`, `File`, `Folder`, `Web`, `Site`, `User` … | `DriveItem`, `Team`, `Message`, `Event`, `User`, `Group`, `PlannerTask` … |
117
+ | **Auth** | certificate, interactive, device flow, cookies, NTLM (on-prem) | client secret, certificate, interactive, device flow, ROPC |
118
+ | **Examples** | [`examples/sharepoint/`](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint) | [`examples/`](https://github.com/vgrem/office365-rest-python-client/tree/master/examples) by product |
119
+ | **API reference** | [SharePoint REST](https://learn.microsoft.com/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service) | [Microsoft Graph](https://learn.microsoft.com/graph/overview) |
120
+
121
+ **Rule of thumb**
122
+
123
+ - SharePoint lists, files, site or tenant administration → **`ClientContext`**
124
+ - Teams, Outlook, OneDrive, Entra ID, Intune, Purview, reports → **`GraphClient`**
125
+ - OneDrive files work with either client; `GraphClient` is the modern, cross-service path.
126
+
127
+ ## Installation
128
+
129
+ ```bash
130
+ pip install office365-rest-python-client
131
+ ```
132
+
133
+ With [uv](https://docs.astral.sh/uv/):
134
+
135
+ ```bash
136
+ uv add office365-rest-python-client
137
+ ```
138
+
139
+ Directly from source:
140
+
141
+ ```bash
142
+ pip install git+https://github.com/vgrem/office365-rest-python-client.git
143
+ ```
144
+
145
+ ## Authentication
146
+
147
+ Modern flows authenticate through **Microsoft Entra ID** using [MSAL](https://learn.microsoft.com/entra/identity-platform/msal-overview). Both clients support delegated (user) and app-only (application) access.
148
+
149
+ > [!IMPORTANT]
150
+ > SharePoint **ACS app-only** access was retired in April 2026 and **SAML-based** authentication in May 2026. Use the certificate, interactive or device-code flows below instead — see [`examples/sharepoint/auth/modern/`](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/auth/modern) and the migration script [`migrate_from_saml_to_cert.py`](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/modern/migrate_from_saml_to_cert.py).
151
+
152
+ ### ClientContext (SharePoint)
153
+
154
+ | Flow | Access | Method |
155
+ |---|---|---|
156
+ | Certificate | App-only | `with_client_certificate(tenant, client_id, thumbprint, cert_path=...)` |
157
+ | Interactive | Delegated (MFA) | `with_interactive(tenant, client_id)` |
158
+ | Device code | Delegated (MFA) | `with_device_flow(tenant, client_id)` |
159
+ | Username / password | Delegated | `with_username_and_password(tenant, client_id, username, password)` |
160
+ | Custom token | Either | `with_access_token(token_func)` |
161
+ | Browser cookies | Delegated | `with_cookies(cookie_source)` |
162
+ | NTLM | On-premises | `ClientContext(url, allow_ntlm=True).with_user_credentials(username, password)` |
163
+ | ACS / SAML | On-premises (legacy) | [legacy app-only](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/legacy/with_app_only.py) · [legacy SAML](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/legacy/with_user_credential.py) |
164
+
165
+ > [!NOTE]
166
+ > SharePoint app-only access requires a **certificate**. A client secret is not accepted by the SharePoint `/_api` endpoints — use `GraphClient` for secret-based app-only. See [why a client secret doesn't work for SharePoint](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/README.md).
167
+
168
+ ```python
169
+ from office365.sharepoint.client_context import ClientContext
170
+
171
+ ctx = ClientContext("https://contoso.sharepoint.com/sites/team").with_client_certificate(
172
+ "contoso.onmicrosoft.com",
173
+ client_id="00000000-0000-0000-0000-000000000000",
174
+ thumbprint="AA11BB22CC33DD44EE55FF66AA77BB88CC99DD00",
175
+ cert_path="./private.pem",
176
+ )
177
+
178
+ web = ctx.web.get().execute_query()
179
+ print(web.title)
180
+ ```
181
+
182
+ Ready-made scripts: [certificate](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/modern/with_certificate.py) ·
183
+ [certificate (private key)](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/modern/with_certificate_and_privkey.py) ·
184
+ [custom scopes](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/modern/with_certificate_and_scopes.py) ·
185
+ [interactive](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/modern/with_interactive.py) ·
186
+ [device flow](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/modern/with_device_flow.py) ·
187
+ [username/password](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/modern/with_username_and_password.py) ·
188
+ [access token](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/files/download_parallel.py) ·
189
+ [cookies](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/modern/with_cookies.py) ·
190
+ [NTLM](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/sharepoint/auth/legacy/with_ntlm.py)
191
+
192
+ ### GraphClient (Microsoft Graph)
193
+
194
+ | Flow | Access | Method |
195
+ |---|---|---|
196
+ | Client secret | App-only | `with_client_secret(client_id, client_secret)` |
197
+ | Certificate | App-only | `with_certificate(client_id, thumbprint, private_key)` |
198
+ | Interactive | Delegated (MFA) | `with_token_interactive(client_id)` |
199
+ | Device code | Delegated (MFA) | `with_device_flow(client_id)` |
200
+ | Username / password | Delegated | `with_username_and_password(client_id, username, password)` |
201
+ | Custom token | Either | `GraphClient(token_callback, tenant=...)` |
202
+
203
+ ```python
204
+ from office365.graph_client import GraphClient
205
+
206
+ client = GraphClient(tenant="contoso.onmicrosoft.com").with_client_secret(
207
+ client_id="00000000-0000-0000-0000-000000000000",
208
+ client_secret="your-client-secret",
209
+ )
210
+
211
+ users = client.users.get().execute_query()
212
+ print(len(users), "users")
213
+ ```
214
+
215
+ Ready-made scripts: [client secret](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/auth/with_client_secret.py) ·
216
+ [certificate](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/auth/with_client_cert.py) ·
217
+ [interactive](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/auth/interactive.py) ·
218
+ [device flow](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/auth/with_device_flow.py) ·
219
+ [username/password](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/auth/with_user_creds.py) ·
220
+ [custom token callback](https://github.com/vgrem/office365-rest-python-client/blob/master/examples/auth/with_token_callback.py)
221
+
222
+ ## Quick start
223
+
224
+ **SharePoint list — read and write items**
225
+
226
+ ```python
227
+ from office365.sharepoint.client_context import ClientContext
228
+
229
+ ctx = ClientContext("https://contoso.sharepoint.com/sites/team").with_client_certificate(
230
+ "contoso.onmicrosoft.com", client_id, thumbprint, cert_path="./private.pem"
231
+ )
232
+
233
+ tasks = ctx.web.lists.get_by_title("Tasks")
234
+ item = tasks.add_item({"Title": "Write the release notes"}).execute_query()
235
+ print("Created item:", item.id)
236
+
237
+ for task in tasks.items.get_all().execute_query():
238
+ print(task.properties["Title"])
239
+ ```
240
+
241
+ **Microsoft Graph — send an email**
242
+
243
+ ```python
244
+ from office365.graph_client import GraphClient
245
+
246
+ client = GraphClient(tenant="contoso.onmicrosoft.com").with_client_secret(client_id, client_secret)
247
+
248
+ client.me.send_mail(
249
+ subject="Hello from Graph API",
250
+ body="This email was sent using the Microsoft Graph API.",
251
+ to_recipients=["alex@contoso.onmicrosoft.com"],
252
+ ).execute_query()
253
+ ```
254
+
255
+ ## Examples by product
256
+
257
+ Every snippet below is lifted from a runnable script. Follow the **More →** link for the full example and its required permissions.
258
+
259
+ ### SharePoint (ClientContext)
260
+
261
+ ```python
262
+ # Lists and items
263
+ tasks = ctx.web.lists.get_by_title("Tasks")
264
+ item = tasks.add_item({"Title": "Ship it", "Status": "Active"}).execute_query()
265
+ tasks.items.get_all().execute_query() # or .filter("Status eq 'Active'").get_all()
266
+
267
+ # Files and folders
268
+ folder = ctx.web.get_folder_by_server_relative_url("/sites/team/Shared Documents")
269
+ with open("report.pdf", "rb") as f:
270
+ file = folder.files.upload(f).execute_query()
271
+
272
+ with open("report.pdf", "wb") as f:
273
+ ctx.web.get_file_by_server_relative_path("/sites/team/Shared Documents/report.pdf").download(f).execute_query()
274
+
275
+ # Large file (chunked upload session)
276
+ with open("video.mp4", "rb") as f:
277
+ folder.files.create_upload_session(f, 10 * 1024 * 1024).execute_query()
278
+ ```
279
+
280
+ | Area | Examples |
281
+ |---|---|
282
+ | Lists and items | [lists](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/lists) · [listitems](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/listitems) · [views](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/views) |
283
+ | Files and folders | [files](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/files) · [folders](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/folders) |
284
+ | Sites and webs | [sites](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/sites) · [webs](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/webs) · [hubsites](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/hubsites) |
285
+ | Search | [search](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/search) |
286
+ | Permissions and sharing | [permissions](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/permissions) · [sharing](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/sharing) |
287
+ | Fields and content types | [fields](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/fields) · [contenttypes](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/contenttypes) |
288
+ | Pages and navigation | [pages](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/pages) · [navigation](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/navigation) |
289
+ | Taxonomy and profiles | [taxonomy](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/taxonomy) · [userprofile](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/userprofile) |
290
+ | Tenant administration | [tenant](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/tenant) · [groups](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/groups) · [users](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/users) |
291
+ | Webhooks, migration, advanced | [webhooks](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/webhooks) · [migration](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/migration) · [advanced](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/sharepoint/advanced) |
292
+
293
+ ### OneDrive
294
+
295
+ ```python
296
+ uploaded = client.me.drive.root.upload_file("report.xlsx").execute_query()
297
+
298
+ with open("report.xlsx", "wb") as f:
299
+ client.me.drive.root.get_by_path("report.xlsx").download(f).execute_query()
300
+ ```
301
+
302
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/onedrive)
303
+
304
+ ### Teams
305
+
306
+ ```python
307
+ team = client.teams.create_and_wait("Contoso Project", "All project collaboration").execute_query()
308
+
309
+ channel = team.channels.add("Project Chat").execute_query()
310
+ channel.messages.add("Hello team!").execute_query()
311
+ ```
312
+
313
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/teams)
314
+
315
+ ### Outlook (mail and calendar)
316
+
317
+ ```python
318
+ from datetime import datetime, timedelta, timezone
319
+
320
+ # Send mail
321
+ client.me.send_mail(
322
+ subject="Hello from Graph API",
323
+ body="This email was sent using the Microsoft Graph API.",
324
+ to_recipients=["alex@contoso.onmicrosoft.com"],
325
+ ).execute_query()
326
+
327
+ # Create a calendar event
328
+ when = datetime.now(timezone.utc) + timedelta(days=1)
329
+ client.me.calendar.events.add(
330
+ subject="Team Lunch",
331
+ body="Let's grab lunch together.",
332
+ start=when,
333
+ end=when + timedelta(hours=1),
334
+ attendees=["alex@contoso.onmicrosoft.com"],
335
+ ).execute_query()
336
+ ```
337
+
338
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/outlook)
339
+
340
+ ### Entra ID
341
+
342
+ ```python
343
+ from office365.directory.users.password_profile import PasswordProfile
344
+ from office365.directory.users.profile import UserProfile
345
+
346
+ profile = UserProfile(
347
+ displayName="Alex Wilber",
348
+ userPrincipalName="alex@contoso.onmicrosoft.com",
349
+ mailNickname="alex",
350
+ accountEnabled=True,
351
+ passwordProfile=PasswordProfile(password="P@ssw0rd!", forceChangePasswordNextSignIn=True),
352
+ )
353
+ user = client.users.add(profile).execute_query()
354
+ print(user.display_name)
355
+ ```
356
+
357
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/entraid)
358
+
359
+ ### Planner
360
+
361
+ ```python
362
+ group = client.groups.get_by_name("My Sample Team").get().execute_query()
363
+ plans = group.planner.plans.get().execute_query()
364
+ task = client.planner.tasks.add("Update client list", plans[0].id).execute_query()
365
+ print(task.title)
366
+ ```
367
+
368
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/planner)
369
+
370
+ ### To Do
371
+
372
+ ```python
373
+ for task_list in client.me.todo.lists.get().execute_query():
374
+ print(task_list.display_name, len(task_list.tasks.get().execute_query()), "tasks")
375
+ ```
376
+
377
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/todo)
378
+
379
+ ### OneNote
380
+
381
+ ```python
382
+ with open("Sample.html", "rb") as page_html:
383
+ page = client.me.onenote.pages.add(presentation_file=page_html).execute_query()
384
+ print(page.links.oneNoteWebUrl)
385
+ ```
386
+
387
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/onenote)
388
+
389
+ <details>
390
+ <summary><strong>More services</strong> — Admin, Reports, Defender, Intune, Purview, Bookings, Communications, Security, Insights, Backup Storage</summary>
391
+
392
+ #### Microsoft 365 admin
393
+
394
+ ```python
395
+ announcement = client.admin.service_announcement
396
+ health = announcement.health_overviews.get().execute_query()
397
+ issues = announcement.issues.get().execute_query()
398
+ messages = announcement.messages.get().execute_query()
399
+ ```
400
+
401
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/admin)
402
+
403
+ #### Usage reports
404
+
405
+ ```python
406
+ report = client.reports.get_email_activity_counts("D30").execute_query()
407
+ print(report.value) # CSV payload
408
+ ```
409
+
410
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/reports)
411
+
412
+ #### Microsoft Defender
413
+
414
+ ```python
415
+ alerts = client.security.alerts_v2.top(20).get().execute_query()
416
+ for alert in alerts:
417
+ print(alert)
418
+ ```
419
+
420
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/defender)
421
+
422
+ #### Microsoft Intune
423
+
424
+ ```python
425
+ devices = client.device_management.managed_devices.get().execute_query()
426
+ for device in devices:
427
+ print(device.device_name, device.operating_system, device.compliance_state)
428
+ ```
429
+
430
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/intune)
431
+
432
+ #### Microsoft Purview
433
+
434
+ ```python
435
+ labels = client.security.data_security_and_governance.sensitivity_labels.get().execute_query()
436
+ for label in labels:
437
+ print(label.display_name, label.id)
438
+ ```
439
+
440
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/purview)
441
+
442
+ #### Microsoft Bookings
443
+
444
+ ```python
445
+ businesses = client.solutions.booking_businesses.get().execute_query()
446
+ for business in businesses:
447
+ print(business.display_name)
448
+ ```
449
+
450
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/booking)
451
+
452
+ #### Cloud communications
453
+
454
+ ```python
455
+ presence = client.users["alex@contoso.onmicrosoft.com"].presence.get().execute_query()
456
+ print(presence.availability, presence.activity)
457
+ ```
458
+
459
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/communications)
460
+
461
+ #### Security (threat intelligence)
462
+
463
+ ```python
464
+ host = client.security.threat_intelligence.hosts["contoso.com"].get().execute_query()
465
+ reputation = host.reputation.get().execute_query()
466
+ print(reputation.properties.get("score"))
467
+ ```
468
+
469
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/security)
470
+
471
+ #### Insights
472
+
473
+ ```python
474
+ for item in client.me.insights.trending.get().execute_query():
475
+ print(item.resource_reference)
476
+ ```
477
+
478
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/insights)
479
+
480
+ #### Backup Storage
481
+
482
+ ```python
483
+ backup = client.solutions.backup_restore
484
+ backup.get().execute_query()
485
+ print(backup.service_status.status)
486
+ ```
487
+
488
+ [More →](https://github.com/vgrem/office365-rest-python-client/tree/master/examples/backuprestore)
489
+
490
+ </details>
491
+
492
+ ## Common patterns
493
+
494
+ **Deferred execution.** Requests are queued and sent only when you call `execute_query()`. Chain the fluent methods first, then execute once.
495
+
496
+ ```python
497
+ items = (
498
+ ctx.web.lists.get_by_title("Tasks")
499
+ .items.select(["Title", "Status"])
500
+ .filter("Status eq 'Active'")
501
+ .order_by("Title")
502
+ .top(100)
503
+ .get()
504
+ .execute_query()
505
+ )
506
+ ```
507
+
508
+ **Reading large collections.** Use `get_all()` to follow paging automatically, and `page_size` to stay under server limits.
509
+
510
+ ```python
511
+ items = ctx.web.lists.get_by_title("Orders").items.get_all(page_size=2000).execute_query()
512
+
513
+ files = ctx.web.get_folder_by_server_relative_url("/sites/team/Shared Documents").get_files(
514
+ recursive=True, page_size=2000
515
+ ).execute_query()
516
+ ```
517
+
518
+ **Batching.** Dispatch many queued operations in one round trip. Raise `concurrency` to run batches in parallel; throttled sub-requests are retried individually, honoring `Retry-After`.
519
+
520
+ ```python
521
+ for row in rows:
522
+ ctx.web.lists.get_by_title("Contacts").add_item(row)
523
+
524
+ ctx.execute_batch() # sequential
525
+ ctx.execute_batch(concurrency=5) # up to 5 batches in flight
526
+
527
+ # Graph
528
+ for user in new_users:
529
+ client.users.add(user)
530
+ client.execute_batch(concurrency=5)
531
+ ```
532
+
533
+ **Large lists (> 5,000 items).** SharePoint refuses filtered/sorted queries on non-indexed columns. The library can tell you what to index and pre-flight the query.
534
+
535
+ ```python
536
+ from office365.sharepoint.listitems.caml import Caml, CamlQuery
537
+
538
+ query = (
539
+ CamlQuery.builder()
540
+ .where(Caml.text("Status").eq("Active"))
541
+ .order_by("ID")
542
+ .row_limit(2000, paged=True)
543
+ .build()
544
+ )
545
+
546
+ lst.check_query(query) # raises with a clear message if an index is missing
547
+ print(lst.index_candidates(query)) # columns worth indexing
548
+ lst.ensure_indexed("Status").execute_query() # create the index (builds in the background)
549
+ ```
550
+
551
+ **Import and export DataFrames.** Optional helpers turn list items into [pandas](https://pandas.pydata.org/) / [Polars](https://pola.rs/) frames and back.
552
+
553
+ ```python
554
+ lst = ctx.web.lists.ensure_list("Orders").execute_query()
555
+
556
+ df = lst.to_dataframe().execute_query().value
557
+ lst.from_dataframe(df, chunksize=100).execute_query()
558
+ ```
559
+
560
+ ## Dependencies
561
+
562
+ Install the core package on its own, or add the extras you need:
563
+
564
+ | Extra | Adds | Use it for |
565
+ |---|---|---|
566
+ | `azure` | `azure-storage-blob`, `cryptography` | Azure Blob Storage and certificate helpers |
567
+ | `excel` | `openpyxl` | Reading and writing Excel workbooks |
568
+ | `examples` | `faker` | Running the sample scripts |
569
+ | `ntlm` | `requests-ntlm` | On-premises SharePoint with NTLM |
570
+ | `pandas` | `pandas` | `to_dataframe()` / `from_dataframe()` |
571
+ | `parquet` | `pyarrow` | Parquet import and export |
572
+ | `duckdb` | `duckdb` | Querying exported data locally |
573
+ | `sql` | `sqlalchemy` | SQL-backed import and export |
574
+ | `notebooks` | `jupyter`, `nbformat`, `jinja2` | Running the notebook samples |
575
+
576
+ ```bash
577
+ pip install "office365-rest-python-client[pandas,excel]"
578
+ ```
579
+
580
+ ## Contributing
581
+
582
+ Issues and pull requests are welcome — please use the
583
+ [issue tracker](https://github.com/vgrem/office365-rest-python-client/issues) for bugs and ideas.
584
+
585
+ ```bash
586
+ git clone https://github.com/vgrem/office365-rest-python-client.git
587
+ cd office365-rest-python-client
588
+ uv sync --all-extras
589
+ pytest --offline -q
590
+ ```
591
+
592
+ See [CONTRIBUTING.md](https://github.com/vgrem/office365-rest-python-client/blob/master/CONTRIBUTING.md) for the full development setup. Run the gate before submitting: `ruff check .`, `ruff format --check .`, `pyright` and `pytest --offline -q`.
593
+
594
+ ## Support
595
+
596
+ - **Source and examples** — [github.com/vgrem/office365-rest-python-client](https://github.com/vgrem/office365-rest-python-client)
597
+ - **Documentation** — [vgrem.github.io/office365-rest-python-client](https://vgrem.github.io/office365-rest-python-client/)
598
+ - **Changelog** — [CHANGELOG.md](https://github.com/vgrem/office365-rest-python-client/blob/master/CHANGELOG.md)
599
+ - **Questions** — [GitHub Discussions](https://github.com/vgrem/office365-rest-python-client/discussions) or tag [`office365-rest-python-client` on Stack Overflow](https://stackoverflow.com/questions/tagged/office365-rest-python-client)
600
+
601
+ If this project saves you time, please consider [sponsoring its development](https://github.com/sponsors/vgrem). ⭐
602
+
603
+ ## License
604
+
605
+ Released under the [MIT License](https://github.com/vgrem/office365-rest-python-client/blob/master/LICENSE).