Created
December 1, 2017 20:34
-
-
Save jiffyclub/145f7a997e6c7953c34a349b11cd91de to your computer and use it in GitHub Desktop.
Utilities for creating command line-like interfaces for Slack /slash commands.
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
""" | |
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