Backpack Checker
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 installawslocal. But if you'd rather useaws --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...
Release files for backpack-checker 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| backpack_checker-0.1.0.tar.gz | 66.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| backpack_checker-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 76.5 kB
Release files / backpack_checker-0.1.0.tar.gz
| Download URL | backpack_checker-0.1.0.tar.gz |
|---|---|
| Size | 66.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7ce3d175a0b66c1cd05e4e5decd4b2538d2be65345bbdf5f7baa4a70f2e3383c
|
|
BLAKE2b-256 checksum How to use checksums |
f1cdb164686fc27bf066f5e7a783b83838479a7fd6f7bb812f27683de79b21d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.0.1 CPython/3.12.8
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 31, 2024.
Transparency logRelease files / backpack_checker-0.1.0-py3-none-any.whl
| Download URL | backpack_checker-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d9f937ea706db707062dcfea4eef8dbd603fddaee03e5c12e5ff3ccea813a9c1
|
|
BLAKE2b-256 checksum How to use checksums |
29f2dc06b6497acecce7c4a60486eeefbcf8ea1703b66f02e8725f3c8c271270
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.0.1 CPython/3.12.8
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 31, 2024.
Transparency log