From 85247038f70d7eb2f3e272cfeaa4c44459cafba8 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Mon, 26 Sep 2022 11:57:11 -0700 Subject: [PATCH] install and uninstall commands, closes #483 --- docs/cli-reference.rst | 38 ++++++++++++++++++++++++++++++++++++++ docs/cli.rst | 26 ++++++++++++++++++++++++++ sqlite_utils/cli.py | 25 +++++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/docs/cli-reference.rst b/docs/cli-reference.rst index d74855e..b88e38a 100644 --- a/docs/cli-reference.rst +++ b/docs/cli-reference.rst @@ -59,6 +59,8 @@ This page lists the ``--help`` for every ``sqlite-utils`` CLI sub-command. "convert": "cli_convert", "add-geometry-column": "cli_spatialite", "create-spatial-index": "cli_spatialite_indexes", + "install": "cli_install", + "uninstall": "cli_uninstall", } commands.sort(key = lambda command: go_first.index(command) if command in go_first else 999) cog.out("\n") @@ -1349,6 +1351,42 @@ See :ref:`cli_drop_view`. -h, --help Show this message and exit. +.. _cli_ref_install: + +install +======= + +See :ref:`cli_install`. + +:: + + Usage: sqlite-utils install [OPTIONS] PACKAGES... + + Install packages from PyPI into the same environment as sqlite-utils + + Options: + -U, --upgrade Upgrade packages to latest version + -h, --help Show this message and exit. + + +.. _cli_ref_uninstall: + +uninstall +========= + +See :ref:`cli_uninstall`. + +:: + + Usage: sqlite-utils uninstall [OPTIONS] PACKAGES... + + Uninstall Python packages from the sqlite-utils environment + + Options: + -y, --yes Don't ask for confirmation + -h, --help Show this message and exit. + + .. _cli_ref_add_geometry_column: add-geometry-column diff --git a/docs/cli.rst b/docs/cli.rst index 3adec26..5f85e55 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -2116,3 +2116,29 @@ Once you have a geometry column, you can speed up bounding box queries by adding $ sqlite-utils create-spatial-index spatial.db locations geometry See this `SpatiaLite Cookbook recipe `__ for examples of how to use a spatial index. + +.. _cli_install: + +Installing packages +------------------- + +The :ref:`insert -\\-convert ` and :ref:`query -\\-functions ` options can be provided with a Python script that imports additional modules from the ``sqlite-utils`` environment. + +You can install packages from PyPI directly into the correct environment using ``sqlite-utils install ``. This is a wrapper around ``pip install``. + +:: + + $ sqlite-utils install beautifulsoup4 + +Use ``-U`` to upgrade an existing package. + +.. _cli_uninstall: + +Uninstalling packages +--------------------- + +You can uninstall packages that were installed using ``sqlite-utils install`` with ``sqlite-utils uninstall ``:: + + $ sqlite-utils uninstall beautifulsoup4 + +Use ``-y`` to skip the request for confirmation. diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 767b170..bf7fae4 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -4,6 +4,7 @@ from click_default_group import DefaultGroup # type: ignore from datetime import datetime import hashlib import pathlib +from runpy import run_module import sqlite_utils from sqlite_utils.db import AlterError, BadMultiValues, DescIndex, NoTable from sqlite_utils.utils import maximize_csv_field_size_limit @@ -2657,6 +2658,30 @@ def _analyze(db, tables, columns, save): click.echo(details) +@cli.command() +@click.argument("packages", nargs=-1, required=True) +@click.option( + "-U", "--upgrade", is_flag=True, help="Upgrade packages to latest version" +) +def install(packages, upgrade): + """Install packages from PyPI into the same environment as sqlite-utils""" + args = ["pip", "install"] + if upgrade: + args += ["--upgrade"] + args += list(packages) + sys.argv = args + run_module("pip", run_name="__main__") + + +@cli.command() +@click.argument("packages", nargs=-1, required=True) +@click.option("-y", "--yes", is_flag=True, help="Don't ask for confirmation") +def uninstall(packages, yes): + """Uninstall Python packages from the sqlite-utils environment""" + sys.argv = ["pip", "uninstall"] + list(packages) + (["-y"] if yes else []) + run_module("pip", run_name="__main__") + + def _generate_convert_help(): help = textwrap.dedent( """