earthengine-api 1.6.13__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.6.13.dist-info → earthengine_api-1.7.4.dist-info}/METADATA +2 -3
- {earthengine_api-1.6.13.dist-info → earthengine_api-1.7.4.dist-info}/RECORD +44 -44
- ee/__init__.py +13 -13
- ee/_cloud_api_utils.py +29 -28
- ee/_helpers.py +6 -6
- ee/_utils.py +2 -1
- ee/apitestcase.py +10 -10
- ee/batch.py +7 -0
- ee/cli/commands.py +6 -10
- ee/cli/utils.py +28 -23
- ee/collection.py +3 -2
- ee/computedobject.py +4 -1
- ee/customfunction.py +2 -1
- ee/data.py +32 -31
- ee/deprecation.py +8 -2
- ee/deserializer.py +10 -10
- ee/ee_number.py +6 -16
- ee/encodable.py +2 -1
- ee/image_converter.py +3 -3
- ee/imagecollection.py +2 -2
- ee/model.py +29 -31
- ee/oauth.py +37 -37
- ee/reducer.py +2 -0
- ee/serializer.py +6 -6
- ee/table_converter.py +3 -3
- ee/terrain.py +1 -1
- ee/tests/batch_test.py +67 -3
- ee/tests/collection_test.py +35 -0
- ee/tests/data_test.py +300 -4
- ee/tests/deprecation_test.py +4 -2
- ee/tests/deserializer_test.py +47 -0
- ee/tests/ee_number_test.py +40 -1
- ee/tests/image_converter_test.py +1 -3
- ee/tests/kernel_test.py +4 -0
- ee/tests/model_test.py +12 -0
- ee/tests/oauth_test.py +170 -7
- ee/tests/reducer_test.py +13 -0
- ee/tests/serializer_test.py +29 -2
- ee/tests/table_converter_test.py +49 -5
- ee/tests/terrain_test.py +8 -0
- {earthengine_api-1.6.13.dist-info → earthengine_api-1.7.4.dist-info}/WHEEL +0 -0
- {earthengine_api-1.6.13.dist-info → earthengine_api-1.7.4.dist-info}/entry_points.txt +0 -0
- {earthengine_api-1.6.13.dist-info → earthengine_api-1.7.4.dist-info}/licenses/LICENSE +0 -0
- {earthengine_api-1.6.13.dist-info → earthengine_api-1.7.4.dist-info}/top_level.txt +0 -0
ee/tests/data_test.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"""Test for the ee.data module."""
|
|
3
3
|
|
|
4
4
|
import json
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
6
6
|
from unittest import mock
|
|
7
7
|
|
|
8
8
|
import googleapiclient
|
|
@@ -28,7 +28,7 @@ def NotFoundError() -> googleapiclient.errors.HttpError:
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
def NewFolderAsset(
|
|
31
|
-
name: str, quota:
|
|
31
|
+
name: str, quota: dict[str, int] | None = None
|
|
32
32
|
) -> dict[str, Any]:
|
|
33
33
|
return {
|
|
34
34
|
'type': 'FOLDER',
|
|
@@ -66,7 +66,9 @@ class DataTest(unittest.TestCase):
|
|
|
66
66
|
mock_install_cloud_api_resource.assert_called_once()
|
|
67
67
|
|
|
68
68
|
@mock.patch.object(ee.data, '_install_cloud_api_resource', return_value=None)
|
|
69
|
-
def test_initialize_with_project(
|
|
69
|
+
def test_initialize_with_project(
|
|
70
|
+
self, unused_mock_install_cloud_api_resource
|
|
71
|
+
):
|
|
70
72
|
ee.data.initialize(project='my-project')
|
|
71
73
|
|
|
72
74
|
self.assertTrue(ee.data.is_initialized())
|
|
@@ -85,6 +87,26 @@ class DataTest(unittest.TestCase):
|
|
|
85
87
|
_state.get_state().cloud_api_user_project, 'earthengine-legacy'
|
|
86
88
|
)
|
|
87
89
|
|
|
90
|
+
@mock.patch.object(ee.data, '_install_cloud_api_resource', return_value=None)
|
|
91
|
+
def test_initialize_with_credentials(
|
|
92
|
+
self, unused_mock_install_cloud_api_resource
|
|
93
|
+
):
|
|
94
|
+
creds = mock.MagicMock()
|
|
95
|
+
ee.data.initialize(credentials=creds)
|
|
96
|
+
|
|
97
|
+
self.assertTrue(ee.data.is_initialized())
|
|
98
|
+
self.assertEqual(creds, _state.get_state().credentials)
|
|
99
|
+
|
|
100
|
+
@mock.patch.object(ee.data, '_install_cloud_api_resource', return_value=None)
|
|
101
|
+
def test_initialize_with_cloud_api_key(
|
|
102
|
+
self, unused_mock_install_cloud_api_resource
|
|
103
|
+
):
|
|
104
|
+
cloud_api_key = 'a cloud api key'
|
|
105
|
+
ee.data.initialize(cloud_api_key=cloud_api_key)
|
|
106
|
+
|
|
107
|
+
self.assertTrue(ee.data.is_initialized())
|
|
108
|
+
self.assertEqual(cloud_api_key, _state.get_state().cloud_api_key)
|
|
109
|
+
|
|
88
110
|
def test_set_max_retries_bad_values(self):
|
|
89
111
|
with self.assertRaises(ValueError):
|
|
90
112
|
ee.data.setMaxRetries(-1)
|
|
@@ -108,6 +130,46 @@ class DataTest(unittest.TestCase):
|
|
|
108
130
|
.execute.call_args.kwargs['num_retries'],
|
|
109
131
|
)
|
|
110
132
|
|
|
133
|
+
def test_set_cloud_api_key(self):
|
|
134
|
+
cloud_api_key = 'a cloud api key'
|
|
135
|
+
with mock.patch.object(
|
|
136
|
+
ee.data, '_install_cloud_api_resource', return_value=None
|
|
137
|
+
) as mock_install_cloud_api_resource:
|
|
138
|
+
ee.data.setCloudApiKey(cloud_api_key)
|
|
139
|
+
self.assertEqual(cloud_api_key, _state.get_state().cloud_api_key)
|
|
140
|
+
mock_install_cloud_api_resource.assert_called_once()
|
|
141
|
+
|
|
142
|
+
def test_set_deadline(self):
|
|
143
|
+
deadline_ms = 12345
|
|
144
|
+
with mock.patch.object(
|
|
145
|
+
ee.data, '_install_cloud_api_resource', return_value=None
|
|
146
|
+
) as mock_install_cloud_api_resource:
|
|
147
|
+
ee.data.setDeadline(deadline_ms)
|
|
148
|
+
self.assertEqual(deadline_ms, _state.get_state().deadline_ms)
|
|
149
|
+
mock_install_cloud_api_resource.assert_called_once()
|
|
150
|
+
|
|
151
|
+
def test_get_set_user_agent(self):
|
|
152
|
+
self.assertIsNone(ee.data.getUserAgent())
|
|
153
|
+
user_agent = 'user-agent'
|
|
154
|
+
ee.data.setUserAgent(user_agent)
|
|
155
|
+
self.assertEqual(user_agent, ee.data.getUserAgent())
|
|
156
|
+
|
|
157
|
+
def test_authorize_http_no_credentials(self):
|
|
158
|
+
self.assertIsNone(ee.data._get_state().credentials)
|
|
159
|
+
http = mock.MagicMock()
|
|
160
|
+
self.assertEqual(http, ee.data.authorizeHttp(http))
|
|
161
|
+
|
|
162
|
+
def test_authorize_http_with_credentials(self):
|
|
163
|
+
creds = mock.MagicMock()
|
|
164
|
+
ee.data._get_state().credentials = creds
|
|
165
|
+
http = mock.MagicMock()
|
|
166
|
+
with mock.patch.object(
|
|
167
|
+
ee.data.google_auth_httplib2, 'AuthorizedHttp'
|
|
168
|
+
) as mock_authorized_http:
|
|
169
|
+
result = ee.data.authorizeHttp(http)
|
|
170
|
+
self.assertEqual(mock_authorized_http.return_value, result)
|
|
171
|
+
mock_authorized_http.assert_called_once_with(creds)
|
|
172
|
+
|
|
111
173
|
def test_list_operations(self):
|
|
112
174
|
mock_http = mock.MagicMock(httplib2.Http)
|
|
113
175
|
# Return in three groups.
|
|
@@ -340,6 +402,14 @@ class DataTest(unittest.TestCase):
|
|
|
340
402
|
asset = mock_create_asset.call_args.kwargs['body']
|
|
341
403
|
self.assertEqual(asset, {'type': 'FOLDER'})
|
|
342
404
|
|
|
405
|
+
@mock.patch.object(ee.data, 'createAsset')
|
|
406
|
+
def test_create_asset_home(self, mock_create_asset):
|
|
407
|
+
ee.data.createAssetHome('users/test')
|
|
408
|
+
mock_create_asset.assert_called_once_with({
|
|
409
|
+
'name': 'projects/earthengine-legacy/assets/users/test',
|
|
410
|
+
'type': 'FOLDER',
|
|
411
|
+
})
|
|
412
|
+
|
|
343
413
|
def test_create_assets(self):
|
|
344
414
|
cloud_api_resource = mock.MagicMock()
|
|
345
415
|
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
@@ -430,6 +500,68 @@ class DataTest(unittest.TestCase):
|
|
|
430
500
|
)
|
|
431
501
|
self.assertTrue(import_args['overwrite'])
|
|
432
502
|
|
|
503
|
+
def test_start_table_ingestion(self):
|
|
504
|
+
cloud_api_resource = mock.MagicMock()
|
|
505
|
+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
506
|
+
mock_result = {'name': 'operations/ingestion', 'done': False}
|
|
507
|
+
cloud_api_resource.projects().table().import_.return_value.execute.return_value = (
|
|
508
|
+
mock_result
|
|
509
|
+
)
|
|
510
|
+
params = {
|
|
511
|
+
'id': 'users/test/table',
|
|
512
|
+
'sources': [{'uris': ['gs://bucket/file.shp'], 'charset': 'UTF-8'}],
|
|
513
|
+
}
|
|
514
|
+
result = ee.data.startTableIngestion('request_id', params, True)
|
|
515
|
+
self.assertEqual(result['id'], 'ingestion')
|
|
516
|
+
self.assertEqual(result['name'], 'operations/ingestion')
|
|
517
|
+
|
|
518
|
+
mock_import = cloud_api_resource.projects().table().import_
|
|
519
|
+
mock_import.assert_called_once()
|
|
520
|
+
call_kwargs = mock_import.call_args.kwargs
|
|
521
|
+
self.assertEqual(call_kwargs['project'], 'projects/earthengine-legacy')
|
|
522
|
+
body = call_kwargs['body']
|
|
523
|
+
self.assertEqual(
|
|
524
|
+
body['tableManifest'],
|
|
525
|
+
{
|
|
526
|
+
'name': 'projects/earthengine-legacy/assets/users/test/table',
|
|
527
|
+
'sources': [
|
|
528
|
+
{'uris': ['gs://bucket/file.shp'], 'charset': 'UTF-8'}
|
|
529
|
+
],
|
|
530
|
+
},
|
|
531
|
+
)
|
|
532
|
+
self.assertEqual(body['requestId'], 'request_id')
|
|
533
|
+
self.assertTrue(body['overwrite'])
|
|
534
|
+
|
|
535
|
+
def test_start_external_image_ingestion(self):
|
|
536
|
+
cloud_api_resource = mock.MagicMock()
|
|
537
|
+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
538
|
+
cloud_api_resource.projects().image().importExternal.return_value.execute.return_value = (
|
|
539
|
+
{}
|
|
540
|
+
)
|
|
541
|
+
manifest = {
|
|
542
|
+
'id': 'users/test/image',
|
|
543
|
+
'tilesets': [{'sources': [{'uris': ['gs://bucket/file.tif']}]}],
|
|
544
|
+
}
|
|
545
|
+
result = ee.data.startExternalImageIngestion(manifest, True)
|
|
546
|
+
expected_name = 'projects/earthengine-legacy/assets/users/test/image'
|
|
547
|
+
self.assertEqual(result['name'], expected_name)
|
|
548
|
+
|
|
549
|
+
mock_import_external = (
|
|
550
|
+
cloud_api_resource.projects().image().importExternal
|
|
551
|
+
)
|
|
552
|
+
mock_import_external.assert_called_once()
|
|
553
|
+
call_kwargs = mock_import_external.call_args.kwargs
|
|
554
|
+
self.assertEqual(call_kwargs['project'], 'projects/earthengine-legacy')
|
|
555
|
+
body = call_kwargs['body']
|
|
556
|
+
self.assertEqual(
|
|
557
|
+
body['imageManifest'],
|
|
558
|
+
{
|
|
559
|
+
'name': expected_name,
|
|
560
|
+
'tilesets': [{'sources': [{'uris': ['gs://bucket/file.tif']}]}],
|
|
561
|
+
},
|
|
562
|
+
)
|
|
563
|
+
self.assertTrue(body['overwrite'])
|
|
564
|
+
|
|
433
565
|
def test_set_asset_properties(self):
|
|
434
566
|
mock_http = mock.MagicMock(httplib2.Http)
|
|
435
567
|
with apitestcase.UsingCloudApi(mock_http=mock_http), mock.patch.object(
|
|
@@ -451,6 +583,18 @@ class DataTest(unittest.TestCase):
|
|
|
451
583
|
{'properties.\"mYPropErTy\"',
|
|
452
584
|
'properties.\"system:time_start\"'})
|
|
453
585
|
|
|
586
|
+
def test_update_asset(self):
|
|
587
|
+
cloud_api_resource = mock.MagicMock()
|
|
588
|
+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
589
|
+
asset_id = 'users/test/asset'
|
|
590
|
+
asset = {'properties': {'foo': 'bar'}}
|
|
591
|
+
update_mask = ['properties.foo']
|
|
592
|
+
ee.data.updateAsset(asset_id, asset, update_mask)
|
|
593
|
+
cloud_api_resource.projects().assets().patch.assert_called_once_with(
|
|
594
|
+
name='projects/earthengine-legacy/assets/users/test/asset',
|
|
595
|
+
body={'updateMask': {'paths': update_mask}, 'asset': asset},
|
|
596
|
+
)
|
|
597
|
+
|
|
454
598
|
def test_list_assets(self):
|
|
455
599
|
cloud_api_resource = mock.MagicMock()
|
|
456
600
|
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
@@ -574,6 +718,16 @@ class DataTest(unittest.TestCase):
|
|
|
574
718
|
cloud_api_resource.projects().listAssets().execute.assert_called_once()
|
|
575
719
|
self.assertEqual(mock_result, actual_result)
|
|
576
720
|
|
|
721
|
+
def test_get_asset_roots(self):
|
|
722
|
+
with mock.patch.object(
|
|
723
|
+
ee.data,
|
|
724
|
+
'listBuckets',
|
|
725
|
+
return_value={'assets': [{'name': 'id1', 'type': 'FOLDER'}]},
|
|
726
|
+
) as mock_list_buckets:
|
|
727
|
+
result = ee.data.getAssetRoots()
|
|
728
|
+
mock_list_buckets.assert_called_once()
|
|
729
|
+
self.assertEqual([{'id': 'id1', 'type': 'Folder'}], result)
|
|
730
|
+
|
|
577
731
|
def test_simple_get_list_via_cloud_api(self):
|
|
578
732
|
cloud_api_resource = mock.MagicMock()
|
|
579
733
|
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
@@ -879,6 +1033,50 @@ class DataTest(unittest.TestCase):
|
|
|
879
1033
|
).execute.assert_called_once()
|
|
880
1034
|
self.assertEqual(mock_result, actual_result)
|
|
881
1035
|
|
|
1036
|
+
def test_get_pixels(self):
|
|
1037
|
+
cloud_api_resource_raw = mock.MagicMock()
|
|
1038
|
+
with apitestcase.UsingCloudApi(
|
|
1039
|
+
cloud_api_resource_raw=cloud_api_resource_raw
|
|
1040
|
+
):
|
|
1041
|
+
assets = cloud_api_resource_raw.projects().assets()
|
|
1042
|
+
mock_result = b'pixel data'
|
|
1043
|
+
assets.getPixels.return_value.execute.return_value = mock_result
|
|
1044
|
+
asset_id = 'users/foo/bar'
|
|
1045
|
+
params = {'assetId': asset_id}
|
|
1046
|
+
result = ee.data.getPixels(params)
|
|
1047
|
+
self.assertEqual(mock_result, result)
|
|
1048
|
+
assets.getPixels.assert_called_once_with(
|
|
1049
|
+
name='projects/earthengine-legacy/assets/users/foo/bar',
|
|
1050
|
+
body={'fileFormat': 'AUTO_JPEG_PNG'},
|
|
1051
|
+
)
|
|
1052
|
+
|
|
1053
|
+
def test_compute_pixels(self):
|
|
1054
|
+
cloud_api_resource_raw = mock.MagicMock()
|
|
1055
|
+
with apitestcase.UsingCloudApi(
|
|
1056
|
+
cloud_api_resource_raw=cloud_api_resource_raw
|
|
1057
|
+
):
|
|
1058
|
+
mock_result = b'pixel data'
|
|
1059
|
+
(
|
|
1060
|
+
cloud_api_resource_raw.projects()
|
|
1061
|
+
.image()
|
|
1062
|
+
.computePixels.return_value.execute.return_value
|
|
1063
|
+
) = mock_result
|
|
1064
|
+
expression = ee.Image(1)
|
|
1065
|
+
params = {'expression': expression}
|
|
1066
|
+
result = ee.data.computePixels(params)
|
|
1067
|
+
self.assertEqual(mock_result, result)
|
|
1068
|
+
(
|
|
1069
|
+
cloud_api_resource_raw.projects()
|
|
1070
|
+
.image()
|
|
1071
|
+
.computePixels.assert_called_once_with(
|
|
1072
|
+
project='projects/earthengine-legacy',
|
|
1073
|
+
body={
|
|
1074
|
+
'expression': ee.serializer.encode(expression),
|
|
1075
|
+
'fileFormat': 'AUTO_JPEG_PNG',
|
|
1076
|
+
},
|
|
1077
|
+
)
|
|
1078
|
+
)
|
|
1079
|
+
|
|
882
1080
|
def test_get_feature_view_tiles_key(self):
|
|
883
1081
|
cloud_api_resource = mock.MagicMock()
|
|
884
1082
|
_state.get_state().tile_base_url = 'base_url'
|
|
@@ -920,8 +1118,31 @@ class DataTest(unittest.TestCase):
|
|
|
920
1118
|
cloud_api_resource.projects().updateConfig().execute.return_value = (
|
|
921
1119
|
mock_result
|
|
922
1120
|
)
|
|
1121
|
+
project_config = {'maxConcurrentExports': 2}
|
|
923
1122
|
actual_result = ee.data.updateProjectConfig(
|
|
924
|
-
|
|
1123
|
+
project_config, ['max_concurrent_exports']
|
|
1124
|
+
)
|
|
1125
|
+
cloud_api_resource.projects().updateConfig.assert_called_with(
|
|
1126
|
+
name='projects/earthengine-legacy/config',
|
|
1127
|
+
body=project_config,
|
|
1128
|
+
updateMask='max_concurrent_exports',
|
|
1129
|
+
)
|
|
1130
|
+
cloud_api_resource.projects().updateConfig().execute.assert_called_once()
|
|
1131
|
+
self.assertEqual(mock_result, actual_result)
|
|
1132
|
+
|
|
1133
|
+
def test_update_project_config_no_mask(self) -> None:
|
|
1134
|
+
cloud_api_resource = mock.MagicMock()
|
|
1135
|
+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
1136
|
+
mock_result = {'fake-project-config-value': 1}
|
|
1137
|
+
cloud_api_resource.projects().updateConfig().execute.return_value = (
|
|
1138
|
+
mock_result
|
|
1139
|
+
)
|
|
1140
|
+
project_config = {'maxConcurrentExports': 2}
|
|
1141
|
+
actual_result = ee.data.updateProjectConfig(project_config)
|
|
1142
|
+
cloud_api_resource.projects().updateConfig.assert_called_with(
|
|
1143
|
+
name='projects/earthengine-legacy/config',
|
|
1144
|
+
body=project_config,
|
|
1145
|
+
updateMask='max_concurrent_exports',
|
|
925
1146
|
)
|
|
926
1147
|
cloud_api_resource.projects().updateConfig().execute.assert_called_once()
|
|
927
1148
|
self.assertEqual(mock_result, actual_result)
|
|
@@ -1038,6 +1259,81 @@ class DataTest(unittest.TestCase):
|
|
|
1038
1259
|
}
|
|
1039
1260
|
self.assertEqual(expected, quota)
|
|
1040
1261
|
|
|
1262
|
+
def test_get_asset_root_quota_not_root(self):
|
|
1263
|
+
cloud_api_resource = mock.MagicMock()
|
|
1264
|
+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
1265
|
+
asset_id = 'users/test/asset'
|
|
1266
|
+
fake_asset = {
|
|
1267
|
+
'type': 'IMAGE',
|
|
1268
|
+
'name': 'projects/earthengine-legacy/assets/users/test/asset',
|
|
1269
|
+
}
|
|
1270
|
+
cloud_api_resource.projects().assets().get().execute.return_value = (
|
|
1271
|
+
fake_asset
|
|
1272
|
+
)
|
|
1273
|
+
with self.assertRaisesRegex(
|
|
1274
|
+
ee.ee_exception.EEException, f'{asset_id} is not a root folder.'
|
|
1275
|
+
):
|
|
1276
|
+
ee.data.getAssetRootQuota(asset_id)
|
|
1277
|
+
|
|
1278
|
+
def test_get_iam_policy(self):
|
|
1279
|
+
cloud_api_resource = mock.MagicMock()
|
|
1280
|
+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
1281
|
+
asset_id = 'users/test/asset'
|
|
1282
|
+
ee.data.getIamPolicy(asset_id)
|
|
1283
|
+
cloud_api_resource.projects().assets().getIamPolicy.assert_called_once_with(
|
|
1284
|
+
resource='projects/earthengine-legacy/assets/users/test/asset',
|
|
1285
|
+
body={},
|
|
1286
|
+
prettyPrint=False,
|
|
1287
|
+
)
|
|
1288
|
+
|
|
1289
|
+
def test_get_asset_acl(self):
|
|
1290
|
+
asset_id = 'users/test/asset'
|
|
1291
|
+
policy = {'bindings': [{'role': 'roles/viewer', 'members': ['allUsers']}]}
|
|
1292
|
+
acl = {'readers': ['allUsers']}
|
|
1293
|
+
with mock.patch.object(
|
|
1294
|
+
ee.data, 'getIamPolicy', return_value=policy
|
|
1295
|
+
) as mock_get_iam_policy, mock.patch.object(
|
|
1296
|
+
ee.data._cloud_api_utils, 'convert_iam_policy_to_acl', return_value=acl
|
|
1297
|
+
) as mock_convert:
|
|
1298
|
+
result = ee.data.getAssetAcl(asset_id)
|
|
1299
|
+
mock_get_iam_policy.assert_called_once_with(asset_id)
|
|
1300
|
+
mock_convert.assert_called_once_with(policy)
|
|
1301
|
+
self.assertEqual(acl, result)
|
|
1302
|
+
|
|
1303
|
+
def test_set_asset_acl(self):
|
|
1304
|
+
asset_id = 'users/test/asset'
|
|
1305
|
+
acl_update_dict = {'readers': ['allUsers']}
|
|
1306
|
+
acl_update_str = '{"readers": ["allUsers"]}'
|
|
1307
|
+
policy = {'bindings': [{'role': 'roles/viewer', 'members': ['allUsers']}]}
|
|
1308
|
+
with mock.patch.object(
|
|
1309
|
+
ee.data._cloud_api_utils,
|
|
1310
|
+
'convert_acl_to_iam_policy',
|
|
1311
|
+
return_value=policy,
|
|
1312
|
+
) as mock_convert, mock.patch.object(
|
|
1313
|
+
ee.data, 'setIamPolicy'
|
|
1314
|
+
) as mock_set_iam_policy:
|
|
1315
|
+
ee.data.setAssetAcl(asset_id, acl_update_dict)
|
|
1316
|
+
mock_convert.assert_called_once_with(acl_update_dict)
|
|
1317
|
+
mock_set_iam_policy.assert_called_once_with(asset_id, policy)
|
|
1318
|
+
|
|
1319
|
+
mock_convert.reset_mock()
|
|
1320
|
+
mock_set_iam_policy.reset_mock()
|
|
1321
|
+
ee.data.setAssetAcl(asset_id, acl_update_str)
|
|
1322
|
+
mock_convert.assert_called_once_with(acl_update_dict)
|
|
1323
|
+
mock_set_iam_policy.assert_called_once_with(asset_id, policy)
|
|
1324
|
+
|
|
1325
|
+
def test_set_iam_policy(self):
|
|
1326
|
+
cloud_api_resource = mock.MagicMock()
|
|
1327
|
+
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
|
|
1328
|
+
asset_id = 'users/test/asset'
|
|
1329
|
+
policy = {'bindings': [{'role': 'roles/viewer', 'members': ['allUsers']}]}
|
|
1330
|
+
ee.data.setIamPolicy(asset_id, policy)
|
|
1331
|
+
cloud_api_resource.projects().assets().setIamPolicy.assert_called_once_with(
|
|
1332
|
+
resource='projects/earthengine-legacy/assets/users/test/asset',
|
|
1333
|
+
body={'policy': policy},
|
|
1334
|
+
prettyPrint=False,
|
|
1335
|
+
)
|
|
1336
|
+
|
|
1041
1337
|
|
|
1042
1338
|
def DoCloudProfileStubHttp(test, expect_profiling):
|
|
1043
1339
|
|
ee/tests/deprecation_test.py
CHANGED
|
@@ -100,7 +100,8 @@ _EXPECTED_WARNINGS = {
|
|
|
100
100
|
r'Attention required for date_and_learn_more! You are using a'
|
|
101
101
|
r' deprecated asset.\nTo make sure your code keeps working, please'
|
|
102
102
|
r' update'
|
|
103
|
-
r' it by July 1, 2024.\
|
|
103
|
+
r' it by July 1, 2024.\nThis dataset has been superseded by'
|
|
104
|
+
r' replacement_id\n\nLearn more: learn_more_url'
|
|
104
105
|
),
|
|
105
106
|
'date_only': (
|
|
106
107
|
r'Attention required for date_only! You are using a deprecated asset.\n'
|
|
@@ -124,7 +125,8 @@ _EXPECTED_WARNINGS = {
|
|
|
124
125
|
r'Attention required for learn_more_url_only! You are using a'
|
|
125
126
|
r' deprecated asset.\nTo make sure your code keeps working, please'
|
|
126
127
|
r' update'
|
|
127
|
-
r' it.\
|
|
128
|
+
r' it.\nThis dataset has been superseded by replacement_id\n\nLearn'
|
|
129
|
+
r' more: learn_more_url'
|
|
128
130
|
),
|
|
129
131
|
}
|
|
130
132
|
|
ee/tests/deserializer_test.py
CHANGED
|
@@ -80,6 +80,53 @@ class DeserializerTest(apitestcase.ApiTestCase):
|
|
|
80
80
|
):
|
|
81
81
|
deserializer.decode(encoded)
|
|
82
82
|
|
|
83
|
+
def test_duplicate_scope_key(self):
|
|
84
|
+
"""Verifies raising duplicate scope key in decode()."""
|
|
85
|
+
encoded = {
|
|
86
|
+
'type': 'CompoundValue',
|
|
87
|
+
'scope': [['a', 1], ['a', 2]],
|
|
88
|
+
'value': 3,
|
|
89
|
+
}
|
|
90
|
+
with self.assertRaisesRegex(
|
|
91
|
+
ee.EEException, 'Duplicate scope key "a" in scope #1.'
|
|
92
|
+
):
|
|
93
|
+
deserializer.decode(encoded)
|
|
94
|
+
|
|
95
|
+
def test_cannot_decode_object(self):
|
|
96
|
+
"""Verifies raising EEException for non-dict objects in _decodeValue()."""
|
|
97
|
+
with self.assertRaisesRegex(
|
|
98
|
+
ee.EEException, r'Cannot decode object: \(1\+1j\)'
|
|
99
|
+
):
|
|
100
|
+
deserializer.decode([1 + 1j])
|
|
101
|
+
|
|
102
|
+
def test_invalid_date_value(self):
|
|
103
|
+
"""Verifies EEException for invalid date values in _decodeValue()."""
|
|
104
|
+
with self.assertRaisesRegex(
|
|
105
|
+
ee.EEException, r'Invalid date value: not-a-number'
|
|
106
|
+
):
|
|
107
|
+
deserializer.decode({'type': 'Date', 'value': 'not-a-number'})
|
|
108
|
+
|
|
109
|
+
def test_invocation_of_custom_function(self):
|
|
110
|
+
"""Verifies decoding of an Invocation of a CustomFunction."""
|
|
111
|
+
encoded = {
|
|
112
|
+
'type': 'Invocation',
|
|
113
|
+
'function': {
|
|
114
|
+
'type': 'Function',
|
|
115
|
+
'argumentNames': ['foo'],
|
|
116
|
+
'body': {'type': 'ArgumentRef', 'value': 'foo'},
|
|
117
|
+
},
|
|
118
|
+
'arguments': {'foo': 1},
|
|
119
|
+
}
|
|
120
|
+
decoded = deserializer.decode(encoded)
|
|
121
|
+
self.assertIsInstance(decoded, ee.ComputedObject)
|
|
122
|
+
|
|
123
|
+
def test_date_decode(self):
|
|
124
|
+
"""Verifies decoding of a Date."""
|
|
125
|
+
encoded = {'type': 'Date', 'value': 1609459200000000}
|
|
126
|
+
decoded = deserializer.decode(encoded)
|
|
127
|
+
self.assertIsInstance(decoded, ee.Date)
|
|
128
|
+
self.assertEqual({'value': 1609459200000}, decoded.args)
|
|
129
|
+
|
|
83
130
|
|
|
84
131
|
if __name__ == '__main__':
|
|
85
132
|
unittest.main()
|
ee/tests/ee_number_test.py
CHANGED
|
@@ -396,6 +396,31 @@ class NumberTest(apitestcase.ApiTestCase):
|
|
|
396
396
|
result = json.loads(expression.serialize())
|
|
397
397
|
self.assertEqual(expect, result)
|
|
398
398
|
|
|
399
|
+
def test_expression(self):
|
|
400
|
+
expression = ee.Number.expression('1 + 2')
|
|
401
|
+
self.assertIsInstance(expression, ee.Number)
|
|
402
|
+
self.assertEqual(
|
|
403
|
+
ee.ApiFunction.lookup('Number.expression'), expression.func
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
expect = make_expression_graph({
|
|
407
|
+
'arguments': {'expression': {'constantValue': '1 + 2'}},
|
|
408
|
+
'functionName': 'Number.expression',
|
|
409
|
+
})
|
|
410
|
+
result = json.loads(expression.serialize())
|
|
411
|
+
self.assertEqual(expect, result)
|
|
412
|
+
|
|
413
|
+
expression_vars = ee.Number.expression('a + b', {'a': 1, 'b': 2})
|
|
414
|
+
expect_vars = make_expression_graph({
|
|
415
|
+
'arguments': {
|
|
416
|
+
'expression': {'constantValue': 'a + b'},
|
|
417
|
+
'vars': {'constantValue': {'a': 1, 'b': 2}},
|
|
418
|
+
},
|
|
419
|
+
'functionName': 'Number.expression',
|
|
420
|
+
})
|
|
421
|
+
result_vars = json.loads(expression_vars.serialize())
|
|
422
|
+
self.assertEqual(expect_vars, result_vars)
|
|
423
|
+
|
|
399
424
|
def test_first(self):
|
|
400
425
|
expect = make_expression_graph({
|
|
401
426
|
'arguments': {
|
|
@@ -795,7 +820,21 @@ class NumberTest(apitestcase.ApiTestCase):
|
|
|
795
820
|
result = json.loads(expression.serialize())
|
|
796
821
|
self.assertEqual(expect, result)
|
|
797
822
|
|
|
798
|
-
|
|
823
|
+
def test_parse(self):
|
|
824
|
+
expect = make_expression_graph({
|
|
825
|
+
'arguments': {
|
|
826
|
+
'input': {'constantValue': '1'},
|
|
827
|
+
'radix': {'constantValue': 2},
|
|
828
|
+
},
|
|
829
|
+
'functionName': 'Number.parse',
|
|
830
|
+
})
|
|
831
|
+
expression = ee.Number.parse('1', 2)
|
|
832
|
+
result = json.loads(expression.serialize())
|
|
833
|
+
self.assertEqual(expect, result)
|
|
834
|
+
|
|
835
|
+
expression = ee.Number.parse(input='1', radix=2)
|
|
836
|
+
result = json.loads(expression.serialize())
|
|
837
|
+
self.assertEqual(expect, result)
|
|
799
838
|
|
|
800
839
|
def test_pow(self):
|
|
801
840
|
expect = make_expression_graph({
|
ee/tests/image_converter_test.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Tests for the image_converter module."""
|
|
3
3
|
|
|
4
|
-
from typing import Optional
|
|
5
|
-
|
|
6
4
|
from absl.testing import parameterized
|
|
7
5
|
import numpy
|
|
8
6
|
|
|
@@ -20,7 +18,7 @@ class ImageConverterTest(parameterized.TestCase):
|
|
|
20
18
|
def test_from_file_format(
|
|
21
19
|
self,
|
|
22
20
|
data_format: str,
|
|
23
|
-
expected:
|
|
21
|
+
expected: type[image_converter.ImageConverter] | None,
|
|
24
22
|
) -> None:
|
|
25
23
|
"""Verifies `from_file_format` returns the correct converter class."""
|
|
26
24
|
if expected is None:
|
ee/tests/kernel_test.py
CHANGED
|
@@ -287,6 +287,10 @@ class KernelTest(apitestcase.ApiTestCase):
|
|
|
287
287
|
result = json.loads(expression.serialize())
|
|
288
288
|
self.assertEqual(expect, result)
|
|
289
289
|
|
|
290
|
+
def test_fixed_no_weights(self):
|
|
291
|
+
with self.assertRaisesRegex(ValueError, 'weights is required.'):
|
|
292
|
+
ee.Kernel.fixed()
|
|
293
|
+
|
|
290
294
|
def test_gaussian(self):
|
|
291
295
|
radius = 1.1
|
|
292
296
|
sigma = 2.2
|
ee/tests/model_test.py
CHANGED
|
@@ -115,6 +115,18 @@ class ModelTest(apitestcase.ApiTestCase):
|
|
|
115
115
|
}
|
|
116
116
|
self.assertEqual(expect, result)
|
|
117
117
|
|
|
118
|
+
def test_model_constructor_invalid(self):
|
|
119
|
+
with self.assertRaisesRegex(
|
|
120
|
+
TypeError, 'Model constructor can only cast to Model.'
|
|
121
|
+
):
|
|
122
|
+
ee.Model('not a computed object') # pytype: disable=wrong-arg-types
|
|
123
|
+
|
|
124
|
+
def test_model_constructor_invalid_int(self):
|
|
125
|
+
with self.assertRaisesRegex(
|
|
126
|
+
TypeError, 'Model constructor can only cast to Model.'
|
|
127
|
+
):
|
|
128
|
+
ee.Model(123) # pytype: disable=wrong-arg-types
|
|
129
|
+
|
|
118
130
|
def test_from_ai_platform_predictor(self):
|
|
119
131
|
project_name = 'some project'
|
|
120
132
|
project_id = 'a project id'
|