earthengine-api 1.7.1rc0__tar.gz → 1.7.3__tar.gz

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.

Files changed (116) hide show
  1. {earthengine_api-1.7.1rc0/earthengine_api.egg-info → earthengine_api-1.7.3}/PKG-INFO +1 -1
  2. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3/earthengine_api.egg-info}/PKG-INFO +1 -1
  3. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/__init__.py +1 -1
  4. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/batch.py +7 -0
  5. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/data.py +1 -0
  6. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/oauth.py +2 -2
  7. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/batch_test.py +56 -0
  8. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/data_test.py +295 -1
  9. earthengine_api-1.7.3/ee/tests/oauth_test.py +263 -0
  10. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/table_converter_test.py +47 -3
  11. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/pyproject.toml +1 -1
  12. earthengine_api-1.7.1rc0/ee/tests/oauth_test.py +0 -100
  13. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/LICENSE +0 -0
  14. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/MANIFEST.in +0 -0
  15. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/README.md +0 -0
  16. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/earthengine_api.egg-info/SOURCES.txt +0 -0
  17. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/earthengine_api.egg-info/dependency_links.txt +0 -0
  18. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/earthengine_api.egg-info/entry_points.txt +0 -0
  19. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/earthengine_api.egg-info/requires.txt +0 -0
  20. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/earthengine_api.egg-info/top_level.txt +0 -0
  21. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/_arg_types.py +0 -0
  22. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/_cloud_api_utils.py +0 -0
  23. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/_helpers.py +0 -0
  24. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/_state.py +0 -0
  25. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/_utils.py +0 -0
  26. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/apifunction.py +0 -0
  27. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/apitestcase.py +0 -0
  28. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/blob.py +0 -0
  29. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/classifier.py +0 -0
  30. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/cli/__init__.py +0 -0
  31. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/cli/commands.py +0 -0
  32. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/cli/eecli.py +0 -0
  33. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/cli/eecli_wrapper.py +0 -0
  34. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/cli/utils.py +0 -0
  35. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/clusterer.py +0 -0
  36. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/collection.py +0 -0
  37. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/computedobject.py +0 -0
  38. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/confusionmatrix.py +0 -0
  39. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/customfunction.py +0 -0
  40. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/daterange.py +0 -0
  41. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/deprecation.py +0 -0
  42. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/deserializer.py +0 -0
  43. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/dictionary.py +0 -0
  44. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/ee_array.py +0 -0
  45. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/ee_date.py +0 -0
  46. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/ee_exception.py +0 -0
  47. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/ee_list.py +0 -0
  48. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/ee_number.py +0 -0
  49. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/ee_string.py +0 -0
  50. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/ee_types.py +0 -0
  51. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/element.py +0 -0
  52. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/encodable.py +0 -0
  53. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/errormargin.py +0 -0
  54. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/feature.py +0 -0
  55. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/featurecollection.py +0 -0
  56. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/filter.py +0 -0
  57. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/function.py +0 -0
  58. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/geometry.py +0 -0
  59. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/image.py +0 -0
  60. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/image_converter.py +0 -0
  61. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/imagecollection.py +0 -0
  62. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/join.py +0 -0
  63. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/kernel.py +0 -0
  64. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/mapclient.py +0 -0
  65. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/model.py +0 -0
  66. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/pixeltype.py +0 -0
  67. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/projection.py +0 -0
  68. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/py.typed +0 -0
  69. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/reducer.py +0 -0
  70. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/serializer.py +0 -0
  71. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/table_converter.py +0 -0
  72. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/terrain.py +0 -0
  73. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/_cloud_api_utils_test.py +0 -0
  74. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/_helpers_test.py +0 -0
  75. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/_state_test.py +0 -0
  76. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/_utils_test.py +0 -0
  77. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/algorithms.json +0 -0
  78. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/apifunction_test.py +0 -0
  79. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/blob_test.py +0 -0
  80. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/classifier_test.py +0 -0
  81. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/cloud_api_discovery_document.json +0 -0
  82. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/clusterer_test.py +0 -0
  83. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/collection_test.py +0 -0
  84. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/computedobject_test.py +0 -0
  85. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/confusionmatrix_test.py +0 -0
  86. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/daterange_test.py +0 -0
  87. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/deprecation_test.py +0 -0
  88. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/deserializer_test.py +0 -0
  89. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/dictionary_test.py +0 -0
  90. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/ee_array_test.py +0 -0
  91. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/ee_date_test.py +0 -0
  92. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/ee_list_test.py +0 -0
  93. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/ee_number_test.py +0 -0
  94. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/ee_string_test.py +0 -0
  95. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/ee_test.py +0 -0
  96. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/ee_types_test.py +0 -0
  97. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/element_test.py +0 -0
  98. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/errormargin_test.py +0 -0
  99. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/feature_test.py +0 -0
  100. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/featurecollection_test.py +0 -0
  101. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/filter_test.py +0 -0
  102. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/function_test.py +0 -0
  103. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/geometry_point_test.py +0 -0
  104. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/geometry_test.py +0 -0
  105. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/image_converter_test.py +0 -0
  106. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/image_test.py +0 -0
  107. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/imagecollection_test.py +0 -0
  108. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/join_test.py +0 -0
  109. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/kernel_test.py +0 -0
  110. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/model_test.py +0 -0
  111. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/pixeltype_test.py +0 -0
  112. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/projection_test.py +0 -0
  113. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/reducer_test.py +0 -0
  114. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/serializer_test.py +0 -0
  115. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/ee/tests/terrain_test.py +0 -0
  116. {earthengine_api-1.7.1rc0 → earthengine_api-1.7.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: earthengine-api
3
- Version: 1.7.1rc0
3
+ Version: 1.7.3
4
4
  Summary: Earth Engine Python API
5
5
  Author-email: Google LLC <noreply@google.com>
6
6
  License: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: earthengine-api
3
- Version: 1.7.1rc0
3
+ Version: 1.7.3
4
4
  Summary: Earth Engine Python API
5
5
  Author-email: Google LLC <noreply@google.com>
6
6
  License: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  """The EE Python library."""
2
2
 
3
- __version__ = '1.7.1rc0'
3
+ __version__ = '1.7.3'
4
4
 
5
5
  # Using lowercase function naming to match the JavaScript names.
6
6
  # pylint: disable=g-bad-name
@@ -308,6 +308,7 @@ class Export:
308
308
  crsTransform=None,
309
309
  maxPixels=None,
310
310
  priority=None,
311
+ overwrite=False,
311
312
  **kwargs,
312
313
  ) -> Task:
313
314
  """Creates a task to export an EE Image to an EE Asset.
@@ -344,6 +345,7 @@ class Export:
344
345
  priority: The priority of the task within the project. Higher priority
345
346
  tasks are scheduled sooner. Must be an integer between 0 and 9999.
346
347
  Defaults to 100.
348
+ overwrite: If an existing asset can be overwritten by this export.
347
349
  **kwargs: Holds other keyword arguments that may have been deprecated
348
350
  such as 'crs_transform'.
349
351
 
@@ -739,6 +741,7 @@ class Export:
739
741
  assetId=None,
740
742
  maxVertices=None,
741
743
  priority=None,
744
+ overwrite=False,
742
745
  **kwargs,
743
746
  ) -> Task:
744
747
  """Creates a task to export a FeatureCollection to an EE table asset.
@@ -753,6 +756,7 @@ class Export:
753
756
  priority: The priority of the task within the project. Higher priority
754
757
  tasks are scheduled sooner. Must be an integer between 0 and 9999.
755
758
  Defaults to 100.
759
+ overwrite: If an existing asset can be overwritten by this export.
756
760
  **kwargs: Holds other keyword arguments that may have been deprecated.
757
761
 
758
762
  Returns:
@@ -763,6 +767,7 @@ class Export:
763
767
  'assetId': assetId,
764
768
  'maxVertices': maxVertices,
765
769
  'priority': priority,
770
+ 'overwrite': overwrite,
766
771
  }
767
772
  config = {k: v for k, v, in config.items() if v is not None}
768
773
  config = _prepare_table_export_config(collection, config,
@@ -1738,6 +1743,8 @@ def _build_earth_engine_destination(config: dict[str, Any]) -> dict[str, Any]:
1738
1743
  'name':
1739
1744
  _cloud_api_utils.convert_asset_id_to_asset_name(
1740
1745
  config.pop('assetId')),
1746
+ 'overwrite':
1747
+ config.pop('overwrite', False)
1741
1748
  }
1742
1749
 
1743
1750
 
@@ -2161,6 +2161,7 @@ def setIamPolicy(asset_id: str, policy: Any) -> None:
2161
2161
  .setIamPolicy(resource=name, body={'policy': policy}, prettyPrint=False)
2162
2162
  )
2163
2163
 
2164
+
2164
2165
  @deprecation.Deprecated('Use ee.data.updateAsset().')
2165
2166
  def setAssetProperties(assetId: str, properties: dict[str, Any]) -> None:
2166
2167
  """Sets metadata properties of the asset with the given ID.
@@ -226,7 +226,7 @@ def _in_jupyter_shell() -> bool:
226
226
  """Tests if the code is being executed within Jupyter."""
227
227
  try:
228
228
  import ipykernel.zmqshell
229
- return isinstance(IPython.get_ipython(),
229
+ return isinstance(IPython.get_ipython(), # pylint: disable=undefined-variable
230
230
  ipykernel.zmqshell.ZMQInteractiveShell)
231
231
  except ImportError:
232
232
  return False
@@ -329,7 +329,7 @@ def _display_auth_instructions_with_html(
329
329
  ) -> None:
330
330
  """Displays instructions for authenticating using HTML code."""
331
331
  try:
332
- IPython.display.display(IPython.display.HTML(
332
+ IPython.display.display(IPython.display.HTML( # pylint: disable=undefined-variable
333
333
  """<p>To authorize access needed by Earth Engine, open the following
334
334
  URL in a web browser and follow the instructions:</p>
335
335
  <p><a href={0}>{0}</a></p>
@@ -274,6 +274,7 @@ class BatchTestCase(apitestcase.ApiTestCase):
274
274
  'name': (
275
275
  'projects/earthengine-legacy/assets/users/foo/bar'
276
276
  ),
277
+ 'overwrite': False,
277
278
  }
278
279
  },
279
280
  'description': 'myExportImageTask',
@@ -425,6 +426,7 @@ class BatchTestCase(apitestcase.ApiTestCase):
425
426
  'name': (
426
427
  'projects/earthengine-legacy/assets/users/foo/bar'
427
428
  ),
429
+ 'overwrite': False,
428
430
  },
429
431
  'pyramidingPolicyOverrides': {'B1': 'MIN'},
430
432
  },
@@ -451,6 +453,7 @@ class BatchTestCase(apitestcase.ApiTestCase):
451
453
  'name': (
452
454
  'projects/earthengine-legacy/assets/users/foo/bar'
453
455
  ),
456
+ 'overwrite': False,
454
457
  },
455
458
  'tileSize': {'value': 4},
456
459
  },
@@ -460,6 +463,43 @@ class BatchTestCase(apitestcase.ApiTestCase):
460
463
  task_ordered.config,
461
464
  )
462
465
 
466
+ task_with_overwrite = ee.batch.Export.image.toAsset(
467
+ image=config['image'],
468
+ assetId=config['assetId'],
469
+ overwrite=True,
470
+ )
471
+ self.assertTrue(
472
+ task_with_overwrite.config['assetExportOptions'][
473
+ 'earthEngineDestination'
474
+ ]['overwrite']
475
+ )
476
+
477
+ task_with_priority = ee.batch.Export.image.toAsset(
478
+ image=config['image'],
479
+ assetId=config['assetId'],
480
+ priority=999,
481
+ )
482
+ self.assertIsNone(task_with_priority.id)
483
+ self.assertIsNone(task_with_priority.name)
484
+ self.assertEqual('EXPORT_IMAGE', task_with_priority.task_type)
485
+ self.assertEqual('UNSUBMITTED', task_with_priority.state)
486
+ self.assertEqual(
487
+ {
488
+ 'expression': expected_expression,
489
+ 'description': 'myExportImageTask',
490
+ 'assetExportOptions': {
491
+ 'earthEngineDestination': {
492
+ 'name': (
493
+ 'projects/earthengine-legacy/assets/users/foo/bar'
494
+ ),
495
+ 'overwrite': False,
496
+ }
497
+ },
498
+ 'priority': {'value': 999},
499
+ },
500
+ task_with_priority.config,
501
+ )
502
+
463
503
  def test_export_image_to_asset_cloud_api_with_tile_size(self):
464
504
  """Verifies the Asset export task created by Export.image.toAsset()."""
465
505
  with apitestcase.UsingCloudApi():
@@ -489,6 +529,7 @@ class BatchTestCase(apitestcase.ApiTestCase):
489
529
  'name': (
490
530
  'projects/earthengine-legacy/assets/users/foo/bar'
491
531
  ),
532
+ 'overwrite': False,
492
533
  },
493
534
  'tileSize': {'value': 4},
494
535
  },
@@ -1133,11 +1174,25 @@ class BatchTestCase(apitestcase.ApiTestCase):
1133
1174
  'name': (
1134
1175
  'projects/earthengine-legacy/assets/users/foo/bar'
1135
1176
  ),
1177
+ 'overwrite': False,
1136
1178
  }
1137
1179
  },
1138
1180
  },
1139
1181
  task.config,
1140
1182
  )
1183
+
1184
+ task_with_overwrite = ee.batch.Export.table.toAsset(
1185
+ collection=ee.FeatureCollection('foo'),
1186
+ description='foo',
1187
+ assetId='users/foo/bar',
1188
+ overwrite=True,
1189
+ )
1190
+ self.assertTrue(
1191
+ task_with_overwrite.config['assetExportOptions'][
1192
+ 'earthEngineDestination'
1193
+ ]['overwrite']
1194
+ )
1195
+
1141
1196
  task_with_priority = ee.batch.Export.table.toAsset(
1142
1197
  collection=ee.FeatureCollection('foo'),
1143
1198
  description='foo',
@@ -1153,6 +1208,7 @@ class BatchTestCase(apitestcase.ApiTestCase):
1153
1208
  'name': (
1154
1209
  'projects/earthengine-legacy/assets/users/foo/bar'
1155
1210
  ),
1211
+ 'overwrite': False,
1156
1212
  }
1157
1213
  },
1158
1214
  'priority': {'value': 999},
@@ -87,6 +87,26 @@ class DataTest(unittest.TestCase):
87
87
  _state.get_state().cloud_api_user_project, 'earthengine-legacy'
88
88
  )
89
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
+
90
110
  def test_set_max_retries_bad_values(self):
91
111
  with self.assertRaises(ValueError):
92
112
  ee.data.setMaxRetries(-1)
@@ -110,6 +130,46 @@ class DataTest(unittest.TestCase):
110
130
  .execute.call_args.kwargs['num_retries'],
111
131
  )
112
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
+
113
173
  def test_list_operations(self):
114
174
  mock_http = mock.MagicMock(httplib2.Http)
115
175
  # Return in three groups.
@@ -342,6 +402,14 @@ class DataTest(unittest.TestCase):
342
402
  asset = mock_create_asset.call_args.kwargs['body']
343
403
  self.assertEqual(asset, {'type': 'FOLDER'})
344
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
+
345
413
  def test_create_assets(self):
346
414
  cloud_api_resource = mock.MagicMock()
347
415
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
@@ -432,6 +500,68 @@ class DataTest(unittest.TestCase):
432
500
  )
433
501
  self.assertTrue(import_args['overwrite'])
434
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
+
435
565
  def test_set_asset_properties(self):
436
566
  mock_http = mock.MagicMock(httplib2.Http)
437
567
  with apitestcase.UsingCloudApi(mock_http=mock_http), mock.patch.object(
@@ -453,6 +583,18 @@ class DataTest(unittest.TestCase):
453
583
  {'properties.\"mYPropErTy\"',
454
584
  'properties.\"system:time_start\"'})
455
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
+
456
598
  def test_list_assets(self):
457
599
  cloud_api_resource = mock.MagicMock()
458
600
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
@@ -576,6 +718,16 @@ class DataTest(unittest.TestCase):
576
718
  cloud_api_resource.projects().listAssets().execute.assert_called_once()
577
719
  self.assertEqual(mock_result, actual_result)
578
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
+
579
731
  def test_simple_get_list_via_cloud_api(self):
580
732
  cloud_api_resource = mock.MagicMock()
581
733
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
@@ -881,6 +1033,50 @@ class DataTest(unittest.TestCase):
881
1033
  ).execute.assert_called_once()
882
1034
  self.assertEqual(mock_result, actual_result)
883
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
+
884
1080
  def test_get_feature_view_tiles_key(self):
885
1081
  cloud_api_resource = mock.MagicMock()
886
1082
  _state.get_state().tile_base_url = 'base_url'
@@ -922,8 +1118,31 @@ class DataTest(unittest.TestCase):
922
1118
  cloud_api_resource.projects().updateConfig().execute.return_value = (
923
1119
  mock_result
924
1120
  )
1121
+ project_config = {'maxConcurrentExports': 2}
925
1122
  actual_result = ee.data.updateProjectConfig(
926
- {'maxConcurrentExports': 2}, ['max_concurrent_exports']
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',
927
1146
  )
928
1147
  cloud_api_resource.projects().updateConfig().execute.assert_called_once()
929
1148
  self.assertEqual(mock_result, actual_result)
@@ -1040,6 +1259,81 @@ class DataTest(unittest.TestCase):
1040
1259
  }
1041
1260
  self.assertEqual(expected, quota)
1042
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
+
1043
1337
 
1044
1338
  def DoCloudProfileStubHttp(test, expect_profiling):
1045
1339