Office365-REST-Python-Client 2.6.0__py3-none-any.whl → 2.6.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Office365-REST-Python-Client
3
- Version: 2.6.0
3
+ Version: 2.6.1
4
4
  Summary: Microsoft 365 & Microsoft Graph Library for Python
5
5
  Home-page: https://github.com/vgrem/Office365-REST-Python-Client
6
6
  Author: Vadim Gremyachev
@@ -34,6 +34,7 @@ Requires-Dist: typing-extensions >=4.0.0
34
34
  Provides-Extra: ntlmprovider
35
35
  Requires-Dist: requests-ntlm ; extra == 'ntlmprovider'
36
36
 
37
+
37
38
  # About
38
39
  Microsoft 365 & Microsoft Graph library for Python
39
40
 
@@ -208,19 +209,18 @@ The list of examples:
208
209
 
209
210
  Refer [examples section](examples/sharepoint) for another scenarios
210
211
 
211
- ### Support for non-standard SharePoint Online Environments
212
-
213
- Support for non-standard SharePoint Environments is currently being implemented. Currently supported:
214
- - GCC High
212
+ ### Support for Azure environments
215
213
 
216
- To enable authentication to GCC High endpoints, add the `environment='GCCH'` parameter when calling the
214
+ To enable authentication to specific Azure environment endpoints, add the `environment` parameter when calling the
217
215
  `ClientContext class` with `.with_user_credentials`, `.with_client_credentials`, or `.with_credentials`
218
216
 
219
217
  Example:
220
218
  ```python
219
+ from office365.azure_env import AzureEnvironment
221
220
  from office365.sharepoint.client_context import ClientContext
221
+ from office365.runtime.auth.client_credential import ClientCredential
222
222
  client_credentials = ClientCredential('{client_id}','{client_secret}')
223
- ctx = ClientContext('{url}').with_credentials(client_credentials, environment='GCCH')
223
+ ctx = ClientContext('{site-url}', environment=AzureEnvironment.USGovernmentHigh).with_credentials(client_credentials)
224
224
  ```
225
225
 
226
226
  # Working with Outlook API
@@ -249,26 +249,13 @@ Using [Microsoft Authentication Library (MSAL) for Python](https://pypi.org/proj
249
249
  > in the provided examples. Other forms of token acquisition can be found here: https://msal-python.readthedocs.io/en/latest/
250
250
 
251
251
  ```python
252
- import msal
253
252
  from office365.graph_client import GraphClient
254
-
255
- def acquire_token():
256
- """
257
- Acquire token via MSAL
258
- """
259
- authority_url = 'https://login.microsoftonline.com/{tenant_id_or_name}'
260
- app = msal.ConfidentialClientApplication(
261
- authority=authority_url,
262
- client_id='{client_id}',
263
- client_credential='{client_secret}'
264
- )
265
- token = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
266
- return token
267
-
268
-
269
- client = GraphClient(acquire_token)
270
-
253
+ client = GraphClient(tenant='{tenant_name_or_id}').with_client_secret(
254
+ client_id='{client_id}',
255
+ client_secret='{client_secret}'
256
+ )
271
257
  ```
258
+ Example: [with_client_secret](examples/auth/with_client_secret.py)
272
259
 
273
260
  But in terms of Microsoft Graph API authentication, another OAuth spec compliant libraries
274
261
  such as [adal](https://github.com/AzureAD/azure-activedirectory-library-for-python)
@@ -304,7 +291,9 @@ The example demonstrates how to send an email via [Microsoft Graph endpoint](htt
304
291
  ```python
305
292
  from office365.graph_client import GraphClient
306
293
 
307
- client = GraphClient(acquire_token_func)
294
+ client = GraphClient(tenant='{tenant_name_or_id}').with_username_and_password(
295
+ '{client_id}', '{username}', '{password}'
296
+ )
308
297
 
309
298
  client.me.send_mail(
310
299
  subject="Meet for lunch?",
@@ -370,7 +359,7 @@ which corresponds to [`list available drives` endpoint](https://docs.microsoft.c
370
359
  from office365.graph_client import GraphClient
371
360
 
372
361
  tenant_name = "contoso.onmicrosoft.com"
373
- client = GraphClient(acquire_token_func)
362
+ client = GraphClient(tenant=tenant_name)
374
363
  drives = client.drives.get().execute_query()
375
364
  for drive in drives:
376
365
  print("Drive url: {0}".format(drive.web_url))
@@ -381,7 +370,7 @@ for drive in drives:
381
370
 
382
371
  ```python
383
372
  from office365.graph_client import GraphClient
384
- client = GraphClient(acquire_token_func)
373
+ client = GraphClient(tenant="contoso.onmicrosoft.com")
385
374
  # retrieve drive properties
386
375
  drive = client.users["{user_id_or_principal_name}"].drive.get().execute_query()
387
376
  # download files from OneDrive into local folder
@@ -451,7 +440,9 @@ Example: Create a new page
451
440
 
452
441
  ```python
453
442
  from office365.graph_client import GraphClient
454
- client = GraphClient(acquire_token_func)
443
+ client = GraphClient(tenant='{tenant_name_or_id}').with_username_and_password(
444
+ '{client_id}', '{username}', '{password}'
445
+ )
455
446
 
456
447
  files = {}
457
448
  with open("./MyPage.html", 'rb') as f, \
@@ -864,7 +864,7 @@ office365/runtime/auth/authentication_context.py,sha256=ywUGZpEeJKXfTjDEOPLKtSEw
864
864
  office365/runtime/auth/authentication_provider.py,sha256=B6XwQWg13Fyf9Qmv1L2jEfRmf9bkBJpYmWReNojJsRQ,320
865
865
  office365/runtime/auth/client_credential.py,sha256=nJjmCF6kAChl2XIUxF4MELL0cc5IGTMQuD7IVIK30Bo,274
866
866
  office365/runtime/auth/credential_type.py,sha256=mwqBEoFTi2ZdFM0DhsHY8NuOjQjkCaR14btpEjIBAQ0,114
867
- office365/runtime/auth/sts_profile.py,sha256=UOA0rITprsJe-MbC1YBCyURkwRuAJdmij9HmfjXEK_M,1402
867
+ office365/runtime/auth/sts_profile.py,sha256=lYbKx7AWYbyWVfcoccg-D3XnRnsuBagiNMt65aoSn48,1558
868
868
  office365/runtime/auth/token_response.py,sha256=p1e-rcXtREon3F5XPG-S5LBleZZH_Ook5sSLpUJHrdA,962
869
869
  office365/runtime/auth/user_credential.py,sha256=TyjvuTQs3NioqQAXwZVnfYLaGVEJWDDFnLVz6-x41oU,223
870
870
  office365/runtime/auth/user_realm_info.py,sha256=BIcLI25MiV_5PAgm0ouByo0D2eA23SIDc01Ze18K4yE,237
@@ -874,7 +874,7 @@ office365/runtime/auth/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
874
874
  office365/runtime/auth/providers/acs_token_provider.py,sha256=lUNGf5y34IzCOBz6RgtVYMSLN_9Evpo9--AOxk6PhVE,4595
875
875
  office365/runtime/auth/providers/network_credential_provider.py,sha256=QhftPyDa2C0dO8GjEdBd-09lQGoJlIZTeAiAXtdfc2Y,488
876
876
  office365/runtime/auth/providers/ntlm_provider.py,sha256=XXnSRCVndNpXufzd_ZA_Iti4OMVc3bhRlAoXBSny2Gw,963
877
- office365/runtime/auth/providers/saml_token_provider.py,sha256=r1F7Jtz83Mjw4ppZvwKbhAvz6DbeX4ph27QyoB3zj1c,12561
877
+ office365/runtime/auth/providers/saml_token_provider.py,sha256=JeqR3MOF4TODw5WcbltJWIjOJIf5pOFTWTj-gjW6Wgg,12282
878
878
  office365/runtime/auth/providers/templates/FederatedSAML.xml,sha256=VpJDhxe51ovXuy8yZ0N0ySQmNtaQ8TbkkumC50TcBSs,2115
879
879
  office365/runtime/auth/providers/templates/RST2.xml,sha256=NR4uiTf9wdI8-7ZsJbpb19YJsQzESNXHOmrAyStJRZU,1513
880
880
  office365/runtime/auth/providers/templates/SAML.xml,sha256=GLQ3Jo3umqI839avwPvkQEQMkal4RwPRzxSK_J_8lQA,1526
@@ -955,7 +955,7 @@ office365/sharepoint/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
955
955
  office365/sharepoint/client_context.py,sha256=Ssn0Vw2se3bXpOj4C8EZILq9BiMw8otIUyb-jSjpBpM,29299
956
956
  office365/sharepoint/entity.py,sha256=YLlyA7Zt-CmiNzso_zhdQrteap8nUiUMwm7B_YXkkRc,2775
957
957
  office365/sharepoint/entity_collection.py,sha256=fJXX3frVHmMb7uPxZAKNwh6YyQbtsa-mUyZMUmE5E2I,1242
958
- office365/sharepoint/request.py,sha256=BYKMJD9WdXEJIF92omAO9coLcVBvNRtlQGj24HOATJY,5111
958
+ office365/sharepoint/request.py,sha256=4qOocAm41Ayut57ODfUTBNa4R67gvjvdBYm8ugMBdxs,5133
959
959
  office365/sharepoint/request_context.py,sha256=Bpr14-de8tJgjYQJvd9s9HW5zAzdyTV1WQAzuGSD0G4,854
960
960
  office365/sharepoint/request_user_context.py,sha256=Dqr5QflILGag-ehU4wzE5--WwTVyo6wnMF9Q3r1_XAE,841
961
961
  office365/sharepoint/server_settings.py,sha256=cr-UHh4-EaSDH1fzzwrl7VHgl8LIBsAMbB7ZhZE7Ddo,2366
@@ -2157,8 +2157,8 @@ office365/todo/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
2157
2157
  office365/todo/tasks/list.py,sha256=i8figSfqkRm1wuUZXJntZWnnidT0XIY2SGvCCuRK8C8,1138
2158
2158
  office365/todo/tasks/list_collection.py,sha256=bDKOXgzdCDWnJqPZgBQYZ9yaFNOqXrv5DL1uWy5fg_M,584
2159
2159
  office365/todo/tasks/task.py,sha256=ZWGkBieQ7_7Om4RgBhXfCs6651a2mi_tFttZgaIcY4o,2120
2160
- Office365_REST_Python_Client-2.6.0.dist-info/LICENSE,sha256=oiA-FsK_tSE0PNl3jtQ9ohZjFjPyQK3ejw6le4hzL5Q,1083
2161
- Office365_REST_Python_Client-2.6.0.dist-info/METADATA,sha256=XDEUtcsnyNqUiOHjX3dAIEsURDx8wgASVG-WZWwps-k,18450
2162
- Office365_REST_Python_Client-2.6.0.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
2163
- Office365_REST_Python_Client-2.6.0.dist-info/top_level.txt,sha256=xmwMgIZYmOTzckcPR2A1-3ebpPhfqj1l_QOvsOf30X4,10
2164
- Office365_REST_Python_Client-2.6.0.dist-info/RECORD,,
2160
+ Office365_REST_Python_Client-2.6.1.dist-info/LICENSE,sha256=oiA-FsK_tSE0PNl3jtQ9ohZjFjPyQK3ejw6le4hzL5Q,1083
2161
+ Office365_REST_Python_Client-2.6.1.dist-info/METADATA,sha256=BW-t8fcVkmeC4YAA0A_EU7e_k4MoNLeFqNIc6JZ0APs,18407
2162
+ Office365_REST_Python_Client-2.6.1.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
2163
+ Office365_REST_Python_Client-2.6.1.dist-info/top_level.txt,sha256=xmwMgIZYmOTzckcPR2A1-3ebpPhfqj1l_QOvsOf30X4,10
2164
+ Office365_REST_Python_Client-2.6.1.dist-info/RECORD,,
@@ -17,12 +17,6 @@ from office365.runtime.auth.user_realm_info import UserRealmInfo
17
17
  office365.logger.ensure_debug_secrets()
18
18
 
19
19
 
20
- def resolve_base_url(url):
21
- parts = url.split("://")
22
- host_name = parts[1].split("/")[0]
23
- return parts[0] + "://" + host_name
24
-
25
-
26
20
  def string_escape(value):
27
21
  value = value.replace("&", "&")
28
22
  value = value.replace("<", "&lt;")
@@ -37,7 +31,7 @@ def datetime_escape(value):
37
31
 
38
32
 
39
33
  class SamlTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
40
- def __init__(self, url, username, password, browser_mode, environment="commercial"):
34
+ def __init__(self, url, username, password, browser_mode, environment=None):
41
35
  """
42
36
  SAML Security Token Service provider (claims-based authentication)
43
37
 
@@ -46,13 +40,11 @@ class SamlTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
46
40
  :param str password: The password
47
41
  :param bool browser_mode:
48
42
  :param str environment: The Office 365 Cloud Environment endpoint used for authentication.
49
- By default, this will be set to commercial ('commercial', 'GCCH')
50
43
  """
51
44
  # Security Token Service info
52
- self._sts_profile = STSProfile(resolve_base_url(url), environment)
45
+ self._sts_profile = STSProfile(url, environment)
53
46
  # Obtain authentication cookies, using the browser mode
54
47
  self._browser_mode = browser_mode
55
- self._environment = environment
56
48
  # Last occurred error
57
49
  self.error = ""
58
50
  self._username = username
@@ -137,7 +129,7 @@ class SamlTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
137
129
  "password": string_escape(self._password),
138
130
  "created": datetime_escape(self._sts_profile.created),
139
131
  "expires": datetime_escape(self._sts_profile.expires),
140
- "issuer": self._sts_profile.tokenIssuer,
132
+ "issuer": self._sts_profile.token_issuer,
141
133
  },
142
134
  )
143
135
 
@@ -184,13 +176,13 @@ class SamlTokenProvider(AuthenticationProvider, office365.logger.LoggerContext):
184
176
  payload = self._prepare_request_from_template(
185
177
  "SAML.xml",
186
178
  {
187
- "auth_url": self._sts_profile.authorityUrl,
179
+ "auth_url": self._sts_profile.site_url,
188
180
  "username": string_escape(self._username),
189
181
  "password": string_escape(self._password),
190
182
  "message_id": str(uuid.uuid4()),
191
183
  "created": datetime_escape(self._sts_profile.created),
192
184
  "expires": datetime_escape(self._sts_profile.expires),
193
- "issuer": self._sts_profile.tokenIssuer,
185
+ "issuer": self._sts_profile.token_issuer,
194
186
  },
195
187
  )
196
188
  logger.debug_secrets("options: %s", payload)
@@ -1,40 +1,55 @@
1
1
  from datetime import datetime, timedelta
2
2
 
3
+ from office365.azure_env import AzureEnvironment
3
4
  from office365.runtime.compat import timezone, urlparse
4
5
 
5
6
 
6
7
  class STSProfile(object):
7
- def __init__(self, authority_url, environment):
8
+ def __init__(self, site_url, environment=None):
8
9
  # type: (str, str) -> None
9
- self.authorityUrl = authority_url
10
- if environment == "GCCH":
11
- self.serviceUrl = "https://login.microsoftonline.us"
12
- else:
13
- self.serviceUrl = "https://login.microsoftonline.com"
14
- self.securityTokenServicePath = "extSTS.srf"
15
- self.userRealmServicePath = "GetUserRealm.srf"
16
- self.tokenIssuer = "urn:federation:MicrosoftOnline"
17
- self.created = datetime.now(tz=timezone.utc)
18
- self.expires = self.created + timedelta(minutes=30)
19
- self.signInPage = "_forms/default.aspx?wa=wsignin1.0"
10
+ self._site_url = site_url
11
+ self._environment = environment
12
+ self._created = datetime.now(tz=timezone.utc)
13
+ self._expires = self._created + timedelta(minutes=30)
20
14
 
21
15
  def reset(self):
22
16
  """Renew the expiration time."""
23
- self.created = datetime.now(tz=timezone.utc)
24
- self.expires = self.created + timedelta(minutes=30)
17
+ self._created = datetime.now(tz=timezone.utc)
18
+ self._expires = self._created + timedelta(minutes=30)
25
19
 
26
20
  @property
27
21
  def tenant(self):
28
- return urlparse(self.authorityUrl).netloc
22
+ return urlparse(self._site_url).netloc
29
23
 
30
24
  @property
31
25
  def security_token_service_url(self):
32
- return "/".join([self.serviceUrl, self.securityTokenServicePath])
26
+ return "{0}/extSTS.srf".format(
27
+ AzureEnvironment.get_login_authority(self._environment),
28
+ )
33
29
 
34
30
  @property
35
31
  def signin_page_url(self):
36
- return "/".join([self.authorityUrl, self.signInPage])
32
+ site_info = urlparse(self._site_url)
33
+ return "{0}://{1}/_forms/default.aspx?wa=wsignin1.0".format(site_info.scheme, site_info.netloc)
37
34
 
38
35
  @property
39
36
  def user_realm_service_url(self):
40
- return "/".join([self.serviceUrl, self.userRealmServicePath])
37
+ return "{0}/GetUserRealm.srf".format(
38
+ AzureEnvironment.get_login_authority(self._environment),
39
+ )
40
+
41
+ @property
42
+ def token_issuer(self):
43
+ return "urn:federation:MicrosoftOnline"
44
+
45
+ @property
46
+ def created(self):
47
+ return self._created
48
+
49
+ @property
50
+ def expires(self):
51
+ return self._expires
52
+
53
+ @property
54
+ def site_url(self):
55
+ return self._site_url
@@ -3,6 +3,7 @@ from typing import Callable, List, Optional
3
3
  from requests import Response
4
4
  from typing_extensions import Self
5
5
 
6
+ from office365.azure_env import AzureEnvironment
6
7
  from office365.runtime.auth.authentication_context import AuthenticationContext
7
8
  from office365.runtime.auth.client_credential import ClientCredential
8
9
  from office365.runtime.auth.token_response import TokenResponse
@@ -14,12 +15,11 @@ from office365.runtime.odata.v3.json_light_format import JsonLightFormat
14
15
 
15
16
  class SharePointRequest(ODataRequest):
16
17
  def __init__(
17
- self, base_url, environment="commercial", allow_ntlm=False, browser_mode=False
18
+ self, base_url, environment=AzureEnvironment.Global, allow_ntlm=False, browser_mode=False
18
19
  ):
19
20
  """
20
21
  :param str base_url: Absolute Web or Site Url
21
22
  :param str environment: The Office 365 Cloud Environment endpoint used for authentication
22
- defaults to 'commercial'.
23
23
  :param bool allow_ntlm: Flag indicates whether NTLM scheme is enabled. Disabled by default
24
24
  :param bool browser_mode: Allow browser authentication
25
25
  """