def test_publish_to_restricted_channel(self): with make_client(endpoint=endpoint, appkey=appkey) as client: auth_event = threading.Event() auth_delegate = auth.RoleSecretAuthDelegate(role, secret) mailbox = [] def auth_callback(auth_result): if type(auth_result) == auth.Done: mailbox.append('Auth success') auth_event.set() else: mailbox.append('Auth failure: {0}'.format(auth_result)) auth_event.set() client.authenticate(auth_delegate, auth_callback) if not auth_event.wait(60): raise RuntimeError('Auth never finished') if not mailbox == ['Auth success']: raise RuntimeError(mailbox) sync_publish(client, channel, 'ohai')
def test_auth_before_start(self): client = Client(endpoint=endpoint, appkey=appkey) auth_event = threading.Event() auth_delegate = auth.RoleSecretAuthDelegate(role, secret) mailbox = [] def auth_callback(auth_result): if type(auth_result) == auth.Done: mailbox.append('Auth success') auth_event.set() else: mailbox.append('Auth failure: {0}'.format(auth_result)) auth_event.set() client.authenticate(auth_delegate, auth_callback) client.start() if not auth_event.wait(60): raise RuntimeError('Auth never finished') self.assertEqual(mailbox, ['Auth success']) client.stop() client.dispose()
def test_shorter_fail_case(self): ad = auth.RoleSecretAuthDelegate('superuser', 'bad_secret') with self.assertRaises(AuthError): with make_client(endpoint=endpoint, appkey=appkey, auth_delegate=ad): pass
def main(): print('Creating RTM client instance') if role and secret: auth_delegate = auth.RoleSecretAuthDelegate(role, secret) else: auth_delegate = None with make_client( endpoint=endpoint, appkey=appkey, auth_delegate=auth_delegate) as client: publish_finished_event = Event() def get_ticks(): client.publish(channel, message=gdax_market.get_ticker( 'ETH-USD'), callback=publish_callback) client.publish(channel, message=poloniex_market.get_ticker( 'USDT_ETH'), callback=publish_callback) client.publish(channel, message=gemini_market.get_ticker( 'ETHUSD'), callback=publish_callback) client.publish(channel, message=kraken_market.get_ticker( 'XETHZUSD'), callback=publish_callback) def get_candles(): client.publish(channel, message=poloniex_market.get_candle( 'USDT_ETH', '300'), callback=publish_callback) def publish_callback(ack): if ack['action'] == 'rtm/publish/ok': print('Publish OK') publish_finished_event.set() elif ack['action'] == 'rtm/publish/error': print( 'Publish request failed, error {0}, reason {1}'.format( ack['body']['error'], ack['body']['reason'])) sys.exit(1) logging.info('Initializing Schedules for Ticks and Candles') schedule.every(settings.MARKET_REFRESH_RATE).seconds.do(get_ticks) schedule.every(settings.CANDLE_REFRESH_RATE).seconds.do(get_candles) # Get and Record market data while True: try: schedule.run_pending() sleep(1) except: sleep(1) continue
def test_reauth(self): client = Client(endpoint=endpoint, appkey=appkey, reconnect_interval=0) auth_delegate = auth.RoleSecretAuthDelegate(role, secret) auth_event = threading.Event() mailbox = [] co = ClientObserver() client.observer = co client.start() co.wait_connected() def auth_callback(auth_result): if type(auth_result) == auth.Done: mailbox.append('Auth success') auth_event.set() else: mailbox.append('Auth failure: {0}'.format( auth_result.message)) auth_event.set() client.authenticate(auth_delegate, auth_callback) if not auth_event.wait(30): raise RuntimeError("Auth timeout") self.assertEqual(mailbox, ['Auth success']) so = sync_subscribe(client, restricted_channel) message1 = make_channel_name('before disconnect') sync_publish(client, restricted_channel, message1) first_data = so.wait_for_channel_data() self.assertTrue(message1 in first_data['messages']) emulate_websocket_disconnect(client) co.wait_disconnected() co.wait_connected() message2 = make_channel_name('after reconnect') sync_publish(client, restricted_channel, message2) second_data = so.wait_for_channel_data() self.assertTrue(message2 in second_data['messages']) client.stop() client.dispose()
def main(): import logging logging.basicConfig(level=logging.WARNING) auth_delegate = auth.RoleSecretAuthDelegate(role, role_secret_key) try: with make_client(endpoint=endpoint, appkey=appkey, auth_delegate=auth_delegate) as client: print('Connected to Satori RTM and authenticated as', role) except AuthError as e: print('Failed to authenticate:', e, file=sys.stderr) sys.exit(1) except Exception as e: print('Error occurred:', e, file=sys.stderr) sys.exit(2)
def main(): ad = auth.RoleSecretAuthDelegate(role, secret) with make_client(endpoint=endpoint, appkey=appkey, auth_delegate=ad) as client: # # At this point we are already authenticated and can publish # publish_finished_event = threading.Event() def publish_callback(ack): print('Publish ack:', ack) publish_finished_event.set() client.publish(restricted_channel, message=message, callback=publish_callback) if not publish_finished_event.wait(60): raise RuntimeError('Publish never finished')
def test_handshake_error(self): with make_client(endpoint=endpoint, appkey=appkey) as client: auth_event = threading.Event() auth_delegate = auth.RoleSecretAuthDelegate('waldo', secret) mailbox = [] def auth_callback(auth_result): if type(auth_result) == auth.Done: mailbox.append('Auth success') auth_event.set() else: mailbox.append('Auth failure: {0}'.format( auth_result.message)) auth_event.set() client.authenticate(auth_delegate, auth_callback) if not auth_event.wait(60): raise RuntimeError('Auth never finished') self.assertEqual(mailbox, ['Auth failure: Unauthenticated'])
def main(): import logging logging.basicConfig(level=logging.WARNING) should_authenticate = role and role_secret_key\ and role_secret_key != 'YOUR_SECRET' if should_authenticate: auth_delegate = auth.RoleSecretAuthDelegate(role, role_secret_key) else: auth_delegate = None print("RTM client config:") print("\tendpoint =", endpoint) print("\tappkey =", appkey) if should_authenticate: print("\tauthenticate? = True (as {0})".format(role)) else: print("\tauthenticate? = False") with make_client( endpoint=endpoint, appkey=appkey, auth_delegate=auth_delegate) as client: # Entering here means that 'client' has already connected and # also authenticated (because we have passed auth_delegate to # make_client) print('Connected to Satori RTM!') # We create a subscription observer object in order to receive callbacks # for incoming data, state changes and errors. class SubscriptionObserver(object): # Called when the subscription is established. def on_enter_subscribed(self): print('Subscribed to the channel: ' + channel) def on_enter_failed(self, reason): print('Subscription failed, reason:', reason) sys.exit(1) # This callback allows us to observe incoming messages def on_subscription_data(self, data): for message in data['messages']: print('Animal is received:', message) subscription_observer = SubscriptionObserver() # Send subscribe request. This call is asynchronous: # client implementation internally queues the request and lets the # function exit. Request is then processed from a background thread, # while our main thread goes on. client.subscribe( channel, SubscriptionMode.SIMPLE, subscription_observer) print('\nPress CTRL-C to exit\n') try: while True: coords = [ 34.134358 + random.random(), -118.321506 + random.random()] animal = {u'who': u'zebra', u'where': coords} # In case of publishing, there's no observer object involved # because the process is simpler: we're guaranteed to receive # exactly one reply callback and need only to inspect it to see # if it's an OK or an error. See 'Publish PDU' section at # https://www.satori.com/docs/references/rtm-api for reference. def publish_callback(ack): if ack['action'] == 'rtm/publish/ok': print('Animal is published:', animal) elif ack['action'] == 'rtm/publish/error': print( 'Publish failed, error {0}, reason {1}'.format( ack['body']['error'], ack['body']['reason'])) client.publish( channel, message=animal, callback=publish_callback) sys.stdout.flush() time.sleep(2) except KeyboardInterrupt: pass
def connect(self): config = self.config self.GPIO = GPIO self.GPIO.setmode(self.GPIO.BOARD) should_authenticate = 'role' in config[ 'satori'] and 'role_secret_key' in config['satori'] auth_delegate = None if not should_authenticate else auth.RoleSecretAuthDelegate( config['satori']['role'], config['satori']['role_secret_key']) client = Client( endpoint=config['satori']['endpoint'], appkey=config['satori']['appkey'], ) ready_event = threading.Event() class Observer: def on_enter_connected(self): ready_event.set() def on_enter_stopped(self): ready_event.set() client.observer = Observer() client.start() if not ready_event.wait(70): if client.last_connecting_error(): client.dispose() raise RuntimeError( "Client connection timeout, last connection error: {0}". format(client.last_connecting_error())) else: raise RuntimeError("Client connection timeout") ready_event.clear() if not client.is_connected(): client.dispose() raise RuntimeError("Client connection error: {0}".format( client.last_connecting_error())) auth_mailbox = [] def auth_callback(auth_result): auth_mailbox.append(auth_result) ready_event.set() if auth_delegate: client.authenticate(auth_delegate, callback=auth_callback) if not ready_event.wait(20): client.dispose() print('[FAIL] Authentication process has timed out') raise Exception('Authentication process has timed out') auth_result = auth_mailbox[0] if type(auth_result) == auth.Error: raise Exception(auth_result.message) print('[OK] Auth success in make_client') print("[OK] Connected to Satori RTM") client.subscribe(config['channels']['in'], SubscriptionMode.SIMPLE, self) self.client = client
def main(): print('Creating RTM client instance') if role and secret: auth_delegate = auth.RoleSecretAuthDelegate(role, secret) else: auth_delegate = None with make_client(endpoint=endpoint, appkey=appkey, auth_delegate=auth_delegate) as client: # Entering here means that 'client' has already connected and # also authenticated (because we have passed auth_delegate to # make_client) print('Subscribing to a channel') # At this point we need to be aware of two facts: # 1. client.subscribe(...) method is asynchronous # 2. We want to receive the message we are publishing ourselves # # That means that we must publish the message *only after* we get # a confirmation that subscription is established (this is not a # general principle: some applications may not care to receive the # messages they publish). # We use an `Event` object from the standard 'threading' module, which # is a mechanism for communication between threads: one thread # signals an event and other threads wait for it. subscribed_event = Event() got_message_event = Event() # We create a subscription observer object in order to receive callbacks # for incoming data, state changes and errors. class SubscriptionObserver(object): # Called when the subscription is established. def on_enter_subscribed(self): subscribed_event.set() # This callback allows us to observe incoming messages def on_subscription_data(self, data): for message in data['messages']: print('Client got message {0}'.format(message)) got_message_event.set() subscription_observer = SubscriptionObserver() # Send subscribe request. This call is asynchronous: # client implementation internally queues the request and lets the # function exit. Request is then processed from a background thread, # while our main thread goes on. client.subscribe(channel, SubscriptionMode.SIMPLE, subscription_observer) # Wait on a subscribed_event is going to put our main thread to sleep # (block). As soon as SDK invokes our on_enter_subscribed callback # (from a background thread), the callback notifies this event (`set`), # which wakes up the main thread. To avoid indefinite hang in case of a # failure, the wait is limited to 10 second timeout. # The result value of `wait` indicates notification (True) # or timeout (False). if not subscribed_event.wait(10): print("Couldn't establish the subscription in time") sys.exit(1) # At this point we're subscribed # client.publish(...) method is also asynchronous, again we # use an 'Event' to wait until we have a reply for publish # request or timeout. publish_finished_event = Event() # In case of publishing, there's no observer object involved because # the process is simpler: we're guaranteed to receive exactly one # reply callback and need only to inspect it to see if it's an OK or # an error. # See 'Publish PDU' section at # https://www.satori.com/docs/references/rtm-api for reference. def publish_callback(ack): if ack['action'] == 'rtm/publish/ok': print('Publish OK') publish_finished_event.set() elif ack['action'] == 'rtm/publish/error': print('Publish request failed, error {0}, reason {1}'.format( ack['body']['error'], ack['body']['reason'])) sys.exit(1) client.publish(channel, message=animal, callback=publish_callback) if not publish_finished_event.wait(10): print("Couldn't publish the message in time") sys.exit(1) # At this point we have successfully published the message # (we know this because we just received a PDU with 'rtm/publish/ok') # and we even may have already received that message back via the # subscription. Publish confirmation could come after or before the # subscription data. if not got_message_event.wait(10): print("Couldn't receive the message in time") sys.exit(1) # At this point we have received the message # and printed it to stdout (in on_subscription_data callback code) print('Unsubscribing from a channel') client.unsubscribe(channel)
def test_shorter_ok_case(self): ad = auth.RoleSecretAuthDelegate(role, secret) with make_client(endpoint=endpoint, appkey=appkey, auth_delegate=ad): pass