Skip to content

Commit

Permalink
v0.1.398
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 621871759
  • Loading branch information
Google Earth Engine Authors authored and jgarcia525 committed Apr 10, 2024
1 parent a2703cb commit b85f7af
Show file tree
Hide file tree
Showing 11 changed files with 833 additions and 220 deletions.
32 changes: 16 additions & 16 deletions javascript/build/ee_api_js.js

Large diffs are not rendered by default.

176 changes: 88 additions & 88 deletions javascript/build/ee_api_js_debug.js

Large diffs are not rendered by default.

222 changes: 111 additions & 111 deletions javascript/build/ee_api_js_npm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion javascript/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@google/earthengine",
"version": "0.1.397",
"version": "0.1.398",
"description": "JavaScript client for Google Earth Engine API.",
"author": "Google LLC",
"license": "Apache-2.0",
Expand Down
2 changes: 1 addition & 1 deletion javascript/src/apiclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const {trustedResourceUrl} = goog.require('safevalues');
/** @namespace */
const apiclient = {};

const API_CLIENT_VERSION = '0.1.397';
const API_CLIENT_VERSION = '0.1.398';

exports.VERSION = apiVersion.VERSION;
exports.API_CLIENT_VERSION = API_CLIENT_VERSION;
Expand Down
2 changes: 1 addition & 1 deletion python/ee/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""The EE Python library."""

__version__ = '0.1.397'
__version__ = '0.1.398'

# Using lowercase function naming to match the JavaScript names.
# pylint: disable=g-bad-name
Expand Down
16 changes: 15 additions & 1 deletion python/ee/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,7 @@ def createAsset(
value: Dict[str, Any],
path: Optional[str] = None,
properties: Optional[Dict[str, Any]] = None,
) -> Any:
) -> Dict[str, Any]:
"""Creates an asset from a JSON value.
To create an empty image collection or folder, pass in a "value" object
Expand Down Expand Up @@ -1535,6 +1535,20 @@ def createAsset(
)


def createFolder(path: str) -> Dict[str, Any]:
"""Creates an asset folder.
Returns a description of the newly created folder.
Args:
path: The path to the folder to create.
Returns:
A description of the newly created folder.
"""
return createAsset({'type': 'FOLDER'}, path)


def copyAsset(
sourceId: str,
destinationId: str,
Expand Down
283 changes: 283 additions & 0 deletions python/ee/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,27 @@
from ee import _utils
from ee import apifunction
from ee import computedobject
from ee import ee_array
from ee import ee_list
from ee import ee_number
from ee import ee_string
from ee import geometry
from ee import image

_DictType = Union[
Dict[Any, Any], Sequence[Any], 'Dictionary', computedobject.ComputedObject
]
_EeAnyType = Union[Any, computedobject.ComputedObject]
_EeBoolType = Union[Any, computedobject.ComputedObject]
# bool, float, and int are automatically converted to ee.String for keys.
_EeKeyType = Union[bool, float, int, str, computedobject.ComputedObject]
# TODO: Make a better type for a list of keys.
_EeKeyListType = _EeAnyType
_IntegerType = Union[int, ee_number.Number, computedobject.ComputedObject]
_StringType = Union[str, ee_string.String, computedobject.ComputedObject]
# TODO: Make a better type for a list of strings.
# Or is this the same as _EeKeyListType?
_StringListType = Union[Any, computedobject.ComputedObject]


class Dictionary(computedobject.ComputedObject):
Expand Down Expand Up @@ -76,3 +93,269 @@ def encode_cloud_value(self, encoder=None):
return {'valueReference': encoder(self._dictionary)}
else:
return super().encode_cloud_value(encoder)

def combine(
self, second: _DictType, overwrite: Optional[_EeBoolType] = None
) -> Dictionary:
"""Combines two dictionaries.
In the case of duplicate key names, the output will contain the value of the
second dictionary unless overwrite is false. Null values in both
dictionaries are ignored / removed.
Args:
second: The other dictionary to merge in.
overwrite: If true, this keeps the value of the original dictionary.
Defaults to true.
Returns:
An ee.Dictionary.
"""

return apifunction.ApiFunction.call_(
self.name() + '.combine', self, second, overwrite
)

def contains(self, key: _StringType) -> computedobject.ComputedObject:
"""Returns true if the dictionary contains the given key.
Args:
key: A string to look for in the dictionary.
Returns:
An ee.Boolean.
"""

return apifunction.ApiFunction.call_(self.name() + '.contains', self, key)

# TODO: Add fromLists

def get(
self,
key: _EeKeyType,
# pylint: disable-next=invalid-name
defaultValue: Optional[_EeAnyType] = None,
) -> computedobject.ComputedObject:
"""Extracts a named value from a dictionary.
If the dictionary does not contain the given key, then defaultValue is
returned, unless it is null.
Args:
key: A string to look for in the dictionary.
defaultValue: The value to return if the key is not found.
Returns:
Returns an ee.ComputedObject.
"""

return apifunction.ApiFunction.call_(
self.name() + '.get', self, key, defaultValue
)

def getArray(self, key: _EeKeyType) -> ee_array.Array:
"""Extracts a named array value from a dictionary.
Args:
key: A string to look for in the dictionary.
Returns:
An ee.Array.
"""

return apifunction.ApiFunction.call_(self.name() + '.getArray', self, key)

def getGeometry(self, key: _EeKeyType) -> geometry.Geometry:
"""Extracts a named geometry value from a dictionary.
Args:
key: A string to look for in the dictionary.
Returns:
An ee.Geometry.
"""

return apifunction.ApiFunction.call_(
self.name() + '.getGeometry', self, key
)

def getNumber(self, key: _EeKeyType) -> ee_number.Number:
"""Extracts a named number value from a dictionary.
Args:
key: A string to look for in the dictionary.
Returns:
An ee.Number.
"""

return apifunction.ApiFunction.call_(self.name() + '.getNumber', self, key)

def getString(self, key: _EeKeyType) -> ee_string.String:
"""Extracts a named string value from a dictionary.
Args:
key: A string to look for in the dictionary.
Returns:
An ee.String.
"""

return apifunction.ApiFunction.call_(self.name() + '.getString', self, key)

def keys(self) -> ee_list.List:
"""Retrieve the keys of a dictionary as a list."""

return apifunction.ApiFunction.call_(self.name() + '.keys', self)

# pylint: disable-next=invalid-name
def map(self, baseAlgorithm: _EeAnyType) -> Dictionary:
"""Map an algorithm over a dictionary.
The algorithm is expected to take 2 arguments, a key from the existing
dictionary and the value it corresponds to, and return a new value for the
given key. If the algorithm returns null, the key is dropped.
Args:
baseAlgorithm: A function taking key, value and returning the new value.
Returns:
An ee.Dictionary with new values for each key.
"""

return apifunction.ApiFunction.call_(
self.name() + '.map', self, baseAlgorithm
)

def remove(
self,
selectors: _EeAnyType,
# pylint: disable-next=invalid-name
ignoreMissing: Optional[_EeBoolType] = None,
) -> Dictionary:
"""Returns a dictionary with the specified keys removed.
Args:
selectors: A list of key names or regular expressions of key names to
remove.
ignoreMissing: Ignore selectors that don't match at least 1 key. Defaults
to false.
Returns:
An ee.Dictionary.
"""

return apifunction.ApiFunction.call_(
self.name() + '.remove', self, selectors, ignoreMissing
)

# TODO: Make a tighter method signature.
# pylint: disable-next=g-doc-args
def rename(self, *args, **kwargs) -> Dictionary:
"""Rename elements in a dictionary.
Args:
from: A list of keys to be renamed.
to: A list of the new names for the keys listed in the 'from' parameter.
Must have the same length as the 'from' list.
overwrite: Allow overwriting existing properties with the same name.
Returns:
An ee.Dictionary.
"""

return apifunction.ApiFunction.call_(
self.name() + '.rename', self, *args, **kwargs
)

def select(
self,
selectors: _EeAnyType,
# pylint: disable-next=invalid-name
ignoreMissing: Optional[_EeBoolType] = None,
) -> Dictionary:
"""Returns a dictionary with only the specified keys.
Args:
selectors: A list of keys or regular expressions to select.
ignoreMissing: Ignore selectors that don't match at least 1 key.
Defaults to false.
Returns:
An ee.Dictionary.
"""

return apifunction.ApiFunction.call_(
self.name() + '.select', self, selectors, ignoreMissing
)

def set(self, key: _EeKeyType, value: _EeAnyType) -> Dictionary:
"""Set a value in a dictionary.
Args:
key: A string for where to set the value. Does not need to already exist.
value: The value to set for the key.
Returns:
An ee.Dictionary.
"""

return apifunction.ApiFunction.call_(self.name() + '.set', self, key, value)

def size(self) -> ee_number.Number:
"""Returns the number of entries in a dictionary."""

return apifunction.ApiFunction.call_(self.name() + '.size', self)

def toArray(
self,
keys: Optional[_EeKeyListType] = None,
axis: Optional[_IntegerType] = None,
) -> ee_array.Array:
"""Returns numeric values of a dictionary as an array.
If no keys are specified, all values are returned in the natural ordering of
the dictionary's keys. The default 'axis' is 0.
Args:
keys: An optional list of keys to subselect.
axis: How to interpret values that are ee.Arrays. Defaults to 0.
Returns:
An ee.Array.
"""

return apifunction.ApiFunction.call_(
self.name() + '.toArray', self, keys, axis
)

def toImage(self, names: Optional[_EeAnyType] = None) -> image.Image:
"""Creates an image of constants from values in a dictionary.
The bands of the image are ordered and named according to the names
argument. If no names are specified, the bands are sorted
alpha-numerically.
Args:
names: The order of the output bands.
Returns:
An ee.Image.
"""

return apifunction.ApiFunction.call_(self.name() + '.toImage', self, names)

def values(self, keys: Optional[_EeKeyListType] = None) -> ee_list.List:
"""Returns the values of a dictionary as a list.
If no keys are specified, all values are returned in the natural ordering of
the dictionary's keys.
Args:
keys: An optional list of keys to subselect.
Returns:
An ee.Array.
"""

return apifunction.ApiFunction.call_(self.name() + '.values', self, keys)
22 changes: 22 additions & 0 deletions python/ee/tests/data_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,28 @@ def testCreateAssetWithV1AlphaParams(self):
{'uris': ['gs://my-bucket/path']},
)

@unittest.skip('Does not work on github with python 3.7')
def testCreateFolder(self):
cloud_api_resource = mock.MagicMock()
with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
mock_result = {
'type': 'FOLDER',
'name': 'projects/earthengine-legacy/assets/users/foo/xyz1234',
'id': 'users/foo/xyz1234',
}
cloud_api_resource.projects().assets().create.execute.return_value = (
mock_result
)
ee.data.createFolder('users/foo/xyz123')
mock_create_asset = cloud_api_resource.projects().assets().create
mock_create_asset.assert_called_once()
parent = mock_create_asset.call_args.kwargs['parent']
self.assertEqual(parent, 'projects/earthengine-legacy')
asset_id = mock_create_asset.call_args.kwargs['assetId']
self.assertEqual(asset_id, 'users/foo/xyz123')
asset = mock_create_asset.call_args.kwargs['body']
self.assertEqual(asset, {'type': 'FOLDER'})

def testSetAssetProperties(self):
mock_http = mock.MagicMock(httplib2.Http)
with apitestcase.UsingCloudApi(mock_http=mock_http), mock.patch.object(
Expand Down
Loading

0 comments on commit b85f7af

Please sign in to comment.