<s> """<STR_LIT>""" <EOL> __all__ = [ '<STR_LIT>' ] <EOL> import logging <EOL> import os <EOL> import random <EOL> import time <EOL> from . import api_utils <EOL> try : <EOL> from google . appengine . api import app_identity <EOL> from google . appengine . ext import ndb <EOL> except ImportError : <EOL> from google . appengine . api import app_identity <EOL> from google . appengine . ext import ndb <EOL> def _make_sync_method ( name ) : <EOL> """<STR_LIT>""" <EOL> def sync_wrapper ( self , * args , ** kwds ) : <EOL> method = getattr ( self , name ) <EOL> future = method ( * args , ** kwds ) <EOL> return future . get_result ( ) <EOL> return sync_wrapper <EOL> def add_sync_methods ( cls ) : <EOL> """<STR_LIT>""" <EOL> for name in cls . __dict__ . keys ( ) : <EOL> if name . endswith ( '<STR_LIT>' ) : <EOL> sync_name = name [ : - <NUM_LIT:6> ] <EOL> if not hasattr ( cls , sync_name ) : <EOL> setattr ( cls , sync_name , _make_sync_method ( name ) ) <EOL> return cls <EOL> class _AE_TokenStorage_ ( ndb . Model ) : <EOL> """<STR_LIT>""" <EOL> token = ndb . StringProperty ( ) <EOL> expires = ndb . FloatProperty ( ) <EOL> @ ndb . tasklet <EOL> def _make_token_async ( scopes , service_account_id ) : <EOL> """<STR_LIT>""" <EOL> rpc = app_identity . create_rpc ( ) <EOL> app_identity . make_get_access_token_call ( rpc , scopes , service_account_id ) <EOL> token , expires_at = yield rpc <EOL> raise ndb . Return ( ( token , expires_at ) ) <EOL> class _RestApi ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , scopes , service_account_id = None , token_maker = None , <EOL> retry_params = None ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( scopes , basestring ) : <EOL> scopes = [ scopes ] <EOL> self . scopes = scopes <EOL> self . service_account_id = service_account_id <EOL> self . make_token_async = token_maker or _make_token_async <EOL> if not retry_params : <EOL> retry_params = api_utils . _get_default_retry_params ( ) <EOL> self . retry_params = retry_params <EOL> self . user_agent = { '<STR_LIT>' : retry_params . _user_agent } <EOL> self . expiration_headroom = random . randint ( <NUM_LIT> , <NUM_LIT> ) <EOL> def __getstate__ ( self ) : <EOL> """<STR_LIT>""" <EOL> return { '<STR_LIT>' : self . scopes , <EOL> '<STR_LIT:id>' : self . service_account_id , <EOL> '<STR_LIT>' : ( None if self . make_token_async == _make_token_async <EOL> else self . make_token_async ) , <EOL> '<STR_LIT>' : self . retry_params , <EOL> '<STR_LIT>' : self . expiration_headroom } <EOL> def __setstate__ ( self , state ) : <EOL> """<STR_LIT>""" <EOL> self . __init__ ( state [ '<STR_LIT>' ] , <EOL> service_account_id = state [ '<STR_LIT:id>' ] , <EOL> token_maker = state [ '<STR_LIT>' ] , <EOL> retry_params = state [ '<STR_LIT>' ] ) <EOL> self . expiration_headroom = state [ '<STR_LIT>' ] <EOL> @ ndb . tasklet <EOL> def do_request_async ( self , url , method = '<STR_LIT:GET>' , headers = None , payload = None , <EOL> deadline = None , callback = None ) : <EOL> """<STR_LIT>""" <EOL> retry_wrapper = api_utils . _RetryWrapper ( <EOL> self . retry_params , <EOL> retriable_exceptions = api_utils . _RETRIABLE_EXCEPTIONS , <EOL> should_retry = api_utils . _should_retry ) <EOL> resp = yield retry_wrapper . run ( <EOL> self . urlfetch_async , <EOL> url = url , <EOL> method = method , <EOL> headers = headers , <EOL> payload = payload , <EOL> deadline = deadline , <EOL> callback = callback , <EOL> follow_redirects = False ) <EOL> raise ndb . Return ( ( resp . status_code , resp . headers , resp . content ) ) <EOL> @ ndb . tasklet <EOL> def get_token_async ( self , refresh = False ) : <EOL> """<STR_LIT>""" <EOL> key = '<STR_LIT>' % ( self . service_account_id , '<STR_LIT:U+002C>' . join ( self . scopes ) ) <EOL> ts = yield _AE_TokenStorage_ . get_by_id_async ( <EOL> key , use_cache = True , use_memcache = True , <EOL> use_datastore = self . retry_params . save_access_token ) <EOL> if refresh or ts is None or ts . expires < ( <EOL> time . time ( ) + self . expiration_headroom ) : <EOL> token , expires_at = yield self . make_token_async ( <EOL> self . scopes , self . service_account_id ) <EOL> timeout = int ( expires_at - time . time ( ) ) <EOL> ts = _AE_TokenStorage_ ( id = key , token = token , expires = expires_at ) <EOL> if timeout > <NUM_LIT:0> : <EOL> yield ts . put_async ( memcache_timeout = timeout , <EOL> use_datastore = self . retry_params . save_access_token , <EOL> use_cache = True , use_memcache = True ) <EOL> raise ndb . Return ( ts . token ) <EOL> @ ndb . tasklet <EOL> def urlfetch_async ( self , url , method = '<STR_LIT:GET>' , headers = None , <EOL> payload = None , deadline = None , callback = None , <EOL> follow_redirects = False ) : <EOL> """<STR_LIT>""" <EOL> headers = { } if headers is None else dict ( headers ) <EOL> headers . update ( self . user_agent ) <EOL> try : <EOL> self . token = yield self . get_token_async ( ) <EOL> except app_identity . InternalError , e : <EOL> if os . environ . get ( '<STR_LIT>' , '<STR_LIT>' ) . endswith ( '<STR_LIT>' ) : <EOL> self . token = None <EOL> logging . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> else : <EOL> raise e <EOL> if self . token : <EOL> headers [ '<STR_LIT>' ] = '<STR_LIT>' + self . token <EOL> deadline = deadline or self . retry_params . urlfetch_timeout <EOL> ctx = ndb . get_context ( ) <EOL> resp = yield ctx . urlfetch ( <EOL> url , payload = payload , method = method , <EOL> headers = headers , follow_redirects = follow_redirects , <EOL> deadline = deadline , callback = callback ) <EOL> raise ndb . Return ( resp ) <EOL> _RestApi = add_sync_methods ( _RestApi ) </s>
