py2docfx 0.1.21.dev2253172__py3-none-any.whl → 0.1.22__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 (49) hide show
  1. py2docfx/docfx_yaml/process_doctree.py +3 -23
  2. py2docfx/docfx_yaml/translator.py +6 -35
  3. py2docfx/docfx_yaml/type_mapping.py +102 -0
  4. py2docfx/venv/basevenv/Lib/site-packages/certifi/__init__.py +1 -1
  5. py2docfx/venv/basevenv/Lib/site-packages/markupsafe/__init__.py +3 -2
  6. py2docfx/venv/basevenv/Lib/site-packages/yaml/__init__.py +1 -1
  7. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/default.py +8 -9
  8. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/imds.py +7 -3
  9. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/managed_identity.py +7 -1
  10. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/shared_cache.py +2 -2
  11. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/interactive.py +2 -2
  12. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/msal_managed_identity_client.py +1 -1
  13. py2docfx/venv/venv1/Lib/site-packages/azure/identity/_version.py +1 -1
  14. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/default.py +8 -9
  15. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/imds.py +7 -3
  16. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/managed_identity.py +7 -1
  17. py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/shared_cache.py +2 -2
  18. py2docfx/venv/venv1/Lib/site-packages/cachetools/__init__.py +96 -122
  19. py2docfx/venv/venv1/Lib/site-packages/cachetools/{_decorators.py → _cached.py} +106 -13
  20. py2docfx/venv/venv1/Lib/site-packages/cachetools/_cachedmethod.py +128 -0
  21. py2docfx/venv/venv1/Lib/site-packages/cachetools/func.py +5 -25
  22. py2docfx/venv/venv1/Lib/site-packages/certifi/__init__.py +1 -1
  23. py2docfx/venv/venv1/Lib/site-packages/cryptography/__about__.py +1 -1
  24. py2docfx/venv/venv1/Lib/site-packages/google/api_core/client_options.py +9 -2
  25. py2docfx/venv/venv1/Lib/site-packages/google/api_core/general_helpers.py +36 -0
  26. py2docfx/venv/venv1/Lib/site-packages/google/api_core/grpc_helpers.py +10 -7
  27. py2docfx/venv/venv1/Lib/site-packages/google/api_core/grpc_helpers_async.py +8 -3
  28. py2docfx/venv/venv1/Lib/site-packages/google/api_core/operations_v1/transports/base.py +13 -7
  29. py2docfx/venv/venv1/Lib/site-packages/google/api_core/operations_v1/transports/rest.py +19 -12
  30. py2docfx/venv/venv1/Lib/site-packages/google/api_core/operations_v1/transports/rest_asyncio.py +21 -0
  31. py2docfx/venv/venv1/Lib/site-packages/google/api_core/version.py +1 -1
  32. py2docfx/venv/venv1/Lib/site-packages/google/auth/_default.py +66 -12
  33. py2docfx/venv/venv1/Lib/site-packages/google/auth/_default_async.py +16 -10
  34. py2docfx/venv/venv1/Lib/site-packages/google/auth/_helpers.py +41 -0
  35. py2docfx/venv/venv1/Lib/site-packages/google/auth/compute_engine/credentials.py +67 -6
  36. py2docfx/venv/venv1/Lib/site-packages/google/auth/credentials.py +161 -18
  37. py2docfx/venv/venv1/Lib/site-packages/google/auth/environment_vars.py +4 -0
  38. py2docfx/venv/venv1/Lib/site-packages/google/auth/external_account.py +33 -10
  39. py2docfx/venv/venv1/Lib/site-packages/google/auth/external_account_authorized_user.py +24 -1
  40. py2docfx/venv/venv1/Lib/site-packages/google/auth/identity_pool.py +25 -1
  41. py2docfx/venv/venv1/Lib/site-packages/google/auth/impersonated_credentials.py +57 -9
  42. py2docfx/venv/venv1/Lib/site-packages/google/auth/pluggable.py +25 -1
  43. py2docfx/venv/venv1/Lib/site-packages/google/auth/version.py +1 -1
  44. py2docfx/venv/venv1/Lib/site-packages/google/oauth2/_client.py +117 -0
  45. py2docfx/venv/venv1/Lib/site-packages/google/oauth2/service_account.py +39 -4
  46. {py2docfx-0.1.21.dev2253172.dist-info → py2docfx-0.1.22.dist-info}/METADATA +1 -1
  47. {py2docfx-0.1.21.dev2253172.dist-info → py2docfx-0.1.22.dist-info}/RECORD +49 -47
  48. {py2docfx-0.1.21.dev2253172.dist-info → py2docfx-0.1.22.dist-info}/WHEEL +0 -0
  49. {py2docfx-0.1.21.dev2253172.dist-info → py2docfx-0.1.22.dist-info}/top_level.txt +0 -0
@@ -46,6 +46,9 @@ _REFRESH_ERROR = "Unable to acquire impersonated credentials"
46
46
  _DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
47
47
 
48
48
  _GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token"
49
+ _TRUST_BOUNDARY_LOOKUP_ENDPOINT = (
50
+ "https://iamcredentials.{}/v1/projects/-/serviceAccounts/{}/allowedLocations"
51
+ )
49
52
 
50
53
  _SOURCE_CREDENTIAL_AUTHORIZED_USER_TYPE = "authorized_user"
51
54
  _SOURCE_CREDENTIAL_SERVICE_ACCOUNT_TYPE = "service_account"
@@ -117,7 +120,10 @@ def _make_iam_token_request(
117
120
 
118
121
 
119
122
  class Credentials(
120
- credentials.Scoped, credentials.CredentialsWithQuotaProject, credentials.Signing
123
+ credentials.Scoped,
124
+ credentials.CredentialsWithQuotaProject,
125
+ credentials.Signing,
126
+ credentials.CredentialsWithTrustBoundary,
121
127
  ):
122
128
  """This module defines impersonated credentials which are essentially
123
129
  impersonated identities.
@@ -178,6 +184,14 @@ class Credentials(
178
184
  buckets = client.list_buckets(project='your_project')
179
185
  for bucket in buckets:
180
186
  print(bucket.name)
187
+
188
+ **IMPORTANT**:
189
+ This class does not validate the credential configuration. A security
190
+ risk occurs when a credential configuration configured with malicious urls
191
+ is used.
192
+ When the credential configuration is accepted from an
193
+ untrusted source, you should validate it before using.
194
+ Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.
181
195
  """
182
196
 
183
197
  def __init__(
@@ -190,6 +204,7 @@ class Credentials(
190
204
  lifetime=_DEFAULT_TOKEN_LIFETIME_SECS,
191
205
  quota_project_id=None,
192
206
  iam_endpoint_override=None,
207
+ trust_boundary=None,
193
208
  ):
194
209
  """
195
210
  Args:
@@ -220,6 +235,7 @@ class Credentials(
220
235
  subject (Optional[str]): sub field of a JWT. This field should only be set
221
236
  if you wish to impersonate as a user. This feature is useful when
222
237
  using domain wide delegation.
238
+ trust_boundary (Mapping[str,str]): A credential trust boundary.
223
239
  """
224
240
 
225
241
  super(Credentials, self).__init__()
@@ -251,15 +267,12 @@ class Credentials(
251
267
  self._quota_project_id = quota_project_id
252
268
  self._iam_endpoint_override = iam_endpoint_override
253
269
  self._cred_file_path = None
270
+ self._trust_boundary = trust_boundary
254
271
 
255
272
  def _metric_header_for_usage(self):
256
273
  return metrics.CRED_TYPE_SA_IMPERSONATE
257
274
 
258
- @_helpers.copy_docstring(credentials.Credentials)
259
- def refresh(self, request):
260
- self._update_token(request)
261
-
262
- def _update_token(self, request):
275
+ def _refresh_token(self, request):
263
276
  """Updates credentials with a new access_token representing
264
277
  the impersonated account.
265
278
 
@@ -331,6 +344,28 @@ class Credentials(
331
344
  iam_endpoint_override=self._iam_endpoint_override,
332
345
  )
333
346
 
347
+ def _build_trust_boundary_lookup_url(self):
348
+ """Builds and returns the URL for the trust boundary lookup API.
349
+
350
+ This method constructs the specific URL for the IAM Credentials API's
351
+ `allowedLocations` endpoint, using the credential's universe domain
352
+ and service account email.
353
+
354
+ Raises:
355
+ ValueError: If `self.service_account_email` is None or an empty
356
+ string, as it's required to form the URL.
357
+
358
+ Returns:
359
+ str: The URL for the trust boundary lookup endpoint.
360
+ """
361
+ if not self.service_account_email:
362
+ raise ValueError(
363
+ "Service account email is required to build the trust boundary lookup URL."
364
+ )
365
+ return _TRUST_BOUNDARY_LOOKUP_ENDPOINT.format(
366
+ self.universe_domain, self.service_account_email
367
+ )
368
+
334
369
  def sign_bytes(self, message):
335
370
  from google.auth.transport.requests import AuthorizedSession
336
371
 
@@ -400,10 +435,17 @@ class Credentials(
400
435
  lifetime=self._lifetime,
401
436
  quota_project_id=self._quota_project_id,
402
437
  iam_endpoint_override=self._iam_endpoint_override,
438
+ trust_boundary=self._trust_boundary,
403
439
  )
404
440
  cred._cred_file_path = self._cred_file_path
405
441
  return cred
406
442
 
443
+ @_helpers.copy_docstring(credentials.CredentialsWithTrustBoundary)
444
+ def with_trust_boundary(self, trust_boundary):
445
+ cred = self._make_copy()
446
+ cred._trust_boundary = trust_boundary
447
+ return cred
448
+
407
449
  @_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
408
450
  def with_quota_project(self, quota_project_id):
409
451
  cred = self._make_copy()
@@ -420,6 +462,14 @@ class Credentials(
420
462
  def from_impersonated_service_account_info(cls, info, scopes=None):
421
463
  """Creates a Credentials instance from parsed impersonated service account credentials info.
422
464
 
465
+ **IMPORTANT**:
466
+ This method does not validate the credential configuration. A security
467
+ risk occurs when a credential configuration configured with malicious urls
468
+ is used.
469
+ When the credential configuration is accepted from an
470
+ untrusted source, you should validate it before using with this method.
471
+ Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.
472
+
423
473
  Args:
424
474
  info (Mapping[str, str]): The impersonated service account credentials info in Google
425
475
  format.
@@ -487,9 +537,7 @@ class Credentials(
487
537
 
488
538
 
489
539
  class IDTokenCredentials(credentials.CredentialsWithQuotaProject):
490
- """Open ID Connect ID Token-based service account credentials.
491
-
492
- """
540
+ """Open ID Connect ID Token-based service account credentials."""
493
541
 
494
542
  def __init__(
495
543
  self,
@@ -57,7 +57,15 @@ EXECUTABLE_INTERACTIVE_TIMEOUT_MILLIS_UPPER_BOUND = 30 * 60 * 1000 # 30 minutes
57
57
 
58
58
 
59
59
  class Credentials(external_account.Credentials):
60
- """External account credentials sourced from executables."""
60
+ """External account credentials sourced from executables.
61
+
62
+ **IMPORTANT**:
63
+ This class does not validate the credential configuration. A security
64
+ risk occurs when a credential configuration configured with malicious urls
65
+ is used.
66
+ When the credential configuration is accepted from an
67
+ untrusted source, you should validate it before using.
68
+ Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details."""
61
69
 
62
70
  def __init__(
63
71
  self,
@@ -300,6 +308,14 @@ class Credentials(external_account.Credentials):
300
308
  def from_info(cls, info, **kwargs):
301
309
  """Creates a Pluggable Credentials instance from parsed external account info.
302
310
 
311
+ **IMPORTANT**:
312
+ This method does not validate the credential configuration. A security
313
+ risk occurs when a credential configuration configured with malicious urls
314
+ is used.
315
+ When the credential configuration is accepted from an
316
+ untrusted source, you should validate it before using with this method.
317
+ Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.
318
+
303
319
  Args:
304
320
  info (Mapping[str, str]): The Pluggable external account info in Google
305
321
  format.
@@ -319,6 +335,14 @@ class Credentials(external_account.Credentials):
319
335
  def from_file(cls, filename, **kwargs):
320
336
  """Creates an Pluggable Credentials instance from an external account json file.
321
337
 
338
+ **IMPORTANT**:
339
+ This method does not validate the credential configuration. A security
340
+ risk occurs when a credential configuration configured with malicious urls
341
+ is used.
342
+ When the credential configuration is accepted from an
343
+ untrusted source, you should validate it before using with this method.
344
+ Refer https://cloud.google.com/docs/authentication/external/externally-sourced-credentials for more details.
345
+
322
346
  Args:
323
347
  filename (str): The path to the Pluggable external account json file.
324
348
  kwargs: Additional arguments to pass to the constructor.
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __version__ = "2.40.3"
15
+ __version__ = "2.41.1"
@@ -337,6 +337,8 @@ def call_iam_generate_id_token_endpoint(
337
337
  generateIdToken endpoint.
338
338
  audience (str): The audience for the ID token.
339
339
  access_token (str): The access token used to call the IAM endpoint.
340
+ universe_domain (str): The universe domain for the request. The
341
+ default is ``googleapis.com``.
340
342
 
341
343
  Returns:
342
344
  Tuple[str, datetime]: The ID token and expiration.
@@ -506,3 +508,118 @@ def refresh_grant(
506
508
  request, token_uri, body, can_retry=can_retry
507
509
  )
508
510
  return _handle_refresh_grant_response(response_data, refresh_token)
511
+
512
+
513
+ def _lookup_trust_boundary(request, url, headers=None):
514
+ """Implements the global lookup of a credential trust boundary.
515
+ For the lookup, we send a request to the global lookup endpoint and then
516
+ parse the response. Service account credentials, workload identity
517
+ pools and workforce pools implementation may have trust boundaries configured.
518
+ Args:
519
+ request (google.auth.transport.Request): A callable used to make
520
+ HTTP requests.
521
+ url (str): The trust boundary lookup url.
522
+ headers (Optional[Mapping[str, str]]): The headers for the request.
523
+ Returns:
524
+ Mapping[str,list|str]: A dictionary containing
525
+ "locations" as a list of allowed locations as strings and
526
+ "encodedLocations" as a hex string.
527
+ e.g:
528
+ {
529
+ "locations": [
530
+ "us-central1", "us-east1", "europe-west1", "asia-east1"
531
+ ],
532
+ "encodedLocations": "0xA30"
533
+ }
534
+ If the credential is not set up with explicit trust boundaries, a trust boundary
535
+ of "all" will be returned as a default response.
536
+ {
537
+ "locations": [],
538
+ "encodedLocations": "0x0"
539
+ }
540
+ Raises:
541
+ exceptions.RefreshError: If the response status code is not 200.
542
+ exceptions.MalformedError: If the response is not in a valid format.
543
+ """
544
+
545
+ response_data = _lookup_trust_boundary_request(request, url, headers=headers)
546
+ # In case of no-op response, the "locations" list may or may not be present as an empty list.
547
+ if "encodedLocations" not in response_data:
548
+ raise exceptions.MalformedError(
549
+ "Invalid trust boundary info: {}".format(response_data)
550
+ )
551
+ return response_data
552
+
553
+
554
+ def _lookup_trust_boundary_request(request, url, can_retry=True, headers=None):
555
+ """Makes a request to the trust boundary lookup endpoint.
556
+
557
+ Args:
558
+ request (google.auth.transport.Request): A callable used to make
559
+ HTTP requests.
560
+ url (str): The trust boundary lookup url.
561
+ can_retry (bool): Enable or disable request retry behavior. Defaults to true.
562
+ headers (Optional[Mapping[str, str]]): The headers for the request.
563
+
564
+ Returns:
565
+ Mapping[str, str]: The JSON-decoded response data.
566
+
567
+ Raises:
568
+ google.auth.exceptions.RefreshError: If the token endpoint returned
569
+ an error.
570
+ """
571
+ response_status_ok, response_data, retryable_error = _lookup_trust_boundary_request_no_throw(
572
+ request, url, can_retry, headers
573
+ )
574
+ if not response_status_ok:
575
+ _handle_error_response(response_data, retryable_error)
576
+ return response_data
577
+
578
+
579
+ def _lookup_trust_boundary_request_no_throw(request, url, can_retry=True, headers=None):
580
+ """Makes a request to the trust boundary lookup endpoint. This
581
+ function doesn't throw on response errors.
582
+
583
+ Args:
584
+ request (google.auth.transport.Request): A callable used to make
585
+ HTTP requests.
586
+ url (str): The trust boundary lookup url.
587
+ can_retry (bool): Enable or disable request retry behavior. Defaults to true.
588
+ headers (Optional[Mapping[str, str]]): The headers for the request.
589
+
590
+ Returns:
591
+ Tuple(bool, Mapping[str, str], Optional[bool]): A boolean indicating
592
+ if the request is successful, a mapping for the JSON-decoded response
593
+ data and in the case of an error a boolean indicating if the error
594
+ is retryable.
595
+ """
596
+
597
+ response_data = {}
598
+ retryable_error = False
599
+
600
+ retries = _exponential_backoff.ExponentialBackoff()
601
+ for _ in retries:
602
+ response = request(method="GET", url=url, headers=headers)
603
+ response_body = (
604
+ response.data.decode("utf-8")
605
+ if hasattr(response.data, "decode")
606
+ else response.data
607
+ )
608
+
609
+ try:
610
+ # response_body should be a JSON
611
+ response_data = json.loads(response_body)
612
+ except ValueError:
613
+ response_data = response_body
614
+
615
+ if response.status == http_client.OK:
616
+ return True, response_data, None
617
+
618
+ retryable_error = _can_retry(
619
+ status_code=response.status, response_data=response_data
620
+ )
621
+
622
+ if not can_retry or not retryable_error:
623
+ return False, response_data, retryable_error
624
+
625
+ return False, response_data, retryable_error
@@ -84,6 +84,9 @@ from google.oauth2 import _client
84
84
 
85
85
  _DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
86
86
  _GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token"
87
+ _TRUST_BOUNDARY_LOOKUP_ENDPOINT = (
88
+ "https://iamcredentials.{}/v1/projects/-/serviceAccounts/{}/allowedLocations"
89
+ )
87
90
 
88
91
 
89
92
  class Credentials(
@@ -91,6 +94,7 @@ class Credentials(
91
94
  credentials.Scoped,
92
95
  credentials.CredentialsWithQuotaProject,
93
96
  credentials.CredentialsWithTokenUri,
97
+ credentials.CredentialsWithTrustBoundary,
94
98
  ):
95
99
  """Service account credentials
96
100
 
@@ -164,7 +168,7 @@ class Credentials(
164
168
  universe_domain (str): The universe domain. The default
165
169
  universe domain is googleapis.com. For default value self
166
170
  signed jwt is used for token refresh.
167
- trust_boundary (str): String representation of trust boundary meta.
171
+ trust_boundary (Mapping[str,str]): A credential trust boundary.
168
172
 
169
173
  .. note:: Typically one of the helper constructors
170
174
  :meth:`from_service_account_file` or
@@ -194,7 +198,7 @@ class Credentials(
194
198
  self._additional_claims = additional_claims
195
199
  else:
196
200
  self._additional_claims = {}
197
- self._trust_boundary = {"locations": [], "encoded_locations": "0x0"}
201
+ self._trust_boundary = trust_boundary
198
202
 
199
203
  @classmethod
200
204
  def _from_signer_and_info(cls, signer, info, **kwargs):
@@ -294,6 +298,7 @@ class Credentials(
294
298
  additional_claims=self._additional_claims.copy(),
295
299
  always_use_jwt_access=self._always_use_jwt_access,
296
300
  universe_domain=self._universe_domain,
301
+ trust_boundary=self._trust_boundary,
297
302
  )
298
303
  cred._cred_file_path = self._cred_file_path
299
304
  return cred
@@ -381,6 +386,12 @@ class Credentials(
381
386
  cred._token_uri = token_uri
382
387
  return cred
383
388
 
389
+ @_helpers.copy_docstring(credentials.CredentialsWithTrustBoundary)
390
+ def with_trust_boundary(self, trust_boundary):
391
+ cred = self._make_copy()
392
+ cred._trust_boundary = trust_boundary
393
+ return cred
394
+
384
395
  def _make_authorization_grant_assertion(self):
385
396
  """Create the OAuth 2.0 assertion.
386
397
 
@@ -424,8 +435,8 @@ class Credentials(
424
435
  return metrics.CRED_TYPE_SA_JWT
425
436
  return metrics.CRED_TYPE_SA_ASSERTION
426
437
 
427
- @_helpers.copy_docstring(credentials.Credentials)
428
- def refresh(self, request):
438
+ @_helpers.copy_docstring(credentials.CredentialsWithTrustBoundary)
439
+ def _refresh_token(self, request):
429
440
  if self._always_use_jwt_access and not self._jwt_credentials:
430
441
  # If self signed jwt should be used but jwt credential is not
431
442
  # created, try to create one with scopes
@@ -491,6 +502,28 @@ class Credentials(
491
502
  self, audience
492
503
  )
493
504
 
505
+ def _build_trust_boundary_lookup_url(self):
506
+ """Builds and returns the URL for the trust boundary lookup API.
507
+
508
+ This method constructs the specific URL for the IAM Credentials API's
509
+ `allowedLocations` endpoint, using the credential's universe domain
510
+ and service account email.
511
+
512
+ Raises:
513
+ ValueError: If `self.service_account_email` is None or an empty
514
+ string, as it's required to form the URL.
515
+
516
+ Returns:
517
+ str: The URL for the trust boundary lookup endpoint.
518
+ """
519
+ if not self.service_account_email:
520
+ raise ValueError(
521
+ "Service account email is required to build the trust boundary lookup URL."
522
+ )
523
+ return _TRUST_BOUNDARY_LOOKUP_ENDPOINT.format(
524
+ self._universe_domain, self._service_account_email
525
+ )
526
+
494
527
  @_helpers.copy_docstring(credentials.Signing)
495
528
  def sign_bytes(self, message):
496
529
  return self._signer.sign(message)
@@ -591,6 +624,7 @@ class IDTokenCredentials(
591
624
  token endponint is used for token refresh. Note that
592
625
  iam.serviceAccountTokenCreator role is required to use the IAM
593
626
  endpoint.
627
+
594
628
  .. note:: Typically one of the helper constructors
595
629
  :meth:`from_service_account_file` or
596
630
  :meth:`from_service_account_info` are used instead of calling the
@@ -806,6 +840,7 @@ class IDTokenCredentials(
806
840
  additional_claims={"scope": "https://www.googleapis.com/auth/iam"},
807
841
  )
808
842
  jwt_credentials.refresh(request)
843
+
809
844
  self.token, self.expiry = _client.call_iam_generate_id_token_endpoint(
810
845
  request,
811
846
  self._iam_id_token_endpoint,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: py2docfx
3
- Version: 0.1.21.dev2253172
3
+ Version: 0.1.22
4
4
  Summary: A package built based on Sphinx which download source code package and generate yaml files supported by docfx.
5
5
  Author: Microsoft Corporation
6
6
  License: MIT License