prasb commited on
Commit
c406bae
·
verified ·
1 Parent(s): c2b1c6d

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/__init__.cpython-38.pyc +0 -0
  3. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/exceptions.cpython-38.pyc +0 -0
  4. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/lazy_wheel.cpython-38.pyc +0 -0
  5. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/package_streaming.cpython-38.pyc +0 -0
  6. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/url.cpython-38.pyc +0 -0
  7. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/einops/__pycache__/einops.cpython-38.pyc +0 -0
  8. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/einops/__pycache__/parsing.cpython-38.pyc +0 -0
  9. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/__pycache__/pluggable.cpython-38.pyc +0 -0
  10. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/_cloud_sdk.py +159 -0
  11. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/_credentials_async.py +176 -0
  12. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/_helpers.py +245 -0
  13. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/_service_account_info.py +81 -0
  14. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/app_engine.py +179 -0
  15. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/jwt.py +857 -0
  16. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/version.py +15 -0
  17. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/__init__.cpython-38.pyc +0 -0
  18. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_client.cpython-38.pyc +0 -0
  19. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_client_async.cpython-38.pyc +0 -0
  20. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_credentials_async.cpython-38.pyc +0 -0
  21. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_id_token_async.cpython-38.pyc +0 -0
  22. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_reauth_async.cpython-38.pyc +0 -0
  23. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_service_account_async.cpython-38.pyc +0 -0
  24. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/challenges.cpython-38.pyc +0 -0
  25. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/credentials.cpython-38.pyc +0 -0
  26. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/gdch_credentials.cpython-38.pyc +0 -0
  27. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/id_token.cpython-38.pyc +0 -0
  28. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/reauth.cpython-38.pyc +0 -0
  29. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/service_account.cpython-38.pyc +0 -0
  30. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/sts.cpython-38.pyc +0 -0
  31. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/utils.cpython-38.pyc +0 -0
  32. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/_id_token_async.py +287 -0
  33. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/_reauth_async.py +329 -0
  34. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/credentials.py +490 -0
  35. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/gdch_credentials.py +251 -0
  36. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/id_token.py +341 -0
  37. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/descriptor.cpython-38.pyc +0 -0
  38. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/descriptor_pb2.cpython-38.pyc +0 -0
  39. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/field_mask_pb2.cpython-38.pyc +0 -0
  40. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/message.cpython-38.pyc +0 -0
  41. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/service_reflection.cpython-38.pyc +0 -0
  42. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/source_context_pb2.cpython-38.pyc +0 -0
  43. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/timestamp_pb2.cpython-38.pyc +0 -0
  44. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/type_pb2.cpython-38.pyc +0 -0
  45. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/compiler/__init__.py +0 -0
  46. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/compiler/plugin_pb2.py +35 -0
  47. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/internal/_api_implementation.cpython-38-x86_64-linux-gnu.so +0 -0
  48. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/internal/builder.py +130 -0
  49. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/internal/containers.py +710 -0
  50. my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/internal/type_checkers.py +435 -0
.gitattributes CHANGED
@@ -381,3 +381,4 @@ my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/matplotlib/
381
  my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf filter=lfs diff=lfs merge=lfs -text
382
  my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/matplotlib/__pycache__/widgets.cpython-38.pyc filter=lfs diff=lfs merge=lfs -text
383
  my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf filter=lfs diff=lfs merge=lfs -text
 
 
381
  my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf filter=lfs diff=lfs merge=lfs -text
382
  my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/matplotlib/__pycache__/widgets.cpython-38.pyc filter=lfs diff=lfs merge=lfs -text
383
  my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf filter=lfs diff=lfs merge=lfs -text
384
+ my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf filter=lfs diff=lfs merge=lfs -text
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/__init__.cpython-38.pyc ADDED
Binary file (175 Bytes). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/exceptions.cpython-38.pyc ADDED
Binary file (1.27 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/lazy_wheel.cpython-38.pyc ADDED
Binary file (8.84 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/package_streaming.cpython-38.pyc ADDED
Binary file (5.15 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/conda_package_streaming/__pycache__/url.cpython-38.pyc ADDED
Binary file (2.45 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/einops/__pycache__/einops.cpython-38.pyc ADDED
Binary file (20.9 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/einops/__pycache__/parsing.cpython-38.pyc ADDED
Binary file (4.92 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/__pycache__/pluggable.cpython-38.pyc ADDED
Binary file (9.19 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/_cloud_sdk.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2015 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Helpers for reading the Google Cloud SDK's configuration."""
16
+
17
+ import json
18
+ import os
19
+ import subprocess
20
+
21
+ import six
22
+
23
+ from google.auth import environment_vars
24
+ from google.auth import exceptions
25
+
26
+
27
+ # The ~/.config subdirectory containing gcloud credentials.
28
+ _CONFIG_DIRECTORY = "gcloud"
29
+ # Windows systems store config at %APPDATA%\gcloud
30
+ _WINDOWS_CONFIG_ROOT_ENV_VAR = "APPDATA"
31
+ # The name of the file in the Cloud SDK config that contains default
32
+ # credentials.
33
+ _CREDENTIALS_FILENAME = "application_default_credentials.json"
34
+ # The name of the Cloud SDK shell script
35
+ _CLOUD_SDK_POSIX_COMMAND = "gcloud"
36
+ _CLOUD_SDK_WINDOWS_COMMAND = "gcloud.cmd"
37
+ # The command to get the Cloud SDK configuration
38
+ _CLOUD_SDK_CONFIG_COMMAND = ("config", "config-helper", "--format", "json")
39
+ # The command to get google user access token
40
+ _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND = ("auth", "print-access-token")
41
+ # Cloud SDK's application-default client ID
42
+ CLOUD_SDK_CLIENT_ID = (
43
+ "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com"
44
+ )
45
+
46
+
47
+ def get_config_path():
48
+ """Returns the absolute path the the Cloud SDK's configuration directory.
49
+
50
+ Returns:
51
+ str: The Cloud SDK config path.
52
+ """
53
+ # If the path is explicitly set, return that.
54
+ try:
55
+ return os.environ[environment_vars.CLOUD_SDK_CONFIG_DIR]
56
+ except KeyError:
57
+ pass
58
+
59
+ # Non-windows systems store this at ~/.config/gcloud
60
+ if os.name != "nt":
61
+ return os.path.join(os.path.expanduser("~"), ".config", _CONFIG_DIRECTORY)
62
+ # Windows systems store config at %APPDATA%\gcloud
63
+ else:
64
+ try:
65
+ return os.path.join(
66
+ os.environ[_WINDOWS_CONFIG_ROOT_ENV_VAR], _CONFIG_DIRECTORY
67
+ )
68
+ except KeyError:
69
+ # This should never happen unless someone is really
70
+ # messing with things, but we'll cover the case anyway.
71
+ drive = os.environ.get("SystemDrive", "C:")
72
+ return os.path.join(drive, "\\", _CONFIG_DIRECTORY)
73
+
74
+
75
+ def get_application_default_credentials_path():
76
+ """Gets the path to the application default credentials file.
77
+
78
+ The path may or may not exist.
79
+
80
+ Returns:
81
+ str: The full path to application default credentials.
82
+ """
83
+ config_path = get_config_path()
84
+ return os.path.join(config_path, _CREDENTIALS_FILENAME)
85
+
86
+
87
+ def _run_subprocess_ignore_stderr(command):
88
+ """ Return subprocess.check_output with the given command and ignores stderr."""
89
+ with open(os.devnull, "w") as devnull:
90
+ output = subprocess.check_output(command, stderr=devnull)
91
+ return output
92
+
93
+
94
+ def get_project_id():
95
+ """Gets the project ID from the Cloud SDK.
96
+
97
+ Returns:
98
+ Optional[str]: The project ID.
99
+ """
100
+ if os.name == "nt":
101
+ command = _CLOUD_SDK_WINDOWS_COMMAND
102
+ else:
103
+ command = _CLOUD_SDK_POSIX_COMMAND
104
+
105
+ try:
106
+ # Ignore the stderr coming from gcloud, so it won't be mixed into the output.
107
+ # https://github.com/googleapis/google-auth-library-python/issues/673
108
+ output = _run_subprocess_ignore_stderr((command,) + _CLOUD_SDK_CONFIG_COMMAND)
109
+ except (subprocess.CalledProcessError, OSError, IOError):
110
+ return None
111
+
112
+ try:
113
+ configuration = json.loads(output.decode("utf-8"))
114
+ except ValueError:
115
+ return None
116
+
117
+ try:
118
+ return configuration["configuration"]["properties"]["core"]["project"]
119
+ except KeyError:
120
+ return None
121
+
122
+
123
+ def get_auth_access_token(account=None):
124
+ """Load user access token with the ``gcloud auth print-access-token`` command.
125
+
126
+ Args:
127
+ account (Optional[str]): Account to get the access token for. If not
128
+ specified, the current active account will be used.
129
+
130
+ Returns:
131
+ str: The user access token.
132
+
133
+ Raises:
134
+ google.auth.exceptions.UserAccessTokenError: if failed to get access
135
+ token from gcloud.
136
+ """
137
+ if os.name == "nt":
138
+ command = _CLOUD_SDK_WINDOWS_COMMAND
139
+ else:
140
+ command = _CLOUD_SDK_POSIX_COMMAND
141
+
142
+ try:
143
+ if account:
144
+ command = (
145
+ (command,)
146
+ + _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND
147
+ + ("--account=" + account,)
148
+ )
149
+ else:
150
+ command = (command,) + _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND
151
+
152
+ access_token = subprocess.check_output(command, stderr=subprocess.STDOUT)
153
+ # remove the trailing "\n"
154
+ return access_token.decode("utf-8").strip()
155
+ except (subprocess.CalledProcessError, OSError, IOError) as caught_exc:
156
+ new_exc = exceptions.UserAccessTokenError(
157
+ "Failed to obtain access token", caught_exc
158
+ )
159
+ six.raise_from(new_exc, caught_exc)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/_credentials_async.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ """Interfaces for credentials."""
17
+
18
+ import abc
19
+ import inspect
20
+
21
+ import six
22
+
23
+ from google.auth import credentials
24
+
25
+
26
+ @six.add_metaclass(abc.ABCMeta)
27
+ class Credentials(credentials.Credentials):
28
+ """Async inherited credentials class from google.auth.credentials.
29
+ The added functionality is the before_request call which requires
30
+ async/await syntax.
31
+ All credentials have a :attr:`token` that is used for authentication and
32
+ may also optionally set an :attr:`expiry` to indicate when the token will
33
+ no longer be valid.
34
+
35
+ Most credentials will be :attr:`invalid` until :meth:`refresh` is called.
36
+ Credentials can do this automatically before the first HTTP request in
37
+ :meth:`before_request`.
38
+
39
+ Although the token and expiration will change as the credentials are
40
+ :meth:`refreshed <refresh>` and used, credentials should be considered
41
+ immutable. Various credentials will accept configuration such as private
42
+ keys, scopes, and other options. These options are not changeable after
43
+ construction. Some classes will provide mechanisms to copy the credentials
44
+ with modifications such as :meth:`ScopedCredentials.with_scopes`.
45
+ """
46
+
47
+ async def before_request(self, request, method, url, headers):
48
+ """Performs credential-specific before request logic.
49
+
50
+ Refreshes the credentials if necessary, then calls :meth:`apply` to
51
+ apply the token to the authentication header.
52
+
53
+ Args:
54
+ request (google.auth.transport.Request): The object used to make
55
+ HTTP requests.
56
+ method (str): The request's HTTP method or the RPC method being
57
+ invoked.
58
+ url (str): The request's URI or the RPC service's URI.
59
+ headers (Mapping): The request's headers.
60
+ """
61
+ # pylint: disable=unused-argument
62
+ # (Subclasses may use these arguments to ascertain information about
63
+ # the http request.)
64
+
65
+ if not self.valid:
66
+ if inspect.iscoroutinefunction(self.refresh):
67
+ await self.refresh(request)
68
+ else:
69
+ self.refresh(request)
70
+ self.apply(headers)
71
+
72
+
73
+ class CredentialsWithQuotaProject(credentials.CredentialsWithQuotaProject):
74
+ """Abstract base for credentials supporting ``with_quota_project`` factory"""
75
+
76
+
77
+ class AnonymousCredentials(credentials.AnonymousCredentials, Credentials):
78
+ """Credentials that do not provide any authentication information.
79
+
80
+ These are useful in the case of services that support anonymous access or
81
+ local service emulators that do not use credentials. This class inherits
82
+ from the sync anonymous credentials file, but is kept if async credentials
83
+ is initialized and we would like anonymous credentials.
84
+ """
85
+
86
+
87
+ @six.add_metaclass(abc.ABCMeta)
88
+ class ReadOnlyScoped(credentials.ReadOnlyScoped):
89
+ """Interface for credentials whose scopes can be queried.
90
+
91
+ OAuth 2.0-based credentials allow limiting access using scopes as described
92
+ in `RFC6749 Section 3.3`_.
93
+ If a credential class implements this interface then the credentials either
94
+ use scopes in their implementation.
95
+
96
+ Some credentials require scopes in order to obtain a token. You can check
97
+ if scoping is necessary with :attr:`requires_scopes`::
98
+
99
+ if credentials.requires_scopes:
100
+ # Scoping is required.
101
+ credentials = _credentials_async.with_scopes(scopes=['one', 'two'])
102
+
103
+ Credentials that require scopes must either be constructed with scopes::
104
+
105
+ credentials = SomeScopedCredentials(scopes=['one', 'two'])
106
+
107
+ Or must copy an existing instance using :meth:`with_scopes`::
108
+
109
+ scoped_credentials = _credentials_async.with_scopes(scopes=['one', 'two'])
110
+
111
+ Some credentials have scopes but do not allow or require scopes to be set,
112
+ these credentials can be used as-is.
113
+
114
+ .. _RFC6749 Section 3.3: https://tools.ietf.org/html/rfc6749#section-3.3
115
+ """
116
+
117
+
118
+ class Scoped(credentials.Scoped):
119
+ """Interface for credentials whose scopes can be replaced while copying.
120
+
121
+ OAuth 2.0-based credentials allow limiting access using scopes as described
122
+ in `RFC6749 Section 3.3`_.
123
+ If a credential class implements this interface then the credentials either
124
+ use scopes in their implementation.
125
+
126
+ Some credentials require scopes in order to obtain a token. You can check
127
+ if scoping is necessary with :attr:`requires_scopes`::
128
+
129
+ if credentials.requires_scopes:
130
+ # Scoping is required.
131
+ credentials = _credentials_async.create_scoped(['one', 'two'])
132
+
133
+ Credentials that require scopes must either be constructed with scopes::
134
+
135
+ credentials = SomeScopedCredentials(scopes=['one', 'two'])
136
+
137
+ Or must copy an existing instance using :meth:`with_scopes`::
138
+
139
+ scoped_credentials = credentials.with_scopes(scopes=['one', 'two'])
140
+
141
+ Some credentials have scopes but do not allow or require scopes to be set,
142
+ these credentials can be used as-is.
143
+
144
+ .. _RFC6749 Section 3.3: https://tools.ietf.org/html/rfc6749#section-3.3
145
+ """
146
+
147
+
148
+ def with_scopes_if_required(credentials, scopes):
149
+ """Creates a copy of the credentials with scopes if scoping is required.
150
+
151
+ This helper function is useful when you do not know (or care to know) the
152
+ specific type of credentials you are using (such as when you use
153
+ :func:`google.auth.default`). This function will call
154
+ :meth:`Scoped.with_scopes` if the credentials are scoped credentials and if
155
+ the credentials require scoping. Otherwise, it will return the credentials
156
+ as-is.
157
+
158
+ Args:
159
+ credentials (google.auth.credentials.Credentials): The credentials to
160
+ scope if necessary.
161
+ scopes (Sequence[str]): The list of scopes to use.
162
+
163
+ Returns:
164
+ google.auth._credentials_async.Credentials: Either a new set of scoped
165
+ credentials, or the passed in credentials instance if no scoping
166
+ was required.
167
+ """
168
+ if isinstance(credentials, Scoped) and credentials.requires_scopes:
169
+ return credentials.with_scopes(scopes)
170
+ else:
171
+ return credentials
172
+
173
+
174
+ @six.add_metaclass(abc.ABCMeta)
175
+ class Signing(credentials.Signing):
176
+ """Interface for credentials that can cryptographically sign messages."""
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/_helpers.py ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2015 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Helper functions for commonly used utilities."""
16
+
17
+ import base64
18
+ import calendar
19
+ import datetime
20
+ import sys
21
+
22
+ import six
23
+ from six.moves import urllib
24
+
25
+
26
+ # Token server doesn't provide a new a token when doing refresh unless the
27
+ # token is expiring within 30 seconds, so refresh threshold should not be
28
+ # more than 30 seconds. Otherwise auth lib will send tons of refresh requests
29
+ # until 30 seconds before the expiration, and cause a spike of CPU usage.
30
+ REFRESH_THRESHOLD = datetime.timedelta(seconds=20)
31
+
32
+
33
+ def copy_docstring(source_class):
34
+ """Decorator that copies a method's docstring from another class.
35
+
36
+ Args:
37
+ source_class (type): The class that has the documented method.
38
+
39
+ Returns:
40
+ Callable: A decorator that will copy the docstring of the same
41
+ named method in the source class to the decorated method.
42
+ """
43
+
44
+ def decorator(method):
45
+ """Decorator implementation.
46
+
47
+ Args:
48
+ method (Callable): The method to copy the docstring to.
49
+
50
+ Returns:
51
+ Callable: the same method passed in with an updated docstring.
52
+
53
+ Raises:
54
+ ValueError: if the method already has a docstring.
55
+ """
56
+ if method.__doc__:
57
+ raise ValueError("Method already has a docstring.")
58
+
59
+ source_method = getattr(source_class, method.__name__)
60
+ method.__doc__ = source_method.__doc__
61
+
62
+ return method
63
+
64
+ return decorator
65
+
66
+
67
+ def utcnow():
68
+ """Returns the current UTC datetime.
69
+
70
+ Returns:
71
+ datetime: The current time in UTC.
72
+ """
73
+ return datetime.datetime.utcnow()
74
+
75
+
76
+ def datetime_to_secs(value):
77
+ """Convert a datetime object to the number of seconds since the UNIX epoch.
78
+
79
+ Args:
80
+ value (datetime): The datetime to convert.
81
+
82
+ Returns:
83
+ int: The number of seconds since the UNIX epoch.
84
+ """
85
+ return calendar.timegm(value.utctimetuple())
86
+
87
+
88
+ def to_bytes(value, encoding="utf-8"):
89
+ """Converts a string value to bytes, if necessary.
90
+
91
+ Unfortunately, ``six.b`` is insufficient for this task since in
92
+ Python 2 because it does not modify ``unicode`` objects.
93
+
94
+ Args:
95
+ value (Union[str, bytes]): The value to be converted.
96
+ encoding (str): The encoding to use to convert unicode to bytes.
97
+ Defaults to "utf-8".
98
+
99
+ Returns:
100
+ bytes: The original value converted to bytes (if unicode) or as
101
+ passed in if it started out as bytes.
102
+
103
+ Raises:
104
+ ValueError: If the value could not be converted to bytes.
105
+ """
106
+ result = value.encode(encoding) if isinstance(value, six.text_type) else value
107
+ if isinstance(result, six.binary_type):
108
+ return result
109
+ else:
110
+ raise ValueError("{0!r} could not be converted to bytes".format(value))
111
+
112
+
113
+ def from_bytes(value):
114
+ """Converts bytes to a string value, if necessary.
115
+
116
+ Args:
117
+ value (Union[str, bytes]): The value to be converted.
118
+
119
+ Returns:
120
+ str: The original value converted to unicode (if bytes) or as passed in
121
+ if it started out as unicode.
122
+
123
+ Raises:
124
+ ValueError: If the value could not be converted to unicode.
125
+ """
126
+ result = value.decode("utf-8") if isinstance(value, six.binary_type) else value
127
+ if isinstance(result, six.text_type):
128
+ return result
129
+ else:
130
+ raise ValueError("{0!r} could not be converted to unicode".format(value))
131
+
132
+
133
+ def update_query(url, params, remove=None):
134
+ """Updates a URL's query parameters.
135
+
136
+ Replaces any current values if they are already present in the URL.
137
+
138
+ Args:
139
+ url (str): The URL to update.
140
+ params (Mapping[str, str]): A mapping of query parameter
141
+ keys to values.
142
+ remove (Sequence[str]): Parameters to remove from the query string.
143
+
144
+ Returns:
145
+ str: The URL with updated query parameters.
146
+
147
+ Examples:
148
+
149
+ >>> url = 'http://example.com?a=1'
150
+ >>> update_query(url, {'a': '2'})
151
+ http://example.com?a=2
152
+ >>> update_query(url, {'b': '3'})
153
+ http://example.com?a=1&b=3
154
+ >> update_query(url, {'b': '3'}, remove=['a'])
155
+ http://example.com?b=3
156
+
157
+ """
158
+ if remove is None:
159
+ remove = []
160
+
161
+ # Split the URL into parts.
162
+ parts = urllib.parse.urlparse(url)
163
+ # Parse the query string.
164
+ query_params = urllib.parse.parse_qs(parts.query)
165
+ # Update the query parameters with the new parameters.
166
+ query_params.update(params)
167
+ # Remove any values specified in remove.
168
+ query_params = {
169
+ key: value for key, value in six.iteritems(query_params) if key not in remove
170
+ }
171
+ # Re-encoded the query string.
172
+ new_query = urllib.parse.urlencode(query_params, doseq=True)
173
+ # Unsplit the url.
174
+ new_parts = parts._replace(query=new_query)
175
+ return urllib.parse.urlunparse(new_parts)
176
+
177
+
178
+ def scopes_to_string(scopes):
179
+ """Converts scope value to a string suitable for sending to OAuth 2.0
180
+ authorization servers.
181
+
182
+ Args:
183
+ scopes (Sequence[str]): The sequence of scopes to convert.
184
+
185
+ Returns:
186
+ str: The scopes formatted as a single string.
187
+ """
188
+ return " ".join(scopes)
189
+
190
+
191
+ def string_to_scopes(scopes):
192
+ """Converts stringifed scopes value to a list.
193
+
194
+ Args:
195
+ scopes (Union[Sequence, str]): The string of space-separated scopes
196
+ to convert.
197
+ Returns:
198
+ Sequence(str): The separated scopes.
199
+ """
200
+ if not scopes:
201
+ return []
202
+
203
+ return scopes.split(" ")
204
+
205
+
206
+ def padded_urlsafe_b64decode(value):
207
+ """Decodes base64 strings lacking padding characters.
208
+
209
+ Google infrastructure tends to omit the base64 padding characters.
210
+
211
+ Args:
212
+ value (Union[str, bytes]): The encoded value.
213
+
214
+ Returns:
215
+ bytes: The decoded value
216
+ """
217
+ b64string = to_bytes(value)
218
+ padded = b64string + b"=" * (-len(b64string) % 4)
219
+ return base64.urlsafe_b64decode(padded)
220
+
221
+
222
+ def unpadded_urlsafe_b64encode(value):
223
+ """Encodes base64 strings removing any padding characters.
224
+
225
+ `rfc 7515`_ defines Base64url to NOT include any padding
226
+ characters, but the stdlib doesn't do that by default.
227
+
228
+ _rfc7515: https://tools.ietf.org/html/rfc7515#page-6
229
+
230
+ Args:
231
+ value (Union[str|bytes]): The bytes-like value to encode
232
+
233
+ Returns:
234
+ Union[str|bytes]: The encoded value
235
+ """
236
+ return base64.urlsafe_b64encode(value).rstrip(b"=")
237
+
238
+
239
+ def is_python_3():
240
+ """Check if the Python interpreter is Python 2 or 3.
241
+
242
+ Returns:
243
+ bool: True if the Python interpreter is Python 3 and False otherwise.
244
+ """
245
+ return sys.version_info > (3, 0)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/_service_account_info.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2016 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Helper functions for loading data from a Google service account file."""
16
+
17
+ import io
18
+ import json
19
+
20
+ import six
21
+
22
+ from google.auth import crypt
23
+
24
+
25
+ def from_dict(data, require=None, use_rsa_signer=True):
26
+ """Validates a dictionary containing Google service account data.
27
+
28
+ Creates and returns a :class:`google.auth.crypt.Signer` instance from the
29
+ private key specified in the data.
30
+
31
+ Args:
32
+ data (Mapping[str, str]): The service account data
33
+ require (Sequence[str]): List of keys required to be present in the
34
+ info.
35
+ use_rsa_signer (Optional[bool]): Whether to use RSA signer or EC signer.
36
+ We use RSA signer by default.
37
+
38
+ Returns:
39
+ google.auth.crypt.Signer: A signer created from the private key in the
40
+ service account file.
41
+
42
+ Raises:
43
+ ValueError: if the data was in the wrong format, or if one of the
44
+ required keys is missing.
45
+ """
46
+ keys_needed = set(require if require is not None else [])
47
+
48
+ missing = keys_needed.difference(six.iterkeys(data))
49
+
50
+ if missing:
51
+ raise ValueError(
52
+ "Service account info was not in the expected format, missing "
53
+ "fields {}.".format(", ".join(missing))
54
+ )
55
+
56
+ # Create a signer.
57
+ if use_rsa_signer:
58
+ signer = crypt.RSASigner.from_service_account_info(data)
59
+ else:
60
+ signer = crypt.ES256Signer.from_service_account_info(data)
61
+
62
+ return signer
63
+
64
+
65
+ def from_filename(filename, require=None, use_rsa_signer=True):
66
+ """Reads a Google service account JSON file and returns its parsed info.
67
+
68
+ Args:
69
+ filename (str): The path to the service account .json file.
70
+ require (Sequence[str]): List of keys required to be present in the
71
+ info.
72
+ use_rsa_signer (Optional[bool]): Whether to use RSA signer or EC signer.
73
+ We use RSA signer by default.
74
+
75
+ Returns:
76
+ Tuple[ Mapping[str, str], google.auth.crypt.Signer ]: The verified
77
+ info and a signer instance.
78
+ """
79
+ with io.open(filename, "r", encoding="utf-8") as json_file:
80
+ data = json.load(json_file)
81
+ return data, from_dict(data, require=require, use_rsa_signer=use_rsa_signer)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/app_engine.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2016 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Google App Engine standard environment support.
16
+
17
+ This module provides authentication and signing for applications running on App
18
+ Engine in the standard environment using the `App Identity API`_.
19
+
20
+
21
+ .. _App Identity API:
22
+ https://cloud.google.com/appengine/docs/python/appidentity/
23
+ """
24
+
25
+ import datetime
26
+
27
+ from google.auth import _helpers
28
+ from google.auth import credentials
29
+ from google.auth import crypt
30
+
31
+ # pytype: disable=import-error
32
+ try:
33
+ from google.appengine.api import app_identity # type: ignore
34
+ except ImportError:
35
+ app_identity = None # type: ignore
36
+ # pytype: enable=import-error
37
+
38
+
39
+ class Signer(crypt.Signer):
40
+ """Signs messages using the App Engine App Identity service.
41
+
42
+ This can be used in place of :class:`google.auth.crypt.Signer` when
43
+ running in the App Engine standard environment.
44
+ """
45
+
46
+ @property
47
+ def key_id(self):
48
+ """Optional[str]: The key ID used to identify this private key.
49
+
50
+ .. warning::
51
+ This is always ``None``. The key ID used by App Engine can not
52
+ be reliably determined ahead of time.
53
+ """
54
+ return None
55
+
56
+ @_helpers.copy_docstring(crypt.Signer)
57
+ def sign(self, message):
58
+ message = _helpers.to_bytes(message)
59
+ _, signature = app_identity.sign_blob(message)
60
+ return signature
61
+
62
+
63
+ def get_project_id():
64
+ """Gets the project ID for the current App Engine application.
65
+
66
+ Returns:
67
+ str: The project ID
68
+
69
+ Raises:
70
+ EnvironmentError: If the App Engine APIs are unavailable.
71
+ """
72
+ # pylint: disable=missing-raises-doc
73
+ # Pylint rightfully thinks EnvironmentError is OSError, but doesn't
74
+ # realize it's a valid alias.
75
+ if app_identity is None:
76
+ raise EnvironmentError("The App Engine APIs are not available.")
77
+ return app_identity.get_application_id()
78
+
79
+
80
+ class Credentials(
81
+ credentials.Scoped, credentials.Signing, credentials.CredentialsWithQuotaProject
82
+ ):
83
+ """App Engine standard environment credentials.
84
+
85
+ These credentials use the App Engine App Identity API to obtain access
86
+ tokens.
87
+ """
88
+
89
+ def __init__(
90
+ self,
91
+ scopes=None,
92
+ default_scopes=None,
93
+ service_account_id=None,
94
+ quota_project_id=None,
95
+ ):
96
+ """
97
+ Args:
98
+ scopes (Sequence[str]): Scopes to request from the App Identity
99
+ API.
100
+ default_scopes (Sequence[str]): Default scopes passed by a
101
+ Google client library. Use 'scopes' for user-defined scopes.
102
+ service_account_id (str): The service account ID passed into
103
+ :func:`google.appengine.api.app_identity.get_access_token`.
104
+ If not specified, the default application service account
105
+ ID will be used.
106
+ quota_project_id (Optional[str]): The project ID used for quota
107
+ and billing.
108
+
109
+ Raises:
110
+ EnvironmentError: If the App Engine APIs are unavailable.
111
+ """
112
+ # pylint: disable=missing-raises-doc
113
+ # Pylint rightfully thinks EnvironmentError is OSError, but doesn't
114
+ # realize it's a valid alias.
115
+ if app_identity is None:
116
+ raise EnvironmentError("The App Engine APIs are not available.")
117
+
118
+ super(Credentials, self).__init__()
119
+ self._scopes = scopes
120
+ self._default_scopes = default_scopes
121
+ self._service_account_id = service_account_id
122
+ self._signer = Signer()
123
+ self._quota_project_id = quota_project_id
124
+
125
+ @_helpers.copy_docstring(credentials.Credentials)
126
+ def refresh(self, request):
127
+ scopes = self._scopes if self._scopes is not None else self._default_scopes
128
+ # pylint: disable=unused-argument
129
+ token, ttl = app_identity.get_access_token(scopes, self._service_account_id)
130
+ expiry = datetime.datetime.utcfromtimestamp(ttl)
131
+
132
+ self.token, self.expiry = token, expiry
133
+
134
+ @property
135
+ def service_account_email(self):
136
+ """The service account email."""
137
+ if self._service_account_id is None:
138
+ self._service_account_id = app_identity.get_service_account_name()
139
+ return self._service_account_id
140
+
141
+ @property
142
+ def requires_scopes(self):
143
+ """Checks if the credentials requires scopes.
144
+
145
+ Returns:
146
+ bool: True if there are no scopes set otherwise False.
147
+ """
148
+ return not self._scopes and not self._default_scopes
149
+
150
+ @_helpers.copy_docstring(credentials.Scoped)
151
+ def with_scopes(self, scopes, default_scopes=None):
152
+ return self.__class__(
153
+ scopes=scopes,
154
+ default_scopes=default_scopes,
155
+ service_account_id=self._service_account_id,
156
+ quota_project_id=self.quota_project_id,
157
+ )
158
+
159
+ @_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
160
+ def with_quota_project(self, quota_project_id):
161
+ return self.__class__(
162
+ scopes=self._scopes,
163
+ service_account_id=self._service_account_id,
164
+ quota_project_id=quota_project_id,
165
+ )
166
+
167
+ @_helpers.copy_docstring(credentials.Signing)
168
+ def sign_bytes(self, message):
169
+ return self._signer.sign(message)
170
+
171
+ @property # type: ignore
172
+ @_helpers.copy_docstring(credentials.Signing)
173
+ def signer_email(self):
174
+ return self.service_account_email
175
+
176
+ @property # type: ignore
177
+ @_helpers.copy_docstring(credentials.Signing)
178
+ def signer(self):
179
+ return self._signer
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/jwt.py ADDED
@@ -0,0 +1,857 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2016 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """JSON Web Tokens
16
+
17
+ Provides support for creating (encoding) and verifying (decoding) JWTs,
18
+ especially JWTs generated and consumed by Google infrastructure.
19
+
20
+ See `rfc7519`_ for more details on JWTs.
21
+
22
+ To encode a JWT use :func:`encode`::
23
+
24
+ from google.auth import crypt
25
+ from google.auth import jwt
26
+
27
+ signer = crypt.Signer(private_key)
28
+ payload = {'some': 'payload'}
29
+ encoded = jwt.encode(signer, payload)
30
+
31
+ To decode a JWT and verify claims use :func:`decode`::
32
+
33
+ claims = jwt.decode(encoded, certs=public_certs)
34
+
35
+ You can also skip verification::
36
+
37
+ claims = jwt.decode(encoded, verify=False)
38
+
39
+ .. _rfc7519: https://tools.ietf.org/html/rfc7519
40
+
41
+ """
42
+
43
+ try:
44
+ from collections.abc import Mapping
45
+ # Python 2.7 compatibility
46
+ except ImportError: # pragma: NO COVER
47
+ from collections import Mapping # type: ignore
48
+ import copy
49
+ import datetime
50
+ import json
51
+
52
+ import cachetools
53
+ import six
54
+ from six.moves import urllib
55
+
56
+ from google.auth import _helpers
57
+ from google.auth import _service_account_info
58
+ from google.auth import crypt
59
+ from google.auth import exceptions
60
+ import google.auth.credentials
61
+
62
+ try:
63
+ from google.auth.crypt import es256
64
+ except ImportError: # pragma: NO COVER
65
+ es256 = None # type: ignore
66
+
67
+ _DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds
68
+ _DEFAULT_MAX_CACHE_SIZE = 10
69
+ _ALGORITHM_TO_VERIFIER_CLASS = {"RS256": crypt.RSAVerifier}
70
+ _CRYPTOGRAPHY_BASED_ALGORITHMS = frozenset(["ES256"])
71
+
72
+ if es256 is not None: # pragma: NO COVER
73
+ _ALGORITHM_TO_VERIFIER_CLASS["ES256"] = es256.ES256Verifier # type: ignore
74
+
75
+
76
+ def encode(signer, payload, header=None, key_id=None):
77
+ """Make a signed JWT.
78
+
79
+ Args:
80
+ signer (google.auth.crypt.Signer): The signer used to sign the JWT.
81
+ payload (Mapping[str, str]): The JWT payload.
82
+ header (Mapping[str, str]): Additional JWT header payload.
83
+ key_id (str): The key id to add to the JWT header. If the
84
+ signer has a key id it will be used as the default. If this is
85
+ specified it will override the signer's key id.
86
+
87
+ Returns:
88
+ bytes: The encoded JWT.
89
+ """
90
+ if header is None:
91
+ header = {}
92
+
93
+ if key_id is None:
94
+ key_id = signer.key_id
95
+
96
+ header.update({"typ": "JWT"})
97
+
98
+ if "alg" not in header:
99
+ if es256 is not None and isinstance(signer, es256.ES256Signer):
100
+ header.update({"alg": "ES256"})
101
+ else:
102
+ header.update({"alg": "RS256"})
103
+
104
+ if key_id is not None:
105
+ header["kid"] = key_id
106
+
107
+ segments = [
108
+ _helpers.unpadded_urlsafe_b64encode(json.dumps(header).encode("utf-8")),
109
+ _helpers.unpadded_urlsafe_b64encode(json.dumps(payload).encode("utf-8")),
110
+ ]
111
+
112
+ signing_input = b".".join(segments)
113
+ signature = signer.sign(signing_input)
114
+ segments.append(_helpers.unpadded_urlsafe_b64encode(signature))
115
+
116
+ return b".".join(segments)
117
+
118
+
119
+ def _decode_jwt_segment(encoded_section):
120
+ """Decodes a single JWT segment."""
121
+ section_bytes = _helpers.padded_urlsafe_b64decode(encoded_section)
122
+ try:
123
+ return json.loads(section_bytes.decode("utf-8"))
124
+ except ValueError as caught_exc:
125
+ new_exc = ValueError("Can't parse segment: {0}".format(section_bytes))
126
+ six.raise_from(new_exc, caught_exc)
127
+
128
+
129
+ def _unverified_decode(token):
130
+ """Decodes a token and does no verification.
131
+
132
+ Args:
133
+ token (Union[str, bytes]): The encoded JWT.
134
+
135
+ Returns:
136
+ Tuple[str, str, str, str]: header, payload, signed_section, and
137
+ signature.
138
+
139
+ Raises:
140
+ ValueError: if there are an incorrect amount of segments in the token.
141
+ """
142
+ token = _helpers.to_bytes(token)
143
+
144
+ if token.count(b".") != 2:
145
+ raise ValueError("Wrong number of segments in token: {0}".format(token))
146
+
147
+ encoded_header, encoded_payload, signature = token.split(b".")
148
+ signed_section = encoded_header + b"." + encoded_payload
149
+ signature = _helpers.padded_urlsafe_b64decode(signature)
150
+
151
+ # Parse segments
152
+ header = _decode_jwt_segment(encoded_header)
153
+ payload = _decode_jwt_segment(encoded_payload)
154
+
155
+ return header, payload, signed_section, signature
156
+
157
+
158
+ def decode_header(token):
159
+ """Return the decoded header of a token.
160
+
161
+ No verification is done. This is useful to extract the key id from
162
+ the header in order to acquire the appropriate certificate to verify
163
+ the token.
164
+
165
+ Args:
166
+ token (Union[str, bytes]): the encoded JWT.
167
+
168
+ Returns:
169
+ Mapping: The decoded JWT header.
170
+ """
171
+ header, _, _, _ = _unverified_decode(token)
172
+ return header
173
+
174
+
175
+ def _verify_iat_and_exp(payload, clock_skew_in_seconds=0):
176
+ """Verifies the ``iat`` (Issued At) and ``exp`` (Expires) claims in a token
177
+ payload.
178
+
179
+ Args:
180
+ payload (Mapping[str, str]): The JWT payload.
181
+ clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
182
+ validation.
183
+
184
+ Raises:
185
+ ValueError: if any checks failed.
186
+ """
187
+ now = _helpers.datetime_to_secs(_helpers.utcnow())
188
+
189
+ # Make sure the iat and exp claims are present.
190
+ for key in ("iat", "exp"):
191
+ if key not in payload:
192
+ raise ValueError("Token does not contain required claim {}".format(key))
193
+
194
+ # Make sure the token wasn't issued in the future.
195
+ iat = payload["iat"]
196
+ # Err on the side of accepting a token that is slightly early to account
197
+ # for clock skew.
198
+ earliest = iat - clock_skew_in_seconds
199
+ if now < earliest:
200
+ raise ValueError(
201
+ "Token used too early, {} < {}. Check that your computer's clock is set correctly.".format(
202
+ now, iat
203
+ )
204
+ )
205
+
206
+ # Make sure the token wasn't issued in the past.
207
+ exp = payload["exp"]
208
+ # Err on the side of accepting a token that is slightly out of date
209
+ # to account for clow skew.
210
+ latest = exp + clock_skew_in_seconds
211
+ if latest < now:
212
+ raise ValueError("Token expired, {} < {}".format(latest, now))
213
+
214
+
215
+ def decode(token, certs=None, verify=True, audience=None, clock_skew_in_seconds=0):
216
+ """Decode and verify a JWT.
217
+
218
+ Args:
219
+ token (str): The encoded JWT.
220
+ certs (Union[str, bytes, Mapping[str, Union[str, bytes]]]): The
221
+ certificate used to validate the JWT signature. If bytes or string,
222
+ it must the the public key certificate in PEM format. If a mapping,
223
+ it must be a mapping of key IDs to public key certificates in PEM
224
+ format. The mapping must contain the same key ID that's specified
225
+ in the token's header.
226
+ verify (bool): Whether to perform signature and claim validation.
227
+ Verification is done by default.
228
+ audience (str or list): The audience claim, 'aud', that this JWT should
229
+ contain. Or a list of audience claims. If None then the JWT's 'aud'
230
+ parameter is not verified.
231
+ clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
232
+ validation.
233
+
234
+ Returns:
235
+ Mapping[str, str]: The deserialized JSON payload in the JWT.
236
+
237
+ Raises:
238
+ ValueError: if any verification checks failed.
239
+ """
240
+ header, payload, signed_section, signature = _unverified_decode(token)
241
+
242
+ if not verify:
243
+ return payload
244
+
245
+ # Pluck the key id and algorithm from the header and make sure we have
246
+ # a verifier that can support it.
247
+ key_alg = header.get("alg")
248
+ key_id = header.get("kid")
249
+
250
+ try:
251
+ verifier_cls = _ALGORITHM_TO_VERIFIER_CLASS[key_alg]
252
+ except KeyError as exc:
253
+ if key_alg in _CRYPTOGRAPHY_BASED_ALGORITHMS:
254
+ six.raise_from(
255
+ ValueError(
256
+ "The key algorithm {} requires the cryptography package "
257
+ "to be installed.".format(key_alg)
258
+ ),
259
+ exc,
260
+ )
261
+ else:
262
+ six.raise_from(
263
+ ValueError("Unsupported signature algorithm {}".format(key_alg)), exc
264
+ )
265
+
266
+ # If certs is specified as a dictionary of key IDs to certificates, then
267
+ # use the certificate identified by the key ID in the token header.
268
+ if isinstance(certs, Mapping):
269
+ if key_id:
270
+ if key_id not in certs:
271
+ raise ValueError("Certificate for key id {} not found.".format(key_id))
272
+ certs_to_check = [certs[key_id]]
273
+ # If there's no key id in the header, check against all of the certs.
274
+ else:
275
+ certs_to_check = certs.values()
276
+ else:
277
+ certs_to_check = certs
278
+
279
+ # Verify that the signature matches the message.
280
+ if not crypt.verify_signature(
281
+ signed_section, signature, certs_to_check, verifier_cls
282
+ ):
283
+ raise ValueError("Could not verify token signature.")
284
+
285
+ # Verify the issued at and created times in the payload.
286
+ _verify_iat_and_exp(payload, clock_skew_in_seconds)
287
+
288
+ # Check audience.
289
+ if audience is not None:
290
+ claim_audience = payload.get("aud")
291
+ if isinstance(audience, str):
292
+ audience = [audience]
293
+ if claim_audience not in audience:
294
+ raise ValueError(
295
+ "Token has wrong audience {}, expected one of {}".format(
296
+ claim_audience, audience
297
+ )
298
+ )
299
+
300
+ return payload
301
+
302
+
303
+ class Credentials(
304
+ google.auth.credentials.Signing, google.auth.credentials.CredentialsWithQuotaProject
305
+ ):
306
+ """Credentials that use a JWT as the bearer token.
307
+
308
+ These credentials require an "audience" claim. This claim identifies the
309
+ intended recipient of the bearer token.
310
+
311
+ The constructor arguments determine the claims for the JWT that is
312
+ sent with requests. Usually, you'll construct these credentials with
313
+ one of the helper constructors as shown in the next section.
314
+
315
+ To create JWT credentials using a Google service account private key
316
+ JSON file::
317
+
318
+ audience = 'https://pubsub.googleapis.com/google.pubsub.v1.Publisher'
319
+ credentials = jwt.Credentials.from_service_account_file(
320
+ 'service-account.json',
321
+ audience=audience)
322
+
323
+ If you already have the service account file loaded and parsed::
324
+
325
+ service_account_info = json.load(open('service_account.json'))
326
+ credentials = jwt.Credentials.from_service_account_info(
327
+ service_account_info,
328
+ audience=audience)
329
+
330
+ Both helper methods pass on arguments to the constructor, so you can
331
+ specify the JWT claims::
332
+
333
+ credentials = jwt.Credentials.from_service_account_file(
334
+ 'service-account.json',
335
+ audience=audience,
336
+ additional_claims={'meta': 'data'})
337
+
338
+ You can also construct the credentials directly if you have a
339
+ :class:`~google.auth.crypt.Signer` instance::
340
+
341
+ credentials = jwt.Credentials(
342
+ signer,
343
+ issuer='your-issuer',
344
+ subject='your-subject',
345
+ audience=audience)
346
+
347
+ The claims are considered immutable. If you want to modify the claims,
348
+ you can easily create another instance using :meth:`with_claims`::
349
+
350
+ new_audience = (
351
+ 'https://pubsub.googleapis.com/google.pubsub.v1.Subscriber')
352
+ new_credentials = credentials.with_claims(audience=new_audience)
353
+ """
354
+
355
+ def __init__(
356
+ self,
357
+ signer,
358
+ issuer,
359
+ subject,
360
+ audience,
361
+ additional_claims=None,
362
+ token_lifetime=_DEFAULT_TOKEN_LIFETIME_SECS,
363
+ quota_project_id=None,
364
+ ):
365
+ """
366
+ Args:
367
+ signer (google.auth.crypt.Signer): The signer used to sign JWTs.
368
+ issuer (str): The `iss` claim.
369
+ subject (str): The `sub` claim.
370
+ audience (str): the `aud` claim. The intended audience for the
371
+ credentials.
372
+ additional_claims (Mapping[str, str]): Any additional claims for
373
+ the JWT payload.
374
+ token_lifetime (int): The amount of time in seconds for
375
+ which the token is valid. Defaults to 1 hour.
376
+ quota_project_id (Optional[str]): The project ID used for quota
377
+ and billing.
378
+ """
379
+ super(Credentials, self).__init__()
380
+ self._signer = signer
381
+ self._issuer = issuer
382
+ self._subject = subject
383
+ self._audience = audience
384
+ self._token_lifetime = token_lifetime
385
+ self._quota_project_id = quota_project_id
386
+
387
+ if additional_claims is None:
388
+ additional_claims = {}
389
+
390
+ self._additional_claims = additional_claims
391
+
392
+ @classmethod
393
+ def _from_signer_and_info(cls, signer, info, **kwargs):
394
+ """Creates a Credentials instance from a signer and service account
395
+ info.
396
+
397
+ Args:
398
+ signer (google.auth.crypt.Signer): The signer used to sign JWTs.
399
+ info (Mapping[str, str]): The service account info.
400
+ kwargs: Additional arguments to pass to the constructor.
401
+
402
+ Returns:
403
+ google.auth.jwt.Credentials: The constructed credentials.
404
+
405
+ Raises:
406
+ ValueError: If the info is not in the expected format.
407
+ """
408
+ kwargs.setdefault("subject", info["client_email"])
409
+ kwargs.setdefault("issuer", info["client_email"])
410
+ return cls(signer, **kwargs)
411
+
412
+ @classmethod
413
+ def from_service_account_info(cls, info, **kwargs):
414
+ """Creates an Credentials instance from a dictionary.
415
+
416
+ Args:
417
+ info (Mapping[str, str]): The service account info in Google
418
+ format.
419
+ kwargs: Additional arguments to pass to the constructor.
420
+
421
+ Returns:
422
+ google.auth.jwt.Credentials: The constructed credentials.
423
+
424
+ Raises:
425
+ ValueError: If the info is not in the expected format.
426
+ """
427
+ signer = _service_account_info.from_dict(info, require=["client_email"])
428
+ return cls._from_signer_and_info(signer, info, **kwargs)
429
+
430
+ @classmethod
431
+ def from_service_account_file(cls, filename, **kwargs):
432
+ """Creates a Credentials instance from a service account .json file
433
+ in Google format.
434
+
435
+ Args:
436
+ filename (str): The path to the service account .json file.
437
+ kwargs: Additional arguments to pass to the constructor.
438
+
439
+ Returns:
440
+ google.auth.jwt.Credentials: The constructed credentials.
441
+ """
442
+ info, signer = _service_account_info.from_filename(
443
+ filename, require=["client_email"]
444
+ )
445
+ return cls._from_signer_and_info(signer, info, **kwargs)
446
+
447
+ @classmethod
448
+ def from_signing_credentials(cls, credentials, audience, **kwargs):
449
+ """Creates a new :class:`google.auth.jwt.Credentials` instance from an
450
+ existing :class:`google.auth.credentials.Signing` instance.
451
+
452
+ The new instance will use the same signer as the existing instance and
453
+ will use the existing instance's signer email as the issuer and
454
+ subject by default.
455
+
456
+ Example::
457
+
458
+ svc_creds = service_account.Credentials.from_service_account_file(
459
+ 'service_account.json')
460
+ audience = (
461
+ 'https://pubsub.googleapis.com/google.pubsub.v1.Publisher')
462
+ jwt_creds = jwt.Credentials.from_signing_credentials(
463
+ svc_creds, audience=audience)
464
+
465
+ Args:
466
+ credentials (google.auth.credentials.Signing): The credentials to
467
+ use to construct the new credentials.
468
+ audience (str): the `aud` claim. The intended audience for the
469
+ credentials.
470
+ kwargs: Additional arguments to pass to the constructor.
471
+
472
+ Returns:
473
+ google.auth.jwt.Credentials: A new Credentials instance.
474
+ """
475
+ kwargs.setdefault("issuer", credentials.signer_email)
476
+ kwargs.setdefault("subject", credentials.signer_email)
477
+ return cls(credentials.signer, audience=audience, **kwargs)
478
+
479
+ def with_claims(
480
+ self, issuer=None, subject=None, audience=None, additional_claims=None
481
+ ):
482
+ """Returns a copy of these credentials with modified claims.
483
+
484
+ Args:
485
+ issuer (str): The `iss` claim. If unspecified the current issuer
486
+ claim will be used.
487
+ subject (str): The `sub` claim. If unspecified the current subject
488
+ claim will be used.
489
+ audience (str): the `aud` claim. If unspecified the current
490
+ audience claim will be used.
491
+ additional_claims (Mapping[str, str]): Any additional claims for
492
+ the JWT payload. This will be merged with the current
493
+ additional claims.
494
+
495
+ Returns:
496
+ google.auth.jwt.Credentials: A new credentials instance.
497
+ """
498
+ new_additional_claims = copy.deepcopy(self._additional_claims)
499
+ new_additional_claims.update(additional_claims or {})
500
+
501
+ return self.__class__(
502
+ self._signer,
503
+ issuer=issuer if issuer is not None else self._issuer,
504
+ subject=subject if subject is not None else self._subject,
505
+ audience=audience if audience is not None else self._audience,
506
+ additional_claims=new_additional_claims,
507
+ quota_project_id=self._quota_project_id,
508
+ )
509
+
510
+ @_helpers.copy_docstring(google.auth.credentials.CredentialsWithQuotaProject)
511
+ def with_quota_project(self, quota_project_id):
512
+ return self.__class__(
513
+ self._signer,
514
+ issuer=self._issuer,
515
+ subject=self._subject,
516
+ audience=self._audience,
517
+ additional_claims=self._additional_claims,
518
+ quota_project_id=quota_project_id,
519
+ )
520
+
521
+ def _make_jwt(self):
522
+ """Make a signed JWT.
523
+
524
+ Returns:
525
+ Tuple[bytes, datetime]: The encoded JWT and the expiration.
526
+ """
527
+ now = _helpers.utcnow()
528
+ lifetime = datetime.timedelta(seconds=self._token_lifetime)
529
+ expiry = now + lifetime
530
+
531
+ payload = {
532
+ "iss": self._issuer,
533
+ "sub": self._subject,
534
+ "iat": _helpers.datetime_to_secs(now),
535
+ "exp": _helpers.datetime_to_secs(expiry),
536
+ }
537
+ if self._audience:
538
+ payload["aud"] = self._audience
539
+
540
+ payload.update(self._additional_claims)
541
+
542
+ jwt = encode(self._signer, payload)
543
+
544
+ return jwt, expiry
545
+
546
+ def refresh(self, request):
547
+ """Refreshes the access token.
548
+
549
+ Args:
550
+ request (Any): Unused.
551
+ """
552
+ # pylint: disable=unused-argument
553
+ # (pylint doesn't correctly recognize overridden methods.)
554
+ self.token, self.expiry = self._make_jwt()
555
+
556
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
557
+ def sign_bytes(self, message):
558
+ return self._signer.sign(message)
559
+
560
+ @property # type: ignore
561
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
562
+ def signer_email(self):
563
+ return self._issuer
564
+
565
+ @property # type: ignore
566
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
567
+ def signer(self):
568
+ return self._signer
569
+
570
+
571
+ class OnDemandCredentials(
572
+ google.auth.credentials.Signing, google.auth.credentials.CredentialsWithQuotaProject
573
+ ):
574
+ """On-demand JWT credentials.
575
+
576
+ Like :class:`Credentials`, this class uses a JWT as the bearer token for
577
+ authentication. However, this class does not require the audience at
578
+ construction time. Instead, it will generate a new token on-demand for
579
+ each request using the request URI as the audience. It caches tokens
580
+ so that multiple requests to the same URI do not incur the overhead
581
+ of generating a new token every time.
582
+
583
+ This behavior is especially useful for `gRPC`_ clients. A gRPC service may
584
+ have multiple audience and gRPC clients may not know all of the audiences
585
+ required for accessing a particular service. With these credentials,
586
+ no knowledge of the audiences is required ahead of time.
587
+
588
+ .. _grpc: http://www.grpc.io/
589
+ """
590
+
591
+ def __init__(
592
+ self,
593
+ signer,
594
+ issuer,
595
+ subject,
596
+ additional_claims=None,
597
+ token_lifetime=_DEFAULT_TOKEN_LIFETIME_SECS,
598
+ max_cache_size=_DEFAULT_MAX_CACHE_SIZE,
599
+ quota_project_id=None,
600
+ ):
601
+ """
602
+ Args:
603
+ signer (google.auth.crypt.Signer): The signer used to sign JWTs.
604
+ issuer (str): The `iss` claim.
605
+ subject (str): The `sub` claim.
606
+ additional_claims (Mapping[str, str]): Any additional claims for
607
+ the JWT payload.
608
+ token_lifetime (int): The amount of time in seconds for
609
+ which the token is valid. Defaults to 1 hour.
610
+ max_cache_size (int): The maximum number of JWT tokens to keep in
611
+ cache. Tokens are cached using :class:`cachetools.LRUCache`.
612
+ quota_project_id (Optional[str]): The project ID used for quota
613
+ and billing.
614
+
615
+ """
616
+ super(OnDemandCredentials, self).__init__()
617
+ self._signer = signer
618
+ self._issuer = issuer
619
+ self._subject = subject
620
+ self._token_lifetime = token_lifetime
621
+ self._quota_project_id = quota_project_id
622
+
623
+ if additional_claims is None:
624
+ additional_claims = {}
625
+
626
+ self._additional_claims = additional_claims
627
+ self._cache = cachetools.LRUCache(maxsize=max_cache_size)
628
+
629
+ @classmethod
630
+ def _from_signer_and_info(cls, signer, info, **kwargs):
631
+ """Creates an OnDemandCredentials instance from a signer and service
632
+ account info.
633
+
634
+ Args:
635
+ signer (google.auth.crypt.Signer): The signer used to sign JWTs.
636
+ info (Mapping[str, str]): The service account info.
637
+ kwargs: Additional arguments to pass to the constructor.
638
+
639
+ Returns:
640
+ google.auth.jwt.OnDemandCredentials: The constructed credentials.
641
+
642
+ Raises:
643
+ ValueError: If the info is not in the expected format.
644
+ """
645
+ kwargs.setdefault("subject", info["client_email"])
646
+ kwargs.setdefault("issuer", info["client_email"])
647
+ return cls(signer, **kwargs)
648
+
649
+ @classmethod
650
+ def from_service_account_info(cls, info, **kwargs):
651
+ """Creates an OnDemandCredentials instance from a dictionary.
652
+
653
+ Args:
654
+ info (Mapping[str, str]): The service account info in Google
655
+ format.
656
+ kwargs: Additional arguments to pass to the constructor.
657
+
658
+ Returns:
659
+ google.auth.jwt.OnDemandCredentials: The constructed credentials.
660
+
661
+ Raises:
662
+ ValueError: If the info is not in the expected format.
663
+ """
664
+ signer = _service_account_info.from_dict(info, require=["client_email"])
665
+ return cls._from_signer_and_info(signer, info, **kwargs)
666
+
667
+ @classmethod
668
+ def from_service_account_file(cls, filename, **kwargs):
669
+ """Creates an OnDemandCredentials instance from a service account .json
670
+ file in Google format.
671
+
672
+ Args:
673
+ filename (str): The path to the service account .json file.
674
+ kwargs: Additional arguments to pass to the constructor.
675
+
676
+ Returns:
677
+ google.auth.jwt.OnDemandCredentials: The constructed credentials.
678
+ """
679
+ info, signer = _service_account_info.from_filename(
680
+ filename, require=["client_email"]
681
+ )
682
+ return cls._from_signer_and_info(signer, info, **kwargs)
683
+
684
+ @classmethod
685
+ def from_signing_credentials(cls, credentials, **kwargs):
686
+ """Creates a new :class:`google.auth.jwt.OnDemandCredentials` instance
687
+ from an existing :class:`google.auth.credentials.Signing` instance.
688
+
689
+ The new instance will use the same signer as the existing instance and
690
+ will use the existing instance's signer email as the issuer and
691
+ subject by default.
692
+
693
+ Example::
694
+
695
+ svc_creds = service_account.Credentials.from_service_account_file(
696
+ 'service_account.json')
697
+ jwt_creds = jwt.OnDemandCredentials.from_signing_credentials(
698
+ svc_creds)
699
+
700
+ Args:
701
+ credentials (google.auth.credentials.Signing): The credentials to
702
+ use to construct the new credentials.
703
+ kwargs: Additional arguments to pass to the constructor.
704
+
705
+ Returns:
706
+ google.auth.jwt.Credentials: A new Credentials instance.
707
+ """
708
+ kwargs.setdefault("issuer", credentials.signer_email)
709
+ kwargs.setdefault("subject", credentials.signer_email)
710
+ return cls(credentials.signer, **kwargs)
711
+
712
+ def with_claims(self, issuer=None, subject=None, additional_claims=None):
713
+ """Returns a copy of these credentials with modified claims.
714
+
715
+ Args:
716
+ issuer (str): The `iss` claim. If unspecified the current issuer
717
+ claim will be used.
718
+ subject (str): The `sub` claim. If unspecified the current subject
719
+ claim will be used.
720
+ additional_claims (Mapping[str, str]): Any additional claims for
721
+ the JWT payload. This will be merged with the current
722
+ additional claims.
723
+
724
+ Returns:
725
+ google.auth.jwt.OnDemandCredentials: A new credentials instance.
726
+ """
727
+ new_additional_claims = copy.deepcopy(self._additional_claims)
728
+ new_additional_claims.update(additional_claims or {})
729
+
730
+ return self.__class__(
731
+ self._signer,
732
+ issuer=issuer if issuer is not None else self._issuer,
733
+ subject=subject if subject is not None else self._subject,
734
+ additional_claims=new_additional_claims,
735
+ max_cache_size=self._cache.maxsize,
736
+ quota_project_id=self._quota_project_id,
737
+ )
738
+
739
+ @_helpers.copy_docstring(google.auth.credentials.CredentialsWithQuotaProject)
740
+ def with_quota_project(self, quota_project_id):
741
+
742
+ return self.__class__(
743
+ self._signer,
744
+ issuer=self._issuer,
745
+ subject=self._subject,
746
+ additional_claims=self._additional_claims,
747
+ max_cache_size=self._cache.maxsize,
748
+ quota_project_id=quota_project_id,
749
+ )
750
+
751
+ @property
752
+ def valid(self):
753
+ """Checks the validity of the credentials.
754
+
755
+ These credentials are always valid because it generates tokens on
756
+ demand.
757
+ """
758
+ return True
759
+
760
+ def _make_jwt_for_audience(self, audience):
761
+ """Make a new JWT for the given audience.
762
+
763
+ Args:
764
+ audience (str): The intended audience.
765
+
766
+ Returns:
767
+ Tuple[bytes, datetime]: The encoded JWT and the expiration.
768
+ """
769
+ now = _helpers.utcnow()
770
+ lifetime = datetime.timedelta(seconds=self._token_lifetime)
771
+ expiry = now + lifetime
772
+
773
+ payload = {
774
+ "iss": self._issuer,
775
+ "sub": self._subject,
776
+ "iat": _helpers.datetime_to_secs(now),
777
+ "exp": _helpers.datetime_to_secs(expiry),
778
+ "aud": audience,
779
+ }
780
+
781
+ payload.update(self._additional_claims)
782
+
783
+ jwt = encode(self._signer, payload)
784
+
785
+ return jwt, expiry
786
+
787
+ def _get_jwt_for_audience(self, audience):
788
+ """Get a JWT For a given audience.
789
+
790
+ If there is already an existing, non-expired token in the cache for
791
+ the audience, that token is used. Otherwise, a new token will be
792
+ created.
793
+
794
+ Args:
795
+ audience (str): The intended audience.
796
+
797
+ Returns:
798
+ bytes: The encoded JWT.
799
+ """
800
+ token, expiry = self._cache.get(audience, (None, None))
801
+
802
+ if token is None or expiry < _helpers.utcnow():
803
+ token, expiry = self._make_jwt_for_audience(audience)
804
+ self._cache[audience] = token, expiry
805
+
806
+ return token
807
+
808
+ def refresh(self, request):
809
+ """Raises an exception, these credentials can not be directly
810
+ refreshed.
811
+
812
+ Args:
813
+ request (Any): Unused.
814
+
815
+ Raises:
816
+ google.auth.RefreshError
817
+ """
818
+ # pylint: disable=unused-argument
819
+ # (pylint doesn't correctly recognize overridden methods.)
820
+ raise exceptions.RefreshError(
821
+ "OnDemandCredentials can not be directly refreshed."
822
+ )
823
+
824
+ def before_request(self, request, method, url, headers):
825
+ """Performs credential-specific before request logic.
826
+
827
+ Args:
828
+ request (Any): Unused. JWT credentials do not need to make an
829
+ HTTP request to refresh.
830
+ method (str): The request's HTTP method.
831
+ url (str): The request's URI. This is used as the audience claim
832
+ when generating the JWT.
833
+ headers (Mapping): The request's headers.
834
+ """
835
+ # pylint: disable=unused-argument
836
+ # (pylint doesn't correctly recognize overridden methods.)
837
+ parts = urllib.parse.urlsplit(url)
838
+ # Strip query string and fragment
839
+ audience = urllib.parse.urlunsplit(
840
+ (parts.scheme, parts.netloc, parts.path, "", "")
841
+ )
842
+ token = self._get_jwt_for_audience(audience)
843
+ self.apply(headers, token=token)
844
+
845
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
846
+ def sign_bytes(self, message):
847
+ return self._signer.sign(message)
848
+
849
+ @property # type: ignore
850
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
851
+ def signer_email(self):
852
+ return self._issuer
853
+
854
+ @property # type: ignore
855
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
856
+ def signer(self):
857
+ return self._signer
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/auth/version.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ __version__ = "2.9.0"
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/__init__.cpython-38.pyc ADDED
Binary file (213 Bytes). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_client.cpython-38.pyc ADDED
Binary file (10.9 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_client_async.cpython-38.pyc ADDED
Binary file (7.91 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_credentials_async.cpython-38.pyc ADDED
Binary file (3.33 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_id_token_async.cpython-38.pyc ADDED
Binary file (8.59 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_reauth_async.cpython-38.pyc ADDED
Binary file (9.05 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/_service_account_async.cpython-38.pyc ADDED
Binary file (4.74 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/challenges.cpython-38.pyc ADDED
Binary file (6.12 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/credentials.cpython-38.pyc ADDED
Binary file (16.3 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/gdch_credentials.cpython-38.pyc ADDED
Binary file (7.93 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/id_token.cpython-38.pyc ADDED
Binary file (10.3 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/reauth.cpython-38.pyc ADDED
Binary file (9.49 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/service_account.cpython-38.pyc ADDED
Binary file (21.4 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/sts.cpython-38.pyc ADDED
Binary file (4.65 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/__pycache__/utils.cpython-38.pyc ADDED
Binary file (5.52 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/_id_token_async.py ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2020 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Google ID Token helpers.
16
+
17
+ Provides support for verifying `OpenID Connect ID Tokens`_, especially ones
18
+ generated by Google infrastructure.
19
+
20
+ To parse and verify an ID Token issued by Google's OAuth 2.0 authorization
21
+ server use :func:`verify_oauth2_token`. To verify an ID Token issued by
22
+ Firebase, use :func:`verify_firebase_token`.
23
+
24
+ A general purpose ID Token verifier is available as :func:`verify_token`.
25
+
26
+ Example::
27
+
28
+ from google.oauth2 import _id_token_async
29
+ from google.auth.transport import aiohttp_requests
30
+
31
+ request = aiohttp_requests.Request()
32
+
33
+ id_info = await _id_token_async.verify_oauth2_token(
34
+ token, request, 'my-client-id.example.com')
35
+
36
+ if id_info['iss'] != 'https://accounts.google.com':
37
+ raise ValueError('Wrong issuer.')
38
+
39
+ userid = id_info['sub']
40
+
41
+ By default, this will re-fetch certificates for each verification. Because
42
+ Google's public keys are only changed infrequently (on the order of once per
43
+ day), you may wish to take advantage of caching to reduce latency and the
44
+ potential for network errors. This can be accomplished using an external
45
+ library like `CacheControl`_ to create a cache-aware
46
+ :class:`google.auth.transport.Request`::
47
+
48
+ import cachecontrol
49
+ import google.auth.transport.requests
50
+ import requests
51
+
52
+ session = requests.session()
53
+ cached_session = cachecontrol.CacheControl(session)
54
+ request = google.auth.transport.requests.Request(session=cached_session)
55
+
56
+ .. _OpenID Connect ID Token:
57
+ http://openid.net/specs/openid-connect-core-1_0.html#IDToken
58
+ .. _CacheControl: https://cachecontrol.readthedocs.io
59
+ """
60
+
61
+ import json
62
+ import os
63
+
64
+ import six
65
+ from six.moves import http_client
66
+
67
+ from google.auth import environment_vars
68
+ from google.auth import exceptions
69
+ from google.auth import jwt
70
+ from google.auth.transport import requests
71
+ from google.oauth2 import id_token as sync_id_token
72
+
73
+
74
+ async def _fetch_certs(request, certs_url):
75
+ """Fetches certificates.
76
+
77
+ Google-style cerificate endpoints return JSON in the format of
78
+ ``{'key id': 'x509 certificate'}``.
79
+
80
+ Args:
81
+ request (google.auth.transport.Request): The object used to make
82
+ HTTP requests. This must be an aiohttp request.
83
+ certs_url (str): The certificate endpoint URL.
84
+
85
+ Returns:
86
+ Mapping[str, str]: A mapping of public key ID to x.509 certificate
87
+ data.
88
+ """
89
+ response = await request(certs_url, method="GET")
90
+
91
+ if response.status != http_client.OK:
92
+ raise exceptions.TransportError(
93
+ "Could not fetch certificates at {}".format(certs_url)
94
+ )
95
+
96
+ data = await response.data.read()
97
+
98
+ return json.loads(json.dumps(data))
99
+
100
+
101
+ async def verify_token(
102
+ id_token,
103
+ request,
104
+ audience=None,
105
+ certs_url=sync_id_token._GOOGLE_OAUTH2_CERTS_URL,
106
+ clock_skew_in_seconds=0,
107
+ ):
108
+ """Verifies an ID token and returns the decoded token.
109
+
110
+ Args:
111
+ id_token (Union[str, bytes]): The encoded token.
112
+ request (google.auth.transport.Request): The object used to make
113
+ HTTP requests. This must be an aiohttp request.
114
+ audience (str): The audience that this token is intended for. If None
115
+ then the audience is not verified.
116
+ certs_url (str): The URL that specifies the certificates to use to
117
+ verify the token. This URL should return JSON in the format of
118
+ ``{'key id': 'x509 certificate'}``.
119
+ clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
120
+ validation.
121
+
122
+ Returns:
123
+ Mapping[str, Any]: The decoded token.
124
+ """
125
+ certs = await _fetch_certs(request, certs_url)
126
+
127
+ return jwt.decode(
128
+ id_token,
129
+ certs=certs,
130
+ audience=audience,
131
+ clock_skew_in_seconds=clock_skew_in_seconds,
132
+ )
133
+
134
+
135
+ async def verify_oauth2_token(
136
+ id_token, request, audience=None, clock_skew_in_seconds=0
137
+ ):
138
+ """Verifies an ID Token issued by Google's OAuth 2.0 authorization server.
139
+
140
+ Args:
141
+ id_token (Union[str, bytes]): The encoded token.
142
+ request (google.auth.transport.Request): The object used to make
143
+ HTTP requests. This must be an aiohttp request.
144
+ audience (str): The audience that this token is intended for. This is
145
+ typically your application's OAuth 2.0 client ID. If None then the
146
+ audience is not verified.
147
+ clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
148
+ validation.
149
+
150
+ Returns:
151
+ Mapping[str, Any]: The decoded token.
152
+
153
+ Raises:
154
+ exceptions.GoogleAuthError: If the issuer is invalid.
155
+ """
156
+ idinfo = await verify_token(
157
+ id_token,
158
+ request,
159
+ audience=audience,
160
+ certs_url=sync_id_token._GOOGLE_OAUTH2_CERTS_URL,
161
+ clock_skew_in_seconds=clock_skew_in_seconds,
162
+ )
163
+
164
+ if idinfo["iss"] not in sync_id_token._GOOGLE_ISSUERS:
165
+ raise exceptions.GoogleAuthError(
166
+ "Wrong issuer. 'iss' should be one of the following: {}".format(
167
+ sync_id_token._GOOGLE_ISSUERS
168
+ )
169
+ )
170
+
171
+ return idinfo
172
+
173
+
174
+ async def verify_firebase_token(
175
+ id_token, request, audience=None, clock_skew_in_seconds=0
176
+ ):
177
+ """Verifies an ID Token issued by Firebase Authentication.
178
+
179
+ Args:
180
+ id_token (Union[str, bytes]): The encoded token.
181
+ request (google.auth.transport.Request): The object used to make
182
+ HTTP requests. This must be an aiohttp request.
183
+ audience (str): The audience that this token is intended for. This is
184
+ typically your Firebase application ID. If None then the audience
185
+ is not verified.
186
+ clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
187
+ validation.
188
+
189
+ Returns:
190
+ Mapping[str, Any]: The decoded token.
191
+ """
192
+ return await verify_token(
193
+ id_token,
194
+ request,
195
+ audience=audience,
196
+ certs_url=sync_id_token._GOOGLE_APIS_CERTS_URL,
197
+ clock_skew_in_seconds=clock_skew_in_seconds,
198
+ )
199
+
200
+
201
+ async def fetch_id_token(request, audience):
202
+ """Fetch the ID Token from the current environment.
203
+
204
+ This function acquires ID token from the environment in the following order.
205
+ See https://google.aip.dev/auth/4110.
206
+
207
+ 1. If the environment variable ``GOOGLE_APPLICATION_CREDENTIALS`` is set
208
+ to the path of a valid service account JSON file, then ID token is
209
+ acquired using this service account credentials.
210
+ 2. If the application is running in Compute Engine, App Engine or Cloud Run,
211
+ then the ID token are obtained from the metadata server.
212
+ 3. If metadata server doesn't exist and no valid service account credentials
213
+ are found, :class:`~google.auth.exceptions.DefaultCredentialsError` will
214
+ be raised.
215
+
216
+ Example::
217
+
218
+ import google.oauth2._id_token_async
219
+ import google.auth.transport.aiohttp_requests
220
+
221
+ request = google.auth.transport.aiohttp_requests.Request()
222
+ target_audience = "https://pubsub.googleapis.com"
223
+
224
+ id_token = await google.oauth2._id_token_async.fetch_id_token(request, target_audience)
225
+
226
+ Args:
227
+ request (google.auth.transport.aiohttp_requests.Request): A callable used to make
228
+ HTTP requests.
229
+ audience (str): The audience that this ID token is intended for.
230
+
231
+ Returns:
232
+ str: The ID token.
233
+
234
+ Raises:
235
+ ~google.auth.exceptions.DefaultCredentialsError:
236
+ If metadata server doesn't exist and no valid service account
237
+ credentials are found.
238
+ """
239
+ # 1. Try to get credentials from the GOOGLE_APPLICATION_CREDENTIALS environment
240
+ # variable.
241
+ credentials_filename = os.environ.get(environment_vars.CREDENTIALS)
242
+ if credentials_filename:
243
+ if not (
244
+ os.path.exists(credentials_filename)
245
+ and os.path.isfile(credentials_filename)
246
+ ):
247
+ raise exceptions.DefaultCredentialsError(
248
+ "GOOGLE_APPLICATION_CREDENTIALS path is either not found or invalid."
249
+ )
250
+
251
+ try:
252
+ with open(credentials_filename, "r") as f:
253
+ from google.oauth2 import _service_account_async as service_account
254
+
255
+ info = json.load(f)
256
+ if info.get("type") == "service_account":
257
+ credentials = service_account.IDTokenCredentials.from_service_account_info(
258
+ info, target_audience=audience
259
+ )
260
+ await credentials.refresh(request)
261
+ return credentials.token
262
+ except ValueError as caught_exc:
263
+ new_exc = exceptions.DefaultCredentialsError(
264
+ "GOOGLE_APPLICATION_CREDENTIALS is not valid service account credentials.",
265
+ caught_exc,
266
+ )
267
+ six.raise_from(new_exc, caught_exc)
268
+
269
+ # 2. Try to fetch ID token from metada server if it exists. The code works
270
+ # for GAE and Cloud Run metadata server as well.
271
+ try:
272
+ from google.auth import compute_engine
273
+ from google.auth.compute_engine import _metadata
274
+
275
+ request_new = requests.Request()
276
+ if _metadata.ping(request_new):
277
+ credentials = compute_engine.IDTokenCredentials(
278
+ request_new, audience, use_metadata_identity_endpoint=True
279
+ )
280
+ credentials.refresh(request_new)
281
+ return credentials.token
282
+ except (ImportError, exceptions.TransportError):
283
+ pass
284
+
285
+ raise exceptions.DefaultCredentialsError(
286
+ "Neither metadata server or valid service account credentials are found."
287
+ )
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/_reauth_async.py ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """A module that provides functions for handling rapt authentication.
16
+
17
+ Reauth is a process of obtaining additional authentication (such as password,
18
+ security token, etc.) while refreshing OAuth 2.0 credentials for a user.
19
+
20
+ Credentials that use the Reauth flow must have the reauth scope,
21
+ ``https://www.googleapis.com/auth/accounts.reauth``.
22
+
23
+ This module provides a high-level function for executing the Reauth process,
24
+ :func:`refresh_grant`, and lower-level helpers for doing the individual
25
+ steps of the reauth process.
26
+
27
+ Those steps are:
28
+
29
+ 1. Obtaining a list of challenges from the reauth server.
30
+ 2. Running through each challenge and sending the result back to the reauth
31
+ server.
32
+ 3. Refreshing the access token using the returned rapt token.
33
+ """
34
+
35
+ import sys
36
+
37
+ from six.moves import range
38
+
39
+ from google.auth import exceptions
40
+ from google.oauth2 import _client
41
+ from google.oauth2 import _client_async
42
+ from google.oauth2 import challenges
43
+ from google.oauth2 import reauth
44
+
45
+
46
+ async def _get_challenges(
47
+ request, supported_challenge_types, access_token, requested_scopes=None
48
+ ):
49
+ """Does initial request to reauth API to get the challenges.
50
+
51
+ Args:
52
+ request (google.auth.transport.Request): A callable used to make
53
+ HTTP requests. This must be an aiohttp request.
54
+ supported_challenge_types (Sequence[str]): list of challenge names
55
+ supported by the manager.
56
+ access_token (str): Access token with reauth scopes.
57
+ requested_scopes (Optional(Sequence[str])): Authorized scopes for the credentials.
58
+
59
+ Returns:
60
+ dict: The response from the reauth API.
61
+ """
62
+ body = {"supportedChallengeTypes": supported_challenge_types}
63
+ if requested_scopes:
64
+ body["oauthScopesForDomainPolicyLookup"] = requested_scopes
65
+
66
+ return await _client_async._token_endpoint_request(
67
+ request,
68
+ reauth._REAUTH_API + ":start",
69
+ body,
70
+ access_token=access_token,
71
+ use_json=True,
72
+ )
73
+
74
+
75
+ async def _send_challenge_result(
76
+ request, session_id, challenge_id, client_input, access_token
77
+ ):
78
+ """Attempt to refresh access token by sending next challenge result.
79
+
80
+ Args:
81
+ request (google.auth.transport.Request): A callable used to make
82
+ HTTP requests. This must be an aiohttp request.
83
+ session_id (str): session id returned by the initial reauth call.
84
+ challenge_id (str): challenge id returned by the initial reauth call.
85
+ client_input: dict with a challenge-specific client input. For example:
86
+ ``{'credential': password}`` for password challenge.
87
+ access_token (str): Access token with reauth scopes.
88
+
89
+ Returns:
90
+ dict: The response from the reauth API.
91
+ """
92
+ body = {
93
+ "sessionId": session_id,
94
+ "challengeId": challenge_id,
95
+ "action": "RESPOND",
96
+ "proposalResponse": client_input,
97
+ }
98
+
99
+ return await _client_async._token_endpoint_request(
100
+ request,
101
+ reauth._REAUTH_API + "/{}:continue".format(session_id),
102
+ body,
103
+ access_token=access_token,
104
+ use_json=True,
105
+ )
106
+
107
+
108
+ async def _run_next_challenge(msg, request, access_token):
109
+ """Get the next challenge from msg and run it.
110
+
111
+ Args:
112
+ msg (dict): Reauth API response body (either from the initial request to
113
+ https://reauth.googleapis.com/v2/sessions:start or from sending the
114
+ previous challenge response to
115
+ https://reauth.googleapis.com/v2/sessions/id:continue)
116
+ request (google.auth.transport.Request): A callable used to make
117
+ HTTP requests. This must be an aiohttp request.
118
+ access_token (str): reauth access token
119
+
120
+ Returns:
121
+ dict: The response from the reauth API.
122
+
123
+ Raises:
124
+ google.auth.exceptions.ReauthError: if reauth failed.
125
+ """
126
+ for challenge in msg["challenges"]:
127
+ if challenge["status"] != "READY":
128
+ # Skip non-activated challenges.
129
+ continue
130
+ c = challenges.AVAILABLE_CHALLENGES.get(challenge["challengeType"], None)
131
+ if not c:
132
+ raise exceptions.ReauthFailError(
133
+ "Unsupported challenge type {0}. Supported types: {1}".format(
134
+ challenge["challengeType"],
135
+ ",".join(list(challenges.AVAILABLE_CHALLENGES.keys())),
136
+ )
137
+ )
138
+ if not c.is_locally_eligible:
139
+ raise exceptions.ReauthFailError(
140
+ "Challenge {0} is not locally eligible".format(
141
+ challenge["challengeType"]
142
+ )
143
+ )
144
+ client_input = c.obtain_challenge_input(challenge)
145
+ if not client_input:
146
+ return None
147
+ return await _send_challenge_result(
148
+ request,
149
+ msg["sessionId"],
150
+ challenge["challengeId"],
151
+ client_input,
152
+ access_token,
153
+ )
154
+ return None
155
+
156
+
157
+ async def _obtain_rapt(request, access_token, requested_scopes):
158
+ """Given an http request method and reauth access token, get rapt token.
159
+
160
+ Args:
161
+ request (google.auth.transport.Request): A callable used to make
162
+ HTTP requests. This must be an aiohttp request.
163
+ access_token (str): reauth access token
164
+ requested_scopes (Sequence[str]): scopes required by the client application
165
+
166
+ Returns:
167
+ str: The rapt token.
168
+
169
+ Raises:
170
+ google.auth.exceptions.ReauthError: if reauth failed
171
+ """
172
+ msg = await _get_challenges(
173
+ request,
174
+ list(challenges.AVAILABLE_CHALLENGES.keys()),
175
+ access_token,
176
+ requested_scopes,
177
+ )
178
+
179
+ if msg["status"] == reauth._AUTHENTICATED:
180
+ return msg["encodedProofOfReauthToken"]
181
+
182
+ for _ in range(0, reauth.RUN_CHALLENGE_RETRY_LIMIT):
183
+ if not (
184
+ msg["status"] == reauth._CHALLENGE_REQUIRED
185
+ or msg["status"] == reauth._CHALLENGE_PENDING
186
+ ):
187
+ raise exceptions.ReauthFailError(
188
+ "Reauthentication challenge failed due to API error: {}".format(
189
+ msg["status"]
190
+ )
191
+ )
192
+
193
+ if not reauth.is_interactive():
194
+ raise exceptions.ReauthFailError(
195
+ "Reauthentication challenge could not be answered because you are not"
196
+ " in an interactive session."
197
+ )
198
+
199
+ msg = await _run_next_challenge(msg, request, access_token)
200
+
201
+ if msg["status"] == reauth._AUTHENTICATED:
202
+ return msg["encodedProofOfReauthToken"]
203
+
204
+ # If we got here it means we didn't get authenticated.
205
+ raise exceptions.ReauthFailError("Failed to obtain rapt token.")
206
+
207
+
208
+ async def get_rapt_token(
209
+ request, client_id, client_secret, refresh_token, token_uri, scopes=None
210
+ ):
211
+ """Given an http request method and refresh_token, get rapt token.
212
+
213
+ Args:
214
+ request (google.auth.transport.Request): A callable used to make
215
+ HTTP requests. This must be an aiohttp request.
216
+ client_id (str): client id to get access token for reauth scope.
217
+ client_secret (str): client secret for the client_id
218
+ refresh_token (str): refresh token to refresh access token
219
+ token_uri (str): uri to refresh access token
220
+ scopes (Optional(Sequence[str])): scopes required by the client application
221
+
222
+ Returns:
223
+ str: The rapt token.
224
+ Raises:
225
+ google.auth.exceptions.RefreshError: If reauth failed.
226
+ """
227
+ sys.stderr.write("Reauthentication required.\n")
228
+
229
+ # Get access token for reauth.
230
+ access_token, _, _, _ = await _client_async.refresh_grant(
231
+ request=request,
232
+ client_id=client_id,
233
+ client_secret=client_secret,
234
+ refresh_token=refresh_token,
235
+ token_uri=token_uri,
236
+ scopes=[reauth._REAUTH_SCOPE],
237
+ )
238
+
239
+ # Get rapt token from reauth API.
240
+ rapt_token = await _obtain_rapt(request, access_token, requested_scopes=scopes)
241
+
242
+ return rapt_token
243
+
244
+
245
+ async def refresh_grant(
246
+ request,
247
+ token_uri,
248
+ refresh_token,
249
+ client_id,
250
+ client_secret,
251
+ scopes=None,
252
+ rapt_token=None,
253
+ enable_reauth_refresh=False,
254
+ ):
255
+ """Implements the reauthentication flow.
256
+
257
+ Args:
258
+ request (google.auth.transport.Request): A callable used to make
259
+ HTTP requests. This must be an aiohttp request.
260
+ token_uri (str): The OAuth 2.0 authorizations server's token endpoint
261
+ URI.
262
+ refresh_token (str): The refresh token to use to get a new access
263
+ token.
264
+ client_id (str): The OAuth 2.0 application's client ID.
265
+ client_secret (str): The Oauth 2.0 appliaction's client secret.
266
+ scopes (Optional(Sequence[str])): Scopes to request. If present, all
267
+ scopes must be authorized for the refresh token. Useful if refresh
268
+ token has a wild card scope (e.g.
269
+ 'https://www.googleapis.com/auth/any-api').
270
+ rapt_token (Optional(str)): The rapt token for reauth.
271
+ enable_reauth_refresh (Optional[bool]): Whether reauth refresh flow
272
+ should be used. The default value is False. This option is for
273
+ gcloud only, other users should use the default value.
274
+
275
+ Returns:
276
+ Tuple[str, Optional[str], Optional[datetime], Mapping[str, str], str]: The
277
+ access token, new refresh token, expiration, the additional data
278
+ returned by the token endpoint, and the rapt token.
279
+
280
+ Raises:
281
+ google.auth.exceptions.RefreshError: If the token endpoint returned
282
+ an error.
283
+ """
284
+ body = {
285
+ "grant_type": _client._REFRESH_GRANT_TYPE,
286
+ "client_id": client_id,
287
+ "client_secret": client_secret,
288
+ "refresh_token": refresh_token,
289
+ }
290
+ if scopes:
291
+ body["scope"] = " ".join(scopes)
292
+ if rapt_token:
293
+ body["rapt"] = rapt_token
294
+
295
+ response_status_ok, response_data = await _client_async._token_endpoint_request_no_throw(
296
+ request, token_uri, body
297
+ )
298
+ if (
299
+ not response_status_ok
300
+ and response_data.get("error") == reauth._REAUTH_NEEDED_ERROR
301
+ and (
302
+ response_data.get("error_subtype")
303
+ == reauth._REAUTH_NEEDED_ERROR_INVALID_RAPT
304
+ or response_data.get("error_subtype")
305
+ == reauth._REAUTH_NEEDED_ERROR_RAPT_REQUIRED
306
+ )
307
+ ):
308
+ if not enable_reauth_refresh:
309
+ raise exceptions.RefreshError(
310
+ "Reauthentication is needed. Please run `gcloud auth login --update-adc` to reauthenticate."
311
+ )
312
+
313
+ rapt_token = await get_rapt_token(
314
+ request, client_id, client_secret, refresh_token, token_uri, scopes=scopes
315
+ )
316
+ body["rapt"] = rapt_token
317
+ (
318
+ response_status_ok,
319
+ response_data,
320
+ ) = await _client_async._token_endpoint_request_no_throw(
321
+ request, token_uri, body
322
+ )
323
+
324
+ if not response_status_ok:
325
+ _client._handle_error_response(response_data)
326
+ refresh_response = _client._handle_refresh_grant_response(
327
+ response_data, refresh_token
328
+ )
329
+ return refresh_response + (rapt_token,)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/credentials.py ADDED
@@ -0,0 +1,490 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2016 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """OAuth 2.0 Credentials.
16
+
17
+ This module provides credentials based on OAuth 2.0 access and refresh tokens.
18
+ These credentials usually access resources on behalf of a user (resource
19
+ owner).
20
+
21
+ Specifically, this is intended to use access tokens acquired using the
22
+ `Authorization Code grant`_ and can refresh those tokens using a
23
+ optional `refresh token`_.
24
+
25
+ Obtaining the initial access and refresh token is outside of the scope of this
26
+ module. Consult `rfc6749 section 4.1`_ for complete details on the
27
+ Authorization Code grant flow.
28
+
29
+ .. _Authorization Code grant: https://tools.ietf.org/html/rfc6749#section-1.3.1
30
+ .. _refresh token: https://tools.ietf.org/html/rfc6749#section-6
31
+ .. _rfc6749 section 4.1: https://tools.ietf.org/html/rfc6749#section-4.1
32
+ """
33
+
34
+ from datetime import datetime
35
+ import io
36
+ import json
37
+
38
+ import six
39
+
40
+ from google.auth import _cloud_sdk
41
+ from google.auth import _helpers
42
+ from google.auth import credentials
43
+ from google.auth import exceptions
44
+ from google.oauth2 import reauth
45
+
46
+
47
+ # The Google OAuth 2.0 token endpoint. Used for authorized user credentials.
48
+ _GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token"
49
+
50
+
51
+ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaProject):
52
+ """Credentials using OAuth 2.0 access and refresh tokens.
53
+
54
+ The credentials are considered immutable. If you want to modify the
55
+ quota project, use :meth:`with_quota_project` or ::
56
+
57
+ credentials = credentials.with_quota_project('myproject-123')
58
+
59
+ Reauth is disabled by default. To enable reauth, set the
60
+ `enable_reauth_refresh` parameter to True in the constructor. Note that
61
+ reauth feature is intended for gcloud to use only.
62
+ If reauth is enabled, `pyu2f` dependency has to be installed in order to use security
63
+ key reauth feature. Dependency can be installed via `pip install pyu2f` or `pip install
64
+ google-auth[reauth]`.
65
+ """
66
+
67
+ def __init__(
68
+ self,
69
+ token,
70
+ refresh_token=None,
71
+ id_token=None,
72
+ token_uri=None,
73
+ client_id=None,
74
+ client_secret=None,
75
+ scopes=None,
76
+ default_scopes=None,
77
+ quota_project_id=None,
78
+ expiry=None,
79
+ rapt_token=None,
80
+ refresh_handler=None,
81
+ enable_reauth_refresh=False,
82
+ ):
83
+ """
84
+ Args:
85
+ token (Optional(str)): The OAuth 2.0 access token. Can be None
86
+ if refresh information is provided.
87
+ refresh_token (str): The OAuth 2.0 refresh token. If specified,
88
+ credentials can be refreshed.
89
+ id_token (str): The Open ID Connect ID Token.
90
+ token_uri (str): The OAuth 2.0 authorization server's token
91
+ endpoint URI. Must be specified for refresh, can be left as
92
+ None if the token can not be refreshed.
93
+ client_id (str): The OAuth 2.0 client ID. Must be specified for
94
+ refresh, can be left as None if the token can not be refreshed.
95
+ client_secret(str): The OAuth 2.0 client secret. Must be specified
96
+ for refresh, can be left as None if the token can not be
97
+ refreshed.
98
+ scopes (Sequence[str]): The scopes used to obtain authorization.
99
+ This parameter is used by :meth:`has_scopes`. OAuth 2.0
100
+ credentials can not request additional scopes after
101
+ authorization. The scopes must be derivable from the refresh
102
+ token if refresh information is provided (e.g. The refresh
103
+ token scopes are a superset of this or contain a wild card
104
+ scope like 'https://www.googleapis.com/auth/any-api').
105
+ default_scopes (Sequence[str]): Default scopes passed by a
106
+ Google client library. Use 'scopes' for user-defined scopes.
107
+ quota_project_id (Optional[str]): The project ID used for quota and billing.
108
+ This project may be different from the project used to
109
+ create the credentials.
110
+ rapt_token (Optional[str]): The reauth Proof Token.
111
+ refresh_handler (Optional[Callable[[google.auth.transport.Request, Sequence[str]], [str, datetime]]]):
112
+ A callable which takes in the HTTP request callable and the list of
113
+ OAuth scopes and when called returns an access token string for the
114
+ requested scopes and its expiry datetime. This is useful when no
115
+ refresh tokens are provided and tokens are obtained by calling
116
+ some external process on demand. It is particularly useful for
117
+ retrieving downscoped tokens from a token broker.
118
+ enable_reauth_refresh (Optional[bool]): Whether reauth refresh flow
119
+ should be used. This flag is for gcloud to use only.
120
+ """
121
+ super(Credentials, self).__init__()
122
+ self.token = token
123
+ self.expiry = expiry
124
+ self._refresh_token = refresh_token
125
+ self._id_token = id_token
126
+ self._scopes = scopes
127
+ self._default_scopes = default_scopes
128
+ self._token_uri = token_uri
129
+ self._client_id = client_id
130
+ self._client_secret = client_secret
131
+ self._quota_project_id = quota_project_id
132
+ self._rapt_token = rapt_token
133
+ self.refresh_handler = refresh_handler
134
+ self._enable_reauth_refresh = enable_reauth_refresh
135
+
136
+ def __getstate__(self):
137
+ """A __getstate__ method must exist for the __setstate__ to be called
138
+ This is identical to the default implementation.
139
+ See https://docs.python.org/3.7/library/pickle.html#object.__setstate__
140
+ """
141
+ state_dict = self.__dict__.copy()
142
+ # Remove _refresh_handler function as there are limitations pickling and
143
+ # unpickling certain callables (lambda, functools.partial instances)
144
+ # because they need to be importable.
145
+ # Instead, the refresh_handler setter should be used to repopulate this.
146
+ del state_dict["_refresh_handler"]
147
+ return state_dict
148
+
149
+ def __setstate__(self, d):
150
+ """Credentials pickled with older versions of the class do not have
151
+ all the attributes."""
152
+ self.token = d.get("token")
153
+ self.expiry = d.get("expiry")
154
+ self._refresh_token = d.get("_refresh_token")
155
+ self._id_token = d.get("_id_token")
156
+ self._scopes = d.get("_scopes")
157
+ self._default_scopes = d.get("_default_scopes")
158
+ self._token_uri = d.get("_token_uri")
159
+ self._client_id = d.get("_client_id")
160
+ self._client_secret = d.get("_client_secret")
161
+ self._quota_project_id = d.get("_quota_project_id")
162
+ self._rapt_token = d.get("_rapt_token")
163
+ self._enable_reauth_refresh = d.get("_enable_reauth_refresh")
164
+ # The refresh_handler setter should be used to repopulate this.
165
+ self._refresh_handler = None
166
+
167
+ @property
168
+ def refresh_token(self):
169
+ """Optional[str]: The OAuth 2.0 refresh token."""
170
+ return self._refresh_token
171
+
172
+ @property
173
+ def scopes(self):
174
+ """Optional[str]: The OAuth 2.0 permission scopes."""
175
+ return self._scopes
176
+
177
+ @property
178
+ def token_uri(self):
179
+ """Optional[str]: The OAuth 2.0 authorization server's token endpoint
180
+ URI."""
181
+ return self._token_uri
182
+
183
+ @property
184
+ def id_token(self):
185
+ """Optional[str]: The Open ID Connect ID Token.
186
+
187
+ Depending on the authorization server and the scopes requested, this
188
+ may be populated when credentials are obtained and updated when
189
+ :meth:`refresh` is called. This token is a JWT. It can be verified
190
+ and decoded using :func:`google.oauth2.id_token.verify_oauth2_token`.
191
+ """
192
+ return self._id_token
193
+
194
+ @property
195
+ def client_id(self):
196
+ """Optional[str]: The OAuth 2.0 client ID."""
197
+ return self._client_id
198
+
199
+ @property
200
+ def client_secret(self):
201
+ """Optional[str]: The OAuth 2.0 client secret."""
202
+ return self._client_secret
203
+
204
+ @property
205
+ def requires_scopes(self):
206
+ """False: OAuth 2.0 credentials have their scopes set when
207
+ the initial token is requested and can not be changed."""
208
+ return False
209
+
210
+ @property
211
+ def rapt_token(self):
212
+ """Optional[str]: The reauth Proof Token."""
213
+ return self._rapt_token
214
+
215
+ @property
216
+ def refresh_handler(self):
217
+ """Returns the refresh handler if available.
218
+
219
+ Returns:
220
+ Optional[Callable[[google.auth.transport.Request, Sequence[str]], [str, datetime]]]:
221
+ The current refresh handler.
222
+ """
223
+ return self._refresh_handler
224
+
225
+ @refresh_handler.setter
226
+ def refresh_handler(self, value):
227
+ """Updates the current refresh handler.
228
+
229
+ Args:
230
+ value (Optional[Callable[[google.auth.transport.Request, Sequence[str]], [str, datetime]]]):
231
+ The updated value of the refresh handler.
232
+
233
+ Raises:
234
+ TypeError: If the value is not a callable or None.
235
+ """
236
+ if not callable(value) and value is not None:
237
+ raise TypeError("The provided refresh_handler is not a callable or None.")
238
+ self._refresh_handler = value
239
+
240
+ @_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
241
+ def with_quota_project(self, quota_project_id):
242
+
243
+ return self.__class__(
244
+ self.token,
245
+ refresh_token=self.refresh_token,
246
+ id_token=self.id_token,
247
+ token_uri=self.token_uri,
248
+ client_id=self.client_id,
249
+ client_secret=self.client_secret,
250
+ scopes=self.scopes,
251
+ default_scopes=self.default_scopes,
252
+ quota_project_id=quota_project_id,
253
+ rapt_token=self.rapt_token,
254
+ enable_reauth_refresh=self._enable_reauth_refresh,
255
+ )
256
+
257
+ @_helpers.copy_docstring(credentials.Credentials)
258
+ def refresh(self, request):
259
+ scopes = self._scopes if self._scopes is not None else self._default_scopes
260
+ # Use refresh handler if available and no refresh token is
261
+ # available. This is useful in general when tokens are obtained by calling
262
+ # some external process on demand. It is particularly useful for retrieving
263
+ # downscoped tokens from a token broker.
264
+ if self._refresh_token is None and self.refresh_handler:
265
+ token, expiry = self.refresh_handler(request, scopes=scopes)
266
+ # Validate returned data.
267
+ if not isinstance(token, six.string_types):
268
+ raise exceptions.RefreshError(
269
+ "The refresh_handler returned token is not a string."
270
+ )
271
+ if not isinstance(expiry, datetime):
272
+ raise exceptions.RefreshError(
273
+ "The refresh_handler returned expiry is not a datetime object."
274
+ )
275
+ if _helpers.utcnow() >= expiry - _helpers.REFRESH_THRESHOLD:
276
+ raise exceptions.RefreshError(
277
+ "The credentials returned by the refresh_handler are "
278
+ "already expired."
279
+ )
280
+ self.token = token
281
+ self.expiry = expiry
282
+ return
283
+
284
+ if (
285
+ self._refresh_token is None
286
+ or self._token_uri is None
287
+ or self._client_id is None
288
+ or self._client_secret is None
289
+ ):
290
+ raise exceptions.RefreshError(
291
+ "The credentials do not contain the necessary fields need to "
292
+ "refresh the access token. You must specify refresh_token, "
293
+ "token_uri, client_id, and client_secret."
294
+ )
295
+
296
+ (
297
+ access_token,
298
+ refresh_token,
299
+ expiry,
300
+ grant_response,
301
+ rapt_token,
302
+ ) = reauth.refresh_grant(
303
+ request,
304
+ self._token_uri,
305
+ self._refresh_token,
306
+ self._client_id,
307
+ self._client_secret,
308
+ scopes=scopes,
309
+ rapt_token=self._rapt_token,
310
+ enable_reauth_refresh=self._enable_reauth_refresh,
311
+ )
312
+
313
+ self.token = access_token
314
+ self.expiry = expiry
315
+ self._refresh_token = refresh_token
316
+ self._id_token = grant_response.get("id_token")
317
+ self._rapt_token = rapt_token
318
+
319
+ if scopes and "scope" in grant_response:
320
+ requested_scopes = frozenset(scopes)
321
+ granted_scopes = frozenset(grant_response["scope"].split())
322
+ scopes_requested_but_not_granted = requested_scopes - granted_scopes
323
+ if scopes_requested_but_not_granted:
324
+ raise exceptions.RefreshError(
325
+ "Not all requested scopes were granted by the "
326
+ "authorization server, missing scopes {}.".format(
327
+ ", ".join(scopes_requested_but_not_granted)
328
+ )
329
+ )
330
+
331
+ @classmethod
332
+ def from_authorized_user_info(cls, info, scopes=None):
333
+ """Creates a Credentials instance from parsed authorized user info.
334
+
335
+ Args:
336
+ info (Mapping[str, str]): The authorized user info in Google
337
+ format.
338
+ scopes (Sequence[str]): Optional list of scopes to include in the
339
+ credentials.
340
+
341
+ Returns:
342
+ google.oauth2.credentials.Credentials: The constructed
343
+ credentials.
344
+
345
+ Raises:
346
+ ValueError: If the info is not in the expected format.
347
+ """
348
+ keys_needed = set(("refresh_token", "client_id", "client_secret"))
349
+ missing = keys_needed.difference(six.iterkeys(info))
350
+
351
+ if missing:
352
+ raise ValueError(
353
+ "Authorized user info was not in the expected format, missing "
354
+ "fields {}.".format(", ".join(missing))
355
+ )
356
+
357
+ # access token expiry (datetime obj); auto-expire if not saved
358
+ expiry = info.get("expiry")
359
+ if expiry:
360
+ expiry = datetime.strptime(
361
+ expiry.rstrip("Z").split(".")[0], "%Y-%m-%dT%H:%M:%S"
362
+ )
363
+ else:
364
+ expiry = _helpers.utcnow() - _helpers.REFRESH_THRESHOLD
365
+
366
+ # process scopes, which needs to be a seq
367
+ if scopes is None and "scopes" in info:
368
+ scopes = info.get("scopes")
369
+ if isinstance(scopes, six.string_types):
370
+ scopes = scopes.split(" ")
371
+
372
+ return cls(
373
+ token=info.get("token"),
374
+ refresh_token=info.get("refresh_token"),
375
+ token_uri=_GOOGLE_OAUTH2_TOKEN_ENDPOINT, # always overrides
376
+ scopes=scopes,
377
+ client_id=info.get("client_id"),
378
+ client_secret=info.get("client_secret"),
379
+ quota_project_id=info.get("quota_project_id"), # may not exist
380
+ expiry=expiry,
381
+ rapt_token=info.get("rapt_token"), # may not exist
382
+ )
383
+
384
+ @classmethod
385
+ def from_authorized_user_file(cls, filename, scopes=None):
386
+ """Creates a Credentials instance from an authorized user json file.
387
+
388
+ Args:
389
+ filename (str): The path to the authorized user json file.
390
+ scopes (Sequence[str]): Optional list of scopes to include in the
391
+ credentials.
392
+
393
+ Returns:
394
+ google.oauth2.credentials.Credentials: The constructed
395
+ credentials.
396
+
397
+ Raises:
398
+ ValueError: If the file is not in the expected format.
399
+ """
400
+ with io.open(filename, "r", encoding="utf-8") as json_file:
401
+ data = json.load(json_file)
402
+ return cls.from_authorized_user_info(data, scopes)
403
+
404
+ def to_json(self, strip=None):
405
+ """Utility function that creates a JSON representation of a Credentials
406
+ object.
407
+
408
+ Args:
409
+ strip (Sequence[str]): Optional list of members to exclude from the
410
+ generated JSON.
411
+
412
+ Returns:
413
+ str: A JSON representation of this instance. When converted into
414
+ a dictionary, it can be passed to from_authorized_user_info()
415
+ to create a new credential instance.
416
+ """
417
+ prep = {
418
+ "token": self.token,
419
+ "refresh_token": self.refresh_token,
420
+ "token_uri": self.token_uri,
421
+ "client_id": self.client_id,
422
+ "client_secret": self.client_secret,
423
+ "scopes": self.scopes,
424
+ "rapt_token": self.rapt_token,
425
+ }
426
+ if self.expiry: # flatten expiry timestamp
427
+ prep["expiry"] = self.expiry.isoformat() + "Z"
428
+
429
+ # Remove empty entries (those which are None)
430
+ prep = {k: v for k, v in prep.items() if v is not None}
431
+
432
+ # Remove entries that explicitely need to be removed
433
+ if strip is not None:
434
+ prep = {k: v for k, v in prep.items() if k not in strip}
435
+
436
+ return json.dumps(prep)
437
+
438
+
439
+ class UserAccessTokenCredentials(credentials.CredentialsWithQuotaProject):
440
+ """Access token credentials for user account.
441
+
442
+ Obtain the access token for a given user account or the current active
443
+ user account with the ``gcloud auth print-access-token`` command.
444
+
445
+ Args:
446
+ account (Optional[str]): Account to get the access token for. If not
447
+ specified, the current active account will be used.
448
+ quota_project_id (Optional[str]): The project ID used for quota
449
+ and billing.
450
+ """
451
+
452
+ def __init__(self, account=None, quota_project_id=None):
453
+ super(UserAccessTokenCredentials, self).__init__()
454
+ self._account = account
455
+ self._quota_project_id = quota_project_id
456
+
457
+ def with_account(self, account):
458
+ """Create a new instance with the given account.
459
+
460
+ Args:
461
+ account (str): Account to get the access token for.
462
+
463
+ Returns:
464
+ google.oauth2.credentials.UserAccessTokenCredentials: The created
465
+ credentials with the given account.
466
+ """
467
+ return self.__class__(account=account, quota_project_id=self._quota_project_id)
468
+
469
+ @_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
470
+ def with_quota_project(self, quota_project_id):
471
+ return self.__class__(account=self._account, quota_project_id=quota_project_id)
472
+
473
+ def refresh(self, request):
474
+ """Refreshes the access token.
475
+
476
+ Args:
477
+ request (google.auth.transport.Request): This argument is required
478
+ by the base class interface but not used in this implementation,
479
+ so just set it to `None`.
480
+
481
+ Raises:
482
+ google.auth.exceptions.UserAccessTokenError: If the access token
483
+ refresh failed.
484
+ """
485
+ self.token = _cloud_sdk.get_auth_access_token(self._account)
486
+
487
+ @_helpers.copy_docstring(credentials.Credentials)
488
+ def before_request(self, request, method, url, headers):
489
+ self.refresh(request)
490
+ self.apply(headers)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/gdch_credentials.py ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2022 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Experimental GDCH credentials support.
16
+ """
17
+
18
+ import datetime
19
+
20
+ from google.auth import _helpers
21
+ from google.auth import _service_account_info
22
+ from google.auth import credentials
23
+ from google.auth import exceptions
24
+ from google.auth import jwt
25
+ from google.oauth2 import _client
26
+
27
+
28
+ TOKEN_EXCHANGE_TYPE = "urn:ietf:params:oauth:token-type:token-exchange"
29
+ ACCESS_TOKEN_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token"
30
+ SERVICE_ACCOUNT_TOKEN_TYPE = "urn:k8s:params:oauth:token-type:serviceaccount"
31
+ JWT_LIFETIME = datetime.timedelta(seconds=3600) # 1 hour
32
+
33
+
34
+ class ServiceAccountCredentials(credentials.Credentials):
35
+ """Credentials for GDCH (`Google Distributed Cloud Hosted`_) for service
36
+ account users.
37
+
38
+ .. _Google Distributed Cloud Hosted:
39
+ https://cloud.google.com/blog/topics/hybrid-cloud/\
40
+ announcing-google-distributed-cloud-edge-and-hosted
41
+
42
+ To create a GDCH service account credential, first create a JSON file of
43
+ the following format::
44
+
45
+ {
46
+ "type": "gdch_service_account",
47
+ "format_version": "1",
48
+ "project": "<project name>",
49
+ "private_key_id": "<key id>",
50
+ "private_key": "-----BEGIN EC PRIVATE KEY-----\n<key bytes>\n-----END EC PRIVATE KEY-----\n",
51
+ "name": "<service identity name>",
52
+ "ca_cert_path": "<CA cert path>",
53
+ "token_uri": "https://service-identity.<Domain>/authenticate"
54
+ }
55
+
56
+ The "format_version" field stands for the format of the JSON file. For now
57
+ it is always "1". The `private_key_id` and `private_key` is used for signing.
58
+ The `ca_cert_path` is used for token server TLS certificate verification.
59
+
60
+ After the JSON file is created, set `GOOGLE_APPLICATION_CREDENTIALS` environment
61
+ variable to the JSON file path, then use the following code to create the
62
+ credential::
63
+
64
+ import google.auth
65
+
66
+ credential, _ = google.auth.default()
67
+ credential = credential.with_gdch_audience("<the audience>")
68
+
69
+ We can also create the credential directly::
70
+
71
+ from google.oauth import gdch_credentials
72
+
73
+ credential = gdch_credentials.ServiceAccountCredentials.from_service_account_file("<the json file path>")
74
+ credential = credential.with_gdch_audience("<the audience>")
75
+
76
+ The token is obtained in the following way. This class first creates a
77
+ self signed JWT. It uses the `name` value as the `iss` and `sub` claim, and
78
+ the `token_uri` as the `aud` claim, and signs the JWT with the `private_key`.
79
+ It then sends the JWT to the `token_uri` to exchange a final token for
80
+ `audience`.
81
+ """
82
+
83
+ def __init__(
84
+ self, signer, service_identity_name, project, audience, token_uri, ca_cert_path
85
+ ):
86
+ """
87
+ Args:
88
+ signer (google.auth.crypt.Signer): The signer used to sign JWTs.
89
+ service_identity_name (str): The service identity name. It will be
90
+ used as the `iss` and `sub` claim in the self signed JWT.
91
+ project (str): The project.
92
+ audience (str): The audience for the final token.
93
+ token_uri (str): The token server uri.
94
+ ca_cert_path (str): The CA cert path for token server side TLS
95
+ certificate verification. If the token server uses well known
96
+ CA, then this parameter can be `None`.
97
+ """
98
+ super(ServiceAccountCredentials, self).__init__()
99
+ self._signer = signer
100
+ self._service_identity_name = service_identity_name
101
+ self._project = project
102
+ self._audience = audience
103
+ self._token_uri = token_uri
104
+ self._ca_cert_path = ca_cert_path
105
+
106
+ def _create_jwt(self):
107
+ now = _helpers.utcnow()
108
+ expiry = now + JWT_LIFETIME
109
+ iss_sub_value = "system:serviceaccount:{}:{}".format(
110
+ self._project, self._service_identity_name
111
+ )
112
+
113
+ payload = {
114
+ "iss": iss_sub_value,
115
+ "sub": iss_sub_value,
116
+ "aud": self._token_uri,
117
+ "iat": _helpers.datetime_to_secs(now),
118
+ "exp": _helpers.datetime_to_secs(expiry),
119
+ }
120
+
121
+ return _helpers.from_bytes(jwt.encode(self._signer, payload))
122
+
123
+ @_helpers.copy_docstring(credentials.Credentials)
124
+ def refresh(self, request):
125
+ import google.auth.transport.requests
126
+
127
+ if not isinstance(request, google.auth.transport.requests.Request):
128
+ raise exceptions.RefreshError(
129
+ "For GDCH service account credentials, request must be a google.auth.transport.requests.Request object"
130
+ )
131
+
132
+ # Create a self signed JWT, and do token exchange.
133
+ jwt_token = self._create_jwt()
134
+ request_body = {
135
+ "grant_type": TOKEN_EXCHANGE_TYPE,
136
+ "audience": self._audience,
137
+ "requested_token_type": ACCESS_TOKEN_TOKEN_TYPE,
138
+ "subject_token": jwt_token,
139
+ "subject_token_type": SERVICE_ACCOUNT_TOKEN_TYPE,
140
+ }
141
+ response_data = _client._token_endpoint_request(
142
+ request,
143
+ self._token_uri,
144
+ request_body,
145
+ access_token=None,
146
+ use_json=True,
147
+ verify=self._ca_cert_path,
148
+ )
149
+
150
+ self.token, _, self.expiry, _ = _client._handle_refresh_grant_response(
151
+ response_data, None
152
+ )
153
+
154
+ def with_gdch_audience(self, audience):
155
+ """Create a copy of GDCH credentials with the specified audience.
156
+
157
+ Args:
158
+ audience (str): The intended audience for GDCH credentials.
159
+ """
160
+ return self.__class__(
161
+ self._signer,
162
+ self._service_identity_name,
163
+ self._project,
164
+ audience,
165
+ self._token_uri,
166
+ self._ca_cert_path,
167
+ )
168
+
169
+ @classmethod
170
+ def _from_signer_and_info(cls, signer, info):
171
+ """Creates a Credentials instance from a signer and service account
172
+ info.
173
+
174
+ Args:
175
+ signer (google.auth.crypt.Signer): The signer used to sign JWTs.
176
+ info (Mapping[str, str]): The service account info.
177
+
178
+ Returns:
179
+ google.oauth2.gdch_credentials.ServiceAccountCredentials: The constructed
180
+ credentials.
181
+
182
+ Raises:
183
+ ValueError: If the info is not in the expected format.
184
+ """
185
+ if info["format_version"] != "1":
186
+ raise ValueError("Only format version 1 is supported")
187
+
188
+ return cls(
189
+ signer,
190
+ info["name"], # service_identity_name
191
+ info["project"],
192
+ None, # audience
193
+ info["token_uri"],
194
+ info.get("ca_cert_path", None),
195
+ )
196
+
197
+ @classmethod
198
+ def from_service_account_info(cls, info):
199
+ """Creates a Credentials instance from parsed service account info.
200
+
201
+ Args:
202
+ info (Mapping[str, str]): The service account info in Google
203
+ format.
204
+ kwargs: Additional arguments to pass to the constructor.
205
+
206
+ Returns:
207
+ google.oauth2.gdch_credentials.ServiceAccountCredentials: The constructed
208
+ credentials.
209
+
210
+ Raises:
211
+ ValueError: If the info is not in the expected format.
212
+ """
213
+ signer = _service_account_info.from_dict(
214
+ info,
215
+ require=[
216
+ "format_version",
217
+ "private_key_id",
218
+ "private_key",
219
+ "name",
220
+ "project",
221
+ "token_uri",
222
+ ],
223
+ use_rsa_signer=False,
224
+ )
225
+ return cls._from_signer_and_info(signer, info)
226
+
227
+ @classmethod
228
+ def from_service_account_file(cls, filename):
229
+ """Creates a Credentials instance from a service account json file.
230
+
231
+ Args:
232
+ filename (str): The path to the service account json file.
233
+ kwargs: Additional arguments to pass to the constructor.
234
+
235
+ Returns:
236
+ google.oauth2.gdch_credentials.ServiceAccountCredentials: The constructed
237
+ credentials.
238
+ """
239
+ info, signer = _service_account_info.from_filename(
240
+ filename,
241
+ require=[
242
+ "format_version",
243
+ "private_key_id",
244
+ "private_key",
245
+ "name",
246
+ "project",
247
+ "token_uri",
248
+ ],
249
+ use_rsa_signer=False,
250
+ )
251
+ return cls._from_signer_and_info(signer, info)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/oauth2/id_token.py ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2016 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Google ID Token helpers.
16
+
17
+ Provides support for verifying `OpenID Connect ID Tokens`_, especially ones
18
+ generated by Google infrastructure.
19
+
20
+ To parse and verify an ID Token issued by Google's OAuth 2.0 authorization
21
+ server use :func:`verify_oauth2_token`. To verify an ID Token issued by
22
+ Firebase, use :func:`verify_firebase_token`.
23
+
24
+ A general purpose ID Token verifier is available as :func:`verify_token`.
25
+
26
+ Example::
27
+
28
+ from google.oauth2 import id_token
29
+ from google.auth.transport import requests
30
+
31
+ request = requests.Request()
32
+
33
+ id_info = id_token.verify_oauth2_token(
34
+ token, request, 'my-client-id.example.com')
35
+
36
+ userid = id_info['sub']
37
+
38
+ By default, this will re-fetch certificates for each verification. Because
39
+ Google's public keys are only changed infrequently (on the order of once per
40
+ day), you may wish to take advantage of caching to reduce latency and the
41
+ potential for network errors. This can be accomplished using an external
42
+ library like `CacheControl`_ to create a cache-aware
43
+ :class:`google.auth.transport.Request`::
44
+
45
+ import cachecontrol
46
+ import google.auth.transport.requests
47
+ import requests
48
+
49
+ session = requests.session()
50
+ cached_session = cachecontrol.CacheControl(session)
51
+ request = google.auth.transport.requests.Request(session=cached_session)
52
+
53
+ .. _OpenID Connect ID Tokens:
54
+ http://openid.net/specs/openid-connect-core-1_0.html#IDToken
55
+ .. _CacheControl: https://cachecontrol.readthedocs.io
56
+ """
57
+
58
+ import json
59
+ import os
60
+
61
+ import six
62
+ from six.moves import http_client
63
+
64
+ from google.auth import environment_vars
65
+ from google.auth import exceptions
66
+ from google.auth import jwt
67
+ import google.auth.transport.requests
68
+
69
+
70
+ # The URL that provides public certificates for verifying ID tokens issued
71
+ # by Google's OAuth 2.0 authorization server.
72
+ _GOOGLE_OAUTH2_CERTS_URL = "https://www.googleapis.com/oauth2/v1/certs"
73
+
74
+ # The URL that provides public certificates for verifying ID tokens issued
75
+ # by Firebase and the Google APIs infrastructure
76
+ _GOOGLE_APIS_CERTS_URL = (
77
+ "https://www.googleapis.com/robot/v1/metadata/x509"
78
+ "/securetoken@system.gserviceaccount.com"
79
+ )
80
+
81
+ _GOOGLE_ISSUERS = ["accounts.google.com", "https://accounts.google.com"]
82
+
83
+
84
+ def _fetch_certs(request, certs_url):
85
+ """Fetches certificates.
86
+
87
+ Google-style cerificate endpoints return JSON in the format of
88
+ ``{'key id': 'x509 certificate'}``.
89
+
90
+ Args:
91
+ request (google.auth.transport.Request): The object used to make
92
+ HTTP requests.
93
+ certs_url (str): The certificate endpoint URL.
94
+
95
+ Returns:
96
+ Mapping[str, str]: A mapping of public key ID to x.509 certificate
97
+ data.
98
+ """
99
+ response = request(certs_url, method="GET")
100
+
101
+ if response.status != http_client.OK:
102
+ raise exceptions.TransportError(
103
+ "Could not fetch certificates at {}".format(certs_url)
104
+ )
105
+
106
+ return json.loads(response.data.decode("utf-8"))
107
+
108
+
109
+ def verify_token(
110
+ id_token,
111
+ request,
112
+ audience=None,
113
+ certs_url=_GOOGLE_OAUTH2_CERTS_URL,
114
+ clock_skew_in_seconds=0,
115
+ ):
116
+ """Verifies an ID token and returns the decoded token.
117
+
118
+ Args:
119
+ id_token (Union[str, bytes]): The encoded token.
120
+ request (google.auth.transport.Request): The object used to make
121
+ HTTP requests.
122
+ audience (str or list): The audience or audiences that this token is
123
+ intended for. If None then the audience is not verified.
124
+ certs_url (str): The URL that specifies the certificates to use to
125
+ verify the token. This URL should return JSON in the format of
126
+ ``{'key id': 'x509 certificate'}``.
127
+ clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
128
+ validation.
129
+
130
+ Returns:
131
+ Mapping[str, Any]: The decoded token.
132
+ """
133
+ certs = _fetch_certs(request, certs_url)
134
+
135
+ return jwt.decode(
136
+ id_token,
137
+ certs=certs,
138
+ audience=audience,
139
+ clock_skew_in_seconds=clock_skew_in_seconds,
140
+ )
141
+
142
+
143
+ def verify_oauth2_token(id_token, request, audience=None, clock_skew_in_seconds=0):
144
+ """Verifies an ID Token issued by Google's OAuth 2.0 authorization server.
145
+
146
+ Args:
147
+ id_token (Union[str, bytes]): The encoded token.
148
+ request (google.auth.transport.Request): The object used to make
149
+ HTTP requests.
150
+ audience (str): The audience that this token is intended for. This is
151
+ typically your application's OAuth 2.0 client ID. If None then the
152
+ audience is not verified.
153
+ clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
154
+ validation.
155
+
156
+ Returns:
157
+ Mapping[str, Any]: The decoded token.
158
+
159
+ Raises:
160
+ exceptions.GoogleAuthError: If the issuer is invalid.
161
+ ValueError: If token verification fails
162
+ """
163
+ idinfo = verify_token(
164
+ id_token,
165
+ request,
166
+ audience=audience,
167
+ certs_url=_GOOGLE_OAUTH2_CERTS_URL,
168
+ clock_skew_in_seconds=clock_skew_in_seconds,
169
+ )
170
+
171
+ if idinfo["iss"] not in _GOOGLE_ISSUERS:
172
+ raise exceptions.GoogleAuthError(
173
+ "Wrong issuer. 'iss' should be one of the following: {}".format(
174
+ _GOOGLE_ISSUERS
175
+ )
176
+ )
177
+
178
+ return idinfo
179
+
180
+
181
+ def verify_firebase_token(id_token, request, audience=None, clock_skew_in_seconds=0):
182
+ """Verifies an ID Token issued by Firebase Authentication.
183
+
184
+ Args:
185
+ id_token (Union[str, bytes]): The encoded token.
186
+ request (google.auth.transport.Request): The object used to make
187
+ HTTP requests.
188
+ audience (str): The audience that this token is intended for. This is
189
+ typically your Firebase application ID. If None then the audience
190
+ is not verified.
191
+ clock_skew_in_seconds (int): The clock skew used for `iat` and `exp`
192
+ validation.
193
+
194
+ Returns:
195
+ Mapping[str, Any]: The decoded token.
196
+ """
197
+ return verify_token(
198
+ id_token,
199
+ request,
200
+ audience=audience,
201
+ certs_url=_GOOGLE_APIS_CERTS_URL,
202
+ clock_skew_in_seconds=clock_skew_in_seconds,
203
+ )
204
+
205
+
206
+ def fetch_id_token_credentials(audience, request=None):
207
+ """Create the ID Token credentials from the current environment.
208
+
209
+ This function acquires ID token from the environment in the following order.
210
+ See https://google.aip.dev/auth/4110.
211
+
212
+ 1. If the environment variable ``GOOGLE_APPLICATION_CREDENTIALS`` is set
213
+ to the path of a valid service account JSON file, then ID token is
214
+ acquired using this service account credentials.
215
+ 2. If the application is running in Compute Engine, App Engine or Cloud Run,
216
+ then the ID token are obtained from the metadata server.
217
+ 3. If metadata server doesn't exist and no valid service account credentials
218
+ are found, :class:`~google.auth.exceptions.DefaultCredentialsError` will
219
+ be raised.
220
+
221
+ Example::
222
+
223
+ import google.oauth2.id_token
224
+ import google.auth.transport.requests
225
+
226
+ request = google.auth.transport.requests.Request()
227
+ target_audience = "https://pubsub.googleapis.com"
228
+
229
+ # Create ID token credentials.
230
+ credentials = google.oauth2.id_token.fetch_id_token_credentials(target_audience, request=request)
231
+
232
+ # Refresh the credential to obtain an ID token.
233
+ credentials.refresh(request)
234
+
235
+ id_token = credentials.token
236
+ id_token_expiry = credentials.expiry
237
+
238
+ Args:
239
+ audience (str): The audience that this ID token is intended for.
240
+ request (Optional[google.auth.transport.Request]): A callable used to make
241
+ HTTP requests. A request object will be created if not provided.
242
+
243
+ Returns:
244
+ google.auth.credentials.Credentials: The ID token credentials.
245
+
246
+ Raises:
247
+ ~google.auth.exceptions.DefaultCredentialsError:
248
+ If metadata server doesn't exist and no valid service account
249
+ credentials are found.
250
+ """
251
+ # 1. Try to get credentials from the GOOGLE_APPLICATION_CREDENTIALS environment
252
+ # variable.
253
+ credentials_filename = os.environ.get(environment_vars.CREDENTIALS)
254
+ if credentials_filename:
255
+ if not (
256
+ os.path.exists(credentials_filename)
257
+ and os.path.isfile(credentials_filename)
258
+ ):
259
+ raise exceptions.DefaultCredentialsError(
260
+ "GOOGLE_APPLICATION_CREDENTIALS path is either not found or invalid."
261
+ )
262
+
263
+ try:
264
+ with open(credentials_filename, "r") as f:
265
+ from google.oauth2 import service_account
266
+
267
+ info = json.load(f)
268
+ if info.get("type") == "service_account":
269
+ return service_account.IDTokenCredentials.from_service_account_info(
270
+ info, target_audience=audience
271
+ )
272
+ except ValueError as caught_exc:
273
+ new_exc = exceptions.DefaultCredentialsError(
274
+ "GOOGLE_APPLICATION_CREDENTIALS is not valid service account credentials.",
275
+ caught_exc,
276
+ )
277
+ six.raise_from(new_exc, caught_exc)
278
+
279
+ # 2. Try to fetch ID token from metada server if it exists. The code
280
+ # works for GAE and Cloud Run metadata server as well.
281
+ try:
282
+ from google.auth import compute_engine
283
+ from google.auth.compute_engine import _metadata
284
+
285
+ # Create a request object if not provided.
286
+ if not request:
287
+ request = google.auth.transport.requests.Request()
288
+
289
+ if _metadata.ping(request):
290
+ return compute_engine.IDTokenCredentials(
291
+ request, audience, use_metadata_identity_endpoint=True
292
+ )
293
+ except (ImportError, exceptions.TransportError):
294
+ pass
295
+
296
+ raise exceptions.DefaultCredentialsError(
297
+ "Neither metadata server or valid service account credentials are found."
298
+ )
299
+
300
+
301
+ def fetch_id_token(request, audience):
302
+ """Fetch the ID Token from the current environment.
303
+
304
+ This function acquires ID token from the environment in the following order.
305
+ See https://google.aip.dev/auth/4110.
306
+
307
+ 1. If the environment variable ``GOOGLE_APPLICATION_CREDENTIALS`` is set
308
+ to the path of a valid service account JSON file, then ID token is
309
+ acquired using this service account credentials.
310
+ 2. If the application is running in Compute Engine, App Engine or Cloud Run,
311
+ then the ID token are obtained from the metadata server.
312
+ 3. If metadata server doesn't exist and no valid service account credentials
313
+ are found, :class:`~google.auth.exceptions.DefaultCredentialsError` will
314
+ be raised.
315
+
316
+ Example::
317
+
318
+ import google.oauth2.id_token
319
+ import google.auth.transport.requests
320
+
321
+ request = google.auth.transport.requests.Request()
322
+ target_audience = "https://pubsub.googleapis.com"
323
+
324
+ id_token = google.oauth2.id_token.fetch_id_token(request, target_audience)
325
+
326
+ Args:
327
+ request (google.auth.transport.Request): A callable used to make
328
+ HTTP requests.
329
+ audience (str): The audience that this ID token is intended for.
330
+
331
+ Returns:
332
+ str: The ID token.
333
+
334
+ Raises:
335
+ ~google.auth.exceptions.DefaultCredentialsError:
336
+ If metadata server doesn't exist and no valid service account
337
+ credentials are found.
338
+ """
339
+ id_token_credentials = fetch_id_token_credentials(audience, request=request)
340
+ id_token_credentials.refresh(request)
341
+ return id_token_credentials.token
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/descriptor.cpython-38.pyc ADDED
Binary file (36.8 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/descriptor_pb2.cpython-38.pyc ADDED
Binary file (34.5 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/field_mask_pb2.cpython-38.pyc ADDED
Binary file (1.2 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/message.cpython-38.pyc ADDED
Binary file (13 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/service_reflection.cpython-38.pyc ADDED
Binary file (10.5 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/source_context_pb2.cpython-38.pyc ADDED
Binary file (1.23 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/timestamp_pb2.cpython-38.pyc ADDED
Binary file (1.21 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/__pycache__/type_pb2.cpython-38.pyc ADDED
Binary file (2.94 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/compiler/__init__.py ADDED
File without changes
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/compiler/plugin_pb2.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: google/protobuf/compiler/plugin.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+ from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
15
+
16
+
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"F\n\x07Version\x12\r\n\x05major\x18\x01 \x01(\x05\x12\r\n\x05minor\x18\x02 \x01(\x05\x12\r\n\x05patch\x18\x03 \x01(\x05\x12\x0e\n\x06suffix\x18\x04 \x01(\t\"\xba\x01\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12;\n\x10\x63ompiler_version\x18\x03 \x01(\x0b\x32!.google.protobuf.compiler.Version\"\xc1\x02\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x1a\n\x12supported_features\x18\x02 \x01(\x04\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a\x7f\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\t\x12?\n\x13generated_code_info\x18\x10 \x01(\x0b\x32\".google.protobuf.GeneratedCodeInfo\"8\n\x07\x46\x65\x61ture\x12\x10\n\x0c\x46\x45\x41TURE_NONE\x10\x00\x12\x1b\n\x17\x46\x45\x41TURE_PROTO3_OPTIONAL\x10\x01\x42W\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtosZ)google.golang.org/protobuf/types/pluginpb')
18
+
19
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
20
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.compiler.plugin_pb2', globals())
21
+ if _descriptor._USE_C_DESCRIPTORS == False:
22
+
23
+ DESCRIPTOR._options = None
24
+ DESCRIPTOR._serialized_options = b'\n\034com.google.protobuf.compilerB\014PluginProtosZ)google.golang.org/protobuf/types/pluginpb'
25
+ _VERSION._serialized_start=101
26
+ _VERSION._serialized_end=171
27
+ _CODEGENERATORREQUEST._serialized_start=174
28
+ _CODEGENERATORREQUEST._serialized_end=360
29
+ _CODEGENERATORRESPONSE._serialized_start=363
30
+ _CODEGENERATORRESPONSE._serialized_end=684
31
+ _CODEGENERATORRESPONSE_FILE._serialized_start=499
32
+ _CODEGENERATORRESPONSE_FILE._serialized_end=626
33
+ _CODEGENERATORRESPONSE_FEATURE._serialized_start=628
34
+ _CODEGENERATORRESPONSE_FEATURE._serialized_end=684
35
+ # @@protoc_insertion_point(module_scope)
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/internal/_api_implementation.cpython-38-x86_64-linux-gnu.so ADDED
Binary file (5.5 kB). View file
 
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/internal/builder.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2008 Google Inc. All rights reserved.
3
+ # https://developers.google.com/protocol-buffers/
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ """Builds descriptors, message classes and services for generated _pb2.py.
32
+
33
+ This file is only called in python generated _pb2.py files. It builds
34
+ descriptors, message classes and services that users can directly use
35
+ in generated code.
36
+ """
37
+
38
+ __author__ = 'jieluo@google.com (Jie Luo)'
39
+
40
+ from google.protobuf.internal import enum_type_wrapper
41
+ from google.protobuf import message as _message
42
+ from google.protobuf import reflection as _reflection
43
+ from google.protobuf import symbol_database as _symbol_database
44
+
45
+ _sym_db = _symbol_database.Default()
46
+
47
+
48
+ def BuildMessageAndEnumDescriptors(file_des, module):
49
+ """Builds message and enum descriptors.
50
+
51
+ Args:
52
+ file_des: FileDescriptor of the .proto file
53
+ module: Generated _pb2 module
54
+ """
55
+
56
+ def BuildNestedDescriptors(msg_des, prefix):
57
+ for (name, nested_msg) in msg_des.nested_types_by_name.items():
58
+ module_name = prefix + name.upper()
59
+ module[module_name] = nested_msg
60
+ BuildNestedDescriptors(nested_msg, module_name + '_')
61
+ for enum_des in msg_des.enum_types:
62
+ module[prefix + enum_des.name.upper()] = enum_des
63
+
64
+ for (name, msg_des) in file_des.message_types_by_name.items():
65
+ module_name = '_' + name.upper()
66
+ module[module_name] = msg_des
67
+ BuildNestedDescriptors(msg_des, module_name + '_')
68
+
69
+
70
+ def BuildTopDescriptorsAndMessages(file_des, module_name, module):
71
+ """Builds top level descriptors and message classes.
72
+
73
+ Args:
74
+ file_des: FileDescriptor of the .proto file
75
+ module_name: str, the name of generated _pb2 module
76
+ module: Generated _pb2 module
77
+ """
78
+
79
+ def BuildMessage(msg_des):
80
+ create_dict = {}
81
+ for (name, nested_msg) in msg_des.nested_types_by_name.items():
82
+ create_dict[name] = BuildMessage(nested_msg)
83
+ create_dict['DESCRIPTOR'] = msg_des
84
+ create_dict['__module__'] = module_name
85
+ message_class = _reflection.GeneratedProtocolMessageType(
86
+ msg_des.name, (_message.Message,), create_dict)
87
+ _sym_db.RegisterMessage(message_class)
88
+ return message_class
89
+
90
+ # top level enums
91
+ for (name, enum_des) in file_des.enum_types_by_name.items():
92
+ module['_' + name.upper()] = enum_des
93
+ module[name] = enum_type_wrapper.EnumTypeWrapper(enum_des)
94
+ for enum_value in enum_des.values:
95
+ module[enum_value.name] = enum_value.number
96
+
97
+ # top level extensions
98
+ for (name, extension_des) in file_des.extensions_by_name.items():
99
+ module[name.upper() + '_FIELD_NUMBER'] = extension_des.number
100
+ module[name] = extension_des
101
+
102
+ # services
103
+ for (name, service) in file_des.services_by_name.items():
104
+ module['_' + name.upper()] = service
105
+
106
+ # Build messages.
107
+ for (name, msg_des) in file_des.message_types_by_name.items():
108
+ module[name] = BuildMessage(msg_des)
109
+
110
+
111
+ def BuildServices(file_des, module_name, module):
112
+ """Builds services classes and services stub class.
113
+
114
+ Args:
115
+ file_des: FileDescriptor of the .proto file
116
+ module_name: str, the name of generated _pb2 module
117
+ module: Generated _pb2 module
118
+ """
119
+ # pylint: disable=g-import-not-at-top
120
+ from google.protobuf import service as _service
121
+ from google.protobuf import service_reflection
122
+ # pylint: enable=g-import-not-at-top
123
+ for (name, service) in file_des.services_by_name.items():
124
+ module[name] = service_reflection.GeneratedServiceType(
125
+ name, (_service.Service,),
126
+ dict(DESCRIPTOR=service, __module__=module_name))
127
+ stub_name = name + '_Stub'
128
+ module[stub_name] = service_reflection.GeneratedServiceStubType(
129
+ stub_name, (module[name],),
130
+ dict(DESCRIPTOR=service, __module__=module_name))
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/internal/containers.py ADDED
@@ -0,0 +1,710 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2008 Google Inc. All rights reserved.
3
+ # https://developers.google.com/protocol-buffers/
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ """Contains container classes to represent different protocol buffer types.
32
+
33
+ This file defines container classes which represent categories of protocol
34
+ buffer field types which need extra maintenance. Currently these categories
35
+ are:
36
+
37
+ - Repeated scalar fields - These are all repeated fields which aren't
38
+ composite (e.g. they are of simple types like int32, string, etc).
39
+ - Repeated composite fields - Repeated fields which are composite. This
40
+ includes groups and nested messages.
41
+ """
42
+
43
+ import collections.abc
44
+ import copy
45
+ import pickle
46
+ from typing import (
47
+ Any,
48
+ Iterable,
49
+ Iterator,
50
+ List,
51
+ MutableMapping,
52
+ MutableSequence,
53
+ NoReturn,
54
+ Optional,
55
+ Sequence,
56
+ TypeVar,
57
+ Union,
58
+ overload,
59
+ )
60
+
61
+
62
+ _T = TypeVar('_T')
63
+ _K = TypeVar('_K')
64
+ _V = TypeVar('_V')
65
+
66
+
67
+ class BaseContainer(Sequence[_T]):
68
+ """Base container class."""
69
+
70
+ # Minimizes memory usage and disallows assignment to other attributes.
71
+ __slots__ = ['_message_listener', '_values']
72
+
73
+ def __init__(self, message_listener: Any) -> None:
74
+ """
75
+ Args:
76
+ message_listener: A MessageListener implementation.
77
+ The RepeatedScalarFieldContainer will call this object's
78
+ Modified() method when it is modified.
79
+ """
80
+ self._message_listener = message_listener
81
+ self._values = []
82
+
83
+ @overload
84
+ def __getitem__(self, key: int) -> _T:
85
+ ...
86
+
87
+ @overload
88
+ def __getitem__(self, key: slice) -> List[_T]:
89
+ ...
90
+
91
+ def __getitem__(self, key):
92
+ """Retrieves item by the specified key."""
93
+ return self._values[key]
94
+
95
+ def __len__(self) -> int:
96
+ """Returns the number of elements in the container."""
97
+ return len(self._values)
98
+
99
+ def __ne__(self, other: Any) -> bool:
100
+ """Checks if another instance isn't equal to this one."""
101
+ # The concrete classes should define __eq__.
102
+ return not self == other
103
+
104
+ __hash__ = None
105
+
106
+ def __repr__(self) -> str:
107
+ return repr(self._values)
108
+
109
+ def sort(self, *args, **kwargs) -> None:
110
+ # Continue to support the old sort_function keyword argument.
111
+ # This is expected to be a rare occurrence, so use LBYL to avoid
112
+ # the overhead of actually catching KeyError.
113
+ if 'sort_function' in kwargs:
114
+ kwargs['cmp'] = kwargs.pop('sort_function')
115
+ self._values.sort(*args, **kwargs)
116
+
117
+ def reverse(self) -> None:
118
+ self._values.reverse()
119
+
120
+
121
+ # TODO(slebedev): Remove this. BaseContainer does *not* conform to
122
+ # MutableSequence, only its subclasses do.
123
+ collections.abc.MutableSequence.register(BaseContainer)
124
+
125
+
126
+ class RepeatedScalarFieldContainer(BaseContainer[_T], MutableSequence[_T]):
127
+ """Simple, type-checked, list-like container for holding repeated scalars."""
128
+
129
+ # Disallows assignment to other attributes.
130
+ __slots__ = ['_type_checker']
131
+
132
+ def __init__(
133
+ self,
134
+ message_listener: Any,
135
+ type_checker: Any,
136
+ ) -> None:
137
+ """Args:
138
+
139
+ message_listener: A MessageListener implementation. The
140
+ RepeatedScalarFieldContainer will call this object's Modified() method
141
+ when it is modified.
142
+ type_checker: A type_checkers.ValueChecker instance to run on elements
143
+ inserted into this container.
144
+ """
145
+ super().__init__(message_listener)
146
+ self._type_checker = type_checker
147
+
148
+ def append(self, value: _T) -> None:
149
+ """Appends an item to the list. Similar to list.append()."""
150
+ self._values.append(self._type_checker.CheckValue(value))
151
+ if not self._message_listener.dirty:
152
+ self._message_listener.Modified()
153
+
154
+ def insert(self, key: int, value: _T) -> None:
155
+ """Inserts the item at the specified position. Similar to list.insert()."""
156
+ self._values.insert(key, self._type_checker.CheckValue(value))
157
+ if not self._message_listener.dirty:
158
+ self._message_listener.Modified()
159
+
160
+ def extend(self, elem_seq: Iterable[_T]) -> None:
161
+ """Extends by appending the given iterable. Similar to list.extend()."""
162
+ if elem_seq is None:
163
+ return
164
+ try:
165
+ elem_seq_iter = iter(elem_seq)
166
+ except TypeError:
167
+ if not elem_seq:
168
+ # silently ignore falsy inputs :-/.
169
+ # TODO(ptucker): Deprecate this behavior. b/18413862
170
+ return
171
+ raise
172
+
173
+ new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter]
174
+ if new_values:
175
+ self._values.extend(new_values)
176
+ self._message_listener.Modified()
177
+
178
+ def MergeFrom(
179
+ self,
180
+ other: Union['RepeatedScalarFieldContainer[_T]', Iterable[_T]],
181
+ ) -> None:
182
+ """Appends the contents of another repeated field of the same type to this
183
+ one. We do not check the types of the individual fields.
184
+ """
185
+ self._values.extend(other)
186
+ self._message_listener.Modified()
187
+
188
+ def remove(self, elem: _T):
189
+ """Removes an item from the list. Similar to list.remove()."""
190
+ self._values.remove(elem)
191
+ self._message_listener.Modified()
192
+
193
+ def pop(self, key: Optional[int] = -1) -> _T:
194
+ """Removes and returns an item at a given index. Similar to list.pop()."""
195
+ value = self._values[key]
196
+ self.__delitem__(key)
197
+ return value
198
+
199
+ @overload
200
+ def __setitem__(self, key: int, value: _T) -> None:
201
+ ...
202
+
203
+ @overload
204
+ def __setitem__(self, key: slice, value: Iterable[_T]) -> None:
205
+ ...
206
+
207
+ def __setitem__(self, key, value) -> None:
208
+ """Sets the item on the specified position."""
209
+ if isinstance(key, slice):
210
+ if key.step is not None:
211
+ raise ValueError('Extended slices not supported')
212
+ self._values[key] = map(self._type_checker.CheckValue, value)
213
+ self._message_listener.Modified()
214
+ else:
215
+ self._values[key] = self._type_checker.CheckValue(value)
216
+ self._message_listener.Modified()
217
+
218
+ def __delitem__(self, key: Union[int, slice]) -> None:
219
+ """Deletes the item at the specified position."""
220
+ del self._values[key]
221
+ self._message_listener.Modified()
222
+
223
+ def __eq__(self, other: Any) -> bool:
224
+ """Compares the current instance with another one."""
225
+ if self is other:
226
+ return True
227
+ # Special case for the same type which should be common and fast.
228
+ if isinstance(other, self.__class__):
229
+ return other._values == self._values
230
+ # We are presumably comparing against some other sequence type.
231
+ return other == self._values
232
+
233
+ def __deepcopy__(
234
+ self,
235
+ unused_memo: Any = None,
236
+ ) -> 'RepeatedScalarFieldContainer[_T]':
237
+ clone = RepeatedScalarFieldContainer(
238
+ copy.deepcopy(self._message_listener), self._type_checker)
239
+ clone.MergeFrom(self)
240
+ return clone
241
+
242
+ def __reduce__(self, **kwargs) -> NoReturn:
243
+ raise pickle.PickleError(
244
+ "Can't pickle repeated scalar fields, convert to list first")
245
+
246
+
247
+ # TODO(slebedev): Constrain T to be a subtype of Message.
248
+ class RepeatedCompositeFieldContainer(BaseContainer[_T], MutableSequence[_T]):
249
+ """Simple, list-like container for holding repeated composite fields."""
250
+
251
+ # Disallows assignment to other attributes.
252
+ __slots__ = ['_message_descriptor']
253
+
254
+ def __init__(self, message_listener: Any, message_descriptor: Any) -> None:
255
+ """
256
+ Note that we pass in a descriptor instead of the generated directly,
257
+ since at the time we construct a _RepeatedCompositeFieldContainer we
258
+ haven't yet necessarily initialized the type that will be contained in the
259
+ container.
260
+
261
+ Args:
262
+ message_listener: A MessageListener implementation.
263
+ The RepeatedCompositeFieldContainer will call this object's
264
+ Modified() method when it is modified.
265
+ message_descriptor: A Descriptor instance describing the protocol type
266
+ that should be present in this container. We'll use the
267
+ _concrete_class field of this descriptor when the client calls add().
268
+ """
269
+ super().__init__(message_listener)
270
+ self._message_descriptor = message_descriptor
271
+
272
+ def add(self, **kwargs: Any) -> _T:
273
+ """Adds a new element at the end of the list and returns it. Keyword
274
+ arguments may be used to initialize the element.
275
+ """
276
+ new_element = self._message_descriptor._concrete_class(**kwargs)
277
+ new_element._SetListener(self._message_listener)
278
+ self._values.append(new_element)
279
+ if not self._message_listener.dirty:
280
+ self._message_listener.Modified()
281
+ return new_element
282
+
283
+ def append(self, value: _T) -> None:
284
+ """Appends one element by copying the message."""
285
+ new_element = self._message_descriptor._concrete_class()
286
+ new_element._SetListener(self._message_listener)
287
+ new_element.CopyFrom(value)
288
+ self._values.append(new_element)
289
+ if not self._message_listener.dirty:
290
+ self._message_listener.Modified()
291
+
292
+ def insert(self, key: int, value: _T) -> None:
293
+ """Inserts the item at the specified position by copying."""
294
+ new_element = self._message_descriptor._concrete_class()
295
+ new_element._SetListener(self._message_listener)
296
+ new_element.CopyFrom(value)
297
+ self._values.insert(key, new_element)
298
+ if not self._message_listener.dirty:
299
+ self._message_listener.Modified()
300
+
301
+ def extend(self, elem_seq: Iterable[_T]) -> None:
302
+ """Extends by appending the given sequence of elements of the same type
303
+
304
+ as this one, copying each individual message.
305
+ """
306
+ message_class = self._message_descriptor._concrete_class
307
+ listener = self._message_listener
308
+ values = self._values
309
+ for message in elem_seq:
310
+ new_element = message_class()
311
+ new_element._SetListener(listener)
312
+ new_element.MergeFrom(message)
313
+ values.append(new_element)
314
+ listener.Modified()
315
+
316
+ def MergeFrom(
317
+ self,
318
+ other: Union['RepeatedCompositeFieldContainer[_T]', Iterable[_T]],
319
+ ) -> None:
320
+ """Appends the contents of another repeated field of the same type to this
321
+ one, copying each individual message.
322
+ """
323
+ self.extend(other)
324
+
325
+ def remove(self, elem: _T) -> None:
326
+ """Removes an item from the list. Similar to list.remove()."""
327
+ self._values.remove(elem)
328
+ self._message_listener.Modified()
329
+
330
+ def pop(self, key: Optional[int] = -1) -> _T:
331
+ """Removes and returns an item at a given index. Similar to list.pop()."""
332
+ value = self._values[key]
333
+ self.__delitem__(key)
334
+ return value
335
+
336
+ @overload
337
+ def __setitem__(self, key: int, value: _T) -> None:
338
+ ...
339
+
340
+ @overload
341
+ def __setitem__(self, key: slice, value: Iterable[_T]) -> None:
342
+ ...
343
+
344
+ def __setitem__(self, key, value):
345
+ # This method is implemented to make RepeatedCompositeFieldContainer
346
+ # structurally compatible with typing.MutableSequence. It is
347
+ # otherwise unsupported and will always raise an error.
348
+ raise TypeError(
349
+ f'{self.__class__.__name__} object does not support item assignment')
350
+
351
+ def __delitem__(self, key: Union[int, slice]) -> None:
352
+ """Deletes the item at the specified position."""
353
+ del self._values[key]
354
+ self._message_listener.Modified()
355
+
356
+ def __eq__(self, other: Any) -> bool:
357
+ """Compares the current instance with another one."""
358
+ if self is other:
359
+ return True
360
+ if not isinstance(other, self.__class__):
361
+ raise TypeError('Can only compare repeated composite fields against '
362
+ 'other repeated composite fields.')
363
+ return self._values == other._values
364
+
365
+
366
+ class ScalarMap(MutableMapping[_K, _V]):
367
+ """Simple, type-checked, dict-like container for holding repeated scalars."""
368
+
369
+ # Disallows assignment to other attributes.
370
+ __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener',
371
+ '_entry_descriptor']
372
+
373
+ def __init__(
374
+ self,
375
+ message_listener: Any,
376
+ key_checker: Any,
377
+ value_checker: Any,
378
+ entry_descriptor: Any,
379
+ ) -> None:
380
+ """
381
+ Args:
382
+ message_listener: A MessageListener implementation.
383
+ The ScalarMap will call this object's Modified() method when it
384
+ is modified.
385
+ key_checker: A type_checkers.ValueChecker instance to run on keys
386
+ inserted into this container.
387
+ value_checker: A type_checkers.ValueChecker instance to run on values
388
+ inserted into this container.
389
+ entry_descriptor: The MessageDescriptor of a map entry: key and value.
390
+ """
391
+ self._message_listener = message_listener
392
+ self._key_checker = key_checker
393
+ self._value_checker = value_checker
394
+ self._entry_descriptor = entry_descriptor
395
+ self._values = {}
396
+
397
+ def __getitem__(self, key: _K) -> _V:
398
+ try:
399
+ return self._values[key]
400
+ except KeyError:
401
+ key = self._key_checker.CheckValue(key)
402
+ val = self._value_checker.DefaultValue()
403
+ self._values[key] = val
404
+ return val
405
+
406
+ def __contains__(self, item: _K) -> bool:
407
+ # We check the key's type to match the strong-typing flavor of the API.
408
+ # Also this makes it easier to match the behavior of the C++ implementation.
409
+ self._key_checker.CheckValue(item)
410
+ return item in self._values
411
+
412
+ @overload
413
+ def get(self, key: _K) -> Optional[_V]:
414
+ ...
415
+
416
+ @overload
417
+ def get(self, key: _K, default: _T) -> Union[_V, _T]:
418
+ ...
419
+
420
+ # We need to override this explicitly, because our defaultdict-like behavior
421
+ # will make the default implementation (from our base class) always insert
422
+ # the key.
423
+ def get(self, key, default=None):
424
+ if key in self:
425
+ return self[key]
426
+ else:
427
+ return default
428
+
429
+ def __setitem__(self, key: _K, value: _V) -> _T:
430
+ checked_key = self._key_checker.CheckValue(key)
431
+ checked_value = self._value_checker.CheckValue(value)
432
+ self._values[checked_key] = checked_value
433
+ self._message_listener.Modified()
434
+
435
+ def __delitem__(self, key: _K) -> None:
436
+ del self._values[key]
437
+ self._message_listener.Modified()
438
+
439
+ def __len__(self) -> int:
440
+ return len(self._values)
441
+
442
+ def __iter__(self) -> Iterator[_K]:
443
+ return iter(self._values)
444
+
445
+ def __repr__(self) -> str:
446
+ return repr(self._values)
447
+
448
+ def MergeFrom(self, other: 'ScalarMap[_K, _V]') -> None:
449
+ self._values.update(other._values)
450
+ self._message_listener.Modified()
451
+
452
+ def InvalidateIterators(self) -> None:
453
+ # It appears that the only way to reliably invalidate iterators to
454
+ # self._values is to ensure that its size changes.
455
+ original = self._values
456
+ self._values = original.copy()
457
+ original[None] = None
458
+
459
+ # This is defined in the abstract base, but we can do it much more cheaply.
460
+ def clear(self) -> None:
461
+ self._values.clear()
462
+ self._message_listener.Modified()
463
+
464
+ def GetEntryClass(self) -> Any:
465
+ return self._entry_descriptor._concrete_class
466
+
467
+
468
+ class MessageMap(MutableMapping[_K, _V]):
469
+ """Simple, type-checked, dict-like container for with submessage values."""
470
+
471
+ # Disallows assignment to other attributes.
472
+ __slots__ = ['_key_checker', '_values', '_message_listener',
473
+ '_message_descriptor', '_entry_descriptor']
474
+
475
+ def __init__(
476
+ self,
477
+ message_listener: Any,
478
+ message_descriptor: Any,
479
+ key_checker: Any,
480
+ entry_descriptor: Any,
481
+ ) -> None:
482
+ """
483
+ Args:
484
+ message_listener: A MessageListener implementation.
485
+ The ScalarMap will call this object's Modified() method when it
486
+ is modified.
487
+ key_checker: A type_checkers.ValueChecker instance to run on keys
488
+ inserted into this container.
489
+ value_checker: A type_checkers.ValueChecker instance to run on values
490
+ inserted into this container.
491
+ entry_descriptor: The MessageDescriptor of a map entry: key and value.
492
+ """
493
+ self._message_listener = message_listener
494
+ self._message_descriptor = message_descriptor
495
+ self._key_checker = key_checker
496
+ self._entry_descriptor = entry_descriptor
497
+ self._values = {}
498
+
499
+ def __getitem__(self, key: _K) -> _V:
500
+ key = self._key_checker.CheckValue(key)
501
+ try:
502
+ return self._values[key]
503
+ except KeyError:
504
+ new_element = self._message_descriptor._concrete_class()
505
+ new_element._SetListener(self._message_listener)
506
+ self._values[key] = new_element
507
+ self._message_listener.Modified()
508
+ return new_element
509
+
510
+ def get_or_create(self, key: _K) -> _V:
511
+ """get_or_create() is an alias for getitem (ie. map[key]).
512
+
513
+ Args:
514
+ key: The key to get or create in the map.
515
+
516
+ This is useful in cases where you want to be explicit that the call is
517
+ mutating the map. This can avoid lint errors for statements like this
518
+ that otherwise would appear to be pointless statements:
519
+
520
+ msg.my_map[key]
521
+ """
522
+ return self[key]
523
+
524
+ @overload
525
+ def get(self, key: _K) -> Optional[_V]:
526
+ ...
527
+
528
+ @overload
529
+ def get(self, key: _K, default: _T) -> Union[_V, _T]:
530
+ ...
531
+
532
+ # We need to override this explicitly, because our defaultdict-like behavior
533
+ # will make the default implementation (from our base class) always insert
534
+ # the key.
535
+ def get(self, key, default=None):
536
+ if key in self:
537
+ return self[key]
538
+ else:
539
+ return default
540
+
541
+ def __contains__(self, item: _K) -> bool:
542
+ item = self._key_checker.CheckValue(item)
543
+ return item in self._values
544
+
545
+ def __setitem__(self, key: _K, value: _V) -> NoReturn:
546
+ raise ValueError('May not set values directly, call my_map[key].foo = 5')
547
+
548
+ def __delitem__(self, key: _K) -> None:
549
+ key = self._key_checker.CheckValue(key)
550
+ del self._values[key]
551
+ self._message_listener.Modified()
552
+
553
+ def __len__(self) -> int:
554
+ return len(self._values)
555
+
556
+ def __iter__(self) -> Iterator[_K]:
557
+ return iter(self._values)
558
+
559
+ def __repr__(self) -> str:
560
+ return repr(self._values)
561
+
562
+ def MergeFrom(self, other: 'MessageMap[_K, _V]') -> None:
563
+ # pylint: disable=protected-access
564
+ for key in other._values:
565
+ # According to documentation: "When parsing from the wire or when merging,
566
+ # if there are duplicate map keys the last key seen is used".
567
+ if key in self:
568
+ del self[key]
569
+ self[key].CopyFrom(other[key])
570
+ # self._message_listener.Modified() not required here, because
571
+ # mutations to submessages already propagate.
572
+
573
+ def InvalidateIterators(self) -> None:
574
+ # It appears that the only way to reliably invalidate iterators to
575
+ # self._values is to ensure that its size changes.
576
+ original = self._values
577
+ self._values = original.copy()
578
+ original[None] = None
579
+
580
+ # This is defined in the abstract base, but we can do it much more cheaply.
581
+ def clear(self) -> None:
582
+ self._values.clear()
583
+ self._message_listener.Modified()
584
+
585
+ def GetEntryClass(self) -> Any:
586
+ return self._entry_descriptor._concrete_class
587
+
588
+
589
+ class _UnknownField:
590
+ """A parsed unknown field."""
591
+
592
+ # Disallows assignment to other attributes.
593
+ __slots__ = ['_field_number', '_wire_type', '_data']
594
+
595
+ def __init__(self, field_number, wire_type, data):
596
+ self._field_number = field_number
597
+ self._wire_type = wire_type
598
+ self._data = data
599
+ return
600
+
601
+ def __lt__(self, other):
602
+ # pylint: disable=protected-access
603
+ return self._field_number < other._field_number
604
+
605
+ def __eq__(self, other):
606
+ if self is other:
607
+ return True
608
+ # pylint: disable=protected-access
609
+ return (self._field_number == other._field_number and
610
+ self._wire_type == other._wire_type and
611
+ self._data == other._data)
612
+
613
+
614
+ class UnknownFieldRef: # pylint: disable=missing-class-docstring
615
+
616
+ def __init__(self, parent, index):
617
+ self._parent = parent
618
+ self._index = index
619
+
620
+ def _check_valid(self):
621
+ if not self._parent:
622
+ raise ValueError('UnknownField does not exist. '
623
+ 'The parent message might be cleared.')
624
+ if self._index >= len(self._parent):
625
+ raise ValueError('UnknownField does not exist. '
626
+ 'The parent message might be cleared.')
627
+
628
+ @property
629
+ def field_number(self):
630
+ self._check_valid()
631
+ # pylint: disable=protected-access
632
+ return self._parent._internal_get(self._index)._field_number
633
+
634
+ @property
635
+ def wire_type(self):
636
+ self._check_valid()
637
+ # pylint: disable=protected-access
638
+ return self._parent._internal_get(self._index)._wire_type
639
+
640
+ @property
641
+ def data(self):
642
+ self._check_valid()
643
+ # pylint: disable=protected-access
644
+ return self._parent._internal_get(self._index)._data
645
+
646
+
647
+ class UnknownFieldSet:
648
+ """UnknownField container"""
649
+
650
+ # Disallows assignment to other attributes.
651
+ __slots__ = ['_values']
652
+
653
+ def __init__(self):
654
+ self._values = []
655
+
656
+ def __getitem__(self, index):
657
+ if self._values is None:
658
+ raise ValueError('UnknownFields does not exist. '
659
+ 'The parent message might be cleared.')
660
+ size = len(self._values)
661
+ if index < 0:
662
+ index += size
663
+ if index < 0 or index >= size:
664
+ raise IndexError('index %d out of range'.index)
665
+
666
+ return UnknownFieldRef(self, index)
667
+
668
+ def _internal_get(self, index):
669
+ return self._values[index]
670
+
671
+ def __len__(self):
672
+ if self._values is None:
673
+ raise ValueError('UnknownFields does not exist. '
674
+ 'The parent message might be cleared.')
675
+ return len(self._values)
676
+
677
+ def _add(self, field_number, wire_type, data):
678
+ unknown_field = _UnknownField(field_number, wire_type, data)
679
+ self._values.append(unknown_field)
680
+ return unknown_field
681
+
682
+ def __iter__(self):
683
+ for i in range(len(self)):
684
+ yield UnknownFieldRef(self, i)
685
+
686
+ def _extend(self, other):
687
+ if other is None:
688
+ return
689
+ # pylint: disable=protected-access
690
+ self._values.extend(other._values)
691
+
692
+ def __eq__(self, other):
693
+ if self is other:
694
+ return True
695
+ # Sort unknown fields because their order shouldn't
696
+ # affect equality test.
697
+ values = list(self._values)
698
+ if other is None:
699
+ return not values
700
+ values.sort()
701
+ # pylint: disable=protected-access
702
+ other_values = sorted(other._values)
703
+ return values == other_values
704
+
705
+ def _clear(self):
706
+ for value in self._values:
707
+ # pylint: disable=protected-access
708
+ if isinstance(value._data, UnknownFieldSet):
709
+ value._data._clear() # pylint: disable=protected-access
710
+ self._values = None
my_container_sandbox/workspace/anaconda3/lib/python3.8/site-packages/google/protobuf/internal/type_checkers.py ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2008 Google Inc. All rights reserved.
3
+ # https://developers.google.com/protocol-buffers/
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ """Provides type checking routines.
32
+
33
+ This module defines type checking utilities in the forms of dictionaries:
34
+
35
+ VALUE_CHECKERS: A dictionary of field types and a value validation object.
36
+ TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing
37
+ function.
38
+ TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization
39
+ function.
40
+ FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their
41
+ corresponding wire types.
42
+ TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
43
+ function.
44
+ """
45
+
46
+ __author__ = 'robinson@google.com (Will Robinson)'
47
+
48
+ import ctypes
49
+ import numbers
50
+
51
+ from google.protobuf.internal import decoder
52
+ from google.protobuf.internal import encoder
53
+ from google.protobuf.internal import wire_format
54
+ from google.protobuf import descriptor
55
+
56
+ _FieldDescriptor = descriptor.FieldDescriptor
57
+
58
+
59
+ def TruncateToFourByteFloat(original):
60
+ return ctypes.c_float(original).value
61
+
62
+
63
+ def ToShortestFloat(original):
64
+ """Returns the shortest float that has same value in wire."""
65
+ # All 4 byte floats have between 6 and 9 significant digits, so we
66
+ # start with 6 as the lower bound.
67
+ # It has to be iterative because use '.9g' directly can not get rid
68
+ # of the noises for most values. For example if set a float_field=0.9
69
+ # use '.9g' will print 0.899999976.
70
+ precision = 6
71
+ rounded = float('{0:.{1}g}'.format(original, precision))
72
+ while TruncateToFourByteFloat(rounded) != original:
73
+ precision += 1
74
+ rounded = float('{0:.{1}g}'.format(original, precision))
75
+ return rounded
76
+
77
+
78
+ def SupportsOpenEnums(field_descriptor):
79
+ return field_descriptor.containing_type.syntax == 'proto3'
80
+
81
+
82
+ def GetTypeChecker(field):
83
+ """Returns a type checker for a message field of the specified types.
84
+
85
+ Args:
86
+ field: FieldDescriptor object for this field.
87
+
88
+ Returns:
89
+ An instance of TypeChecker which can be used to verify the types
90
+ of values assigned to a field of the specified type.
91
+ """
92
+ if (field.cpp_type == _FieldDescriptor.CPPTYPE_STRING and
93
+ field.type == _FieldDescriptor.TYPE_STRING):
94
+ return UnicodeValueChecker()
95
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
96
+ if SupportsOpenEnums(field):
97
+ # When open enums are supported, any int32 can be assigned.
98
+ return _VALUE_CHECKERS[_FieldDescriptor.CPPTYPE_INT32]
99
+ else:
100
+ return EnumValueChecker(field.enum_type)
101
+ return _VALUE_CHECKERS[field.cpp_type]
102
+
103
+
104
+ # None of the typecheckers below make any attempt to guard against people
105
+ # subclassing builtin types and doing weird things. We're not trying to
106
+ # protect against malicious clients here, just people accidentally shooting
107
+ # themselves in the foot in obvious ways.
108
+ class TypeChecker(object):
109
+
110
+ """Type checker used to catch type errors as early as possible
111
+ when the client is setting scalar fields in protocol messages.
112
+ """
113
+
114
+ def __init__(self, *acceptable_types):
115
+ self._acceptable_types = acceptable_types
116
+
117
+ def CheckValue(self, proposed_value):
118
+ """Type check the provided value and return it.
119
+
120
+ The returned value might have been normalized to another type.
121
+ """
122
+ if not isinstance(proposed_value, self._acceptable_types):
123
+ message = ('%.1024r has type %s, but expected one of: %s' %
124
+ (proposed_value, type(proposed_value), self._acceptable_types))
125
+ raise TypeError(message)
126
+ return proposed_value
127
+
128
+
129
+ class TypeCheckerWithDefault(TypeChecker):
130
+
131
+ def __init__(self, default_value, *acceptable_types):
132
+ TypeChecker.__init__(self, *acceptable_types)
133
+ self._default_value = default_value
134
+
135
+ def DefaultValue(self):
136
+ return self._default_value
137
+
138
+
139
+ class BoolValueChecker(object):
140
+ """Type checker used for bool fields."""
141
+
142
+ def CheckValue(self, proposed_value):
143
+ if not hasattr(proposed_value, '__index__') or (
144
+ type(proposed_value).__module__ == 'numpy' and
145
+ type(proposed_value).__name__ == 'ndarray'):
146
+ message = ('%.1024r has type %s, but expected one of: %s' %
147
+ (proposed_value, type(proposed_value), (bool, int)))
148
+ raise TypeError(message)
149
+ return bool(proposed_value)
150
+
151
+ def DefaultValue(self):
152
+ return False
153
+
154
+
155
+ # IntValueChecker and its subclasses perform integer type-checks
156
+ # and bounds-checks.
157
+ class IntValueChecker(object):
158
+
159
+ """Checker used for integer fields. Performs type-check and range check."""
160
+
161
+ def CheckValue(self, proposed_value):
162
+ if not hasattr(proposed_value, '__index__') or (
163
+ type(proposed_value).__module__ == 'numpy' and
164
+ type(proposed_value).__name__ == 'ndarray'):
165
+ message = ('%.1024r has type %s, but expected one of: %s' %
166
+ (proposed_value, type(proposed_value), (int,)))
167
+ raise TypeError(message)
168
+
169
+ if not self._MIN <= int(proposed_value) <= self._MAX:
170
+ raise ValueError('Value out of range: %d' % proposed_value)
171
+ # We force all values to int to make alternate implementations where the
172
+ # distinction is more significant (e.g. the C++ implementation) simpler.
173
+ proposed_value = int(proposed_value)
174
+ return proposed_value
175
+
176
+ def DefaultValue(self):
177
+ return 0
178
+
179
+
180
+ class EnumValueChecker(object):
181
+
182
+ """Checker used for enum fields. Performs type-check and range check."""
183
+
184
+ def __init__(self, enum_type):
185
+ self._enum_type = enum_type
186
+
187
+ def CheckValue(self, proposed_value):
188
+ if not isinstance(proposed_value, numbers.Integral):
189
+ message = ('%.1024r has type %s, but expected one of: %s' %
190
+ (proposed_value, type(proposed_value), (int,)))
191
+ raise TypeError(message)
192
+ if int(proposed_value) not in self._enum_type.values_by_number:
193
+ raise ValueError('Unknown enum value: %d' % proposed_value)
194
+ return proposed_value
195
+
196
+ def DefaultValue(self):
197
+ return self._enum_type.values[0].number
198
+
199
+
200
+ class UnicodeValueChecker(object):
201
+
202
+ """Checker used for string fields.
203
+
204
+ Always returns a unicode value, even if the input is of type str.
205
+ """
206
+
207
+ def CheckValue(self, proposed_value):
208
+ if not isinstance(proposed_value, (bytes, str)):
209
+ message = ('%.1024r has type %s, but expected one of: %s' %
210
+ (proposed_value, type(proposed_value), (bytes, str)))
211
+ raise TypeError(message)
212
+
213
+ # If the value is of type 'bytes' make sure that it is valid UTF-8 data.
214
+ if isinstance(proposed_value, bytes):
215
+ try:
216
+ proposed_value = proposed_value.decode('utf-8')
217
+ except UnicodeDecodeError:
218
+ raise ValueError('%.1024r has type bytes, but isn\'t valid UTF-8 '
219
+ 'encoding. Non-UTF-8 strings must be converted to '
220
+ 'unicode objects before being added.' %
221
+ (proposed_value))
222
+ else:
223
+ try:
224
+ proposed_value.encode('utf8')
225
+ except UnicodeEncodeError:
226
+ raise ValueError('%.1024r isn\'t a valid unicode string and '
227
+ 'can\'t be encoded in UTF-8.'%
228
+ (proposed_value))
229
+
230
+ return proposed_value
231
+
232
+ def DefaultValue(self):
233
+ return u""
234
+
235
+
236
+ class Int32ValueChecker(IntValueChecker):
237
+ # We're sure to use ints instead of longs here since comparison may be more
238
+ # efficient.
239
+ _MIN = -2147483648
240
+ _MAX = 2147483647
241
+
242
+
243
+ class Uint32ValueChecker(IntValueChecker):
244
+ _MIN = 0
245
+ _MAX = (1 << 32) - 1
246
+
247
+
248
+ class Int64ValueChecker(IntValueChecker):
249
+ _MIN = -(1 << 63)
250
+ _MAX = (1 << 63) - 1
251
+
252
+
253
+ class Uint64ValueChecker(IntValueChecker):
254
+ _MIN = 0
255
+ _MAX = (1 << 64) - 1
256
+
257
+
258
+ # The max 4 bytes float is about 3.4028234663852886e+38
259
+ _FLOAT_MAX = float.fromhex('0x1.fffffep+127')
260
+ _FLOAT_MIN = -_FLOAT_MAX
261
+ _INF = float('inf')
262
+ _NEG_INF = float('-inf')
263
+
264
+
265
+ class DoubleValueChecker(object):
266
+ """Checker used for double fields.
267
+
268
+ Performs type-check and range check.
269
+ """
270
+
271
+ def CheckValue(self, proposed_value):
272
+ """Check and convert proposed_value to float."""
273
+ if (not hasattr(proposed_value, '__float__') and
274
+ not hasattr(proposed_value, '__index__')) or (
275
+ type(proposed_value).__module__ == 'numpy' and
276
+ type(proposed_value).__name__ == 'ndarray'):
277
+ message = ('%.1024r has type %s, but expected one of: int, float' %
278
+ (proposed_value, type(proposed_value)))
279
+ raise TypeError(message)
280
+ return float(proposed_value)
281
+
282
+ def DefaultValue(self):
283
+ return 0.0
284
+
285
+
286
+ class FloatValueChecker(DoubleValueChecker):
287
+ """Checker used for float fields.
288
+
289
+ Performs type-check and range check.
290
+
291
+ Values exceeding a 32-bit float will be converted to inf/-inf.
292
+ """
293
+
294
+ def CheckValue(self, proposed_value):
295
+ """Check and convert proposed_value to float."""
296
+ converted_value = super().CheckValue(proposed_value)
297
+ # This inf rounding matches the C++ proto SafeDoubleToFloat logic.
298
+ if converted_value > _FLOAT_MAX:
299
+ return _INF
300
+ if converted_value < _FLOAT_MIN:
301
+ return _NEG_INF
302
+
303
+ return TruncateToFourByteFloat(converted_value)
304
+
305
+ # Type-checkers for all scalar CPPTYPEs.
306
+ _VALUE_CHECKERS = {
307
+ _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(),
308
+ _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(),
309
+ _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
310
+ _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
311
+ _FieldDescriptor.CPPTYPE_DOUBLE: DoubleValueChecker(),
312
+ _FieldDescriptor.CPPTYPE_FLOAT: FloatValueChecker(),
313
+ _FieldDescriptor.CPPTYPE_BOOL: BoolValueChecker(),
314
+ _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes),
315
+ }
316
+
317
+
318
+ # Map from field type to a function F, such that F(field_num, value)
319
+ # gives the total byte size for a value of the given type. This
320
+ # byte size includes tag information and any other additional space
321
+ # associated with serializing "value".
322
+ TYPE_TO_BYTE_SIZE_FN = {
323
+ _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize,
324
+ _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize,
325
+ _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize,
326
+ _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize,
327
+ _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize,
328
+ _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize,
329
+ _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize,
330
+ _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize,
331
+ _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize,
332
+ _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize,
333
+ _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize,
334
+ _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize,
335
+ _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize,
336
+ _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize,
337
+ _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize,
338
+ _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize,
339
+ _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize,
340
+ _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize
341
+ }
342
+
343
+
344
+ # Maps from field types to encoder constructors.
345
+ TYPE_TO_ENCODER = {
346
+ _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder,
347
+ _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder,
348
+ _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder,
349
+ _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder,
350
+ _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder,
351
+ _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder,
352
+ _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder,
353
+ _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder,
354
+ _FieldDescriptor.TYPE_STRING: encoder.StringEncoder,
355
+ _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder,
356
+ _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder,
357
+ _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder,
358
+ _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder,
359
+ _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder,
360
+ _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder,
361
+ _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder,
362
+ _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder,
363
+ _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder,
364
+ }
365
+
366
+
367
+ # Maps from field types to sizer constructors.
368
+ TYPE_TO_SIZER = {
369
+ _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer,
370
+ _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer,
371
+ _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer,
372
+ _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer,
373
+ _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer,
374
+ _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer,
375
+ _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer,
376
+ _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer,
377
+ _FieldDescriptor.TYPE_STRING: encoder.StringSizer,
378
+ _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer,
379
+ _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer,
380
+ _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer,
381
+ _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer,
382
+ _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer,
383
+ _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer,
384
+ _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer,
385
+ _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer,
386
+ _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer,
387
+ }
388
+
389
+
390
+ # Maps from field type to a decoder constructor.
391
+ TYPE_TO_DECODER = {
392
+ _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder,
393
+ _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder,
394
+ _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder,
395
+ _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder,
396
+ _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder,
397
+ _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder,
398
+ _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder,
399
+ _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder,
400
+ _FieldDescriptor.TYPE_STRING: decoder.StringDecoder,
401
+ _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder,
402
+ _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder,
403
+ _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder,
404
+ _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder,
405
+ _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder,
406
+ _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder,
407
+ _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder,
408
+ _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder,
409
+ _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder,
410
+ }
411
+
412
+ # Maps from field type to expected wiretype.
413
+ FIELD_TYPE_TO_WIRE_TYPE = {
414
+ _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64,
415
+ _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32,
416
+ _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT,
417
+ _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT,
418
+ _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT,
419
+ _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64,
420
+ _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32,
421
+ _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT,
422
+ _FieldDescriptor.TYPE_STRING:
423
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
424
+ _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP,
425
+ _FieldDescriptor.TYPE_MESSAGE:
426
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
427
+ _FieldDescriptor.TYPE_BYTES:
428
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
429
+ _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT,
430
+ _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT,
431
+ _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32,
432
+ _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64,
433
+ _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT,
434
+ _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT,
435
+ }