> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/sast-and-sca/prezero/static-analysis-sast/analyzing-applications/python.md).

# Python

This article shows you how to analyze your applications written in Python using Qwiet AI by Harness.

{% tabs %}
{% tab title="Python (Source) - Preferred" %}

## Requirements <a href="#requirements" id="requirements"></a>

See [Prerequisites](broken://spaces/uPVBkglG6gsk2SsnsKgG/pages/0c1ezDgaUil5NxR4VnY3#language-support-and-requirements) for more information.

## Analyzing your Python application <a href="#analyzing-your-python-application" id="analyzing-your-python-application"></a>

```
sl analyze --app <name> --pythonsrc [<path>]
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

| Parameter      | Description                                               |
| -------------- | --------------------------------------------------------- |
| `--app <name>` | The name of the application to be analyzed                |
| `--pythonsrc`  | The flag identifying the application as written in Python |
| `<path>`       | The path to the Python application to be analyzed         |

### Additional parameters <a href="#additional-parameters" id="additional-parameters"></a>

The analysis accepts additional parameters after a double hyphen `--`.

| Additional parameter | Description                                                                                                                                                                                        |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--ignore-paths`     | Ignores the specified paths from the analysis. Accepts both absolute and relative file paths; relative file paths are interpreted in relation to the directory provided as part of `sl analyze...` |
| `--ignore-dir-names` | Excludes all files where the relative path (from directory provided in `sl analyze`) contains at least one of names specified here                                                                 |

Such parameters, if valid, are passed directly to the Python analyzer.

### Sample usage of additional parameters <a href="#sample-usage-of-additional-parameters" id="sample-usage-of-additional-parameters"></a>

To ignore a specific path from the analysis:

```
sl analyze --app <name> --pythonsrc [<path>] -- --ignore-paths [<path>]
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

### SCA <a href="#sca" id="sca"></a>

To [identify open-source vulnerabilities](/sast-and-sca/prezero/oss-vulnerabilities.md), Qwiet preZero automatically searches for build manifests in the project path you provided when running `sl analyze`. Depending on your build system, you may need to generate a dependency file before running `sl`.

Currently, `sl` supports `requirements.txt`, `poetry.lock`, and `uv.lock`. Use the appropriate command for your package manager to generate the required file:

* **pip**: Run `pip freeze > requirements.txt` from your activated virtual environment.
* **Poetry**: Run `poetry lock` to generate a `poetry.lock` file.
* **uv**: Run `uv lock` to generate a `uv.lock` file. If a lock file is not found, `sl` will attempt to parse the `pyproject.toml` (if it exists), but providing a `uv.lock` file is recommended.
  {% endtab %}

{% tab title="Python 3.8, 3.9" %}

## Requirements <a href="#requirements" id="requirements"></a>

See [Prerequisites](broken://spaces/uPVBkglG6gsk2SsnsKgG/pages/0c1ezDgaUil5NxR4VnY3#language-support-and-requirements) for more information.

## Analyzing your Python application <a href="#analyzing-your-python-application" id="analyzing-your-python-application"></a>

![](/files/mlZo7QhbBaWAQlpvEVi9)note

Qwiet offers a [sample application](https://github.com/ShiftLeftSecurity/shiftleft-python-demo) that you can use to run and test Qwiet AI by Harness. It also includes a functioning configuration file to demonstrate how you can leverage GitHub Actions to automate code analysis whenever you open a new Pull Request (PR).

We also offer samples for [GitLab integration](https://gitlab.com/ShiftLeftSecurity/flask-webgoat/-/blob/main/.gitlab-ci.yml), as well as [configurations for Docker, Linux, macOS, and Windows](https://github.com/HooliCorp/flask-webgoat/tree/main/.github/workflows).

Before running code analysis, please run `pip install` using the version of Python you used to write the application and make sure this is successful.

```
pip install -r requirements.txt
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

On macOS and in some Linux environments, `pip` and `python` may be using Python 2 instead of Python 3. If so, use `pip3` and `python3` instead.

To analyze your Python application:

```
sl analyze --app <name> --python [<path>]
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

| Parameter      | Description                                                                 |
| -------------- | --------------------------------------------------------------------------- |
| `--app <name>` | The name of the application to be analyzed (maximum length: 100 characters) |
| `--python`     | The flag identifying the application as written in Python                   |
| `<path>`       | The path to the Python application to be analyzed                           |

### Additional parameters <a href="#additional-parameters-1" id="additional-parameters-1"></a>

The analysis accepts additional parameters after a double hyphen `--`.

For example, the following CLI invocation ignores the `dev-folder` directory and all directories named `experiments` and adds a new entry to Python's module search path:

```
sl analyze --app <name> --python [<path>] -- --ignore-paths /path/to/dev-folder --ignore-dir-names experiments --extra-sys-paths /path/to/lib/python3.8/site-packages
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

| Additional parameter         | Description                                                                                                            |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `--extra-sys-paths [<path>]` | Include additional module search paths in the analysis. Required for applications that aren't written using Python 3.8 |
| `--strict-deps`              | Requires that all of the project's module paths can be followed for analysis to proceed                                |
| `--ignore-paths`             | Ignores the specified paths from the analysis. Requires the full path, not a relative path, to be provided             |
| `--ignore-dir-names`         | Excludes all matching directories from the analysis. You must provide the exact directory name                         |

Such parameters, if valid, are passed directly to the Python analyzer.

### Sample usage of additional parameters <a href="#sample-usage-of-additional-parameters-1" id="sample-usage-of-additional-parameters-1"></a>

To provide an additional module search path for the analysis:

```
sl analyze --app <name> --python [<path>] -- --extra-sys-paths [<path>]
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

To specify that the analysis should only continue if all the project's modules can be followed:

```
sl analyze --app <name> --python [<path>] -- --strict-deps
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

To ignore specific paths from the analysis:

```
sl analyze --app <name> --python [<path>] -- --ignore-paths [<ignore_path_1>] [<ignore_path_2>]
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

To ignore specific directory names from the analysis:

```
sl analyze --app <name> --python [<path>] -- --ignore-dir-names [<ignore_dir_name_1>] [<ignore_dir_name_2>]
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

To enable detailed logging of the analysis in case of troubleshooting:

```
 sl analyze --app <name> --python [<path>] -- -l debug # append --verbose if providing logs to Qwiet for support
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

See the [CLI reference](broken://spaces/4t03gua31tHpZwtcczPO/pages/bfq0NtVB7O7f6pFvFzK3) for additional `sl analyze` options.

### SCA <a href="#sca-1" id="sca-1"></a>

To [identify open-source vulnerabilities](/sast-and-sca/prezero/oss-vulnerabilities.md), Qwiet AI by Harness automatically searches for build manifests in the project path you provided when running `sl analyze`. However, depending on how your project repo is structured, you may need to provide `--oss-project-dir <project-path>` so that Qwiet AI by Harness can identify where your dependencies are located.

### Considerations <a href="#considerations" id="considerations"></a>

Qwiet's Python analyzer attempts to gather as much information about your project as possible to achieve accuracy. It expects an environment set up close to the one you have for *running* your project. This means that the Python interpreter must find all of the project's dependencies set up in one of the directories of its [module search path](https://docs.python.org/3/tutorial/modules.html#the-module-search-path). The most straightforward way to do this is to create a virtual environment and install the project's dependencies in it.

Qwiet supports setups that do not use virtual environments as long as the Python interpreter can find the dependencies in its [search path](https://docs.python.org/3/tutorial/modules.html#the-module-search-path). You can specify additional directories to look for dependencies using the `--extra-sys-paths` flag.

Additionally, the Python analyzer goes through your project's files and modules in a similar way to the Python interpreter. This process is crucial for gathering necessary information and can be fragile for certain setups. If the analyzer cannot follow one of the imports in your project, the analysis will proceed. Still, the files related to the import may not be included in the resulting analysis and Qwiet AI by Harness may also not detect security vulnerabilities related to these files. To receive a complete analysis, include the `--strict-deps` flag.

### Tagging results with your branch name <a href="#tagging-results-with-your-branch-name" id="tagging-results-with-your-branch-name"></a>

To include the branch name in your Qwiet AI by Harness results, allowing you to distinguish one set of results from another, add the following to your invocation of Qwiet:

```
sl analyze --tag branch=`git symbolic-ref --short HEAD`
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

If you're working in a GitHub environment (e.g., [GitHub Actions](https://github.com/features/actions)), you can also use `--tag branch=${{ github.head_ref }}` to populate your branch name.

If you don't provide a branch name, but Qwiet detects one available in your environment, it will use that name.

## Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

If you have any issues scanning your project, please see our [general troubleshooting page](/sast-and-sca/prezero/tutorials/troubleshooting.md), as well as our Python-specific suggestions that follow.

### Package installation <a href="#package-installation" id="package-installation"></a>

Before running analysis on your Python application, make sure to run `pip install`:

```
pip install -r requirements.txt
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

### Python versions <a href="#python-versions" id="python-versions"></a>

If you receive the following error when analyzing your Python application, please make sure that you have Python v3.8 installed (regardless of which version of Python you app uses):

```
Error:  analyze: python3.8 is required but not found | issuer=/go/src/github.com/ShiftLeftSecurity/go-services/cmd/sl/main.go:1824
analyze: python3.8 is required but not found
Error: Process completed with exit code 1.
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

### Module import errors <a href="#module-import-errors" id="module-import-errors"></a>

* Check to see if running `pip install` for your application was successful.
* If using a private registry, such as Sonatype or JFrog, ensure the `.pypirc` file contains the authentication token required to install all the dependencies.
* Some applications might have a common directory referred to by multiple packages. To provide this additional module search path for the analysis:

  ```prism-code
  sl analyze --app <name> --python [<path>] -- --extra-sys-paths [<path>]
  ```

  ![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)
* Some applications have development and test scripts that contain errors preventing security analysis. To omit specific paths from the analysis:

  ```prism-code
  sl analyze --app <name> --python [<path>] -- --ignore-paths [<ignore_path_1>] [<ignore_path_2>]
  ```

  ![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

  > The paths are separated by spaces.
* To ignore specific directory by name from the analysis:

  ```prism-code
  sl analyze --app <name> --python [<path>] -- --ignore-dir-names [<ignore_dir_name_1>] [<ignore_dir_name_2>]
  ```

  ![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)
* To enable detailed logging of the analysis in case of troubleshooting:

  ```prism-code
  sl analyze --verbose --app <name> --python [<path>] -- -l debug
  ```

  ![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)

  The detailed log file can then be found in the user's temporary directory.
  {% endtab %}
  {% endtabs %}

### Analyzing Jupyter notebooks <a href="#analyzing-jupyter-notebooks" id="analyzing-jupyter-notebooks"></a>

To submit a Jupyter notebook for analysis with Qwiet AI by Harness, you must first convert all of your `.ipynb` files to `.py` files:

```
# convert the notebooks (*.ipynb) into Python files (*.py)
jupyter nbconvert --to python *.ipynb

# analyze the Python files with Qwiet AI by Harness
sl analyze --app ipynb-pythonsrc --pythonsrc .
```

![](/files/DfHDmRpYn5HJOmhRtTva) ![](/files/P5vj8JOtHNJWVEvAqKym)
