Skip to main content

A tool to check the status of your "backpack", "backpack" being your local setup for a project.

Project description

Backpack Checker

Logo

Rationale

Let's be honest... I made this mainly to try out the amazing Textual on something. But there's some merit to it (if you look hard enough :D). When working with a team, you might want to rely on a tool, like saying, "everyone, let's install uv or hatch so we can work with inline script metadata." Half of your team will ask you three months later how to run your script... not to mention any newcomers.

And yeah, there are tools—or should I say frameworks—like Nix and similar ones. But I don't care how you got the tool or what machine/system you are using. I only care to know if I can rely on the fact that everyone can use Docker Compose in a specific version.

There might be better tools for this, but I didn't look. Anyway, if you find this useful, that's awesome—it's here for you to use.

Usage

What this provides is a bunch of Check classes and a TUI application made with the amazing Textual (honestly, the tool itself is great, but the way it was made is something else...).

The idea is to install it however you prefer and write a backpack.py script. Probably the most convenient method would be to use the aforementioned inline script metadata:

# /// script
# requires-python = ">=3.12"
# dependencies = [
#   "backpack-checker",
# ]
# ///
import json
from backpack_checker.app import BackpackApp
from backpack_checker.checker import (
    And,
    Check,
    DockerContainerRunning,
    EnvVarsRequired,
    EnvVarsSuggested,
    MinimalVersionCheck,
    Necessity,
    Or,
    SubprocessCheck,
)
from semver import Version

class UVCheck(MinimalVersionCheck):
    _name = "Check if `uv` is installed"
    _explanation = "Check if Docker Compose is installed"
    command = "uv version --output-format=json"
    necessity = Necessity.SUGGESTED

    async def validate(self, result: str) -> bool:
        return self.minimal_version <= Version.parse(json.loads(result)["version"])


app = BackpackApp(
    checks=[UVCheck("0.5.8")]
)
if __name__ == "__main__":
    app.run()

and run it with uv run backpack.py or hatch run backpack.py.

Checkers

You can use the premade checkers. To do that, you'll need to define some data for them.

As you'll see in the examples below, you can customize these extensively: you can create a __init__ method to provide arguments to the checker or override the name and explanation properties to make the messaging dynamic.

For example:

SubprocessCheck

from backpack_checker.checker import SubprocessCheck, Necessity

class AWSLocal(SubprocessCheck):
    _name = "Check if `awslocal` is installed"
    _explanation = """\
AWS Local is a wrapper for the AWS CLI that allows you to interface with AWS instances 
running locally, e.g., with Localstack.

More about awslocal [here](https://github.com/localstack/awscli-local?tab=readme-ov-file#example).
"""
    necessity = Necessity.SUGGESTED
    command = "awslocal --version"

This checks if the awslocal --version command executes with return code 0. The message is designed to provide instructions for backpack users. You can use Markdown when defining the name and explanation. The necessity attribute (default is Necessity.REQUIRED) will only throw a warning (painted yellow) and mark the failure as non-critical.

[!TIP]
In this example, I'm suggesting you install awslocal. But if you'd rather use aws --endpoint-url=http://localhost:4566, that's fine too.

MinimalVersionCheck

You can also use a derivative of SubprocessCheck, called MinimalVersionCheck, to check for the existence of a tool and enforce a minimal semantic version.

from backpack_checker.checker import MinimalVersionCheck

class DockerComposeCheck(MinimalVersionCheck):
    _name = "Check if `docker-compose` is installed"
    _explanation = "Check if Docker Compose is installed"
    command = "docker-compose --version --short"

app = BackpackApp(
    checks=[
        DockerComposeCheck("2.20.3"),
    ]
)

If a command doesn't directly return something like 2.20.3 (as docker-compose --version --short does), you can override the validate method:

from semver import Version
from backpack_checker.checker import MinimalVersionCheck

class UVCheck(MinimalVersionCheck):
    _name = "Check if `uv` is installed"
    _explanation = "Check if UV is installed"
    command = "uv version --output-format=json"

    async def validate(self, result: str) -> bool:
        return self.minimal_version <= Version.parse(json.loads(result)["version"])

app = BackpackApp(
    checks=[
        UVCheck("0.5.8"),
    ]
)

DockerContainerRunning

Another checker is DockerContainerRunning, which uses the Docker SDK for Python to interact with your Docker engine and query running containers. It effectively invokes docker.from_env().containers.list(filters=self.container_list_filters).

class LocalstackRunning(DockerContainerRunning):
    _name = "Check if Localstack is running"
    _explanation = """..."""
    container_list_filters = {"status": "running", "name": "localstack"}

EnvVarsRequired and EnvVarsSuggested

These check whether specific environment variables are set:

UV_EXTRA_INDEX_URL_EXPLANATION = """..."""
PIP_EXTRA_INDEX_URL_EXPLANATION = """..."""

app = BackpackApp(
    checks=[
        EnvVarsRequired(
            "Check if `UV_EXTRA_INDEX_URL` env var is set",
            ["UV_EXTRA_INDEX_URL"],
            UV_EXTRA_INDEX_URL_EXPLANATION,
        ),
        EnvVarsSuggested(
            "Check if `PIP_EXTRA_INDEX_URL` env var is set",
            ["PIP_EXTRA_INDEX_URL"],
            PIP_EXTRA_INDEX_URL_EXPLANATION,
        ),
    ]
)

And/Or Checkers

You can also group checks using And or Or:

from backpack_checker.checker import MinimalVersionCheck, Or

class _DockerComposeCheck(MinimalVersionCheck):
    _name = ""
    _explanation = ""
    command = "docker-compose --version --short"

class _DockerComposeCheck2(_DockerComposeCheck):
    _name = ""
    command = "docker compose version --short"

class OrDockerCompose(Or[str]):
    _name = "Check if `docker compose` or `docker-compose` are installed"

    @property
    def explanation(self) -> str:
        return f"""\
This check ensures either `docker-compose` or `docker compose` is installed. 
Additionally, the version must be at least `{self.minimal_version}`, which supports 
features like the `include` directive with relative paths in `docker-compose.yml` files. 
We rely on that feature.
"""

    def __init__(self, minimal_version: Version | str):
        super().__init__()
        self.minimal_version = minimal_version
        self.checks = [
            _DockerComposeCheck(minimal_version),
            _DockerComposeCheck2(minimal_version),
        ]

app = BackpackApp(
    checks=[
        OrDockerCompose("2.20.3")
    ]
)

The Or checker returns True if any outcome is positive, while the And checker succeeds only if all outcomes are successful.

What would be cool

If I ever have time to play with this again, I’d probably:

  • Separate the UI (TUI) from the checking process.
    • Allow running the checker with a JSON result usable by the UI (potentially multiple UIs).
  • Create a CLI entry point that works like backpack check path/to/your/backpack.py.
  • Add some test coverage here—it would be cool...

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

backpack_checker-0.1.0.tar.gz (66.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

backpack_checker-0.1.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file backpack_checker-0.1.0.tar.gz.

File metadata

  • Download URL: backpack_checker-0.1.0.tar.gz
  • Upload date:
  • Size: 66.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for backpack_checker-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7ce3d175a0b66c1cd05e4e5decd4b2538d2be65345bbdf5f7baa4a70f2e3383c
MD5 764ccb10f21dbf480c3ff1dd9a102387
BLAKE2b-256 f1cdb164686fc27bf066f5e7a783b83838479a7fd6f7bb812f27683de79b21d2

See more details on using hashes here.

Provenance

The following attestation bundles were made for backpack_checker-0.1.0.tar.gz:

Publisher: publish.yml on pkucmus/backpack-checker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file backpack_checker-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for backpack_checker-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d9f937ea706db707062dcfea4eef8dbd603fddaee03e5c12e5ff3ccea813a9c1
MD5 48f4cf2f1f7d1d7291002cca00176e50
BLAKE2b-256 29f2dc06b6497acecce7c4a60486eeefbcf8ea1703b66f02e8725f3c8c271270

See more details on using hashes here.

Provenance

The following attestation bundles were made for backpack_checker-0.1.0-py3-none-any.whl:

Publisher: publish.yml on pkucmus/backpack-checker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page