earthengine-api 1.7.9__tar.gz → 1.7.10__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.9/earthengine_api.egg-info → earthengine_api-1.7.10}/PKG-INFO +1 -1
  2. {earthengine_api-1.7.9 → earthengine_api-1.7.10/earthengine_api.egg-info}/PKG-INFO +1 -1
  3. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/__init__.py +1 -1
  4. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/data.py +1 -1
  5. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/filter.py +2 -29
  6. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/imagecollection.py +2 -1
  7. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/data_test.py +38 -12
  8. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/filter_test.py +58 -0
  9. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/image_test.py +54 -0
  10. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/imagecollection_test.py +34 -3
  11. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/pyproject.toml +1 -1
  12. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/LICENSE +0 -0
  13. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/MANIFEST.in +0 -0
  14. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/README.md +0 -0
  15. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/earthengine_api.egg-info/SOURCES.txt +0 -0
  16. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/earthengine_api.egg-info/dependency_links.txt +0 -0
  17. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/earthengine_api.egg-info/entry_points.txt +0 -0
  18. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/earthengine_api.egg-info/requires.txt +0 -0
  19. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/earthengine_api.egg-info/top_level.txt +0 -0
  20. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/_arg_types.py +0 -0
  21. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/_cloud_api_utils.py +0 -0
  22. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/_helpers.py +0 -0
  23. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/_state.py +0 -0
  24. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/_utils.py +0 -0
  25. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/apifunction.py +0 -0
  26. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/apitestcase.py +0 -0
  27. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/batch.py +0 -0
  28. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/blob.py +0 -0
  29. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/classifier.py +0 -0
  30. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/cli/__init__.py +0 -0
  31. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/cli/commands.py +0 -0
  32. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/cli/eecli.py +0 -0
  33. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/cli/eecli_wrapper.py +0 -0
  34. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/cli/utils.py +0 -0
  35. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/clusterer.py +0 -0
  36. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/collection.py +0 -0
  37. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/computedobject.py +0 -0
  38. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/confusionmatrix.py +0 -0
  39. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/customfunction.py +0 -0
  40. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/daterange.py +0 -0
  41. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/deprecation.py +0 -0
  42. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/deserializer.py +0 -0
  43. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/dictionary.py +0 -0
  44. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/ee_array.py +0 -0
  45. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/ee_date.py +0 -0
  46. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/ee_exception.py +0 -0
  47. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/ee_list.py +0 -0
  48. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/ee_number.py +0 -0
  49. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/ee_string.py +0 -0
  50. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/ee_types.py +0 -0
  51. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/element.py +0 -0
  52. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/encodable.py +0 -0
  53. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/errormargin.py +0 -0
  54. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/feature.py +0 -0
  55. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/featurecollection.py +0 -0
  56. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/function.py +0 -0
  57. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/geometry.py +0 -0
  58. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/image.py +0 -0
  59. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/image_converter.py +0 -0
  60. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/join.py +0 -0
  61. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/kernel.py +0 -0
  62. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/mapclient.py +0 -0
  63. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/model.py +0 -0
  64. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/oauth.py +0 -0
  65. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/pixeltype.py +0 -0
  66. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/projection.py +0 -0
  67. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/py.typed +0 -0
  68. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/reducer.py +0 -0
  69. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/serializer.py +0 -0
  70. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/table_converter.py +0 -0
  71. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/terrain.py +0 -0
  72. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/_cloud_api_utils_test.py +0 -0
  73. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/_helpers_test.py +0 -0
  74. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/_state_test.py +0 -0
  75. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/_utils_test.py +0 -0
  76. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/algorithms.json +0 -0
  77. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/apifunction_test.py +0 -0
  78. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/batch_test.py +0 -0
  79. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/blob_test.py +0 -0
  80. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/classifier_test.py +0 -0
  81. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/cloud_api_discovery_document.json +0 -0
  82. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/clusterer_test.py +0 -0
  83. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/collection_test.py +0 -0
  84. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/computedobject_test.py +0 -0
  85. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/confusionmatrix_test.py +0 -0
  86. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/daterange_test.py +0 -0
  87. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/deprecation_test.py +0 -0
  88. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/deserializer_test.py +0 -0
  89. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/dictionary_test.py +0 -0
  90. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/ee_array_test.py +0 -0
  91. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/ee_date_test.py +0 -0
  92. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/ee_list_test.py +0 -0
  93. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/ee_number_test.py +0 -0
  94. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/ee_string_test.py +0 -0
  95. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/ee_test.py +0 -0
  96. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/ee_types_test.py +0 -0
  97. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/element_test.py +0 -0
  98. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/encodable_test.py +0 -0
  99. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/errormargin_test.py +0 -0
  100. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/feature_test.py +0 -0
  101. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/featurecollection_test.py +0 -0
  102. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/function_test.py +0 -0
  103. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/geometry_point_test.py +0 -0
  104. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/geometry_test.py +0 -0
  105. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/image_converter_test.py +0 -0
  106. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/join_test.py +0 -0
  107. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/kernel_test.py +0 -0
  108. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/model_test.py +0 -0
  109. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/oauth_test.py +0 -0
  110. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/pixeltype_test.py +0 -0
  111. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/projection_test.py +0 -0
  112. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/reducer_test.py +0 -0
  113. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/serializer_test.py +0 -0
  114. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/table_converter_test.py +0 -0
  115. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/ee/tests/terrain_test.py +0 -0
  116. {earthengine_api-1.7.9 → earthengine_api-1.7.10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: earthengine-api
3
- Version: 1.7.9
3
+ Version: 1.7.10
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.9
3
+ Version: 1.7.10
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.9'
3
+ __version__ = '1.7.10'
4
4
 
5
5
  # Using lowercase function naming to match the JavaScript names.
6
6
  # pylint: disable=g-bad-name
@@ -691,7 +691,7 @@ def getMapId(params: dict[str, Any]) -> dict[str, Any]:
691
691
  map_name = result['name']
692
692
  version = _cloud_api_utils.VERSION
693
693
  url_format = (
694
- '{state.tile_base_url}/{version}/{map_name)}/tiles/{{z}}/{{x}}/{{y}}'
694
+ f'{state.tile_base_url}/{version}/{map_name}/tiles/{{z}}/{{x}}/{{y}}'
695
695
  )
696
696
  if state.cloud_api_key:
697
697
  url_format += f'?key={state.cloud_api_key}'
@@ -7,7 +7,6 @@ Example usage:
7
7
  .lt('time', value)
8
8
  """
9
9
 
10
- # Using lowercase function naming to match the JavaScript names.
11
10
  # pylint: disable=g-bad-name
12
11
 
13
12
  from __future__ import annotations
@@ -70,9 +69,8 @@ class Filter(computedobject.ComputedObject):
70
69
  super().__init__(filter_.func, filter_.args, filter_.varName)
71
70
  self._filter = (filter_,)
72
71
  elif filter_ is None:
73
- # A silly call with no arguments left for backward-compatibility.
74
- # Encoding such a filter is expected to fail, but it can be composed
75
- # by calling the various methods that end up in _append().
72
+ # A call with no arguments left for backward-compatibility.
73
+ # Encoding such a filter is expected to fail.
76
74
  super().__init__(None, None)
77
75
  self._filter = ()
78
76
  else:
@@ -102,31 +100,6 @@ class Filter(computedobject.ComputedObject):
102
100
  """
103
101
  return len(self._filter)
104
102
 
105
- def _append(self, new_filter: _arg_types.Filter) -> Filter:
106
- """Append a predicate to this filter.
107
-
108
- These are implicitly ANDed.
109
-
110
- Args:
111
- new_filter: The filter to append to this one. Possible types are:
112
- 1) another fully constructed Filter,
113
- 2) a JSON representation of a filter,
114
- 3) an array of 1 or 2.
115
-
116
- Returns:
117
- A new filter that is the combination of both.
118
- """
119
- if new_filter is None:
120
- raise ValueError('new_filter should never be None')
121
- prev = list(self._filter)
122
- if isinstance(new_filter, Filter):
123
- prev.extend(new_filter._filter) # pylint: disable=protected-access
124
- elif isinstance(new_filter, list):
125
- prev.extend(new_filter)
126
- else:
127
- prev.append(new_filter)
128
- return Filter(prev)
129
-
130
103
  @staticmethod
131
104
  def metadata_(name: str, operator: str, value: _arg_types.Any) -> Filter:
132
105
  """Filter on metadata. This is deprecated.
@@ -299,7 +299,8 @@ class ImageCollection(collection.Collection[image.Image]):
299
299
  request['format'] = params.get('format', valid_formats[0])
300
300
  if request['format'] not in valid_formats:
301
301
  raise ee_exception.EEException(
302
- 'Invalid format specified for thumbnail. ' + str(params['format']))
302
+ f'Invalid format specified for thumbnail: "{request["format"]}"'
303
+ )
303
304
 
304
305
  if params and 'framesPerSecond' in params:
305
306
  request['framesPerSecond'] = params.get('framesPerSecond')
@@ -565,23 +565,22 @@ class DataTest(unittest.TestCase):
565
565
  def test_set_asset_properties(self):
566
566
  mock_http = mock.MagicMock(httplib2.Http)
567
567
  with apitestcase.UsingCloudApi(mock_http=mock_http), mock.patch.object(
568
- ee.data, 'updateAsset', autospec=True) as mock_update_asset:
569
- ee.data.setAssetProperties('foo', {
570
- 'mYPropErTy': 'Value',
571
- 'system:time_start': 1
572
- })
568
+ ee.data, 'updateAsset', autospec=True
569
+ ) as mock_update_asset:
570
+ ee.data.setAssetProperties(
571
+ 'foo', {'mYPropErTy': 'Value', 'system:time_start': 1}
572
+ )
573
573
  asset_id = mock_update_asset.call_args[0][0]
574
574
  self.assertEqual(asset_id, 'foo')
575
575
  asset = mock_update_asset.call_args[0][1]
576
- self.assertEqual(asset['properties'], {
577
- 'mYPropErTy': 'Value',
578
- 'system:time_start': 1
579
- })
576
+ self.assertEqual(
577
+ asset['properties'], {'mYPropErTy': 'Value', 'system:time_start': 1}
578
+ )
580
579
  update_mask = mock_update_asset.call_args[0][2]
581
580
  self.assertSetEqual(
582
581
  set(update_mask),
583
- {'properties.\"mYPropErTy\"',
584
- 'properties.\"system:time_start\"'})
582
+ {'properties."mYPropErTy"', 'properties."system:time_start"'},
583
+ )
585
584
 
586
585
  def test_update_asset(self):
587
586
  cloud_api_resource = mock.MagicMock()
@@ -895,7 +894,10 @@ class DataTest(unittest.TestCase):
895
894
  def test_get_map_id_with_cloud_api_key(self):
896
895
  cloud_api_resource = mock.MagicMock()
897
896
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
897
+ custom_url = 'https://example.test'
898
898
  ee.data._get_state().cloud_api_key = 'my-api-key'
899
+ ee.data._get_state().tile_base_url = custom_url
900
+
899
901
  mock_result = {
900
902
  'name': 'projects/earthengine-legacy/maps/DOCID',
901
903
  }
@@ -905,7 +907,31 @@ class DataTest(unittest.TestCase):
905
907
  actual_result = ee.data.getMapId({
906
908
  'image': image.Image('my-image'),
907
909
  })
908
- self.assertIn('?key=my-api-key', actual_result['tile_fetcher'].url_format)
910
+ expected_url = (
911
+ custom_url
912
+ + '/v1/projects/earthengine-legacy/maps/DOCID/tiles/{z}/{x}/{y}'
913
+ '?key=my-api-key'
914
+ )
915
+ self.assertEqual(expected_url, actual_result['tile_fetcher'].url_format)
916
+
917
+ def test_get_map_id_no_cloud_api_key(self):
918
+ cloud_api_resource = mock.MagicMock()
919
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
920
+ custom_url = 'https://example.test'
921
+ ee.data._get_state().cloud_api_key = None
922
+ ee.data._get_state().tile_base_url = custom_url
923
+ mock_result = {
924
+ 'name': 'projects/earthengine-legacy/maps/DOCID',
925
+ }
926
+ cloud_api_resource.projects().maps().create().execute.return_value = (
927
+ mock_result
928
+ )
929
+ actual_result = ee.data.getMapId({'image': image.Image('my-image')})
930
+ expected_url = (
931
+ custom_url
932
+ + '/v1/projects/earthengine-legacy/maps/DOCID/tiles/{z}/{x}/{y}'
933
+ )
934
+ self.assertEqual(expected_url, actual_result['tile_fetcher'].url_format)
909
935
 
910
936
  def test_get_thumbnail_default(self):
911
937
  cloud_api_resource_raw = mock.MagicMock()
@@ -40,6 +40,64 @@ class FilterTest(apitestcase.ApiTestCase):
40
40
  copy = ee.Filter(from_static_method)
41
41
  self.assertEqual(from_static_method, copy)
42
42
 
43
+ def test_constructor_no_args(self):
44
+ # This is code to be avoided, but since it has been this way for a long
45
+ # time, this captures the current behavior.
46
+ # Please do not use `ee.Filter()` to access static methods like `Or`.
47
+ # Instead, call them directly on the class, e.g., `ee.Filter.Or(...)`.
48
+ a_filter = ee.Filter()
49
+ self.assertEqual(a_filter.predicateCount(), 0)
50
+
51
+ self.assertTrue(a_filter.isVariable())
52
+
53
+ # Not very intuitive error message.
54
+ with self.assertRaisesRegex(ee.EEException, 'arguments cannot be used'):
55
+ a_filter.serialize()
56
+
57
+ # Not very intuitive error message.
58
+ with self.assertRaisesRegex(ee.EEException, 'arguments cannot be used'):
59
+ str(a_filter)
60
+
61
+ def test_empty_list_filter(self):
62
+ with self.assertRaisesRegex(
63
+ ee.EEException, 'Empty list specified for ee.Filter().'
64
+ ):
65
+ ee.Filter([])
66
+
67
+ def test_list_of_filters(self):
68
+ f1 = ee.Filter.eq('x', 1)
69
+ f2 = ee.Filter.eq('y', 2)
70
+ filters = [f1, f2]
71
+ multi_filter = ee.Filter(filters)
72
+ self.assertEqual(tuple(filters), multi_filter._filter)
73
+ self.assertEqual(ee.ApiFunction.lookup('Filter.and'), multi_filter.func)
74
+ self.assertEqual({'filters': tuple(filters)}, multi_filter.args)
75
+
76
+ def test_invalid_argument(self):
77
+ with self.assertRaisesRegex(
78
+ ee.EEException, 'Invalid argument specified for ee.Filter().*'
79
+ ):
80
+ ee.Filter(123) # pytype: disable=wrong-arg-types
81
+
82
+ def test_predicate_count(self):
83
+ self.assertEqual(0, ee.Filter().predicateCount())
84
+ self.assertEqual(1, ee.Filter(ee.Filter.eq('x', 1)).predicateCount())
85
+ self.assertEqual(1, ee.Filter([ee.Filter.eq('x', 1)]).predicateCount())
86
+ self.assertEqual(
87
+ 2,
88
+ ee.Filter(
89
+ [ee.Filter.eq('x', 1), ee.Filter.eq('y', 2)]
90
+ ).predicateCount(),
91
+ )
92
+ self.assertEqual(
93
+ 3,
94
+ ee.Filter([
95
+ ee.Filter.eq('x', 1),
96
+ ee.Filter.eq('y', 2),
97
+ ee.Filter.eq('z', 3),
98
+ ]).predicateCount(),
99
+ )
100
+
43
101
  def test_metadata(self):
44
102
  """Verifies that the metadata_() method works."""
45
103
  self.assertEqual(
@@ -148,6 +148,60 @@ class ImageTest(apitestcase.ApiTestCase):
148
148
  'srcImg': image2
149
149
  }, combined.args['input'].args)
150
150
 
151
+ def test_rgb(self):
152
+ """Verifies the behavior of ee.Image.rgb()."""
153
+ r = 1.1
154
+ g = 2.2
155
+ b = 3.3
156
+ expression = ee.Image.rgb(r, g, b)
157
+ expect = make_expression_graph({
158
+ 'arguments': {
159
+ 'input': {
160
+ 'functionInvocationValue': {
161
+ 'functionName': 'Image.addBands',
162
+ 'arguments': {
163
+ 'dstImg': {
164
+ 'functionInvocationValue': {
165
+ 'functionName': 'Image.addBands',
166
+ 'arguments': {
167
+ 'dstImg': {
168
+ 'functionInvocationValue': {
169
+ 'functionName': 'Image.constant',
170
+ 'arguments': {
171
+ 'value': {'constantValue': r}
172
+ },
173
+ }
174
+ },
175
+ 'srcImg': {
176
+ 'functionInvocationValue': {
177
+ 'functionName': 'Image.constant',
178
+ 'arguments': {
179
+ 'value': {'constantValue': g}
180
+ },
181
+ }
182
+ },
183
+ },
184
+ }
185
+ },
186
+ 'srcImg': {
187
+ 'functionInvocationValue': {
188
+ 'functionName': 'Image.constant',
189
+ 'arguments': {'value': {'constantValue': b}},
190
+ }
191
+ },
192
+ },
193
+ }
194
+ },
195
+ 'bandSelectors': {'constantValue': ['.*']},
196
+ 'newNames': {
197
+ 'constantValue': ['vis-red', 'vis-green', 'vis-blue']
198
+ },
199
+ },
200
+ 'functionName': 'Image.select',
201
+ })
202
+ result = json.loads(expression.serialize())
203
+ self.assertEqual(expect, result)
204
+
151
205
  def test_select(self):
152
206
  """Verifies regression in the behavior of empty ee.Image.select()."""
153
207
  image = ee.Image([1, 2]).select()
@@ -144,13 +144,13 @@ class ImageCollectionTest(apitestcase.ApiTestCase):
144
144
 
145
145
  def test_filmstrip_thumb_url_invalid_format(self):
146
146
  """Verifies correct thumbnailing behavior."""
147
- message = r'Invalid format specified for thumbnail\. gif'
147
+ message = r'Invalid format specified for thumbnail: "gif"'
148
148
  with self.assertRaisesRegex(ee.EEException, message):
149
149
  ee.ImageCollection(ee.Image(1)).getFilmstripThumbURL({'format': 'gif'})
150
150
 
151
151
  def test_video_thumb_url_invalid_format(self):
152
152
  """Verifies correct thumbnailing behavior."""
153
- message = r'Invalid format specified for thumbnail\. png'
153
+ message = r'Invalid format specified for thumbnail: "png"'
154
154
  with self.assertRaisesRegex(ee.EEException, message):
155
155
  ee.ImageCollection(ee.Image(1)).getVideoThumbURL({'format': 'png'})
156
156
 
@@ -722,7 +722,38 @@ class ImageCollectionTest(apitestcase.ApiTestCase):
722
722
  result = json.loads(expression.serialize())
723
723
  self.assertEqual(expect, result)
724
724
 
725
- # fromImages already tested in other tests.
725
+ def test_from_images(self):
726
+ images = [ee.Image(1), ee.Image(2)]
727
+ expect = make_expression_graph({
728
+ 'arguments': {
729
+ 'images': {
730
+ 'arrayValue': {
731
+ 'values': [
732
+ {
733
+ 'functionInvocationValue': {
734
+ 'functionName': 'Image.constant',
735
+ 'arguments': {'value': {'constantValue': 1}},
736
+ }
737
+ },
738
+ {
739
+ 'functionInvocationValue': {
740
+ 'functionName': 'Image.constant',
741
+ 'arguments': {'value': {'constantValue': 2}},
742
+ }
743
+ },
744
+ ]
745
+ }
746
+ }
747
+ },
748
+ 'functionName': 'ImageCollection.fromImages',
749
+ })
750
+ expression = ee.ImageCollection.fromImages(images)
751
+ result = json.loads(expression.serialize())
752
+ self.assertEqual(expect, result)
753
+
754
+ expression = ee.ImageCollection.fromImages(images=images)
755
+ result = json.loads(expression.serialize())
756
+ self.assertEqual(expect, result)
726
757
 
727
758
  def test_geometry(self):
728
759
  max_error = 1.1
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "earthengine-api"
3
- version = "1.7.9"
3
+ version = "1.7.10"
4
4
  description = "Earth Engine Python API"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"