package goal creates an artifact that can be deployed or distributed.
The exact type of artifact depends on the type of target the goal is invoked on.
You can run
./pants package :: to build all artifacts in your project. Pants will filter to only the relevant targets.
Benefit of Pants: artifacts only include your true dependencies
Because Pants understands the dependencies of your code, and the dependencies of those dependencies, the generated artifact will only include the exact code needed for your package to work. This results in smaller, more focused packages.
Benefit of Pants: easily write automated tests of your packaging pipeline
You can depend on a package target in a
python_teststarget through the
runtime_package_dependenciesfield. Pants will run the equivalent of
./pants packagebeforehand and copy the built artifact into the test's chroot, allowing you to test things like that the artifact has the correct files present and that it's executable.
This allows you to test your packaging pipeline by simply running
./pants test ::, without needing custom integration test scripts.
See test for more information.
package on a
pex_binary target will create an executable PEX file.
The PEX file will contain all the code needed to run the binary, namely:
- All Python code and resources the binary transitively depends on.
- The resolved 3rd-party Python dependencies (sdists, eggs and wheels) of all targets the binary transitively depends on.
The PEX metadata will include:
- The entry point specified by the
- The intersection of all interpreter constraints applicable to the code in the Pex. See Interpreter compatibility.
You can also tweak many options, such as if the binary is zip safe. Run
./pants help pex_binary.
The entry point sets the behavior for what happens when you run
./dist/my_app.pex, such as if it runs a particular script or launches an app. You must specify the
entry_point field for every
For the first two approaches, Pants will use dependency inference, which you can confirm by running
./pants dependencies path/to:app. You can also manually add to the
You can specify a file name, which Pants will convert into a well-formed entry point. Like with the
sources field, file paths are relative to the BUILD file, rather than the build root.
# The default `sources` field will include `main.py`. python_library() # Pants will convert the entry point to `helloworld.main`. pex_binary( name="app", entry_point="main.py", ) # You can also specify the function to run. pex_binary( name="app_with_func", entry_point="main.py:my_func", )
This approach has an added benefit that you can use file arguments, e.g.
./pants package helloworld/main.py, rather than needing to use target addresses like
./pants package helloworld:app.
You can directly specify the entry point in the format
path.to.module:my_func. This allows you to use an entry point for a third-party requirement or the Python standard library.
# The default `sources` field will include `main.py`. python_library() pex_binary( name="app", entry_point="helloworld.main", ) # You can also specify the function to run. pex_binary( name="app_with_func", entry_point="helloworld.main:my_func", ) # You can specify third-party requirements and the std lib. pex_binary( name="3rdparty_app", entry_point="bandit:main", )
Unlike Approach #1, this does not work with file arguments; you must use the target address, like
./pants package helloworld:app.
entry_point="<none>" to leave off an entry point. This will create a PEX that behaves similarly to a virtual environment's Python interpreter; for example, running
./dist/my_app.pex will open a Python REPL with all of the first party code and third-party requirements included.
Note that Pants cannot use dependency inference in this case, so you must manually add to the
dependencies field if you want to include first-party code and/or third-party requirements in the binary.
python_library(name="lib") pex_binary( name="app", entry_point="<none>", dependencies=[":lib", "3rdparty/python:my_req"], )
PEX files may be platform-specific
If your code's requirements include distributions that include native code, then the resulting PEX file will only run on the platform it was built on.
However, if all native code requirements are available as wheels for the target platform, then you can cross-build a PEX file on a different source platform by specifying the
platformsfield on the
Tip: inspect the
.pexfile is simply a ZIP file, you can use the Unix tool
unzipto inspect the contents. For example, run
unzip -l dist/app.pexto see all file members.
filestargets will not be included in the built PEX because filesystem APIs like
open()would not load them as expected. Instead, use the
resourcestarget or wrap your
archivetarget. See Resources and archives for further explanation.
$ ./pants package helloworld/main.py 17:36:42 [INFO] Wrote dist/helloworld/helloworld.pex
We can also build the same Pex by using the address of the
pex_binary target, as described here.
$ ./pants package helloworld:app 17:36:42 [INFO] Wrote dist/helloworld/helloworld.pex
package on a
python_distribution target will create a standard setuptools-style Python distribution, such as an sdist or a wheel. See Building Distributions for details.
See Resources and archives for how to create a zip or tar file with built binaries and/or loose files in it. This is often useful when you want to create a PEX binary using the
pex_binary target, and bundle it with some loose config files.
If you have the
pants.backend.awslambda.python backend enabled, then you can use the
package goal to build AWS Lambdas. See AWS Lambda for more details.
Updated 4 months ago