#NEWLINE# def json_request( self , registration_ids , data = None , collapse_key = None , delay_while_idle = False , time_to_live = None , retries = 5 , dry_run = False ) : #NEWLINE# #INDENT# '\n        Makes a JSON request to GCM servers\n\n        :param registration_ids: list of the registration ids\n        :param data: dict mapping of key-value pairs of messages\n        :return dict of response body from Google including multicast_id, success, failure, canonical_ids, etc\n        :raises GCMMissingRegistrationException: if the list of registration_ids is empty\n        :raises GCMTooManyRegIdsException: if the list of registration_ids exceeds 1000 items\n        ' #NEWLINE# if ( not registration_ids ) : #NEWLINE# #INDENT# raise GCMMissingRegistrationException ( 'Missing registration_ids' ) #NEWLINE# #UNINDENT# if ( len ( registration_ids ) > 1000 ) : #NEWLINE# #INDENT# raise GCMTooManyRegIdsException ( 'Exceded number of registration_ids' ) #NEWLINE# #UNINDENT# attempt = 0 #NEWLINE# backoff = self . BACKOFF_INITIAL_DELAY #NEWLINE# for attempt in range ( retries ) : #NEWLINE# #INDENT# payload = self . construct_payload ( registration_ids , data , collapse_key , delay_while_idle , time_to_live , True , dry_run ) #NEWLINE# response = self . make_request ( payload , is_json = True ) #NEWLINE# info = self . handle_json_response ( response , registration_ids ) #NEWLINE# unsent_reg_ids = self . extract_unsent_reg_ids ( info ) #NEWLINE# if unsent_reg_ids : #NEWLINE# #INDENT# registration_ids = unsent_reg_ids #NEWLINE# sleep_time = ( ( backoff / 2 ) + random . randrange ( backoff ) ) #NEWLINE# time . sleep ( ( float ( sleep_time ) / 1000 ) ) #NEWLINE# if ( ( 2 * backoff ) < self . MAX_BACKOFF_DELAY ) : #NEWLINE# #INDENT# backoff *= 2 #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# #UNINDENT# return info