Skip to content

Commit

Permalink
v0.1.397
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 620069254
  • Loading branch information
Google Earth Engine Authors authored and jgarcia525 committed Apr 3, 2024
1 parent 7c525ff commit a2703cb
Show file tree
Hide file tree
Showing 32 changed files with 3,578 additions and 1,117 deletions.
782 changes: 392 additions & 390 deletions javascript/build/ee_api_js.js

Large diffs are not rendered by default.

215 changes: 119 additions & 96 deletions javascript/build/ee_api_js_debug.js

Large diffs are not rendered by default.

260 changes: 142 additions & 118 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.395",
"version": "0.1.397",
"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.395';
const API_CLIENT_VERSION = '0.1.397';

exports.VERSION = apiVersion.VERSION;
exports.API_CLIENT_VERSION = API_CLIENT_VERSION;
Expand Down
47 changes: 40 additions & 7 deletions javascript/src/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -1659,14 +1659,41 @@ ee.data.getInfo = ee.data.getAsset;
ee.data.makeListAssetsCall_ = function(
parent, opt_params = {}, opt_callback = undefined,
opt_postProcessing = goog.functions.identity) {
/** @type {!ee.api.ProjectsAssetsListAssetsNamedParameters} */
const params = Object.assign({}, opt_params);
const call = new ee.apiclient.Call(opt_callback);
// Detect project asset root call.
const isProjectAssetRoot = ee.rpc_convert.CLOUD_ASSET_ROOT_RE.test(parent);
const call = new ee.apiclient.Call(opt_callback);
const methodRoot = isProjectAssetRoot ? call.projects() : call.assets();
parent = isProjectAssetRoot ? ee.rpc_convert.projectParentFromPath(parent) :
ee.rpc_convert.assetIdToAssetName(parent);
return call.handle(
methodRoot.listAssets(parent, opt_params).then(opt_postProcessing));
const getNextPageIfNeeded = (response) => {
// We currently treat pageSize as a cap on the results, if this param was
// provided we should break fast and not return more than the asked for
// amount.
if (params.pageSize != null || !response.nextPageToken) {
return response;
}
const previousAssets = response.assets || [];
params.pageToken = response.nextPageToken;
const nextResponse = methodRoot.listAssets(parent, params)
.then((response) => {
// Add previous assets to front.
response.assets = previousAssets.concat(response.assets);
return response;
})
.then(getNextPageIfNeeded);
if (opt_callback) {
// For async, make sure we have only a single chained `call.handle` call.
return nextResponse;
}
// For sync mode, the response data needs to be uplifted from the fake
// Promise object to be returned immediately.
return call.handle(nextResponse);
};
return call.handle(methodRoot.listAssets(parent, params)
.then(getNextPageIfNeeded)
.then(opt_postProcessing));
};


Expand All @@ -1686,9 +1713,15 @@ ee.data.makeListAssetsCall_ = function(
* @export
*/
ee.data.getList = function(params, opt_callback) {
const convertedParams = ee.rpc_convert.getListToListAssets(params);
// Force a single page of results by explicitly specifying a page size.
// This maintains backward compatibility, as well as compatibility with the
// Python implementation.
if (!convertedParams.pageSize) {
convertedParams.pageSize = 1000;
}
return ee.data.makeListAssetsCall_(
params['id'], ee.rpc_convert.getListToListAssets(params), opt_callback,
(r) => {
params['id'], convertedParams, opt_callback, (r) => {
if (r == null) {
return null;
}
Expand All @@ -1709,7 +1742,7 @@ ee.data.getList = function(params, opt_callback) {
* <table>
* <tr>
* <td><code> pageSize </code> (string) The number of results to
* return. Defaults to 1000.</td>
* return. If not specified, all results are returned.</td>
* </tr>
* <tr>
* <td><code> pageToken </code> (string) The token for the page of
Expand Down Expand Up @@ -1753,7 +1786,7 @@ ee.data.listAssets = function(
* <table>
* <tr>
* <td><code> pageSize </code> (string) The number of results to return.
* Defaults to 1000.</td>
* If not specified, all results are returned.</td>
* </tr>
* <tr>
* <td><code> pageToken </code> (string) The token page of results to
Expand Down
4 changes: 3 additions & 1 deletion javascript/src/examples/Demos/Landsat8HarmonicModeling.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ var addHarmonics = function(freqs) {
};
};

// Filter to the area of interest, mask clouds, add variables.
// Filter to the desired date range and area of interest, mask clouds,
// and add variables.
var harmonicLandsat = landsatCollection
.filterDate('2015-01-01', '2020-01-01')
.filterBounds(roi)
.map(maskClouds)
.map(addNDVI)
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.395'
__version__ = '0.1.397'

# Using lowercase function naming to match the JavaScript names.
# pylint: disable=g-bad-name
Expand Down
16 changes: 13 additions & 3 deletions python/ee/_cloud_api_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,19 @@ def request( # pylint: disable=invalid-name
del connection_type # Ignored
del redirections # Ignored

response = self._session.request(
method, uri, data=body, headers=headers, timeout=self._timeout
)
try:
# googleapiclient is expecting an httplib2 object, and doesn't include
# requests error in the list of transient errors. Therefore, transient
# requests errors should be converted to kinds that googleapiclient
# consider transient.
response = self._session.request(
method, uri, data=body, headers=headers, timeout=self._timeout
)
except requests.exceptions.ConnectionError as connection_error:
raise ConnectionError(connection_error) from connection_error
except requests.exceptions.ChunkedEncodingError as encoding_error:
# This is not a one-to-one match, but it's close enough.
raise ConnectionError(encoding_error) from encoding_error
headers = dict(response.headers)
headers['status'] = response.status_code
content = response.content
Expand Down
37 changes: 25 additions & 12 deletions python/ee/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@
from ee import geometry


def _transform_operation_to_task(operation: Dict[str, Any]) -> Task:
"""Converts an operation to a task."""
status = _cloud_api_utils.convert_operation_to_task(operation)
return Task(
status['id'],
status.get('task_type'),
status.get('state'),
{'description': status.get('description')},
status.get('name'),
)


class Task:
"""A batch task that can be run on the EE batch processing system."""

Expand Down Expand Up @@ -108,6 +120,14 @@ def __init__(
self.state = state
self.name = name

@property
def operation_name(self) -> Optional[str]:
if self.name:
return self.name
if self.id:
return _cloud_api_utils.convert_task_id_to_operation_name(self.id)
return None

def start(self) -> None:
"""Starts the task. No-op for started tasks."""
if not self.config:
Expand Down Expand Up @@ -152,8 +172,9 @@ def status(self) -> Dict[str, Any]:
- error_message: Failure reason. Appears only if state is FAILED.
May also include other fields.
"""
if self.id:
result = data.getTaskStatus(self.id)[0]
if self.operation_name:
operation = data.getOperation(self.operation_name)
result = _cloud_api_utils.convert_operation_to_task(operation)
if result['state'] == 'UNKNOWN':
result['state'] = Task.State.UNSUBMITTED
else:
Expand All @@ -166,7 +187,7 @@ def active(self) -> bool:

def cancel(self) -> None:
"""Cancels the task."""
data.cancelTask(self.id)
data.cancelOperation(self.operation_name)

@staticmethod
def list() -> List[Task]:
Expand All @@ -178,15 +199,7 @@ def list() -> List[Task]:
Returns:
A list of Tasks.
"""
statuses = data.getTaskList()
tasks = []
for status in statuses:
tasks.append(Task(status['id'],
status.get('task_type'),
status.get('state'),
{'description': status.get('description')},
status.get('name')))
return tasks
return list(map(_transform_operation_to_task, data.listOperations()))

def __repr__(self) -> str:
"""Returns a string representation of the task."""
Expand Down
20 changes: 13 additions & 7 deletions python/ee/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,14 +556,18 @@ def getList(params: Dict[str, Any]) -> Any:
return result


def listImages(params: Dict[str, Any]) -> Dict[str, Optional[List[int]]]:
def listImages(
params: Union[str, Dict[str, Any]],
) -> Dict[str, Optional[List[int]]]:
"""Returns the images in an image collection or folder.
Args:
params: An object containing request parameters with the following possible
params: Either a string representing the ID of the image collection to list,
or an object containing request parameters with the following possible
values, all but 'parent` are optional:
parent - (string) The ID of the image collection to list, required.
pageSize - (string) The number of results to return. Defaults to 1000.
pageSize - (string) The number of results to return. If not specified, all
results are returned.
pageToken - (string) The token page of results to return.
startTime - (ISO 8601 string): The minimum start time (inclusive).
endTime - (ISO 8601 string): The maximum end time (exclusive).
Expand Down Expand Up @@ -591,14 +595,16 @@ def listImages(params: Dict[str, Any]) -> Dict[str, Optional[List[int]]]:
return images


def listAssets(params: Dict[str, Any]) -> Dict[str, List[Any]]:
def listAssets(params: Union[str, Dict[str, Any]]) -> Dict[str, List[Any]]:
"""Returns the assets in a folder.
Args:
params: An object containing request parameters with the following possible
values, all but 'parent` are optional:
params: Either a string representing the ID of the collection or folder to
list, or an object containing request parameters with the following
possible values, all but 'parent` are optional:
parent - (string) The ID of the collection or folder to list, required.
pageSize - (string) The number of results to return. Defaults to 1000.
pageSize - (string) The number of results to return. If not specified, all
results are returned.
pageToken - (string) The token page of results to return.
filter - (string) An additional filter query to apply. Example query:
'''properties.my_property>=1 AND properties.my_property<2 AND
Expand Down
83 changes: 82 additions & 1 deletion python/ee/daterange.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from ee import ee_string

_DateRangeType = Union['DateRange', computedobject.ComputedObject]
_DateType = Union[float, str, ee_date.Date, computedobject.ComputedObject]
_DateType = Union[float, str, 'ee_date.Date', computedobject.ComputedObject]
_StringType = Union[str, ee_string.String, computedobject.ComputedObject]


Expand Down Expand Up @@ -87,3 +87,84 @@ def reset(cls) -> None:
@staticmethod
def name() -> str:
return 'DateRange'

def contains(
self, other: Union[_DateType, _DateRangeType]
) -> computedobject.ComputedObject:
"""Returns true if the given Date or DateRange is within this DateRange.
Args:
other: The Date or DateRange to check if it is inside the DateRange.
Returns:
A Boolean ComputedObject.
"""

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

def end(self) -> ee_date.Date:
"""Returns the (exclusive) end of this DateRange."""

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

def intersection(
self, other: Union[_DateType, _DateRangeType]
) -> 'DateRange':
"""Returns a DateRange that contains all the timespan of this and other.
Args:
other: The other DateRange to include in the intersection.
Raises:
EEException if the result is an empty DateRange.
Returns:
An ee.DateRange.
"""

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

def intersects(
self, other: Union[_DateType, _DateRangeType]
) -> computedobject.ComputedObject:
"""Returns true if the other DateRange has at least one time in common.
Args:
other: The other DateRange to check against.
Returns:
A Boolean ComputedObject.
"""

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

def isEmpty(self) -> computedobject.ComputedObject:
"""Returns true if this DateRange contains no dates, i.e. start >= end."""

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

def isUnbounded(self) -> computedobject.ComputedObject:
"""Returns true if this DateRange contains all dates."""

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

def start(self) -> ee_date.Date:
"""Returns the (inclusive) start of this DateRange."""

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

def union(self, other: Union[_DateType, _DateRangeType]) -> DateRange:
"""Returns a DateRange that contains all points in this and other.
Args:
other: The DateRange to union with.
Returns:
An ee.DateRange.
"""

return apifunction.ApiFunction.call_(self.name() + '.union', self, other)
3 changes: 2 additions & 1 deletion python/ee/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ def _IssueAssetDeprecationWarning(asset: _DeprecatedAsset) -> None:
f'\n\nAttention required for {asset.id}! You are using a deprecated'
' asset.\nTo ensure continued functionality, please update it'
)
if removal_date := asset.removal_date:
removal_date = asset.removal_date
if removal_date:
formatted_date = removal_date.strftime('%B %-d, %Y')
warning = warning + f' by {formatted_date}.'
else:
Expand Down
6 changes: 4 additions & 2 deletions python/ee/ee_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@

from ee import apifunction
from ee import computedobject
# pylint: disable=unused-import
from ee import ee_list
from ee import ee_string
# pylint: enable=unused-import

_ArrayType = Union[
Any, List[Any], 'Array', ee_list.List, computedobject.ComputedObject
Any, List[Any], 'Array', 'ee_list.List', computedobject.ComputedObject
]
_StringType = Union[str, ee_string.String, computedobject.ComputedObject]
_StringType = Union[str, 'ee_string.String', computedobject.ComputedObject]


class Array(computedobject.ComputedObject):
Expand Down
Loading

0 comments on commit a2703cb

Please sign in to comment.