diff --git a/README.md b/README.md
index 4dde423c..6281af21 100644
--- a/README.md
+++ b/README.md
@@ -177,7 +177,7 @@ public class TrustifyExample {
Java - Maven
JavaScript - Npm
Golang - Go Modules
-Python - pip Installer
+Python - pip Installer (requirements.txt, pyproject.toml)
Gradle - Gradle Installation
Rust - Cargo
@@ -264,7 +264,7 @@ require (
-Python pip users can add in requirement text a comment with #trustify-da-ignore(or # trustify-da-ignore) to the right of the same artifact to be ignored, for example:
+Python pip users can add in requirements.txt a comment with #trustify-da-ignore(or # trustify-da-ignore) to the right of the same artifact to be ignored, for example:
```properties
anyio==3.6.2
@@ -297,6 +297,20 @@ zipp==3.6.0
```
+
+Python pyproject.toml users can add a comment with #trustify-da-ignore next to a dependency in pyproject.toml:
+
+```toml
+[project]
+name = "my-project"
+dependencies = [
+ "requests>=2.28.1",
+ "flask>=2.0", # trustify-da-ignore
+ "click>=8.0",
+]
+```
+
+
Gradle users can add in build.gradle a comment with //trustify-da-ignore next to the package to be ignored:
```build.gradle
@@ -538,7 +552,7 @@ System.setProperty("TRUSTIFY_DA_MVN_LOCAL_REPO", "/home/user/custom-maven-repo")
##### Background
In Python pip and in golang go modules package managers ( especially in Python pip) , There is a big chance that for a certain manifest and a given package inside it, the client machine environment has different version installed/resolved
-for that package, which can lead to perform the analysis on the installed packages' versions , instead on the declared versions ( in manifests - that is requirements.txt/go.mod ), and this
+for that package, which can lead to perform the analysis on the installed packages' versions , instead on the declared versions ( in manifests - that is requirements.txt/pyproject.toml/go.mod ), and this
can cause a confusion for the user in the client consuming the API and leads to inconsistent output ( in THE manifest there is version X For a given Package `A` , and in the analysis report there is another version for the same package `A` - Y).
##### Usage
@@ -579,16 +593,18 @@ TRUSTIFY_DA_GO_MVS_LOGIC_ENABLED=false
#### Python Support
+Python support works with both `requirements.txt` and `pyproject.toml` manifest files. The `pyproject.toml` provider scans production dependencies from PEP 621 `[project.dependencies]` and Poetry `[tool.poetry.dependencies]` sections. Optional dependencies (`[project.optional-dependencies]`) and Poetry group dependencies (`[tool.poetry.group.*.dependencies]`) are intentionally excluded to focus on runtime dependencies.
+
By default, Python support assumes that the package is installed using the pip/pip3 binary on the system PATH, or of the customized
Binaries passed to environment variables. If the package is not installed , then an error will be thrown.
-There is an experimental feature of installing the requirement.txt on a virtual env(only python3 or later is supported for this feature) - in this case,
+There is an experimental feature of installing the dependencies on a virtual env(only python3 or later is supported for this feature) - in this case,
it's important to pass in a path to python3 binary as `TRUSTIFY_DA_PYTHON3_PATH` or instead make sure that python3 is on the system path.
-in such case, You can use that feature by setting environment variable `TRUSTIFY_DA_PYTHON_VIRTUAL_ENV` to true
+in such case, You can use that feature by setting environment variable `TRUSTIFY_DA_PYTHON_VIRTUAL_ENV` to true
##### "Best Efforts Installation"
Since Python pip packages are very sensitive/picky regarding python version changes( every small range of versions is only tailored for a certain python version), I'm introducing this feature, that
-tries to install all packages in requirements.txt onto created virtual environment while **disregarding** versions declared for packages in requirements.txt
+tries to install all packages in the manifest onto created virtual environment while **disregarding** versions declared for packages
This increasing the chances and the probability a lot that the automatic installation will succeed.
##### Usage
@@ -693,6 +709,9 @@ java -jar trustify-da-java-client-cli.jar stack /path/to/build.gradle --html
# Component analysis with JSON output (default)
java -jar trustify-da-java-client-cli.jar component /path/to/requirements.txt
+# Component analysis for pyproject.toml
+java -jar trustify-da-java-client-cli.jar component /path/to/pyproject.toml
+
# Component analysis with summary
java -jar trustify-da-java-client-cli.jar component /path/to/go.mod --summary
diff --git a/src/main/java/io/github/guacsec/trustifyda/providers/PythonPipProvider.java b/src/main/java/io/github/guacsec/trustifyda/providers/PythonPipProvider.java
index 9d6ce7ef..ab44ceac 100644
--- a/src/main/java/io/github/guacsec/trustifyda/providers/PythonPipProvider.java
+++ b/src/main/java/io/github/guacsec/trustifyda/providers/PythonPipProvider.java
@@ -16,196 +16,42 @@
*/
package io.github.guacsec.trustifyda.providers;
-import static io.github.guacsec.trustifyda.impl.ExhortApi.debugLoggingIsNeeded;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.github.packageurl.MalformedPackageURLException;
import com.github.packageurl.PackageURL;
-import io.github.guacsec.trustifyda.Api;
-import io.github.guacsec.trustifyda.Provider;
-import io.github.guacsec.trustifyda.license.LicenseUtils;
-import io.github.guacsec.trustifyda.logging.LoggersFactory;
-import io.github.guacsec.trustifyda.sbom.Sbom;
-import io.github.guacsec.trustifyda.sbom.SbomFactory;
-import io.github.guacsec.trustifyda.tools.Ecosystem;
-import io.github.guacsec.trustifyda.tools.Operations;
-import io.github.guacsec.trustifyda.utils.Environment;
-import io.github.guacsec.trustifyda.utils.IgnorePatternDetector;
import io.github.guacsec.trustifyda.utils.PythonControllerBase;
-import io.github.guacsec.trustifyda.utils.PythonControllerRealEnv;
-import io.github.guacsec.trustifyda.utils.PythonControllerVirtualEnv;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
-import java.util.logging.Logger;
import java.util.stream.Collectors;
-public final class PythonPipProvider extends Provider {
-
- private static final Logger log = LoggersFactory.getLogger(PythonPipProvider.class.getName());
- private static final String DEFAULT_PIP_ROOT_COMPONENT_NAME = "default-pip-root";
- private static final String DEFAULT_PIP_ROOT_COMPONENT_VERSION = "0.0.0";
-
- public void setPythonController(PythonControllerBase pythonController) {
- this.pythonController = pythonController;
- }
-
- private PythonControllerBase pythonController;
+public final class PythonPipProvider extends PythonProvider {
public PythonPipProvider(Path manifest) {
- super(Ecosystem.Type.PYTHON, manifest);
+ super(manifest);
}
@Override
- public String readLicenseFromManifest() {
- return LicenseUtils.readLicenseFile(manifest);
+ protected Path getRequirementsPath() {
+ return manifest;
}
@Override
- public Content provideStack() throws IOException {
- PythonControllerBase pythonController = getPythonController();
- List