{"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907537366", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907537366, "node_id": "IC_kwDOBm6k_c42F-vW", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:29:16Z", "updated_at": "2021-08-28T00:29:29Z", "author_association": "OWNER", "body": "The closest plugin hook to this right now is [publish_subcommand](https://docs.datasette.io/en/stable/plugin_hooks.html#publish-subcommand-publish) - which looks like this:\r\n```python\r\n@hookimpl\r\ndef publish_subcommand(publish):\r\n @publish.command()\r\n @add_common_publish_arguments_and_options\r\n @click.option(\r\n \"-k\",\r\n \"--api_key\",\r\n help=\"API key for talking to my hosting provider\",\r\n )\r\n def my_hosting_provider(...):\r\n```\r\nBut there are also several plugin hooks with `register_` prefixes, which may be a good naming convention to stick to here: `register_output_renderer(datasette)`, `register_routes(datasette)`, `register_facet_classes()`, `register_magic_parameters(datasette)`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907537610", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907537610, "node_id": "IC_kwDOBm6k_c42F-zK", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:30:51Z", "updated_at": "2021-08-28T00:30:51Z", "author_association": "OWNER", "body": "There's also the option for plugins to muck around with existing registered commands - this could get a bit untidy if multiple plugins try to do it, but being able to replace `serve` with a fresh implementation that adds an additional command-line option before calling back to the original might open up some interesting possibilities.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907537693", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907537693, "node_id": "IC_kwDOBm6k_c42F-0d", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:31:26Z", "updated_at": "2021-08-28T00:31:26Z", "author_association": "OWNER", "body": "Terminology question: is it correct to call these subcommands or should they be commands? `publish_subcommand()` adds subcommands of the format `datasette publish X` - but are we instead adding commands with this new one?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907538940", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907538940, "node_id": "IC_kwDOBm6k_c42F_H8", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:39:28Z", "updated_at": "2021-08-28T00:39:28Z", "author_association": "OWNER", "body": "Here's the answer to that:\r\n```\r\n~ % datasette --help\r\nUsage: datasette [OPTIONS] COMMAND [ARGS]...\r\n\r\n Datasette!\r\n\r\nOptions:\r\n --version Show the version and exit.\r\n --help Show this message and exit.\r\n\r\nCommands:\r\n serve* Serve up specified SQLite database files with a web UI\r\n inspect\r\n install Install Python packages - e.g.\r\n package Package specified SQLite files into a new datasette Docker...\r\n plugins List currently available plugins\r\n publish Publish specified SQLite database files to the internet...\r\n uninstall Uninstall Python packages (e.g.\r\n```\r\nSince it's adding extra things that show up in `--help` under the \"Commands:\" heading, I should call them commands.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907539065", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907539065, "node_id": "IC_kwDOBm6k_c42F_J5", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:40:24Z", "updated_at": "2021-08-28T00:40:24Z", "author_association": "OWNER", "body": "I'm going to call the new hook `register_commands` - since it will allow ambitious plugins to register more than one command if they want to. That's also pleasingly similar to `register_routes`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907539251", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907539251, "node_id": "IC_kwDOBm6k_c42F_Mz", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:41:37Z", "updated_at": "2021-08-28T00:41:50Z", "author_association": "OWNER", "body": "The first example plugin I'm going to build for this will be `datasette verify file.db file2.db` - it will take one or more paths to SQLite files and verify if they can be opened by Datasette or not.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907539668", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907539668, "node_id": "IC_kwDOBm6k_c42F_TU", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:44:16Z", "updated_at": "2021-08-28T00:44:16Z", "author_association": "OWNER", "body": "Considering this piece of code: https://github.com/simonw/datasette/blob/a1a33bb5822214be1cebd98cd858b2058d91a4aa/datasette/cli.py#L122-L142\r\n\r\nI think the hook itself gets called with a single argument, `cli`, which it can then use in the standard Click way to register extra stuff.\r\n\r\nI can't pass it `datasette` (like I do with `register_routes()`) because the Datasette object itself is instantiated by the `serve` command, which will not have been called.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907540790", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907540790, "node_id": "IC_kwDOBm6k_c42F_k2", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:52:32Z", "updated_at": "2021-08-28T00:52:32Z", "author_association": "OWNER", "body": "I don't think I can get this new hook to support the handy [--plugins-dir= mechanism](https://docs.datasette.io/en/stable/plugins.html#one-off-plugins-using-plugins-dir) for loading plugins from Python files as opposed to registering them with setuptools - that mechanism is itself implemented inside of code called by `datasette serve` so I don't have a way of taking advantage of it from outside that command.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907540928", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907540928, "node_id": "IC_kwDOBm6k_c42F_nA", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T00:53:37Z", "updated_at": "2021-08-28T00:53:37Z", "author_association": "OWNER", "body": "I'll probably have to use this mechanism for the tests then: https://til.simonwillison.net/pytest/registering-plugins-in-tests", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907542214", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907542214, "node_id": "IC_kwDOBm6k_c42F_7G", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T01:02:38Z", "updated_at": "2021-08-28T01:02:38Z", "author_association": "OWNER", "body": "Partial prototype of `datasette-verify`:\r\n```python\r\nfrom datasette import hookimpl\r\nimport click\r\n\r\n\r\n@hookimpl\r\ndef register_commands(cli):\r\n from datasette.cli import sqlite_extensions\r\n @cli.command()\r\n @click.argument(\"files\", type=click.Path(exists=True), nargs=-1)\r\n @sqlite_extensions\r\n def verify(files, sqlite_extensions):\r\n \"Verify that files can be opened by Datasette\"\r\n for file in files:\r\n print(file)\r\n```\r\nI had to move the `from datasette.cli import sqlite_extensions` inside the hook function to avoid a circular import.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907543982", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907543982, "node_id": "IC_kwDOBm6k_c42GAWu", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T01:14:27Z", "updated_at": "2021-08-28T01:14:27Z", "author_association": "OWNER", "body": "Writing the test for this is proving difficult, because the `cli` module has already been imported when I attempt to register a new plugin - so it doesn't pick up on the additional command registrations.\r\n\r\nTrying to work around that with `importlib.reload(cli)`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907547624", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907547624, "node_id": "IC_kwDOBm6k_c42GBPo", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T01:44:57Z", "updated_at": "2021-08-28T01:58:35Z", "author_association": "OWNER", "body": "Documentation: https://docs.datasette.io/en/latest/plugin_hooks.html#register-commands-cli", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1449#issuecomment-907547736", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1449", "id": 907547736, "node_id": "IC_kwDOBm6k_c42GBRY", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-08-28T01:45:36Z", "updated_at": "2021-08-28T01:45:36Z", "author_association": "OWNER", "body": "I need to push this out as an alpha so I can release a demo plugin that uses it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 981676832, "label": "`register_commands()` plugin hook to register extra CLI commands"}, "performed_via_github_app": null}