def init(self, *args): """Initializer for dynamically created classes. Args: self: The instance of this class. Listed to make the linter hush. *args: Either a ComputedObject to be promoted to this type, or arguments to an algorithm with the same name as this class. Returns: The new class. """ klass = globals()[name] onlyOneArg = (len(args) == 1) # Are we trying to cast something that's already of the right class? if onlyOneArg and isinstance(args[0], klass): result = args[0] else: # Decide whether to call a server-side constructor or just do a # client-side cast. ctor = ApiFunction.lookupInternal(name) firstArgIsPrimitive = not isinstance(args[0], ComputedObject) shouldUseConstructor = False if ctor: if not onlyOneArg: # Can't client-cast multiple arguments. shouldUseConstructor = True elif firstArgIsPrimitive: # Can't cast a primitive. shouldUseConstructor = True elif args[0].func != ctor: # We haven't already called the constructor on this object. shouldUseConstructor = True # Apply our decision. if shouldUseConstructor: # Call ctor manually to avoid having promote() called on the output. ComputedObject.__init__(self, ctor, ctor.promoteArgs(ctor.nameArgs(args))) else: # Just cast and hope for the best. if not onlyOneArg: # We don't know what to do with multiple args. raise EEException('Too many arguments for ee.%s(): %s' % (name, args)) elif firstArgIsPrimitive: # Can't cast a primitive. raise EEException( 'Invalid argument for ee.%s(): %s. Must be a ComputedObject.' % (name, args)) else: result = args[0] ComputedObject.__init__(self, result.func, result.args, result.varName)
def _GetPersistentCredentials(): """Read persistent credentials from ~/.config/earthengine. Raises EEException with helpful explanation if credentials don't exist. Returns: OAuth2Credentials built from persistently stored refresh_token """ try: tokens = json.load(open(OAuthInfo.credentials_path())) refresh_token = tokens['refresh_token'] return oauth2client.client.OAuth2Credentials( None, OAuthInfo.CLIENT_ID, OAuthInfo.CLIENT_SECRET, refresh_token, None, 'https://accounts.google.com/o/oauth2/token', None) except IOError: raise EEException( 'Please authorize access to your Earth Engine account ' 'by running\n\nearthengine authenticate\n\nin your ' 'command line, and then retry.')
def _GetPersistentCredentials(): """Read persistent credentials from ~/.config/earthengine. Raises EEException with helpful explanation if credentials don't exist. Returns: OAuth2Credentials built from persistently stored refresh_token """ try: tokens = json.load(open(OAuthInfo.credentials_path())) refresh_token = tokens['refresh_token'] return oauth2client.client.OAuth2Credentials( None, OAuthInfo.CLIENT_ID, OAuthInfo.CLIENT_SECRET, refresh_token, None, 'https://accounts.google.com/o/oauth2/token', None) except IOError: script = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'authenticate.py') raise EEException( 'Please authorize access to your Earth Engine account ' + 'by running\n\npython %s\n\nand then retry.' % script)
def _Promote(arg, klass): """Wrap an argument in an object of the specified class. This is used to e.g.: promote numbers or strings to Images and arrays to Collections. Args: arg: The object to promote. klass: The expected type. Returns: The argument promoted if the class is recognized, otherwise the original argument. """ if arg is None: return arg if klass == 'Image': return Image(arg) elif klass == 'Feature': if isinstance(arg, Collection): # TODO(user): Decide whether we want to leave this in. It can be # quite dangerous on large collections. return ApiFunction.call_( 'Feature', ApiFunction.call_('Collection.geometry', arg)) else: return Feature(arg) elif klass == 'Element': if isinstance(arg, Element): # Already an Element. return arg elif isinstance(arg, Geometry): # Geometries get promoted to Features. return Feature(arg) elif isinstance(arg, ComputedObject): # Try a cast. return Element(arg.func, arg.args, arg.varName) else: # No way to convert. raise EEException('Cannot convert %s to Element.' % arg) elif klass == 'Geometry': if isinstance(arg, Collection): return ApiFunction.call_('Collection.geometry', arg) else: return Geometry(arg) elif klass in ('FeatureCollection', 'Collection'): # For now Collection is synonymous with FeatureCollection. if isinstance(arg, Collection): return arg else: return FeatureCollection(arg) elif klass == 'ImageCollection': return ImageCollection(arg) elif klass == 'Filter': return Filter(arg) elif klass == 'Algorithm': if isinstance(arg, basestring): # An API function name. return ApiFunction.lookup(arg) elif callable(arg): # A native function that needs to be wrapped. args_count = len(inspect.getargspec(arg).args) return CustomFunction.create(arg, 'Object', ['Object'] * args_count) elif isinstance(arg, Encodable): # An ee.Function or a computed function like the return value of # Image.parseExpression(). return arg else: raise EEException('Argument is not a function: %s' % arg) elif klass == 'Dictionary': if isinstance(arg, dict): return arg else: return Dictionary(arg) elif klass == 'String': if (types.isString(arg) or isinstance(arg, ComputedObject) or isinstance(arg, String)): return String(arg) else: return arg elif klass == 'List': return List(arg) elif klass in ('Number', 'Float', 'Long', 'Integer', 'Short', 'Byte'): return Number(arg) elif klass in globals(): cls = globals()[klass] ctor = ApiFunction.lookupInternal(klass) # Handle dynamically created classes. if isinstance(arg, cls): # Return unchanged. return arg elif ctor: # The client-side constructor will call the server-side constructor. return cls(arg) elif isinstance(arg, basestring): if hasattr(cls, arg): # arg is the name of a method in klass. return getattr(cls, arg)() else: raise EEException('Unknown algorithm: %s.%s' % (klass, arg)) else: # Client-side cast. return cls(arg) else: return arg
def _Promote(arg, klass): """Wrap an argument in an object of the specified class. This is used to e.g.: promote numbers or strings to Images and arrays to Collections. Args: arg: The object to promote. klass: The expected type. Returns: The argument promoted if the class is recognized, otherwise the original argument. """ if arg is None: return arg if klass == 'Image': return Image(arg) elif klass == 'Feature': if isinstance(arg, Collection): # TODO(user): Decide whether we want to leave this in. It can be # quite dangerous on large collections. return ApiFunction.call_( 'Feature', ApiFunction.call_('Collection.geometry', arg)) else: return Feature(arg) elif klass in ('Element', 'EEObject'): # TODO(user): Remove EEObject once the server is updated. if isinstance(arg, Element): # Already an EEObject. return arg elif isinstance(arg, ComputedObject): # Try a cast. return Element(arg.func, arg.args) else: # No way to convert. raise EEException('Cannot convert %s to Element.' % arg) elif klass == 'Geometry': if isinstance(arg, Collection): return ApiFunction.call_('Collection.geometry', arg) else: return Geometry(arg) elif klass in ('FeatureCollection', 'Collection'): # For now Collection is synonymous with FeatureCollection. if isinstance(arg, Collection): return arg else: return FeatureCollection(arg) elif klass == 'ImageCollection': return ImageCollection(arg) elif klass == 'Filter': return Filter(arg) elif klass == 'Algorithm' and isinstance(arg, basestring): return ApiFunction.lookup(arg) elif klass == 'Date': if isinstance(arg, basestring): try: import dateutil.parser # pylint: disable=g-import-not-at-top except ImportError: raise EEException( 'Conversion of strings to dates requires the dateutil library.') else: return dateutil.parser.parse(arg) elif isinstance(arg, numbers.Number): return datetime.datetime.fromtimestamp(arg / 1000) elif isinstance(arg, ComputedObject): # Bypass promotion of this and do it directly. func = ApiFunction.lookup('Date') return ComputedObject(func, func.promoteArgs(func.nameArgs([arg]))) else: return arg elif klass == 'Dictionary': if klass not in globals(): # No dictionary class defined. return arg cls = globals()[klass] if isinstance(arg, cls): return arg elif isinstance(arg, ComputedObject): return cls(arg) else: # Can't promote non-ComputedObjects up to Dictionary; no constructor. return arg elif klass == 'String': if (types.isString(arg) or isinstance(arg, ComputedObject) or isinstance(arg, String) or types.isVarOfType(arg, String)): return String(arg) else: return arg elif klass in globals(): cls = globals()[klass] # Handle dynamically created classes. if isinstance(arg, cls): return arg elif isinstance(arg, basestring): if not hasattr(cls, arg): raise EEException('Unknown algorithm: %s.%s' % (klass, arg)) return getattr(cls, arg)() else: return cls(arg) else: return arg