# Python

Trivy supports three types of Python package managers: `pip`, `Pipenv` and `Poetry`.
The following scanners are supported for package managers.

| Package manager | SBOM | Vulnerability | License |
|-----------------|:----:|:-------------:|:-------:|
| pip             |  ✓   |       ✓       |    ✓    |
| Pipenv          |  ✓   |       ✓       |    -    |
| Poetry          |  ✓   |       ✓       |    -    |
| uv              |  ✓   |       ✓       |    -    |

In addition, Trivy supports three formats of Python packages: `egg`, `wheel` and `conda`.
The following scanners are supported for Python packages.

| Packaging | SBOM | Vulnerability | License |
|-----------|:----:|:-------------:|:-------:|
| Egg       |  ✓   |       ✓       |    ✓    |
| Wheel     |  ✓   |       ✓       |    ✓    |
| Conda     |  ✓   |       -       |    -    |


The following table provides an outline of the features Trivy offers.

| Package manager | File             | Transitive dependencies | Dev dependencies | [Dependency graph][dependency-graph] | Position | [Detection Priority][detection-priority] |
|-----------------|------------------|:-----------------------:|:----------------:|:------------------------------------:|:--------:|:----------------------------------------:|
| pip             | requirements.txt |            -            |     Include      |                  -                   |    ✓     |                    ✓                     |
| Pipenv          | Pipfile.lock     |            ✓            |     Include      |                  -                   |    ✓     |                Not needed                |
| Poetry          | poetry.lock      |            ✓            |     [Exclude](#poetry)      |                  ✓                   |    -     |                Not needed                |
| uv              | uv.lock          |            ✓            |     [Exclude](#uv)      |                  ✓                   |    -     |                Not needed                |          |


| Packaging | Dependency graph |
| --------- | :--------------: |
| Egg       |        ✓         |
| Wheel     |        ✓         |

These may be enabled or disabled depending on the target.
See [here](./index.md) for the detail.

## Package managers
Trivy parses your files generated by package managers in filesystem/repository scanning.

### pip

#### Dependency detection
By default, Trivy only parses [version specifiers](https://packaging.python.org/en/latest/specifications/version-specifiers/#id5) with `==` comparison operator and without `.*`.

Using the [--detection-priority comprehensive][detection-priority] option ensures that the tool establishes a minimum version, which is particularly useful in scenarios where identifying the exact version is challenging. 
In such case Trivy parses specifiers `>=`,`~=` and a trailing `.*`.

```
keyring >= 4.1.1            # Minimum version 4.1.1
Mopidy-Dirble ~= 1.1        # Minimum version 1.1
python-gitlab==2.0.*        # Minimum version 2.0.0
```
Also, there is a way to convert unsupported version specifiers - use either the `pip-compile` tool (which doesn't install the packages)
or call `pip freeze` from the virtual environment where the requirements are already installed.

```bash
$ cat requirements.txt 
boto3~=1.24.60
click>=8.0
json-fix==0.5.*
$ pip install -r requirements.txt
...
$ pip freeze > requirements.txt 
$ cat requirements.txt 
boto3==1.24.96
botocore==1.27.96
click==8.1.7
jmespath==1.0.1
json-fix==0.5.2
python-dateutil==2.8.2
s3transfer==0.6.2
setuptools==69.0.2
six==1.16.0
urllib3==1.26.18
wheel==0.42.0
```

`requirements.txt` files usually contain only the direct dependencies and not contain the transitive dependencies.
Therefore, Trivy scans only for the direct dependencies with `requirements.txt`.

To detect transitive dependencies as well, you need to generate `requirements.txt` that contains them.
Like described above, tou can do it with `pip freeze` or `pip-compile`.

```zsh
$ cat requirements.txt # it will only find `requests@2.28.2`.
requests==2.28.2 
$ pip install -r requirements.txt
...

$ pip freeze > requirements.txt   
$ cat requirements.txt # it will also find the transitive dependencies of `requests@2.28.2`.
certifi==2022.12.7
charset-normalizer==3.1.0
idna==3.4
PyJWT==2.1.0
requests==2.28.2
urllib3==1.26.15
```

`pip freeze` also helps to resolve [extras](https://packaging.python.org/en/latest/tutorials/installing-packages/#installing-extras)(optional) dependencies (like `package[extras]=0.0.0`).

`requirements.txt` files don't contain information about dependencies used for development.
Trivy could detect vulnerabilities on the development packages, which not affect your production environment.

#### License detection

`requirements.txt` files don't contain information about licenses.
Therefore, Trivy checks `METADATA` files from `lib/site-packages` directory. 

Trivy uses 3 ways to detect `site-packages` directory:

- Checks `VIRTUAL_ENV` environment variable.
- Detects path to `python`[^1] binary and checks `../lib/pythonX.Y/site-packages` directory.
- Detects path to `python`[^1] binary and checks `../../lib/site-packages` directory.

### Pipenv
Trivy parses `Pipfile.lock`.
`Pipfile.lock` files don't contain information about dependencies used for development.
Trivy could detect vulnerabilities on the development packages, which not affect your production environment.

License detection is not supported for `Pipenv`.

### Poetry
Trivy uses `poetry.lock` to identify dependencies and find vulnerabilities.
To build the correct dependency graph, `pyproject.toml` also needs to be present next to `poetry.lock`.

License detection is not supported for `Poetry`.

By default, Trivy doesn't report development dependencies. Use the `--include-dev-deps` flag to include them.


### uv
Trivy uses `uv.lock` to identify dependencies and find vulnerabilities.

License detection is not supported for `uv`.

By default, Trivy doesn't report development dependencies. Use the `--include-dev-deps` flag to include them.

## Packaging
Trivy parses the manifest files of installed packages in container image scanning and so on.
See [here](https://packaging.python.org/en/latest/discussions/package-formats/) for the detail.

### Egg
Trivy looks for `*.egg-info`, `*.egg-info/METADATA`, `*.egg-info/PKG-INFO`, `*.egg` and `EGG-INFO/PKG-INFO` to identify Python packages.

### Wheel
Trivy looks for `.dist-info/METADATA` to identify Python packages.

[^1]: Trivy checks `python`, `python3`, `python2` and `python.exe` file names.

[dependency-graph]: ../../configuration/reporting.md#show-origins-of-vulnerable-dependencies
[detection-priority]: ../../scanner/vulnerability.md#detection-priority
