+
Skip to content

alexeagle/play-py

Repository files navigation

Python Bazel Starter

# This is executable Markdown that's tested on CI.
set -o errexit -o nounset -o xtrace
alias ~~~=":<<'~~~sh'";:<<'~~~sh'

This repo includes:

  • 🧱 Latest version of Bazel and dependencies
  • 📦 Curated bazelrc flags via [bazelrc-preset.bzl]
  • 🧰 Developer environment setup with [bazel_env.bzl]
  • 🎨 ruff, using rules_lint
  • ✅ Pre-commit hooks for automatic linting and formatting
  • 📚 PyPI package manager integration

Try it out

Before following these instructions, setup the developer environment by running direnv allow and follow any prompts. This ensures that tools we call in the following steps will be on the PATH.

Create a simple application with an external package dependency:

mkdir app
>app/__main__.py cat <<EOF
import requests
print(requests.get("https://api.github.com").status_code)
EOF

Let's create a simple failing test:

>app/app_test.py cat <<EOF
def test_bad():
  assert 1 == 2
EOF

Next, we need to declare the requests dependency in the project definition. There's not a good machine-editing utility for TOML that I could find, so we'll just use sed here to illustrate:

sed -i 's/dependencies = \[/dependencies = ["requests",/' pyproject.toml

Now we need to re-pin the dependencies to the lockfile:

./tools/repin

Generate BUILD files:

bazel run gazelle

Ideally the pytest_main.star file would set these attributes as part of running gazelle.

buildozer 'set pytest_main True' //app:app_test
buildozer 'add deps @pip//pytest' //app:app_test
buildozer 'comment deps @pip//pytest keep' //app:app_test

That's it, now the application should execute:

output=$(bazel run //app:app_bin)

Let's verify the application output matches expectation:

[ "${output}" = "200" ] || {
    echo >&2 "Wanted output '200' but got '${output}'"
    exit 1
}

Scaffold out a library

Let's demonstrate using the copier utility to generate a new library in the project. We'll need to link its requirements file into the requirements.all collector and re-pin again.

copier copy gh:alexeagle/aspect-template-python-lib mylib
buildozer "add data //mylib:requirements" //requirements:requirements.all
echo "-r ../mylib/requirements.txt" >> requirements/all.in
./tools/repin

Next, update the application we created earlier to use that library:

>app/__main__.py cat <<EOF
import requests
from mylib import say
say.moo(requests.get("https://api.github.com").status_code)
EOF

And since the dependency graph was affected by that edit, we re-generate the BUILD file:

bazel run gazelle

Now run the application again to check it still works:

output=$(bazel run //app:app_bin)
echo "${output}" | grep -q "| 200 |" || {
    echo >&2 "Wanted output containing '| 200 |' but got '${output}'"
    exit 1
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载