bots: Add magic method validate_config().
This method allows bots to validate their config info in a standardized way. Adding the method to a bot is optional, but recommended for bots with config options that can be invalid, like api keys. The giphy bot serves as an example. The primary reason behind this is to allow the zulip backend to validate config data for embedded bots. The backend does not have a permanent bot class instance, so validate_config() must be a static method.
This commit is contained in:
parent
7dcec207eb
commit
192e9e101d
5 changed files with 53 additions and 11 deletions
|
@ -7,6 +7,8 @@ import os
|
|||
import re
|
||||
from requests.exceptions import HTTPError, ConnectionError
|
||||
|
||||
from zulip_bots.custom_exceptions import ConfigValidationError
|
||||
|
||||
GIPHY_TRANSLATE_API = 'http://api.giphy.com/v1/gifs/translate'
|
||||
|
||||
class GiphyHandler(object):
|
||||
|
@ -24,21 +26,24 @@ class GiphyHandler(object):
|
|||
The bot responds also to private messages.
|
||||
'''
|
||||
|
||||
def initialize(self, bot_handler: Any) -> None:
|
||||
self.config_info = bot_handler.get_config_info('giphy')
|
||||
@staticmethod
|
||||
def validate_config(config_info: Dict[str, str]) -> None:
|
||||
query = {'s': 'Hello',
|
||||
'api_key': self.config_info['key']}
|
||||
'api_key': config_info['key']}
|
||||
try:
|
||||
data = requests.get(GIPHY_TRANSLATE_API, params=query)
|
||||
data.raise_for_status()
|
||||
except ConnectionError as e:
|
||||
bot_handler.quit(str(e))
|
||||
raise ConfigValidationError(str(e))
|
||||
except HTTPError as e:
|
||||
error_message = str(e)
|
||||
if (data.status_code == 403):
|
||||
error_message += ('This is likely due to an invalid key.\n'
|
||||
'Follow the instructions in doc.md for setting an API key.')
|
||||
bot_handler.quit(error_message)
|
||||
raise ConfigValidationError(error_message)
|
||||
|
||||
def initialize(self, bot_handler: Any) -> None:
|
||||
self.config_info = bot_handler.get_config_info('giphy')
|
||||
|
||||
def handle_message(self, message: Dict[str, str], bot_handler: Any) -> None:
|
||||
bot_response = get_bot_giphy_response(
|
||||
|
|
|
@ -29,18 +29,22 @@ class TestGiphyBot(BotTestCase):
|
|||
'Sorry, I don\'t have a GIF for "world without zulip"! :astonished:',
|
||||
)
|
||||
|
||||
def test_403(self) -> None:
|
||||
def test_invalid_config(self) -> None:
|
||||
bot = get_bot_message_handler(self.bot_name)
|
||||
bot_handler = StubBotHandler()
|
||||
with self.mock_http_conversation('test_403'):
|
||||
self.validate_invalid_config({'key': '12345678'},
|
||||
"This is likely due to an invalid key.\n")
|
||||
|
||||
with self.mock_config_info({'key': '12345678'}), \
|
||||
self.mock_http_conversation('test_403'), \
|
||||
self.assertRaises(bot_handler.BotQuitException):
|
||||
bot.initialize(bot_handler)
|
||||
def test_valid_config(self) -> None:
|
||||
bot = get_bot_message_handler(self.bot_name)
|
||||
bot_handler = StubBotHandler()
|
||||
with self.mock_http_conversation('test_normal'):
|
||||
self.validate_valid_config({'key': '12345678'})
|
||||
|
||||
def test_connection_error_while_running(self) -> None:
|
||||
with self.mock_config_info({'key': '12345678'}), \
|
||||
patch('requests.get', side_effect=[MagicMock(), ConnectionError()]), \
|
||||
patch('requests.get', side_effect=[ConnectionError()]), \
|
||||
patch('logging.exception'):
|
||||
self.verify_reply(
|
||||
'world without chocolate',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue