Skip to content

Instantly share code, notes, and snippets.

@jiffyclub
Created December 1, 2017 20:34
Show Gist options
  • Save jiffyclub/145f7a997e6c7953c34a349b11cd91de to your computer and use it in GitHub Desktop.
Save jiffyclub/145f7a997e6c7953c34a349b11cd91de to your computer and use it in GitHub Desktop.
Utilities for creating command line-like interfaces for Slack /slash commands.
"""
Utilities for creating command line-like interfaces for Slack /slash commands.
Define your parser spec using an instance of SlashParser and then pass it to parse_args
for parsing. Be sure to check the returned success flag to know whether parsing
was successful or if there was a parsing error.
"""
import argparse
import re
class SlashParserException(Exception):
def __init__(self, message, help_text=None):
super().__init__(message)
self._error_message = message
self._help_text = help_text
class SlashParser(argparse.ArgumentParser):
"""
Custom ArgumentParser class that overrides the ``error`` method
to raise SlashesParserException instead of calling ``sys.exit``.
This should be used with the ``parse_args`` function defined in
this module.
Example usage:
parser = utils.SlashParser(description='Description')
parser.add_argument('my_arg')
success, args_or_help_text = parse_args(command_text, parser)
if not success:
# return help text to user
# do your stuff
"""
def print_help(self, file=None):
"""
The default print_help method sends output to stdout, which isn't
useful when run on the server. We have this raise the same exception
as ``error`` so it gets handled in the same way (hopefully with
help text going back to the user.)
"""
raise SlashParserException('', help_text=self.format_help())
def error(self, message: str):
"""
No-op, only raise an exception and let caller decide what to do.
"""
raise SlashParserException(message, help_text=self.format_help())
def parse_args(
command: str, parser: argparse.ArgumentParser) -> argparse.Namespace:
"""
Parse the slash command's text like a command line tool.
Args:
command: slash command text as entered by the user
parser: parser with the slash command interface specification
Returns:
success flag, if True the second return value will be an argparse
namespace object, if False the second return value will be a
string containg the parser's help text.
argparse namespace object as a result of parsing args OR
a string containing the parser's help text.
"""
try:
args = parser.parse_args(shlex.split(re.sub(r'[‘’“”]', '\'', command)))
except SlashParserException as exc:
help_text = exc._help_text or parser.format_help()
if exc._error_message:
help_text = exc._error_message + '\n\n' + help_text
return False, help_text
else:
return True, args
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment