Skip to content

Commit

Permalink
v0.1.395
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 615547185
  • Loading branch information
Google Earth Engine Authors authored and bengalin committed Mar 20, 2024
1 parent 4929ae5 commit 7c525ff
Show file tree
Hide file tree
Showing 22 changed files with 2,445 additions and 1,834 deletions.
44 changes: 22 additions & 22 deletions javascript/build/ee_api_js.js

Large diffs are not rendered by default.

1,726 changes: 863 additions & 863 deletions javascript/build/ee_api_js_debug.js

Large diffs are not rendered by default.

1,771 changes: 885 additions & 886 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.394",
"version": "0.1.395",
"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.394';
const API_CLIENT_VERSION = '0.1.395';

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.394'
__version__ = '0.1.395'

# Using lowercase function naming to match the JavaScript names.
# pylint: disable=g-bad-name
Expand Down
6 changes: 5 additions & 1 deletion python/ee/blob.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
"""A wrapper for Blobs."""
from __future__ import annotations

from typing import Any, Dict, Union

from ee import apifunction
from ee import computedobject
from ee import ee_string

_StringType = Union[str, ee_string.String, computedobject.ComputedObject]


class Blob(computedobject.ComputedObject):
Expand All @@ -28,7 +32,7 @@ class Blob(computedobject.ComputedObject):
# Tell pytype to not complain about dynamic attributes.
_HAS_DYNAMIC_ATTRIBUTES = True

def __init__(self, url: Union[str, computedobject.ComputedObject]):
def __init__(self, url: _StringType):
"""Creates a Blob wrapper.
Args:
Expand Down
10 changes: 8 additions & 2 deletions python/ee/confusionmatrix.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
"""A wrapper for ConfusionMatrices."""
from __future__ import annotations

from typing import Any, Dict, List, Optional, Union

from ee import apifunction
from ee import computedobject
from ee import ee_array

_ArrayType = Union[ee_array.Array, computedobject.ComputedObject]
_ConfusionMatrixType = Union['ConfusionMatrix', computedobject.ComputedObject]
_ListType = Union[List[Any], computedobject.ComputedObject]


class ConfusionMatrix(computedobject.ComputedObject):
Expand All @@ -25,8 +31,8 @@ class ConfusionMatrix(computedobject.ComputedObject):

def __init__(
self,
array: Optional[computedobject.ComputedObject],
order: Optional[Union[List[Any], computedobject.ComputedObject]] = None,
array: Optional[Union[_ArrayType, _ConfusionMatrixType]],
order: Optional[_ListType] = None,
):
"""Creates a ConfusionMatrix wrapper.
Expand Down
13 changes: 10 additions & 3 deletions python/ee/daterange.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
"""A wrapper for DateRanges."""
from __future__ import annotations

from typing import Any, Dict, Optional, Union

from ee import apifunction
from ee import computedobject
from ee import ee_date
from ee import ee_string

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


class DateRange(computedobject.ComputedObject):
Expand All @@ -26,10 +33,10 @@ class DateRange(computedobject.ComputedObject):

def __init__(
self,
start: Union[float, str, computedobject.ComputedObject],
end: Optional[Union[float, str, computedobject.ComputedObject]] = None,
start: Union[_DateType, _DateRangeType],
end: Optional[_DateType] = None,
# pylint: disable-next=invalid-name
timeZone: Optional[Union[str, computedobject.ComputedObject]] = None,
timeZone: Optional[_StringType] = None,
):
"""Creates a DateRange wrapper.
Expand Down
145 changes: 144 additions & 1 deletion python/ee/deprecation.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
"""Decorators to handle various deprecations."""

from __future__ import annotations

import dataclasses
import datetime
import functools
import inspect
import json
from typing import Any, Callable, Dict, Optional
import urllib
import warnings

_DEPRECATED_OBJECT = 'earthengine-stac/catalog/catalog_deprecated.json'
_DEPRECATED_ASSETS_URL = f'https://storage.googleapis.com/{_DEPRECATED_OBJECT}'

# Deprecation warnings are per-asset, per-initialization.
deprecated_assets: Dict[str, _DeprecatedAsset] = None


def Deprecated(message: str):
"""Returns a decorator with a given warning message."""
Expand All @@ -25,11 +39,14 @@ def Wrapper(*args, **kwargs):
'%s() is deprecated: %s' % (func.__name__, message),
category=DeprecationWarning,
filename=func.__code__.co_filename,
lineno=func.__code__.co_firstlineno + 1)
lineno=func.__code__.co_firstlineno + 1,
)
return func(*args, **kwargs)

deprecation_message = '\nDEPRECATED: ' + message
Wrapper.__doc__ += deprecation_message
return Wrapper

return Decorator


Expand All @@ -41,4 +58,130 @@ def Wrapper(*args, **kwargs):
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning)
return func(*args, **kwargs)

return Wrapper


@dataclasses.dataclass
class _DeprecatedAsset:
"""Class for keeping track of a single deprecated asset."""

id: str
replacement_id: Optional[str]
removal_date: Optional[datetime.datetime]
learn_more_url: str

has_warning_been_issued: bool = False

@classmethod
def _ParseDateString(cls, date_str: str) -> datetime.datetime:
return datetime.datetime.fromisoformat(date_str)

@classmethod
def FromStacLink(cls, stac_link: Dict[str, Any]) -> _DeprecatedAsset:
removal_date = stac_link.get('gee:removal_date')
if removal_date:
removal_date = cls._ParseDateString(removal_date)
return _DeprecatedAsset(
id=stac_link['title'],
replacement_id=stac_link.get('gee:replacement_id'),
removal_date=removal_date,
learn_more_url=stac_link.get('gee:learn_more_url'),
)


def WarnForDeprecatedAsset(arg_name: str) -> Callable[..., Any]:
"""Decorator to warn on usage of deprecated assets.
Args:
arg_name: The name of the argument to check for asset deprecation.
Returns:
The decorated function which checks for asset deprecation.
"""

def Decorator(func: Callable[..., Any]):
@functools.wraps(func)
def Wrapper(*args, **kwargs) -> Callable[..., Any]:
argspec = inspect.getfullargspec(func)
index = argspec.args.index(arg_name)
if kwargs.get(arg_name):
asset_name_object = kwargs[arg_name]
elif index < len(args):
asset_name_object = args[index]
else:
asset_name_object = None
asset_name = _GetStringFromObject(asset_name_object)
if asset_name:
asset = (deprecated_assets or {}).get(asset_name)
if asset:
_IssueAssetDeprecationWarning(asset)
return func(*args, **kwargs)

return Wrapper

return Decorator


def InitializeDeprecatedAssets() -> None:
global deprecated_assets
if deprecated_assets is not None:
return
_UnfilterDeprecationWarnings()

deprecated_assets = {}
stac = _FetchDataCatalogStac()
for stac_link in stac.get('links', []):
if stac_link.get('deprecated', False):
asset = _DeprecatedAsset.FromStacLink(stac_link)
deprecated_assets[asset.id] = asset


def Reset() -> None:
global deprecated_assets
deprecated_assets = None


def _FetchDataCatalogStac() -> Dict[str, Any]:
try:
response = urllib.request.urlopen(_DEPRECATED_ASSETS_URL).read()
except (urllib.error.HTTPError, urllib.error.URLError):
return {}
return json.loads(response)


def _GetStringFromObject(obj: Any) -> Optional[str]:
if isinstance(obj, str):
return obj
return None


def _UnfilterDeprecationWarnings() -> None:
"""Unfilters deprecation warnings for this module."""
warnings.filterwarnings(
'default', category=DeprecationWarning, module=__name__
)


def _IssueAssetDeprecationWarning(asset: _DeprecatedAsset) -> None:
"""Issues a warning for a deprecated asset if one hasn't already been issued.
Args:
asset: The asset.
"""
if asset.has_warning_been_issued:
return
asset.has_warning_been_issued = True

warning = (
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:
formatted_date = removal_date.strftime('%B %-d, %Y')
warning = warning + f' by {formatted_date}.'
else:
warning = warning + '.'
if asset.learn_more_url:
warning = warning + f'\nLearn more: {asset.learn_more_url}\n'
warnings.warn(warning, category=DeprecationWarning)
13 changes: 6 additions & 7 deletions python/ee/dictionary.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
"""A wrapper for dictionaries."""

from __future__ import annotations

from typing import Any, Dict, Optional, Sequence, Union

from ee import _utils
from ee import apifunction
from ee import computedobject

_DictType = Union[
Dict[Any, Any], Sequence[Any], 'Dictionary', computedobject.ComputedObject
]


class Dictionary(computedobject.ComputedObject):
"""An object to represent dictionaries."""
Expand All @@ -18,12 +22,7 @@ class Dictionary(computedobject.ComputedObject):
# Tell pytype to not complain about dynamic attributes.
_HAS_DYNAMIC_ATTRIBUTES = True

def __init__(
self,
arg: Optional[
Union[Dict[Any, Any], Sequence[Any], computedobject.ComputedObject]
] = None,
):
def __init__(self, arg: Optional[_DictType] = None):
"""Construct a dictionary.
Args:
Expand Down
16 changes: 11 additions & 5 deletions python/ee/ee_array.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
"""A wrapper for Arrays."""
from __future__ import annotations

from typing import Any, Dict, Optional, Union
from typing import Any, Dict, List, Optional, Union

from ee import apifunction
from ee import computedobject
from ee import ee_list
from ee import ee_string

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


class Array(computedobject.ComputedObject):
Expand All @@ -30,11 +38,9 @@ class Array(computedobject.ComputedObject):

def __init__(
self,
values: Optional[
Union[Any, computedobject.ComputedObject]
],
values: Optional[_ArrayType],
# pylint: disable-next=invalid-name
pixelType: Optional[Union[str, computedobject.ComputedObject]] = None,
pixelType: Optional[_StringType] = None,
):
"""Creates an Array wrapper.
Expand Down
14 changes: 9 additions & 5 deletions python/ee/ee_date.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""A wrapper for dates."""
from __future__ import annotations

import datetime
import math
Expand All @@ -7,9 +8,16 @@
from ee import _utils
from ee import apifunction
from ee import computedobject
from ee import ee_string
from ee import ee_types as types
from ee import serializer

# TODO: b/291072742 - Have a separate type when datetime.Datetime unavailable.
_DateType = Union[
datetime.datetime, float, str, 'Date', computedobject.ComputedObject
]
_StringType = Union[str, ee_string.String, computedobject.ComputedObject]


class Date(computedobject.ComputedObject):
"""An object to represent dates."""
Expand All @@ -20,11 +28,7 @@ class Date(computedobject.ComputedObject):
_HAS_DYNAMIC_ATTRIBUTES = True

@_utils.accept_opt_prefix('opt_tz')
def __init__(
self,
date: Union[datetime.datetime, float, str, computedobject.ComputedObject],
tz: Optional[Union[str, computedobject.ComputedObject]] = None,
):
def __init__(self, date: Union[_DateType], tz: Optional[_StringType] = None):
"""Construct a date.
This sends all inputs (except another Date) through the Date function.
Expand Down
Loading

0 comments on commit 7c525ff

Please sign in to comment.