The `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_test
` / `python_tests
` target through the `runtime_package_dependencies
` field. Pants will run the equivalent of `./pants package
` beforehand 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.
## Creating a PEX file from a `pex_binary
` target
Running `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 or console script specified by the `
pex_binary
` target, if any.The intersection of all interpreter constraints applicable to the code in the Pex. See [Interpreter compatibility](🔗).
You can also tweak many options, such as the `execution_mode
` option to optimize for faster initial runs vs. subsequent runs. Run `./pants help pex_binary
`.
### The `entry_point
` and `script
` fields
The `entry_point
` and `script
` fields set the behavior for what happens when you run `./dist/my_app.pex
`, such as if it runs a particular script or launches an app.
Usually, you'll want to use `entry_point
`, which lets you specify a module and optionally a function to execute, such as `project.my_app:main
`. This is especially useful when you want to run first-party code.
`script
` is useful when you want to directly run a third-party dependency that sets `console_scripts
` in its distribution. This allows you to, for example, set `script="black"
` to create `black.pex
` that behaves like if you had `pip install
`ed `black
` and then run `black
` in your shell:
You can also leave off both fields, which will cause `./dist/my_app.pex
` to launch a Python interpreter with all the relevant code and dependencies loaded.
If you use the `entry_point
` field, Pants will use dependency inference, which you can confirm by running `./pants dependencies path/to:app
`. Otherwise, you must manually add to the `dependencies
` field.
#### `entry_point
` with a file name
You can specify a file name, which Pants will convert into a well-formed entry point. Like with the `source
` / `sources
` field, file paths are relative to the BUILD file, rather than the build root.
This approach has the 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
`.
#### Explicit `entry_point
`
You can directly specify the entry point in the format `path.to.module
` or `path.to.module:my_func
`. This allows you to use an entry point for a third-party requirement or the Python standard library.
Unlike using `entry_point
` with a file name, this does not work with file arguments; you must use the target address, like `./pants package helloworld:app
`.
#### `script
`
You can set the `script
` to any `console_script
` or script exposed by your third-party requirements.
You must explicitly add the dependencies you'd like to the `dependencies
` field.
This does not work with file arguments; you must use the target address, like `./pants package helloworld:black_bin
`.
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 `
platforms
` field on the `pex_binary
`, e.g. `platforms=["linux-x86_64-cp-37-cp37m", "macosx_10_15_x86_64-cp-38-cp38"]
`.
Tip: inspect the `
.pex
` file with `unzip
`Because a `
.pex
` file is simply a ZIP file, you can use the Unix tool `unzip
` to inspect the contents. For example, run `unzip -l dist/app.pex
` to see all file members.
Use `
resource
` instead of `file
``
file
` and `files
` targets will not be included in the built PEX because filesystem APIs like `open()
` would not load them as expected. Instead, use the `resource
` and `resources
` target or wrap your `pex_binary
` in an `archive
` target. See [Resources and archives](🔗) for further explanation.
### Examples
We can also build the same Pex by using the address of the `pex_binary
` target, as described [here](🔗).
## Create a setuptools distribution
Running `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.
## Create a `zip
` or `tar
` file
See [Resources and archives](🔗) for how to create a zip or tar file with built binaries and/or loose files in it by using the `archive
` target.
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.
## Create an AWS Lambda
See [AWS Lambda](🔗) for how to build a zip file that works with AWS Lambda.
## Create a Google Cloud Function
See [Google Cloud Functions](🔗) for how to build a zip file that works with Google Cloud Functions.