pythonbazelbazel-rulesbazel-python

How to materialize Bazel Outputs


I am relatively new to bazel, so this is probably a relatively simple question.

I have a bunch of libraries defined in my build structure. Something like this:

/libraries
- /lib1
  - BUILD
  - files.py
- /lib2
  - BUILD
  - sub_dir
    - other_file.py
    - __init__.py
  - file.json
  - other_file.py

The targets look like this:

load("@rules_python//python:defs.bzl", "py_library")

py_library(
    name = "lib2",
    srcs = glob(["**/*.py"]),
    data = ["file.json"],
    visibility = ["//visibility:public"],
    deps = [requirement("pandas")],
)

Now, when I run build: bazel build //lib2 the command completes, but no output are actually generated in bazel-bin or bazel-out.

From what I understand that is due to the fact that py_library acts as provider, so the results are not materialized?

Use case is that I have a cloud service where I want to deploy these files to. So I would need to generate an output folder that is deployable (zip would work as well, but ideal)

I already tried the following solutions:

  1. use pkg_zip rule, however this seems broken, as it does not include sub-dirs and no dependencies
  2. filegroup target, but that also does not generate any output

I also have a bunch of unit tests so I can verify that the code generation is actually correct and working. This has been a nail-biter, as I haven't found much good documentation on Bazel so far, so any help would be appreciated!!


Update: Thanks for the answers below (cannot accept them due to too little points). I originally wanted to use this for azure functions deployment, so I indeed ended up using a py_binary and leveraged and additional copy_macro (found here) that I had to modify a bit to make sure all files are in the same folder for seemless deployment. A bit more tedious than I would have hoped, but it works :)


Solution

  • With the Python rules, as with most other Bazel rule ecosystems, you need a py_binary or py_test or similar to do much of anything. py_library is only useful as a dependency of other Python rules.

    All rules return providers (including py_library, py_binary, and py_test). A simplified version of what bazel build :x does is:

    1. Look at the DefaultInfo.files provider field for :x
    2. Build those files
    3. Print the paths to them (subject to --show_result)

    py_library's DefaultInfo.files is empty, so bazel build lib2 doesn't do anything.