-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial Python websocket-client to the Resourcer #1
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
env/ | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
|
||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,18 @@ | ||
WIP - Not ready for use. | ||
# WIP - Not ready for use. | ||
|
||
## Development | ||
|
||
Its recommended to setup a virtual environment, e.g. `virtualenv venv`. | ||
|
||
Then do `pip install requirements.txt` | ||
|
||
You will need the following env vars set. In Prod, these would be passed in via Beep Boop. | ||
|
||
`export BEEPBOOP_TOKEN=foo` | ||
|
||
`export BEEPBOOP_ID=bar` | ||
|
||
`export BEEPBOOP_RESOURCER=ws://localhost:9000/ws` -- recommend using the [Beep Boop dev-console](https://github.com/BeepBoopHQ/dev-console) and setting this value to it. | ||
|
||
Run `python ./examples/simple.py` which registers listeners as a consuming app might. Note you may need to set `export PYTHONPATH=.` so that | ||
it can properly import the beepboop module. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# -*- coding: utf8 -*- | ||
|
||
from __future__ import print_function | ||
import os | ||
import json | ||
import time | ||
import sys | ||
|
||
import logging | ||
|
||
log_level = os.getenv("LOG_LEVEL", "INFO") | ||
logging.basicConfig(format='%(asctime)s - %(levelname)s: %(message)s', level=log_level) | ||
logger = logging.getLogger(__name__) | ||
|
||
import websocket | ||
import random | ||
|
||
|
||
class BeepBoop(object): | ||
def __init__(self, token=None, pod_id=None, resourcer=None): | ||
self.token = self._getprop(token, "BEEPBOOP_TOKEN") | ||
self.pod_id = self._getprop(pod_id, "BEEPBOOP_ID") | ||
self.resourcer = self._getprop(resourcer, "BEEPBOOP_RESOURCER") | ||
|
||
self.ws_conn = None | ||
self.ws_app = None | ||
self.handler_funcs = None | ||
self.iter = 0 | ||
|
||
def start(self): | ||
logging.info('Connecting to Beep Boop Resourcer server: ' + self.resourcer) | ||
|
||
ws_app = websocket.WebSocketApp(self.resourcer, | ||
on_message = self.on_message, | ||
on_error = self.on_error, | ||
on_close = self.on_close) | ||
|
||
ws_app.on_open = self.on_open | ||
self.ws_app = ws_app | ||
self._connect() | ||
|
||
# sets handlers "registered" by the client, enabling the bubbling up of events | ||
def handlers(self, handler_funcs_dict): | ||
self.handler_funcs = handler_funcs_dict | ||
|
||
|
||
def _connect(self): | ||
# while loop makes sure we retry to connect on server down or network failure | ||
while True: | ||
self.ws_app.run_forever() | ||
self.iter += 1 | ||
logging.debug('reconnecting attempt: ' + str(self.iter)) | ||
expBackoffSleep(self.iter, 32) | ||
|
||
|
||
def on_message(self, ws, message): | ||
if self.handler_funcs['on_message']: | ||
self.handler_funcs['on_message'](ws, json.loads(message)) | ||
|
||
def on_error(self, ws, error): | ||
if self.handler_funcs['on_error']: | ||
self.handler_funcs['on_error'](ws, error) | ||
|
||
def on_close(self, ws): | ||
if self.handler_funcs['on_close']: | ||
self.handler_funcs['on_close'](ws) | ||
|
||
def on_open(self, ws): | ||
self.ws_conn = ws | ||
self._authorize() | ||
# reset to 0 since we've reopened a connection | ||
self.iter = 0 | ||
if self.handler_funcs['on_open']: | ||
self.handler_funcs['on_open'](ws) | ||
|
||
|
||
|
||
def _authorize(self): | ||
auth_msg = dict([ | ||
('type', 'auth'), | ||
('id', self.pod_id), | ||
('token', self.token), | ||
]) | ||
self.ws_conn.send(json.dumps(auth_msg)) | ||
|
||
def _getprop(self, param, env_var): | ||
v = param or os.getenv(env_var, None) | ||
if not v: | ||
logging.fatal('Missing required environment variable ' + env_var) | ||
exit() | ||
|
||
return v | ||
|
||
# Use binary exponential backoff to desynchronize client requests. | ||
# As described by: https://cloud.google.com/storage/docs/exponential-backoff | ||
def expBackoffSleep(n, max_backoff_time): | ||
time_to_sleep = min(random.random() * (2**n), max_backoff_time) | ||
logging.debug('time to sleep: ' + str(time_to_sleep)) | ||
time.sleep(time_to_sleep) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from __future__ import print_function | ||
import sys | ||
import os | ||
import pprint | ||
|
||
import beepboop | ||
|
||
if __name__ == "__main__": | ||
|
||
# Fires when a data-transfer type of message has been sent from the Beep Boop Resourcer server. | ||
# The following "types" of messages are supported: | ||
# add_resource - a request to add a bot instance to a team has been received. | ||
# update_resource - a request to update an instance of a bot has been received (config changed) | ||
# remove_resource - a request to remove a bot instance from a team has been received. | ||
|
||
# The message has the following (prettyprint) form: | ||
# { | ||
# u'date': u'2016-03-01T15:06:20.471155964-07:00', | ||
# u'msgID': u'00a6d8e1-2f83-439e-9a1c-f9537c8ba0d3', | ||
# u'resource': { u'MY_CUSTOM_CONFIG_NAME': u'the peanuts are friendly'}, | ||
# u'resourceID': u'ec4fba40-1e89-4005-a236-4f6f77ef19ca', | ||
# u'type': u'add_resource' | ||
# } | ||
|
||
def on_message(ws, message): | ||
|
||
# Access the message type | ||
print (message['type']) | ||
|
||
# Access the config defined in the bot.yml (commented avoid error) | ||
# print (message['resource']['MY_CUSTOM_CONFIG']) | ||
|
||
pp = pprint.PrettyPrinter(indent=2) | ||
pp.pprint(message) | ||
|
||
|
||
# Fires when an error occurred in the connection with the Beep Boop Resourcer server. | ||
def on_error(ws, error): | ||
print ('Error: ' + str(error)) | ||
|
||
# Fires the connection with the Beep Boop resourcer has closed. | ||
def on_close(ws): | ||
print ('Closed') | ||
|
||
# Fires when the connection with the Beep Boop resourcer has opened. | ||
def on_open(ws): | ||
print('Opened') | ||
|
||
|
||
# handler_funcs allows you to declare the events you want to listen for and their handlers | ||
handler_funcs = dict([ | ||
('on_open', on_open), | ||
('on_message', on_message), | ||
('on_error', on_error), | ||
('on_close', on_close), | ||
]) | ||
|
||
bp = beepboop.BeepBoop() | ||
bp.handlers(handler_funcs) | ||
bp.start() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
six==1.10.0 | ||
websocket-client==0.35.0 | ||
wheel==0.24.0 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More of a reminder... when we point to the Resourcer-dev, we'll want to add instructions on how they fetch these values from the beepboophq site.