earthengine-api 1.5.13rc0__py3-none-any.whl → 1.7.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of earthengine-api might be problematic. Click here for more details.
- {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/METADATA +3 -3
- earthengine_api-1.7.4.dist-info/RECORD +109 -0
- {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/WHEEL +1 -1
- ee/__init__.py +29 -28
- ee/_arg_types.py +7 -6
- ee/_cloud_api_utils.py +95 -78
- ee/_helpers.py +17 -13
- ee/_state.py +105 -0
- ee/_utils.py +2 -1
- ee/apifunction.py +21 -19
- ee/apitestcase.py +33 -38
- ee/batch.py +87 -77
- ee/blob.py +10 -12
- ee/classifier.py +57 -59
- ee/cli/commands.py +178 -114
- ee/cli/eecli.py +1 -1
- ee/cli/utils.py +61 -42
- ee/clusterer.py +39 -41
- ee/collection.py +64 -54
- ee/computedobject.py +19 -16
- ee/confusionmatrix.py +9 -9
- ee/customfunction.py +13 -12
- ee/data.py +220 -322
- ee/daterange.py +10 -10
- ee/deprecation.py +21 -13
- ee/deserializer.py +25 -20
- ee/dictionary.py +11 -11
- ee/ee_array.py +22 -20
- ee/ee_date.py +23 -23
- ee/ee_list.py +15 -16
- ee/ee_number.py +11 -21
- ee/ee_string.py +24 -32
- ee/ee_types.py +4 -4
- ee/element.py +15 -15
- ee/encodable.py +7 -4
- ee/errormargin.py +4 -4
- ee/feature.py +68 -71
- ee/featurecollection.py +41 -40
- ee/filter.py +90 -92
- ee/function.py +8 -8
- ee/geometry.py +95 -93
- ee/image.py +238 -236
- ee/image_converter.py +4 -4
- ee/imagecollection.py +30 -27
- ee/join.py +13 -15
- ee/kernel.py +55 -57
- ee/mapclient.py +9 -9
- ee/model.py +29 -31
- ee/oauth.py +76 -63
- ee/pixeltype.py +6 -6
- ee/projection.py +5 -4
- ee/reducer.py +41 -41
- ee/serializer.py +14 -14
- ee/table_converter.py +7 -6
- ee/terrain.py +7 -9
- ee/tests/_cloud_api_utils_test.py +21 -6
- ee/tests/_helpers_test.py +57 -4
- ee/tests/_state_test.py +49 -0
- ee/tests/algorithms.json +85 -2
- ee/tests/apifunction_test.py +5 -5
- ee/tests/batch_test.py +135 -57
- ee/tests/blob_test.py +5 -5
- ee/tests/classifier_test.py +3 -3
- ee/tests/clusterer_test.py +3 -3
- ee/tests/collection_test.py +48 -13
- ee/tests/confusionmatrix_test.py +3 -3
- ee/tests/data_test.py +484 -55
- ee/tests/daterange_test.py +4 -4
- ee/tests/deprecation_test.py +6 -4
- ee/tests/deserializer_test.py +64 -5
- ee/tests/dictionary_test.py +12 -12
- ee/tests/ee_array_test.py +3 -3
- ee/tests/ee_date_test.py +4 -4
- ee/tests/ee_list_test.py +3 -3
- ee/tests/ee_number_test.py +75 -30
- ee/tests/ee_string_test.py +11 -3
- ee/tests/ee_test.py +40 -22
- ee/tests/element_test.py +2 -2
- ee/tests/errormargin_test.py +1 -1
- ee/tests/feature_test.py +10 -10
- ee/tests/featurecollection_test.py +3 -3
- ee/tests/filter_test.py +4 -4
- ee/tests/function_test.py +5 -5
- ee/tests/geometry_point_test.py +3 -3
- ee/tests/geometry_test.py +93 -52
- ee/tests/image_converter_test.py +1 -3
- ee/tests/image_test.py +3 -3
- ee/tests/imagecollection_test.py +3 -3
- ee/tests/join_test.py +3 -3
- ee/tests/kernel_test.py +7 -3
- ee/tests/model_test.py +17 -5
- ee/tests/oauth_test.py +189 -7
- ee/tests/pixeltype_test.py +6 -7
- ee/tests/projection_test.py +5 -6
- ee/tests/reducer_test.py +16 -3
- ee/tests/serializer_test.py +39 -12
- ee/tests/table_converter_test.py +51 -7
- ee/tests/terrain_test.py +11 -3
- earthengine_api-1.5.13rc0.dist-info/RECORD +0 -107
- {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/entry_points.txt +0 -0
- {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/licenses/LICENSE +0 -0
- {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/top_level.txt +0 -0
ee/data.py
CHANGED
|
@@ -3,13 +3,16 @@
|
|
|
3
3
|
# Using lowercase function naming to match the JavaScript names.
|
|
4
4
|
# pylint: disable=g-bad-name
|
|
5
5
|
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from collections.abc import Callable, Iterator, Sequence
|
|
6
9
|
import contextlib
|
|
7
10
|
import json
|
|
8
11
|
import platform
|
|
9
12
|
import re
|
|
10
13
|
import sys
|
|
11
14
|
import threading
|
|
12
|
-
from typing import Any
|
|
15
|
+
from typing import Any
|
|
13
16
|
import uuid
|
|
14
17
|
import warnings
|
|
15
18
|
|
|
@@ -22,6 +25,7 @@ import httplib2
|
|
|
22
25
|
import requests
|
|
23
26
|
|
|
24
27
|
from ee import _cloud_api_utils
|
|
28
|
+
from ee import _state
|
|
25
29
|
from ee import _utils
|
|
26
30
|
from ee import computedobject
|
|
27
31
|
from ee import deprecation
|
|
@@ -34,73 +38,6 @@ from ee import table_converter
|
|
|
34
38
|
|
|
35
39
|
from ee import __version__
|
|
36
40
|
|
|
37
|
-
# OAuth2 credentials object. This may be set by ee.Initialize().
|
|
38
|
-
_credentials: Optional[credentials_lib.Credentials] = None
|
|
39
|
-
|
|
40
|
-
# The base URL for all data calls. This is set by ee.Initialize().
|
|
41
|
-
_api_base_url: Optional[str] = None
|
|
42
|
-
|
|
43
|
-
# The base URL for map tiles. This is set by ee.Initialize().
|
|
44
|
-
_tile_base_url: Optional[str] = None
|
|
45
|
-
|
|
46
|
-
# The base URL for all Cloud API calls. This is set by ee.Initialize().
|
|
47
|
-
_cloud_api_base_url: Optional[str] = None
|
|
48
|
-
|
|
49
|
-
# Google Cloud API key. This may be set by ee.Initialize().
|
|
50
|
-
_cloud_api_key: Optional[str] = None
|
|
51
|
-
|
|
52
|
-
# A Requests session. This is set by ee.Initialize()
|
|
53
|
-
_requests_session: Optional[requests.Session] = None
|
|
54
|
-
|
|
55
|
-
# A resource object for making Cloud API calls.
|
|
56
|
-
_cloud_api_resource = None
|
|
57
|
-
|
|
58
|
-
# A resource object for making Cloud API calls and receiving raw return types.
|
|
59
|
-
_cloud_api_resource_raw = None
|
|
60
|
-
|
|
61
|
-
# The default user project to use when making Cloud API calls.
|
|
62
|
-
_cloud_api_user_project: Optional[str] = None
|
|
63
|
-
|
|
64
|
-
# The API client version number to send when making requests.
|
|
65
|
-
_cloud_api_client_version: Optional[str] = None
|
|
66
|
-
|
|
67
|
-
# The http_transport to use.
|
|
68
|
-
_http_transport = None
|
|
69
|
-
|
|
70
|
-
# Whether the module has been initialized.
|
|
71
|
-
_initialized: bool = False
|
|
72
|
-
|
|
73
|
-
# Sets the number of milliseconds to wait for a request before considering
|
|
74
|
-
# it timed out. 0 means no limit.
|
|
75
|
-
_deadline_ms: int = 0
|
|
76
|
-
|
|
77
|
-
# Maximum number of times to retry a rate-limited request.
|
|
78
|
-
_max_retries: int = 5
|
|
79
|
-
|
|
80
|
-
# User agent to indicate which application is calling Earth Engine
|
|
81
|
-
_user_agent: Optional[str] = None
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
class _ThreadLocals(threading.local):
|
|
85
|
-
"""Storage for thread local variables."""
|
|
86
|
-
|
|
87
|
-
def __init__(self):
|
|
88
|
-
# pylint: disable=super-init-not-called
|
|
89
|
-
|
|
90
|
-
# A function called when profile results are received from the server. Takes
|
|
91
|
-
# the profile ID as an argument. None if profiling is disabled.
|
|
92
|
-
#
|
|
93
|
-
# This is a thread-local variable because the alternative is to add a
|
|
94
|
-
# parameter to ee.data.send_, which would then have to be propagated from
|
|
95
|
-
# the assorted API call functions (ee.data.getInfo, ee.data.getMapId, etc.),
|
|
96
|
-
# and the user would have to modify each call to profile, rather than
|
|
97
|
-
# enabling profiling as a wrapper around the entire program (with
|
|
98
|
-
# ee.data.profiling, defined below).
|
|
99
|
-
self.profile_hook: Optional[Callable[[str], None]] = None
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
_thread_locals = _ThreadLocals()
|
|
103
|
-
|
|
104
41
|
# The HTTP header through which profile results are returned.
|
|
105
42
|
# Lowercase because that's how httplib2 does things.
|
|
106
43
|
_PROFILE_RESPONSE_HEADER_LOWERCASE = 'x-earth-engine-computation-profile'
|
|
@@ -160,13 +97,39 @@ _NOT_INITIALIZED_MESSAGE = (
|
|
|
160
97
|
)
|
|
161
98
|
|
|
162
99
|
|
|
100
|
+
class _ThreadLocals(threading.local):
|
|
101
|
+
"""Storage for thread local variables."""
|
|
102
|
+
|
|
103
|
+
def __init__(self):
|
|
104
|
+
# pylint: disable=super-init-not-called
|
|
105
|
+
|
|
106
|
+
# A function called when profile results are received from the server. Takes
|
|
107
|
+
# the profile ID as an argument. None if profiling is disabled.
|
|
108
|
+
#
|
|
109
|
+
# This is a thread-local variable because the alternative is to add a
|
|
110
|
+
# parameter to ee.data.send_, which would then have to be propagated from
|
|
111
|
+
# the assorted API call functions (ee.data.getInfo, ee.data.getMapId, etc.),
|
|
112
|
+
# and the user would have to modify each call to profile, rather than
|
|
113
|
+
# enabling profiling as a wrapper around the entire program (with
|
|
114
|
+
# ee.data.profiling, defined below).
|
|
115
|
+
self.profile_hook: Callable[[str], None] | None = None
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
_thread_locals = _ThreadLocals()
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _get_state() -> _state.EEState:
|
|
122
|
+
"""Returns the current state, or a default state if not initialized."""
|
|
123
|
+
return _state.get_state()
|
|
124
|
+
|
|
125
|
+
|
|
163
126
|
def initialize(
|
|
164
127
|
credentials: Any = None,
|
|
165
|
-
api_base_url:
|
|
166
|
-
tile_base_url:
|
|
167
|
-
cloud_api_base_url:
|
|
168
|
-
cloud_api_key:
|
|
169
|
-
project:
|
|
128
|
+
api_base_url: str | None = None,
|
|
129
|
+
tile_base_url: str | None = None,
|
|
130
|
+
cloud_api_base_url: str | None = None,
|
|
131
|
+
cloud_api_key: str | None = None,
|
|
132
|
+
project: str | None = None,
|
|
170
133
|
http_transport: Any = None,
|
|
171
134
|
) -> None:
|
|
172
135
|
"""Initializes the data module, setting credentials and base URLs.
|
|
@@ -187,58 +150,51 @@ def initialize(
|
|
|
187
150
|
project: The client project ID or number to use when making API calls.
|
|
188
151
|
http_transport: The http transport to use
|
|
189
152
|
"""
|
|
190
|
-
|
|
191
|
-
global _requests_session
|
|
192
|
-
global _cloud_api_base_url
|
|
193
|
-
global _cloud_api_key
|
|
194
|
-
global _cloud_api_user_project, _http_transport
|
|
195
|
-
global _cloud_api_client_version
|
|
196
|
-
|
|
153
|
+
state = _get_state()
|
|
197
154
|
# If already initialized, only replace the explicitly specified parts.
|
|
198
155
|
|
|
199
156
|
if credentials is not None:
|
|
200
|
-
|
|
157
|
+
state.credentials = credentials
|
|
201
158
|
|
|
202
159
|
if api_base_url is not None:
|
|
203
|
-
|
|
204
|
-
elif not
|
|
205
|
-
|
|
160
|
+
state.api_base_url = api_base_url
|
|
161
|
+
elif not state.initialized:
|
|
162
|
+
state.api_base_url = DEFAULT_API_BASE_URL
|
|
206
163
|
|
|
207
164
|
if tile_base_url is not None:
|
|
208
|
-
|
|
209
|
-
elif not
|
|
210
|
-
|
|
165
|
+
state.tile_base_url = tile_base_url
|
|
166
|
+
elif not state.initialized:
|
|
167
|
+
state.tile_base_url = DEFAULT_TILE_BASE_URL
|
|
211
168
|
|
|
212
169
|
if cloud_api_key is not None:
|
|
213
|
-
|
|
170
|
+
state.cloud_api_key = cloud_api_key
|
|
214
171
|
|
|
215
172
|
if cloud_api_base_url is not None:
|
|
216
|
-
|
|
217
|
-
elif not
|
|
218
|
-
|
|
173
|
+
state.cloud_api_base_url = cloud_api_base_url
|
|
174
|
+
elif not state.initialized:
|
|
175
|
+
state.cloud_api_base_url = DEFAULT_CLOUD_API_BASE_URL
|
|
219
176
|
|
|
220
177
|
if __version__ is not None:
|
|
221
178
|
version = __version__
|
|
222
|
-
|
|
179
|
+
state.cloud_api_client_version = version
|
|
223
180
|
|
|
224
|
-
|
|
181
|
+
state.http_transport = http_transport
|
|
225
182
|
|
|
226
|
-
if
|
|
227
|
-
|
|
183
|
+
if state.requests_session is None:
|
|
184
|
+
state.requests_session = requests.Session()
|
|
228
185
|
|
|
229
186
|
_install_cloud_api_resource()
|
|
230
187
|
|
|
231
188
|
if project is not None:
|
|
232
|
-
|
|
233
|
-
_cloud_api_utils.set_cloud_api_user_project(project)
|
|
189
|
+
state.cloud_api_user_project = project
|
|
234
190
|
else:
|
|
235
|
-
|
|
191
|
+
state.cloud_api_user_project = DEFAULT_CLOUD_API_USER_PROJECT
|
|
236
192
|
|
|
237
|
-
|
|
193
|
+
state.initialized = True
|
|
238
194
|
|
|
239
195
|
|
|
240
196
|
def is_initialized() -> bool:
|
|
241
|
-
return
|
|
197
|
+
return _get_state().initialized
|
|
242
198
|
|
|
243
199
|
|
|
244
200
|
def get_persistent_credentials() -> credentials_lib.Credentials:
|
|
@@ -254,7 +210,7 @@ def get_persistent_credentials() -> credentials_lib.Credentials:
|
|
|
254
210
|
args = {}
|
|
255
211
|
try:
|
|
256
212
|
args = oauth.get_credentials_arguments()
|
|
257
|
-
except
|
|
213
|
+
except OSError:
|
|
258
214
|
pass
|
|
259
215
|
|
|
260
216
|
if args.get('refresh_token'):
|
|
@@ -286,93 +242,78 @@ def get_persistent_credentials() -> credentials_lib.Credentials:
|
|
|
286
242
|
|
|
287
243
|
|
|
288
244
|
def reset() -> None:
|
|
289
|
-
"""Resets the
|
|
290
|
-
|
|
291
|
-
global _requests_session, _cloud_api_resource, _cloud_api_resource_raw
|
|
292
|
-
global _cloud_api_base_url, _cloud_api_user_project
|
|
293
|
-
global _cloud_api_key, _http_transport
|
|
294
|
-
_credentials = None
|
|
295
|
-
_api_base_url = None
|
|
296
|
-
_tile_base_url = None
|
|
297
|
-
if _requests_session is not None:
|
|
298
|
-
_requests_session.close()
|
|
299
|
-
_requests_session = None
|
|
300
|
-
_cloud_api_base_url = None
|
|
301
|
-
_cloud_api_key = None
|
|
302
|
-
_cloud_api_resource = None
|
|
303
|
-
_cloud_api_resource_raw = None
|
|
304
|
-
_cloud_api_user_project = None
|
|
305
|
-
_cloud_api_utils.set_cloud_api_user_project(DEFAULT_CLOUD_API_USER_PROJECT)
|
|
306
|
-
_http_transport = None
|
|
307
|
-
_initialized = False
|
|
245
|
+
"""Resets the EE state, clearing credentials and custom base URLs."""
|
|
246
|
+
_state.reset_state()
|
|
308
247
|
|
|
309
248
|
|
|
310
249
|
def _get_projects_path() -> str:
|
|
311
250
|
"""Returns the projects path to use for constructing a request."""
|
|
312
|
-
|
|
313
|
-
return 'projects/' + _cloud_api_user_project
|
|
314
|
-
else:
|
|
315
|
-
return 'projects/' + DEFAULT_CLOUD_API_USER_PROJECT
|
|
251
|
+
return f'projects/{_get_state().cloud_api_user_project}'
|
|
316
252
|
|
|
317
253
|
|
|
318
254
|
def _install_cloud_api_resource() -> None:
|
|
319
255
|
"""Builds or rebuilds the Cloud API resource object, if needed."""
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
timeout = (
|
|
323
|
-
assert
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
credentials=
|
|
328
|
-
api_key=
|
|
256
|
+
state = _get_state()
|
|
257
|
+
|
|
258
|
+
timeout = (state.deadline_ms / 1000.0) or None
|
|
259
|
+
assert state.requests_session is not None
|
|
260
|
+
state.cloud_api_resource = _cloud_api_utils.build_cloud_resource(
|
|
261
|
+
state.cloud_api_base_url,
|
|
262
|
+
state.requests_session,
|
|
263
|
+
credentials=state.credentials,
|
|
264
|
+
api_key=state.cloud_api_key,
|
|
329
265
|
timeout=timeout,
|
|
330
|
-
num_retries=
|
|
266
|
+
num_retries=state.max_retries,
|
|
331
267
|
headers_supplier=_make_request_headers,
|
|
332
268
|
response_inspector=_handle_profiling_response,
|
|
333
|
-
http_transport=
|
|
269
|
+
http_transport=state.http_transport,
|
|
334
270
|
)
|
|
335
271
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
credentials=
|
|
340
|
-
api_key=
|
|
272
|
+
state.cloud_api_resource_raw = _cloud_api_utils.build_cloud_resource(
|
|
273
|
+
state.cloud_api_base_url,
|
|
274
|
+
state.requests_session,
|
|
275
|
+
credentials=state.credentials,
|
|
276
|
+
api_key=state.cloud_api_key,
|
|
341
277
|
timeout=timeout,
|
|
342
|
-
num_retries=
|
|
278
|
+
num_retries=state.max_retries,
|
|
343
279
|
headers_supplier=_make_request_headers,
|
|
344
280
|
response_inspector=_handle_profiling_response,
|
|
345
|
-
http_transport=
|
|
281
|
+
http_transport=state.http_transport,
|
|
346
282
|
raw=True,
|
|
347
283
|
)
|
|
348
284
|
|
|
349
285
|
|
|
350
286
|
def _get_cloud_projects() -> Any:
|
|
351
|
-
|
|
287
|
+
state = _get_state()
|
|
288
|
+
if state.cloud_api_resource is None:
|
|
352
289
|
raise ee_exception.EEException(_NOT_INITIALIZED_MESSAGE)
|
|
353
|
-
return
|
|
290
|
+
return state.cloud_api_resource.projects()
|
|
354
291
|
|
|
355
292
|
|
|
356
293
|
def _get_cloud_projects_raw() -> Any:
|
|
357
|
-
|
|
294
|
+
state = _get_state()
|
|
295
|
+
if state.cloud_api_resource_raw is None:
|
|
358
296
|
raise ee_exception.EEException(_NOT_INITIALIZED_MESSAGE)
|
|
359
|
-
return
|
|
297
|
+
return state.cloud_api_resource_raw.projects()
|
|
360
298
|
|
|
361
299
|
|
|
362
|
-
def _make_request_headers() ->
|
|
300
|
+
def _make_request_headers() -> dict[str, Any] | None:
|
|
363
301
|
"""Adds headers based on client context."""
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
302
|
+
state = _get_state()
|
|
303
|
+
headers: dict[str, Any] = {}
|
|
304
|
+
client_version_header_values: list[Any] = []
|
|
305
|
+
if state.cloud_api_client_version is not None:
|
|
306
|
+
client_version_header_values.append(
|
|
307
|
+
f'ee-py/{state.cloud_api_client_version}'
|
|
308
|
+
)
|
|
309
|
+
if state.user_agent is not None:
|
|
310
|
+
headers[_USER_AGENT_HEADER] = state.user_agent
|
|
370
311
|
client_version_header_values.append('python/' + platform.python_version())
|
|
371
312
|
headers[_API_CLIENT_VERSION_HEADER] = ' '.join(client_version_header_values)
|
|
372
313
|
if _thread_locals.profile_hook:
|
|
373
314
|
headers[_PROFILE_REQUEST_HEADER] = '1'
|
|
374
|
-
if
|
|
375
|
-
headers[_USER_PROJECT_OVERRIDE_HEADER] =
|
|
315
|
+
if state.cloud_api_user_project is not DEFAULT_CLOUD_API_USER_PROJECT:
|
|
316
|
+
headers[_USER_PROJECT_OVERRIDE_HEADER] = state.cloud_api_user_project
|
|
376
317
|
if headers:
|
|
377
318
|
return headers
|
|
378
319
|
return None
|
|
@@ -388,7 +329,7 @@ def _handle_profiling_response(response: httplib2.Response) -> None:
|
|
|
388
329
|
|
|
389
330
|
|
|
390
331
|
def _execute_cloud_call(
|
|
391
|
-
call: googleapiclient.http.HttpRequest, num_retries:
|
|
332
|
+
call: googleapiclient.http.HttpRequest, num_retries: int | None = None
|
|
392
333
|
) -> Any:
|
|
393
334
|
"""Executes a Cloud API call and translates errors to EEExceptions.
|
|
394
335
|
|
|
@@ -403,7 +344,7 @@ def _execute_cloud_call(
|
|
|
403
344
|
Raises:
|
|
404
345
|
EEException if the call fails.
|
|
405
346
|
"""
|
|
406
|
-
num_retries =
|
|
347
|
+
num_retries = _get_state().max_retries if num_retries is None else num_retries
|
|
407
348
|
try:
|
|
408
349
|
return call.execute(num_retries=num_retries)
|
|
409
350
|
except googleapiclient.errors.HttpError as e:
|
|
@@ -426,7 +367,7 @@ def _translate_cloud_exception(
|
|
|
426
367
|
return ee_exception.EEException(http_error._get_reason()) # pylint: disable=protected-access
|
|
427
368
|
|
|
428
369
|
|
|
429
|
-
def _maybe_populate_workload_tag(body:
|
|
370
|
+
def _maybe_populate_workload_tag(body: dict[str, Any]) -> None:
|
|
430
371
|
"""Populates the workload tag on the request body passed in if applicable.
|
|
431
372
|
|
|
432
373
|
Defaults to the workload tag set by ee.data.setWorkloadTag() or related
|
|
@@ -446,24 +387,20 @@ def _maybe_populate_workload_tag(body: Dict[str, Any]) -> None:
|
|
|
446
387
|
|
|
447
388
|
def setCloudApiKey(cloud_api_key: str) -> None:
|
|
448
389
|
"""Sets the Cloud API key parameter ("api_key") for all requests."""
|
|
449
|
-
|
|
450
|
-
_cloud_api_key = cloud_api_key
|
|
390
|
+
_get_state().cloud_api_key = cloud_api_key
|
|
451
391
|
_install_cloud_api_resource()
|
|
452
392
|
|
|
453
393
|
|
|
454
394
|
def setCloudApiUserProject(cloud_api_user_project: str) -> None:
|
|
455
|
-
|
|
456
|
-
_cloud_api_user_project = cloud_api_user_project
|
|
457
|
-
_cloud_api_utils.set_cloud_api_user_project(_cloud_api_user_project)
|
|
395
|
+
_get_state().cloud_api_user_project = cloud_api_user_project
|
|
458
396
|
|
|
459
397
|
|
|
460
398
|
def setUserAgent(user_agent: str) -> None:
|
|
461
|
-
|
|
462
|
-
_user_agent = user_agent
|
|
399
|
+
_get_state().user_agent = user_agent
|
|
463
400
|
|
|
464
401
|
|
|
465
|
-
def getUserAgent() ->
|
|
466
|
-
return
|
|
402
|
+
def getUserAgent() -> str | None:
|
|
403
|
+
return _get_state().user_agent
|
|
467
404
|
|
|
468
405
|
|
|
469
406
|
def setDeadline(milliseconds: float) -> None:
|
|
@@ -473,8 +410,7 @@ def setDeadline(milliseconds: float) -> None:
|
|
|
473
410
|
milliseconds: The number of milliseconds to wait for a request
|
|
474
411
|
before considering it timed out. 0 means no limit.
|
|
475
412
|
"""
|
|
476
|
-
|
|
477
|
-
_deadline_ms = milliseconds
|
|
413
|
+
_get_state().deadline_ms = milliseconds
|
|
478
414
|
_install_cloud_api_resource()
|
|
479
415
|
|
|
480
416
|
|
|
@@ -488,8 +424,7 @@ def setMaxRetries(max_retries: int) -> None:
|
|
|
488
424
|
raise ValueError('max_retries must be non-negative')
|
|
489
425
|
if max_retries >= 100:
|
|
490
426
|
raise ValueError('Too many retries')
|
|
491
|
-
|
|
492
|
-
_max_retries = max_retries
|
|
427
|
+
_get_state().max_retries = max_retries
|
|
493
428
|
|
|
494
429
|
|
|
495
430
|
@contextlib.contextmanager
|
|
@@ -514,7 +449,7 @@ def profiling(hook: Any) -> Iterator[None]:
|
|
|
514
449
|
|
|
515
450
|
|
|
516
451
|
@deprecation.Deprecated('Use getAsset')
|
|
517
|
-
def getInfo(asset_id: str) ->
|
|
452
|
+
def getInfo(asset_id: str) -> Any | None:
|
|
518
453
|
"""Load info for an asset, given an asset id.
|
|
519
454
|
|
|
520
455
|
Args:
|
|
@@ -531,7 +466,7 @@ def getInfo(asset_id: str) -> Optional[Any]:
|
|
|
531
466
|
_get_cloud_projects()
|
|
532
467
|
.assets()
|
|
533
468
|
.get(name=name, prettyPrint=False)
|
|
534
|
-
.execute(num_retries=
|
|
469
|
+
.execute(num_retries=_get_state().max_retries)
|
|
535
470
|
)
|
|
536
471
|
except googleapiclient.errors.HttpError as e:
|
|
537
472
|
if e.resp.status == 404:
|
|
@@ -556,7 +491,7 @@ def getAsset(asset_id: str) -> Any:
|
|
|
556
491
|
|
|
557
492
|
|
|
558
493
|
@deprecation.Deprecated('Use listAssets or listImages')
|
|
559
|
-
def getList(params:
|
|
494
|
+
def getList(params: dict[str, Any]) -> Any:
|
|
560
495
|
"""Get a list of contents for a collection asset.
|
|
561
496
|
|
|
562
497
|
Args:
|
|
@@ -577,8 +512,8 @@ def getList(params: Dict[str, Any]) -> Any:
|
|
|
577
512
|
|
|
578
513
|
|
|
579
514
|
def listImages(
|
|
580
|
-
params:
|
|
581
|
-
) ->
|
|
515
|
+
params: str | dict[str, Any],
|
|
516
|
+
) -> dict[str, list[Any] | None]:
|
|
582
517
|
"""Returns the images in an image collection or folder.
|
|
583
518
|
|
|
584
519
|
Args:
|
|
@@ -615,7 +550,7 @@ def listImages(
|
|
|
615
550
|
return images
|
|
616
551
|
|
|
617
552
|
|
|
618
|
-
def listAssets(params:
|
|
553
|
+
def listAssets(params: str | dict[str, Any]) -> dict[str, list[Any]]:
|
|
619
554
|
"""Returns the assets in a folder.
|
|
620
555
|
|
|
621
556
|
Args:
|
|
@@ -668,7 +603,7 @@ def listAssets(params: Union[str, Dict[str, Any]]) -> Dict[str, List[Any]]:
|
|
|
668
603
|
return assets
|
|
669
604
|
|
|
670
605
|
|
|
671
|
-
def listBuckets(project:
|
|
606
|
+
def listBuckets(project: str | None = None) -> Any:
|
|
672
607
|
"""Returns top-level assets and folders for the Cloud Project or user.
|
|
673
608
|
|
|
674
609
|
Args:
|
|
@@ -687,7 +622,7 @@ def listBuckets(project: Optional[str] = None) -> Any:
|
|
|
687
622
|
return _execute_cloud_call(_get_cloud_projects().listAssets(parent=project))
|
|
688
623
|
|
|
689
624
|
|
|
690
|
-
def getMapId(params:
|
|
625
|
+
def getMapId(params: dict[str, Any]) -> dict[str, Any]:
|
|
691
626
|
"""Get a Map ID for a given asset.
|
|
692
627
|
|
|
693
628
|
Args:
|
|
@@ -752,17 +687,18 @@ def getMapId(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
752
687
|
.maps()
|
|
753
688
|
.create(parent=_get_projects_path(), **queryParams)
|
|
754
689
|
)
|
|
690
|
+
state = _get_state()
|
|
755
691
|
map_name = result['name']
|
|
756
|
-
url_format = '
|
|
757
|
-
|
|
758
|
-
if
|
|
759
|
-
url_format += '?key
|
|
692
|
+
url_format = '{}/{}/{}/tiles/{{z}}/{{x}}/{{y}}'.format(
|
|
693
|
+
state.tile_base_url, _cloud_api_utils.VERSION, map_name)
|
|
694
|
+
if state.cloud_api_key:
|
|
695
|
+
url_format += f'?key={state.cloud_api_key}'
|
|
760
696
|
|
|
761
697
|
return {'mapid': map_name, 'token': '',
|
|
762
698
|
'tile_fetcher': TileFetcher(url_format, map_name=map_name)}
|
|
763
699
|
|
|
764
700
|
|
|
765
|
-
def getFeatureViewTilesKey(params:
|
|
701
|
+
def getFeatureViewTilesKey(params: dict[str, Any]) -> dict[str, Any]:
|
|
766
702
|
"""Get a tiles key for a given map or asset.
|
|
767
703
|
|
|
768
704
|
Args:
|
|
@@ -792,8 +728,9 @@ def getFeatureViewTilesKey(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
792
728
|
)
|
|
793
729
|
name = result['name']
|
|
794
730
|
version = _cloud_api_utils.VERSION
|
|
795
|
-
format_tile_url = (
|
|
796
|
-
|
|
731
|
+
format_tile_url = lambda x, y, z: (
|
|
732
|
+
f'{_get_state().tile_base_url}/{version}/{name}/tiles/{z}/{x}/{y}'
|
|
733
|
+
)
|
|
797
734
|
token = name.rsplit('/', 1).pop()
|
|
798
735
|
return {
|
|
799
736
|
'token': token,
|
|
@@ -801,7 +738,7 @@ def getFeatureViewTilesKey(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
801
738
|
}
|
|
802
739
|
|
|
803
740
|
|
|
804
|
-
def _extract_table_converter(params:
|
|
741
|
+
def _extract_table_converter(params: dict[str, Any]) -> Any | None:
|
|
805
742
|
if 'fileFormat' in params:
|
|
806
743
|
file_format = params.get('fileFormat')
|
|
807
744
|
converter = table_converter.from_file_format(file_format)
|
|
@@ -812,7 +749,7 @@ def _extract_table_converter(params: Dict[str, Any]) -> Optional[Any]:
|
|
|
812
749
|
|
|
813
750
|
|
|
814
751
|
def _extract_image_converter(
|
|
815
|
-
params:
|
|
752
|
+
params: dict[str, Any]
|
|
816
753
|
) -> image_converter.ImageConverter:
|
|
817
754
|
file_format = params.get('fileFormat')
|
|
818
755
|
converter = image_converter.from_file_format(file_format)
|
|
@@ -826,14 +763,13 @@ def _generate(func, list_key: str, **kwargs) -> Iterator[Any]:
|
|
|
826
763
|
args = kwargs.copy()
|
|
827
764
|
while True:
|
|
828
765
|
response = func(**args)
|
|
829
|
-
|
|
830
|
-
yield obj
|
|
766
|
+
yield from response.get(list_key, [])
|
|
831
767
|
if _NEXT_PAGE_TOKEN_KEY not in response:
|
|
832
768
|
break
|
|
833
769
|
args['params'].update({'pageToken': response[_NEXT_PAGE_TOKEN_KEY]})
|
|
834
770
|
|
|
835
771
|
|
|
836
|
-
def listFeatures(params:
|
|
772
|
+
def listFeatures(params: dict[str, Any]) -> Any:
|
|
837
773
|
"""List features for a given table or FeatureView asset.
|
|
838
774
|
|
|
839
775
|
Args:
|
|
@@ -878,7 +814,7 @@ def listFeatures(params: Dict[str, Any]) -> Any:
|
|
|
878
814
|
return call(params)
|
|
879
815
|
|
|
880
816
|
|
|
881
|
-
def getPixels(params:
|
|
817
|
+
def getPixels(params: dict[str, Any]) -> Any:
|
|
882
818
|
"""Fetches pixels from an image asset.
|
|
883
819
|
|
|
884
820
|
Args:
|
|
@@ -921,7 +857,7 @@ def getPixels(params: Dict[str, Any]) -> Any:
|
|
|
921
857
|
return data
|
|
922
858
|
|
|
923
859
|
|
|
924
|
-
def computePixels(params:
|
|
860
|
+
def computePixels(params: dict[str, Any]) -> Any:
|
|
925
861
|
"""Computes a tile by performing an arbitrary computation on image data.
|
|
926
862
|
|
|
927
863
|
Args:
|
|
@@ -961,7 +897,7 @@ def computePixels(params: Dict[str, Any]) -> Any:
|
|
|
961
897
|
return data
|
|
962
898
|
|
|
963
899
|
|
|
964
|
-
def computeImages(params:
|
|
900
|
+
def computeImages(params: dict[str, Any]) -> Any:
|
|
965
901
|
"""Computes a list of images by applying a computation to features.
|
|
966
902
|
|
|
967
903
|
Args:
|
|
@@ -987,7 +923,7 @@ def computeImages(params: Dict[str, Any]) -> Any:
|
|
|
987
923
|
)
|
|
988
924
|
|
|
989
925
|
|
|
990
|
-
def computeFeatures(params:
|
|
926
|
+
def computeFeatures(params: dict[str, Any]) -> Any:
|
|
991
927
|
"""Computes a list of features by applying a computation to features.
|
|
992
928
|
|
|
993
929
|
Args:
|
|
@@ -1033,7 +969,7 @@ def computeFeatures(params: Dict[str, Any]) -> Any:
|
|
|
1033
969
|
return call(params)
|
|
1034
970
|
|
|
1035
971
|
|
|
1036
|
-
def getTileUrl(mapid:
|
|
972
|
+
def getTileUrl(mapid: dict[str, Any], x: float, y: float, z: float) -> str:
|
|
1037
973
|
"""Generate a URL for map tiles from a Map ID and coordinates.
|
|
1038
974
|
|
|
1039
975
|
Args:
|
|
@@ -1134,7 +1070,7 @@ def computeValue(obj: computedobject.ComputedObject) -> Any:
|
|
|
1134
1070
|
|
|
1135
1071
|
@deprecation.Deprecated('Use getThumbId and makeThumbUrl')
|
|
1136
1072
|
def getThumbnail(
|
|
1137
|
-
params:
|
|
1073
|
+
params: dict[str, Any], thumbType: str | None = None
|
|
1138
1074
|
) -> Any:
|
|
1139
1075
|
"""Get a Thumbnail for a given asset.
|
|
1140
1076
|
|
|
@@ -1169,8 +1105,8 @@ def getThumbnail(
|
|
|
1169
1105
|
|
|
1170
1106
|
|
|
1171
1107
|
def getThumbId(
|
|
1172
|
-
params:
|
|
1173
|
-
) ->
|
|
1108
|
+
params: dict[str, Any], thumbType: str | None = None
|
|
1109
|
+
) -> dict[str, str]:
|
|
1174
1110
|
"""Get a Thumbnail ID for a given asset.
|
|
1175
1111
|
|
|
1176
1112
|
Args:
|
|
@@ -1253,7 +1189,7 @@ def getThumbId(
|
|
|
1253
1189
|
return {'thumbid': result['name'], 'token': ''}
|
|
1254
1190
|
|
|
1255
1191
|
|
|
1256
|
-
def makeThumbUrl(thumbId:
|
|
1192
|
+
def makeThumbUrl(thumbId: dict[str, str]) -> str:
|
|
1257
1193
|
"""Create a thumbnail URL from the given thumbid.
|
|
1258
1194
|
|
|
1259
1195
|
Args:
|
|
@@ -1262,14 +1198,16 @@ def makeThumbUrl(thumbId: Dict[str, str]) -> str:
|
|
|
1262
1198
|
Returns:
|
|
1263
1199
|
A URL from which the thumbnail can be obtained.
|
|
1264
1200
|
"""
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1201
|
+
state = _get_state()
|
|
1202
|
+
url = '{}/{}/{}:getPixels'.format(
|
|
1203
|
+
state.tile_base_url, _cloud_api_utils.VERSION, thumbId['thumbid']
|
|
1204
|
+
)
|
|
1205
|
+
if state.cloud_api_key:
|
|
1206
|
+
url += f'?key={state.cloud_api_key}'
|
|
1269
1207
|
return url
|
|
1270
1208
|
|
|
1271
1209
|
|
|
1272
|
-
def getDownloadId(params:
|
|
1210
|
+
def getDownloadId(params: dict[str, Any]) -> dict[str, str]:
|
|
1273
1211
|
"""Get a Download ID.
|
|
1274
1212
|
|
|
1275
1213
|
Args:
|
|
@@ -1385,7 +1323,7 @@ def getDownloadId(params: Dict[str, Any]) -> Dict[str, str]:
|
|
|
1385
1323
|
return {'docid': result['name'], 'token': ''}
|
|
1386
1324
|
|
|
1387
1325
|
|
|
1388
|
-
def makeDownloadUrl(downloadId:
|
|
1326
|
+
def makeDownloadUrl(downloadId: dict[str, str]) -> str:
|
|
1389
1327
|
"""Create a download URL from the given docid.
|
|
1390
1328
|
|
|
1391
1329
|
Args:
|
|
@@ -1394,11 +1332,12 @@ def makeDownloadUrl(downloadId: Dict[str, str]) -> str:
|
|
|
1394
1332
|
Returns:
|
|
1395
1333
|
A URL from which the download can be obtained.
|
|
1396
1334
|
"""
|
|
1397
|
-
return '
|
|
1398
|
-
|
|
1335
|
+
return '{}/{}/{}:getPixels'.format(
|
|
1336
|
+
_get_state().tile_base_url, _cloud_api_utils.VERSION, downloadId['docid']
|
|
1337
|
+
)
|
|
1399
1338
|
|
|
1400
1339
|
|
|
1401
|
-
def getTableDownloadId(params:
|
|
1340
|
+
def getTableDownloadId(params: dict[str, Any]) -> dict[str, str]:
|
|
1402
1341
|
"""Get a Download ID.
|
|
1403
1342
|
|
|
1404
1343
|
Args:
|
|
@@ -1447,7 +1386,7 @@ def getTableDownloadId(params: Dict[str, Any]) -> Dict[str, str]:
|
|
|
1447
1386
|
return {'docid': result['name'], 'token': ''}
|
|
1448
1387
|
|
|
1449
1388
|
|
|
1450
|
-
def makeTableDownloadUrl(downloadId:
|
|
1389
|
+
def makeTableDownloadUrl(downloadId: dict[str, str]) -> str:
|
|
1451
1390
|
"""Create a table download URL from a docid.
|
|
1452
1391
|
|
|
1453
1392
|
Args:
|
|
@@ -1456,19 +1395,20 @@ def makeTableDownloadUrl(downloadId: Dict[str, str]) -> str:
|
|
|
1456
1395
|
Returns:
|
|
1457
1396
|
A Url from which the download can be obtained.
|
|
1458
1397
|
"""
|
|
1459
|
-
return '
|
|
1460
|
-
|
|
1398
|
+
return '{}/{}/{}:getFeatures'.format(
|
|
1399
|
+
_get_state().tile_base_url, _cloud_api_utils.VERSION, downloadId['docid']
|
|
1400
|
+
)
|
|
1461
1401
|
|
|
1462
1402
|
|
|
1463
1403
|
def getAlgorithms() -> Any:
|
|
1464
1404
|
"""Get the list of algorithms.
|
|
1465
1405
|
|
|
1466
1406
|
Returns:
|
|
1467
|
-
The dictionary of algorithms.
|
|
1407
|
+
The dictionary of algorithms. Each algorithm is a dictionary containing
|
|
1468
1408
|
the following fields:
|
|
1469
1409
|
"description" - (string) A text description of the algorithm.
|
|
1470
1410
|
"returns" - (string) The return type of the algorithm.
|
|
1471
|
-
"args" - An array of arguments.
|
|
1411
|
+
"args" - An array of arguments. Each argument specifies the following:
|
|
1472
1412
|
"name" - (string) The name of the argument.
|
|
1473
1413
|
"description" - (string) A text description of the argument.
|
|
1474
1414
|
"type" - (string) The type of the argument.
|
|
@@ -1501,10 +1441,10 @@ def getAlgorithms() -> Any:
|
|
|
1501
1441
|
|
|
1502
1442
|
@_utils.accept_opt_prefix('opt_path', 'opt_force', 'opt_properties')
|
|
1503
1443
|
def createAsset(
|
|
1504
|
-
value:
|
|
1505
|
-
path:
|
|
1506
|
-
properties:
|
|
1507
|
-
) ->
|
|
1444
|
+
value: dict[str, Any],
|
|
1445
|
+
path: str | None = None,
|
|
1446
|
+
properties: dict[str, Any] | None = None,
|
|
1447
|
+
) -> dict[str, Any]:
|
|
1508
1448
|
"""Creates an asset from a JSON value.
|
|
1509
1449
|
|
|
1510
1450
|
To create an empty image collection or folder, pass in a "value" object
|
|
@@ -1560,7 +1500,7 @@ def createAsset(
|
|
|
1560
1500
|
)
|
|
1561
1501
|
|
|
1562
1502
|
|
|
1563
|
-
def createFolder(path: str) ->
|
|
1503
|
+
def createFolder(path: str) -> dict[str, Any]:
|
|
1564
1504
|
"""Creates an asset folder.
|
|
1565
1505
|
|
|
1566
1506
|
Returns a description of the newly created folder.
|
|
@@ -1624,7 +1564,7 @@ def deleteAsset(assetId: str) -> None:
|
|
|
1624
1564
|
_execute_cloud_call(_get_cloud_projects().assets().delete(name=name))
|
|
1625
1565
|
|
|
1626
1566
|
|
|
1627
|
-
def newTaskId(count: int = 1) ->
|
|
1567
|
+
def newTaskId(count: int = 1) -> list[str]:
|
|
1628
1568
|
"""Generate an ID for a long-running task.
|
|
1629
1569
|
|
|
1630
1570
|
Args:
|
|
@@ -1637,7 +1577,7 @@ def newTaskId(count: int = 1) -> List[str]:
|
|
|
1637
1577
|
|
|
1638
1578
|
|
|
1639
1579
|
@deprecation.Deprecated('Use listOperations')
|
|
1640
|
-
def getTaskList() ->
|
|
1580
|
+
def getTaskList() -> list[Any]:
|
|
1641
1581
|
"""Retrieves a list of the user's tasks.
|
|
1642
1582
|
|
|
1643
1583
|
Returns:
|
|
@@ -1649,7 +1589,7 @@ def getTaskList() -> List[Any]:
|
|
|
1649
1589
|
for o in listOperations()]
|
|
1650
1590
|
|
|
1651
1591
|
|
|
1652
|
-
def listOperations(project:
|
|
1592
|
+
def listOperations(project: str | None = None) -> list[Any]:
|
|
1653
1593
|
"""Retrieves a list of the user's tasks.
|
|
1654
1594
|
|
|
1655
1595
|
Args:
|
|
@@ -1676,11 +1616,12 @@ def listOperations(project: Optional[str] = None) -> List[Any]:
|
|
|
1676
1616
|
|
|
1677
1617
|
|
|
1678
1618
|
@deprecation.Deprecated('Use getOperation')
|
|
1679
|
-
def getTaskStatus(taskId:
|
|
1619
|
+
def getTaskStatus(taskId: list[str] | str) -> list[Any]:
|
|
1680
1620
|
"""Retrieve status of one or more long-running tasks.
|
|
1681
1621
|
|
|
1682
1622
|
Args:
|
|
1683
|
-
taskId: ID of the task or a list of multiple IDs.
|
|
1623
|
+
taskId: ID of the task or a list of multiple IDs. These will be assumed to
|
|
1624
|
+
be running in the currently initialized project.
|
|
1684
1625
|
|
|
1685
1626
|
Returns:
|
|
1686
1627
|
List containing one object for each queried task, in the same order as
|
|
@@ -1693,21 +1634,25 @@ def getTaskStatus(taskId: Union[List[str], str]) -> List[Any]:
|
|
|
1693
1634
|
"""
|
|
1694
1635
|
if isinstance(taskId, str):
|
|
1695
1636
|
taskId = [taskId]
|
|
1637
|
+
state = _get_state()
|
|
1696
1638
|
result = []
|
|
1697
1639
|
for one_id in taskId:
|
|
1640
|
+
# Don't use getOperation as it will translate the exception, and we need
|
|
1641
|
+
# to handle 404s specially.
|
|
1642
|
+
name = _cloud_api_utils.convert_task_id_to_operation_name(
|
|
1643
|
+
state.cloud_api_user_project, one_id
|
|
1644
|
+
)
|
|
1698
1645
|
try:
|
|
1699
|
-
# Don't use getOperation as it will translate the exception, and we need
|
|
1700
|
-
# to handle 404s specially.
|
|
1701
1646
|
operation = (
|
|
1702
1647
|
_get_cloud_projects()
|
|
1703
1648
|
.operations()
|
|
1704
|
-
.get(name=
|
|
1705
|
-
.execute(num_retries=
|
|
1649
|
+
.get(name=name)
|
|
1650
|
+
.execute(num_retries=state.max_retries)
|
|
1706
1651
|
)
|
|
1707
1652
|
result.append(_cloud_api_utils.convert_operation_to_task(operation))
|
|
1708
1653
|
except googleapiclient.errors.HttpError as e:
|
|
1709
1654
|
if e.resp.status == 404:
|
|
1710
|
-
result.append({'id': one_id, 'state': 'UNKNOWN'})
|
|
1655
|
+
result.append({'id': one_id, 'state': 'UNKNOWN', 'name': name})
|
|
1711
1656
|
else:
|
|
1712
1657
|
raise _translate_cloud_exception(e) # pylint: disable=raise-missing-from
|
|
1713
1658
|
return result
|
|
@@ -1731,7 +1676,11 @@ def getOperation(operation_name: str) -> Any:
|
|
|
1731
1676
|
@deprecation.Deprecated('Use cancelOperation')
|
|
1732
1677
|
def cancelTask(taskId: str) -> None:
|
|
1733
1678
|
"""Cancels a batch task."""
|
|
1734
|
-
cancelOperation(
|
|
1679
|
+
cancelOperation(
|
|
1680
|
+
_cloud_api_utils.convert_task_id_to_operation_name(
|
|
1681
|
+
_get_state().cloud_api_user_project, taskId
|
|
1682
|
+
)
|
|
1683
|
+
)
|
|
1735
1684
|
|
|
1736
1685
|
|
|
1737
1686
|
def cancelOperation(operation_name: str) -> None:
|
|
@@ -1740,7 +1689,7 @@ def cancelOperation(operation_name: str) -> None:
|
|
|
1740
1689
|
)
|
|
1741
1690
|
|
|
1742
1691
|
|
|
1743
|
-
def exportImage(request_id: str, params:
|
|
1692
|
+
def exportImage(request_id: str, params: dict[str, Any]) -> Any:
|
|
1744
1693
|
"""Starts an image export task running.
|
|
1745
1694
|
|
|
1746
1695
|
This is a low-level method. The higher-level ee.batch.Export.image object
|
|
@@ -1767,7 +1716,7 @@ def exportImage(request_id: str, params: Dict[str, Any]) -> Any:
|
|
|
1767
1716
|
)
|
|
1768
1717
|
|
|
1769
1718
|
|
|
1770
|
-
def exportTable(request_id: str, params:
|
|
1719
|
+
def exportTable(request_id: str, params: dict[str, Any]) -> Any:
|
|
1771
1720
|
"""Starts a table export task running.
|
|
1772
1721
|
|
|
1773
1722
|
This is a low-level method. The higher-level ee.batch.Export.table object
|
|
@@ -1794,7 +1743,7 @@ def exportTable(request_id: str, params: Dict[str, Any]) -> Any:
|
|
|
1794
1743
|
)
|
|
1795
1744
|
|
|
1796
1745
|
|
|
1797
|
-
def exportVideo(request_id: str, params:
|
|
1746
|
+
def exportVideo(request_id: str, params: dict[str, Any]) -> Any:
|
|
1798
1747
|
"""Starts a video export task running.
|
|
1799
1748
|
|
|
1800
1749
|
This is a low-level method. The higher-level ee.batch.Export.video object
|
|
@@ -1821,7 +1770,7 @@ def exportVideo(request_id: str, params: Dict[str, Any]) -> Any:
|
|
|
1821
1770
|
)
|
|
1822
1771
|
|
|
1823
1772
|
|
|
1824
|
-
def exportMap(request_id: str, params:
|
|
1773
|
+
def exportMap(request_id: str, params: dict[str, Any]) -> Any:
|
|
1825
1774
|
"""Starts a map export task running.
|
|
1826
1775
|
|
|
1827
1776
|
This is a low-level method. The higher-level ee.batch.Export.map object
|
|
@@ -1848,7 +1797,7 @@ def exportMap(request_id: str, params: Dict[str, Any]) -> Any:
|
|
|
1848
1797
|
)
|
|
1849
1798
|
|
|
1850
1799
|
|
|
1851
|
-
def exportClassifier(request_id: str, params:
|
|
1800
|
+
def exportClassifier(request_id: str, params: dict[str, Any]) -> Any:
|
|
1852
1801
|
"""Starts a classifier export task.
|
|
1853
1802
|
|
|
1854
1803
|
This is a low-level method. The higher-level ee.batch.Export.classifier
|
|
@@ -1876,7 +1825,7 @@ def exportClassifier(request_id: str, params: Dict[str, Any]) -> Any:
|
|
|
1876
1825
|
|
|
1877
1826
|
|
|
1878
1827
|
def _prepare_and_run_export(
|
|
1879
|
-
request_id: str, params:
|
|
1828
|
+
request_id: str, params: dict[str, Any], export_endpoint: Any
|
|
1880
1829
|
) -> Any:
|
|
1881
1830
|
"""Starts an export task running.
|
|
1882
1831
|
|
|
@@ -1905,7 +1854,7 @@ def _prepare_and_run_export(
|
|
|
1905
1854
|
if isinstance(params['expression'], encodable.Encodable):
|
|
1906
1855
|
params['expression'] = serializer.encode(
|
|
1907
1856
|
params['expression'], for_cloud_api=True)
|
|
1908
|
-
num_retries =
|
|
1857
|
+
num_retries = _get_state().max_retries if request_id else 0
|
|
1909
1858
|
return _execute_cloud_call(
|
|
1910
1859
|
export_endpoint(project=_get_projects_path(), body=params),
|
|
1911
1860
|
num_retries=num_retries)
|
|
@@ -1917,10 +1866,10 @@ _EXTERNAL_IMPORT = 'EXTERNAL_IMPORT'
|
|
|
1917
1866
|
|
|
1918
1867
|
def _startIngestion(
|
|
1919
1868
|
request_id: Any,
|
|
1920
|
-
params:
|
|
1869
|
+
params: dict[str, Any],
|
|
1921
1870
|
allow_overwrite: bool = False,
|
|
1922
|
-
import_mode:
|
|
1923
|
-
) ->
|
|
1871
|
+
import_mode: str | None = _INTERNAL_IMPORT,
|
|
1872
|
+
) -> dict[str, Any]:
|
|
1924
1873
|
"""Starts an ingestion task or creates an external image."""
|
|
1925
1874
|
request = {
|
|
1926
1875
|
'imageManifest':
|
|
@@ -1931,7 +1880,7 @@ def _startIngestion(
|
|
|
1931
1880
|
|
|
1932
1881
|
# It's only safe to retry the request if there's a unique ID to make it
|
|
1933
1882
|
# idempotent.
|
|
1934
|
-
num_retries =
|
|
1883
|
+
num_retries = _get_state().max_retries if request_id else 0
|
|
1935
1884
|
|
|
1936
1885
|
image = _get_cloud_projects().image()
|
|
1937
1886
|
if import_mode == _INTERNAL_IMPORT:
|
|
@@ -1941,9 +1890,7 @@ def _startIngestion(
|
|
|
1941
1890
|
project=_get_projects_path(), body=request
|
|
1942
1891
|
)
|
|
1943
1892
|
else:
|
|
1944
|
-
raise ee_exception.EEException(
|
|
1945
|
-
'{} is not a valid import mode'.format(import_mode)
|
|
1946
|
-
)
|
|
1893
|
+
raise ee_exception.EEException(f'{import_mode} is not a valid import mode')
|
|
1947
1894
|
|
|
1948
1895
|
result = _execute_cloud_call(
|
|
1949
1896
|
import_request,
|
|
@@ -1964,9 +1911,9 @@ def _startIngestion(
|
|
|
1964
1911
|
|
|
1965
1912
|
def startIngestion(
|
|
1966
1913
|
request_id: Any,
|
|
1967
|
-
params:
|
|
1914
|
+
params: dict[str, Any],
|
|
1968
1915
|
allow_overwrite: bool = False,
|
|
1969
|
-
) ->
|
|
1916
|
+
) -> dict[str, Any]:
|
|
1970
1917
|
"""Creates an image asset import task.
|
|
1971
1918
|
|
|
1972
1919
|
Args:
|
|
@@ -2001,9 +1948,9 @@ def startIngestion(
|
|
|
2001
1948
|
|
|
2002
1949
|
|
|
2003
1950
|
def startExternalImageIngestion(
|
|
2004
|
-
image_manifest:
|
|
1951
|
+
image_manifest: dict[str, Any],
|
|
2005
1952
|
allow_overwrite: bool = False,
|
|
2006
|
-
) ->
|
|
1953
|
+
) -> dict[str, Any]:
|
|
2007
1954
|
"""Creates an external image.
|
|
2008
1955
|
|
|
2009
1956
|
Args:
|
|
@@ -2033,8 +1980,8 @@ def startExternalImageIngestion(
|
|
|
2033
1980
|
|
|
2034
1981
|
|
|
2035
1982
|
def startTableIngestion(
|
|
2036
|
-
request_id: str, params:
|
|
2037
|
-
) ->
|
|
1983
|
+
request_id: str, params: dict[str, Any], allow_overwrite: bool = False
|
|
1984
|
+
) -> dict[str, Any]:
|
|
2038
1985
|
"""Creates a table asset import task.
|
|
2039
1986
|
|
|
2040
1987
|
Args:
|
|
@@ -2068,7 +2015,7 @@ def startTableIngestion(
|
|
|
2068
2015
|
}
|
|
2069
2016
|
# It's only safe to retry the request if there's a unique ID to make it
|
|
2070
2017
|
# idempotent.
|
|
2071
|
-
num_retries =
|
|
2018
|
+
num_retries = _get_state().max_retries if request_id else 0
|
|
2072
2019
|
operation = _execute_cloud_call(
|
|
2073
2020
|
_get_cloud_projects()
|
|
2074
2021
|
.table()
|
|
@@ -2103,7 +2050,7 @@ def getAssetRoots() -> Any:
|
|
|
2103
2050
|
listBuckets())
|
|
2104
2051
|
|
|
2105
2052
|
|
|
2106
|
-
def getAssetRootQuota(rootId: str) ->
|
|
2053
|
+
def getAssetRootQuota(rootId: str) -> dict[str, Any]:
|
|
2107
2054
|
"""Returns quota usage details for the asset root with the given ID.
|
|
2108
2055
|
|
|
2109
2056
|
Usage notes:
|
|
@@ -2123,7 +2070,7 @@ def getAssetRootQuota(rootId: str) -> Dict[str, Any]:
|
|
|
2123
2070
|
"""
|
|
2124
2071
|
asset = getAsset(rootId)
|
|
2125
2072
|
if 'quota' not in asset:
|
|
2126
|
-
raise ee_exception.EEException('{} is not a root folder.'
|
|
2073
|
+
raise ee_exception.EEException(f'{rootId} is not a root folder.')
|
|
2127
2074
|
quota = asset['quota']
|
|
2128
2075
|
# The quota fields are int64s, and int64s are represented as strings in
|
|
2129
2076
|
# JSON. Turn them back.
|
|
@@ -2179,7 +2126,7 @@ def getIamPolicy(asset_id: str) -> Any:
|
|
|
2179
2126
|
|
|
2180
2127
|
|
|
2181
2128
|
@deprecation.Deprecated('Use setIamPolicy')
|
|
2182
|
-
def setAssetAcl(assetId: str, aclUpdate:
|
|
2129
|
+
def setAssetAcl(assetId: str, aclUpdate: str | dict[str, Any]) -> None:
|
|
2183
2130
|
"""Sets the access control list of the asset with the given ID.
|
|
2184
2131
|
|
|
2185
2132
|
The owner ACL cannot be changed, and the final ACL of the asset
|
|
@@ -2214,8 +2161,9 @@ def setIamPolicy(asset_id: str, policy: Any) -> None:
|
|
|
2214
2161
|
.setIamPolicy(resource=name, body={'policy': policy}, prettyPrint=False)
|
|
2215
2162
|
)
|
|
2216
2163
|
|
|
2164
|
+
|
|
2217
2165
|
@deprecation.Deprecated('Use ee.data.updateAsset().')
|
|
2218
|
-
def setAssetProperties(assetId: str, properties:
|
|
2166
|
+
def setAssetProperties(assetId: str, properties: dict[str, Any]) -> None:
|
|
2219
2167
|
"""Sets metadata properties of the asset with the given ID.
|
|
2220
2168
|
|
|
2221
2169
|
To delete a property, set its value to None.
|
|
@@ -2280,7 +2228,7 @@ def _get_config_path() -> str:
|
|
|
2280
2228
|
return f'{_get_projects_path()}/config'
|
|
2281
2229
|
|
|
2282
2230
|
|
|
2283
|
-
def getProjectConfig() ->
|
|
2231
|
+
def getProjectConfig() -> dict[str, Any]:
|
|
2284
2232
|
"""Gets the project config for the current project.
|
|
2285
2233
|
|
|
2286
2234
|
Returns:
|
|
@@ -2292,8 +2240,8 @@ def getProjectConfig() -> Dict[str, Any]:
|
|
|
2292
2240
|
|
|
2293
2241
|
|
|
2294
2242
|
def updateProjectConfig(
|
|
2295
|
-
project_config:
|
|
2296
|
-
) ->
|
|
2243
|
+
project_config: dict[str, Any], update_mask: Sequence[str] | None = None
|
|
2244
|
+
) -> dict[str, Any]:
|
|
2297
2245
|
"""Updates the project config for the current project.
|
|
2298
2246
|
|
|
2299
2247
|
Args:
|
|
@@ -2321,8 +2269,8 @@ def updateProjectConfig(
|
|
|
2321
2269
|
|
|
2322
2270
|
|
|
2323
2271
|
def authorizeHttp(http: Any) -> Any:
|
|
2324
|
-
if
|
|
2325
|
-
return google_auth_httplib2.AuthorizedHttp(
|
|
2272
|
+
if credentials := _get_state().credentials:
|
|
2273
|
+
return google_auth_httplib2.AuthorizedHttp(credentials)
|
|
2326
2274
|
else:
|
|
2327
2275
|
return http
|
|
2328
2276
|
|
|
@@ -2364,12 +2312,12 @@ def convert_asset_id_to_asset_name(asset_id: str) -> str:
|
|
|
2364
2312
|
return _cloud_api_utils.convert_asset_id_to_asset_name(asset_id)
|
|
2365
2313
|
|
|
2366
2314
|
|
|
2367
|
-
def getWorkloadTag() ->
|
|
2315
|
+
def getWorkloadTag() -> int | str | None:
|
|
2368
2316
|
"""Returns the currently set workload tag."""
|
|
2369
|
-
return
|
|
2317
|
+
return _get_state().workload_tag.get()
|
|
2370
2318
|
|
|
2371
2319
|
|
|
2372
|
-
def setWorkloadTag(tag:
|
|
2320
|
+
def setWorkloadTag(tag: int | str | None) -> None:
|
|
2373
2321
|
"""Sets the workload tag, used to label computation and exports.
|
|
2374
2322
|
|
|
2375
2323
|
Workload tag must be 1 - 63 characters, beginning and ending with an
|
|
@@ -2379,11 +2327,11 @@ def setWorkloadTag(tag: Optional[Union[int, str]]) -> None:
|
|
|
2379
2327
|
Args:
|
|
2380
2328
|
tag: The tag to set.
|
|
2381
2329
|
"""
|
|
2382
|
-
|
|
2330
|
+
_get_state().workload_tag.set(tag)
|
|
2383
2331
|
|
|
2384
2332
|
|
|
2385
2333
|
@contextlib.contextmanager
|
|
2386
|
-
def workloadTagContext(tag:
|
|
2334
|
+
def workloadTagContext(tag: int | str | None) -> Iterator[None]:
|
|
2387
2335
|
"""Produces a context manager which sets the workload tag, then resets it.
|
|
2388
2336
|
|
|
2389
2337
|
Workload tag must be 1 - 63 characters, beginning and ending with an
|
|
@@ -2403,7 +2351,7 @@ def workloadTagContext(tag: Optional[Union[int, str]]) -> Iterator[None]:
|
|
|
2403
2351
|
resetWorkloadTag()
|
|
2404
2352
|
|
|
2405
2353
|
|
|
2406
|
-
def setDefaultWorkloadTag(tag:
|
|
2354
|
+
def setDefaultWorkloadTag(tag: int | str | None) -> None:
|
|
2407
2355
|
"""Sets the workload tag, and as the default for which to reset back to.
|
|
2408
2356
|
|
|
2409
2357
|
For example, calling `ee.data.resetWorkloadTag()` will reset the workload tag
|
|
@@ -2418,8 +2366,9 @@ def setDefaultWorkloadTag(tag: Optional[Union[int, str]]) -> None:
|
|
|
2418
2366
|
Args:
|
|
2419
2367
|
tag: The tag to set.
|
|
2420
2368
|
"""
|
|
2421
|
-
|
|
2422
|
-
|
|
2369
|
+
state = _get_state()
|
|
2370
|
+
state.workload_tag.set_default(tag)
|
|
2371
|
+
state.workload_tag.set(tag)
|
|
2423
2372
|
|
|
2424
2373
|
|
|
2425
2374
|
@_utils.accept_opt_prefix('opt_resetDefault')
|
|
@@ -2432,58 +2381,7 @@ def resetWorkloadTag(resetDefault: bool = False) -> None:
|
|
|
2432
2381
|
Args:
|
|
2433
2382
|
resetDefault: Whether to reset the default back to empty.
|
|
2434
2383
|
"""
|
|
2384
|
+
state = _get_state()
|
|
2435
2385
|
if resetDefault:
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
# TODO(user): Consider only returning str even for ints.
|
|
2441
|
-
class _WorkloadTag:
|
|
2442
|
-
"""A helper class to manage the workload tag."""
|
|
2443
|
-
_tag: Optional[Union[int, str]]
|
|
2444
|
-
_default: Optional[Union[int, str]]
|
|
2445
|
-
|
|
2446
|
-
def __init__(self):
|
|
2447
|
-
# TODO(user): Consider using None as default and setting them above.
|
|
2448
|
-
self._tag = ''
|
|
2449
|
-
self._default = ''
|
|
2450
|
-
|
|
2451
|
-
def get(self) -> Union[int, str, None]:
|
|
2452
|
-
return self._tag
|
|
2453
|
-
|
|
2454
|
-
def set(self, tag: Optional[Union[int, str]]) -> None:
|
|
2455
|
-
self._tag = self.validate(tag)
|
|
2456
|
-
|
|
2457
|
-
def setDefault(self, newDefault: Optional[Union[int, str]]) -> None:
|
|
2458
|
-
self._default = self.validate(newDefault)
|
|
2459
|
-
|
|
2460
|
-
def reset(self) -> None:
|
|
2461
|
-
self._tag = self._default
|
|
2462
|
-
|
|
2463
|
-
def validate(self, tag: Optional[Union[int, str]]) -> str:
|
|
2464
|
-
"""Throws an error if setting an invalid tag.
|
|
2465
|
-
|
|
2466
|
-
Args:
|
|
2467
|
-
tag: the tag to validate.
|
|
2468
|
-
|
|
2469
|
-
Returns:
|
|
2470
|
-
The validated tag.
|
|
2471
|
-
|
|
2472
|
-
Raises:
|
|
2473
|
-
ValueError if the tag does not match the expected format.
|
|
2474
|
-
"""
|
|
2475
|
-
if not tag and tag != 0:
|
|
2476
|
-
return ''
|
|
2477
|
-
tag = str(tag)
|
|
2478
|
-
if not re.fullmatch(r'([a-z0-9]|[a-z0-9][-_a-z0-9]{0,61}[a-z0-9])', tag):
|
|
2479
|
-
validationMessage = (
|
|
2480
|
-
'Tags must be 1-63 characters, '
|
|
2481
|
-
'beginning and ending with a lowercase alphanumeric character '
|
|
2482
|
-
'([a-z0-9]) with dashes (-), underscores (_), '
|
|
2483
|
-
'and lowercase alphanumerics between.')
|
|
2484
|
-
raise ValueError(f'Invalid tag, "{tag}". {validationMessage}')
|
|
2485
|
-
return tag
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
# Tracks the currently set workload tag.
|
|
2489
|
-
_workloadTag = _WorkloadTag()
|
|
2386
|
+
state.workload_tag.set_default('')
|
|
2387
|
+
state.workload_tag.reset()
|