Coverage for hookee/cli.py: 94.34%

1 import platform

2

3 import click

4

5 from hookee import HookeeManager, pluginmanager

6

7 __author__ = "Alex Laird"

8 __copyright__ = "Copyright 2023, Alex Laird"

9 __version__ = "2.0.0"

10

11

12@click.group(invoke_without_command=True)

13@click.pass_context

14@click.option("--port", type=int, help="The local port for the webserver and ngrok tunnel.")

15@click.option("--subdomain", help="The subdomain to use for ngrok endpoints.")

16@click.option("--region", type=click.Choice(["us", "eu", "ap", "au", "sa", "jp", "in"]),

17 help="The region to use for ngrok endpoints.")

18@click.option("--hostname", help="The hostname to use for ngrok endpoints.")

19@click.option("--auth", help="The basic auth to use for ngrok endpoints.")

20@click.option("--host_header", help="The \"Host\" header value to use for ngrok endpoints.")

21@click.option("--response", type=str,

22 help="Data to set for the response, overriding all body data from plugins and `--response-script`.")

23@click.option("--content-type", type=str,

24 help="The \"Content-Type\" header to set when response body data is given with `--response`")

25@click.option("--request-script", type=click.Path(exists=True),

26 help="A Python script whose `run(request)` method will be called by the default `/webhook` after all "

27 "request plugins have run.")

28@click.option("--response-script", type=click.Path(exists=True),

29 help="A Python script whose `run(request, response)` method will be called by the default `/webhook` "

30 "after all response plugins have run.")

31@click.option("--auth-token", help="A valid ngrok auth token.")

32@click.option("--plugins-dir", type=click.Path(exists=True), help="The directory to scan for custom hookee plugins.")

33@click.option("--plugins", multiple=True, help="A list of hookee plugins to use.")

34@click.option('--version', is_flag=True, default=False, help="Display version information.")

35 def hookee(ctx, **kwargs):

36 """

37 hookee is a utility that provides command line webhooks, on demand! Dump useful request data to the

38 console, process requests and responses, customize response data, and configure hookee and its routes

39 further in any number of ways through custom plugins.

40

41 hookee can be started by using `hookee start` or simply hookee.

42

43 If options are given, they override the default values derived from the config file.

44

45 hookee documentation can be found at https://hookee.readthedocs.io.

46 """

47 if kwargs["version"]:

48 ctx.exit("hookee/{} Python/{}".format(__version__, platform.python_version()))

49

50 ctx.ensure_object(dict)

51 for key, value in kwargs.items():

52 if value:

53 ctx.obj[key] = value

54

55 if kwargs.get("subdomain") and kwargs.get("hostname"):

56 ctx.fail("Can't give both --subdomain and --hostname.")

57

58 hookee_manager = HookeeManager(load_plugins=ctx.invoked_subcommand not in [enable_plugin.name,

59 disable_plugin.name,

60 available_plugins.name,

61 enabled_plugins.name])

62 ctx.obj["hookee_manager"] = hookee_manager

63

64 if ctx.invoked_subcommand is None:

65 hookee_manager.run()

66

67

68@hookee.command()

69@click.pass_context

70 def start(ctx):

71 """

72 Start hookee.

73 """

74 hookee_manager = ctx.obj["hookee_manager"]

75

76 hookee_manager.run()

77

78

79@hookee.command(

80 short_help="Update the default value for a config. Any passable arg to hookee can also be given here to set its "

81 "default in the config so it doesn't need to be passed to the hookee each time."

82)

83@click.pass_context

84@click.argument("key")

85@click.argument("value")

86 def update_config(ctx, key, value):

87 """

88 Update the default value for a config. Any passable arg to hookee can also be given here to set its

89 default in the config so it doesn't need to be passed to the hookee each time.

90 """

91 hookee_manager = ctx.obj["hookee_manager"]

92

93 if key == "plugins":

94 ctx.fail("Enable and disable plugins through the `enable-plugin` and `disable-plugin` commands.")

95 if "-" in key:

96 key = key.replace("-", "_")

97

98 if value.isdigit():

99 value = int(value)

100

101 try:

102 hookee_manager.config.set(key, value)

103

104 hookee_manager.print_util.print_config_update(

105 "The default value for \"{}\" has been updated in the config.".format(key))

106 except KeyError:

107 ctx.fail("No such key exists in the config: {}".format(key))

108

109

110@hookee.command()

111@click.pass_context

112@click.argument("plugin")

113 def enable_plugin(ctx, plugin):

114 """

115 Enable the given plugin by default.

116 """

117 hookee_manager = ctx.obj["hookee_manager"]

118

119 hookee_manager.plugin_manager.get_plugin(plugin)

120

121 hookee_manager.config.append("plugins", plugin)

122

123 hookee_manager.print_util.print_config_update("Plugin \"{}\" has been enabled.".format(plugin))

124

125

126@hookee.command()

127@click.pass_context

128@click.argument("plugin")

129 def disable_plugin(ctx, plugin):

130 """

131 Disable the given plugin by default.

132 """

133 hookee_manager = ctx.obj["hookee_manager"]

134

135 if plugin in pluginmanager.REQUIRED_PLUGINS:

136 ctx.fail("Can't disable the plugin \"{}\".".format(plugin))

137

138 hookee_manager.config.remove("plugins", plugin)

139

140 hookee_manager.print_util.print_config_update("Plugin \"{}\" is disabled.".format(plugin))

141

142

143@hookee.command()

144@click.pass_context

145 def available_plugins(ctx):

146 """

147 List all available plugins.

148 """

149 hookee_manager = ctx.obj["hookee_manager"]

150

151 plugins = hookee_manager.plugin_manager.available_plugins()

152

153 hookee_manager.print_util.print_open_header("Available Plugins")

154

155 for plugin_name in plugins:

156 hookee_manager.print_util.print_basic(" * {}".format(plugin_name))

157

158 try:

159 plugin = hookee_manager.plugin_manager.get_plugin(plugin_name)

160 if plugin.description:

161 hookee_manager.print_util.print_basic(" Description: {}".format(plugin.description))

162 except Exception as e:

163 hookee_manager.print_util.print_basic(" Error: {}".format(e))

164

165 hookee_manager.print_util.print_close_header()

166 hookee_manager.print_util.print_basic()

167

168

169@hookee.command()

170@click.pass_context

171 def enabled_plugins(ctx):

172 """

173 List all enabled plugins.

174 """

175 hookee_manager = ctx.obj["hookee_manager"]

176

177 plugins = hookee_manager.plugin_manager.enabled_plugins()

178

179 hookee_manager.print_util.print_open_header("Enabled Plugins (Order of Execution)")

180

181 for plugin_name in plugins:

182 hookee_manager.print_util.print_basic(" * {}".format(plugin_name))

183

184 try:

185 plugin = hookee_manager.plugin_manager.get_plugin(plugin_name)

186 if plugin.description:

187 hookee_manager.print_util.print_basic(" Description: {}".format(plugin.description))

188 except Exception as e:

189 hookee_manager.print_util.print_basic(" Error: {}".format(e))

190

191 hookee_manager.print_util.print_close_header()

192 hookee_manager.print_util.print_basic()

193

194

195 if __name__ == "__main__":

196 hookee(obj={})