pysentry-rs 0.1.5__cp39-cp39-macosx_11_0_arm64.whl → 0.2.1__cp39-cp39-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pysentry-rs might be problematic. Click here for more details.
- pysentry/__init__.py +181 -56
- pysentry/_internal.cpython-39-darwin.so +0 -0
- {pysentry_rs-0.1.5.dist-info → pysentry_rs-0.2.1.dist-info}/METADATA +85 -34
- pysentry_rs-0.2.1.dist-info/RECORD +8 -0
- pysentry_rs-0.1.5.dist-info/RECORD +0 -8
- {pysentry_rs-0.1.5.dist-info → pysentry_rs-0.2.1.dist-info}/WHEEL +0 -0
- {pysentry_rs-0.1.5.dist-info → pysentry_rs-0.2.1.dist-info}/entry_points.txt +0 -0
- {pysentry_rs-0.1.5.dist-info → pysentry_rs-0.2.1.dist-info}/licenses/LICENSE +0 -0
pysentry/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from ._internal import audit_python, audit_with_options, check_resolvers, check_version
|
|
4
4
|
|
|
5
|
-
__version__ = "0.1
|
|
5
|
+
__version__ = "0.2.1"
|
|
6
6
|
__all__ = [
|
|
7
7
|
"audit_python",
|
|
8
8
|
"audit_with_options",
|
|
@@ -12,78 +12,157 @@ __all__ = [
|
|
|
12
12
|
]
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
def resolve_sources(source, sources_list):
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
resolved_sources = []
|
|
19
|
+
|
|
20
|
+
if sources_list:
|
|
21
|
+
for source_arg in sources_list:
|
|
22
|
+
for source_str in source_arg.split(","):
|
|
23
|
+
source_str = source_str.strip()
|
|
24
|
+
if not source_str:
|
|
25
|
+
continue
|
|
26
|
+
if source_str not in ["pypa", "pypi", "osv"]:
|
|
27
|
+
print(
|
|
28
|
+
f"Error: Invalid vulnerability source: '{source_str}'. Valid sources: pypa, pypi, osv",
|
|
29
|
+
file=sys.stderr,
|
|
30
|
+
)
|
|
31
|
+
sys.exit(1)
|
|
32
|
+
resolved_sources.append(source_str)
|
|
33
|
+
|
|
34
|
+
if not resolved_sources:
|
|
35
|
+
if source != "pypa":
|
|
36
|
+
print(
|
|
37
|
+
"Warning: --source flag is deprecated and will be removed in a future version. Use --sources instead.",
|
|
38
|
+
file=sys.stderr,
|
|
39
|
+
)
|
|
40
|
+
resolved_sources.append(source)
|
|
41
|
+
else:
|
|
42
|
+
resolved_sources.append("pypa")
|
|
43
|
+
|
|
44
|
+
unique_sources = []
|
|
45
|
+
for src in resolved_sources:
|
|
46
|
+
if src not in unique_sources:
|
|
47
|
+
unique_sources.append(src)
|
|
48
|
+
|
|
49
|
+
return unique_sources
|
|
50
|
+
|
|
51
|
+
|
|
15
52
|
def main():
|
|
16
53
|
"""CLI entry point."""
|
|
17
54
|
import sys
|
|
18
55
|
import argparse
|
|
19
56
|
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
# Parse resolvers subcommand
|
|
23
|
-
parser = argparse.ArgumentParser(
|
|
24
|
-
prog="pysentry-rs resolvers",
|
|
25
|
-
description="Check available dependency resolvers",
|
|
26
|
-
)
|
|
27
|
-
parser.add_argument(
|
|
28
|
-
"--verbose", "-v", action="store_true", help="Enable verbose output"
|
|
29
|
-
)
|
|
57
|
+
# Global flag to track if deprecation warning has been shown
|
|
58
|
+
_deprecation_warning_shown = False
|
|
30
59
|
|
|
31
|
-
|
|
32
|
-
|
|
60
|
+
def handle_all_flags(args):
|
|
61
|
+
"""Handle the deprecated --all flag and new --all-extras flag with appropriate warnings."""
|
|
62
|
+
nonlocal _deprecation_warning_shown
|
|
33
63
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
if args.all and getattr(args, "all_extras", False):
|
|
65
|
+
if not _deprecation_warning_shown:
|
|
66
|
+
print(
|
|
67
|
+
"Warning: Both --all and --all-extras flags are specified. Using --all-extras only. The --all flag is deprecated.",
|
|
68
|
+
file=sys.stderr,
|
|
69
|
+
)
|
|
70
|
+
_deprecation_warning_shown = True
|
|
71
|
+
return True
|
|
72
|
+
elif args.all:
|
|
73
|
+
if not _deprecation_warning_shown:
|
|
74
|
+
print(
|
|
75
|
+
"Warning: --all flag is deprecated and will be removed in a future version. Use --all-extras instead.",
|
|
76
|
+
file=sys.stderr,
|
|
77
|
+
)
|
|
78
|
+
_deprecation_warning_shown = True
|
|
79
|
+
return True
|
|
80
|
+
else:
|
|
81
|
+
return getattr(args, "all_extras", False)
|
|
52
82
|
|
|
53
|
-
|
|
54
|
-
|
|
83
|
+
# Handle subcommands manually to match Rust CLI structure exactly
|
|
84
|
+
if len(sys.argv) > 1:
|
|
85
|
+
if sys.argv[1] == "resolvers":
|
|
86
|
+
# Resolvers subcommand
|
|
87
|
+
parser = argparse.ArgumentParser(
|
|
88
|
+
prog="pysentry resolvers",
|
|
89
|
+
description="Check available dependency resolvers",
|
|
90
|
+
)
|
|
91
|
+
parser.add_argument(
|
|
92
|
+
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
93
|
+
)
|
|
55
94
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
95
|
+
args = parser.parse_args(sys.argv[2:])
|
|
96
|
+
try:
|
|
97
|
+
result = check_resolvers(args.verbose)
|
|
98
|
+
print(result)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
101
|
+
sys.exit(1)
|
|
102
|
+
return
|
|
63
103
|
|
|
64
|
-
|
|
104
|
+
elif sys.argv[1] == "check-version":
|
|
105
|
+
# Check-version subcommand
|
|
106
|
+
parser = argparse.ArgumentParser(
|
|
107
|
+
prog="pysentry-rs check-version",
|
|
108
|
+
description="Check if a newer version is available",
|
|
109
|
+
)
|
|
110
|
+
parser.add_argument(
|
|
111
|
+
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
args = parser.parse_args(sys.argv[2:])
|
|
115
|
+
try:
|
|
116
|
+
result = check_version(args.verbose)
|
|
117
|
+
print(result)
|
|
118
|
+
except Exception as e:
|
|
119
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
120
|
+
sys.exit(1)
|
|
121
|
+
return
|
|
122
|
+
elif sys.argv[1] in ["-h", "--help"]:
|
|
123
|
+
# Show main help
|
|
124
|
+
pass
|
|
125
|
+
elif sys.argv[1] in ["-V", "--version"]:
|
|
126
|
+
print(f"pysentry-rs {__version__}")
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
# Main parser for audit command (default) and help
|
|
65
130
|
parser = argparse.ArgumentParser(
|
|
66
131
|
prog="pysentry-rs",
|
|
67
132
|
description="Security vulnerability auditing for Python packages",
|
|
133
|
+
usage="pysentry-rs [OPTIONS] [PATH] [COMMAND]",
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Add version argument
|
|
137
|
+
parser.add_argument(
|
|
138
|
+
"-V", "--version", action="version", version=f"pysentry-rs {__version__}"
|
|
68
139
|
)
|
|
69
140
|
|
|
141
|
+
# Main audit arguments
|
|
70
142
|
parser.add_argument(
|
|
71
143
|
"path",
|
|
72
144
|
nargs="?",
|
|
73
145
|
default=".",
|
|
74
|
-
|
|
146
|
+
metavar="PATH",
|
|
147
|
+
help="Path to the project directory to audit [default: .]",
|
|
75
148
|
)
|
|
76
149
|
parser.add_argument(
|
|
77
150
|
"--format",
|
|
78
|
-
choices=["human", "json", "sarif"],
|
|
151
|
+
choices=["human", "json", "sarif", "markdown"],
|
|
79
152
|
default="human",
|
|
80
|
-
help="Output format
|
|
153
|
+
help="Output format [default: human] [possible values: human, json, sarif, markdown]",
|
|
81
154
|
)
|
|
82
155
|
parser.add_argument(
|
|
83
156
|
"--severity",
|
|
84
157
|
choices=["low", "medium", "high", "critical"],
|
|
85
158
|
default="low",
|
|
86
|
-
help="Minimum severity level to report
|
|
159
|
+
help="Minimum severity level to report [default: low] [possible values: low, medium, high, critical]",
|
|
160
|
+
)
|
|
161
|
+
parser.add_argument(
|
|
162
|
+
"--fail-on",
|
|
163
|
+
choices=["low", "medium", "high", "critical"],
|
|
164
|
+
default="medium",
|
|
165
|
+
help="Fail (exit non-zero) if vulnerabilities of this severity or higher are found [default: medium] [possible values: low, medium, high, critical]",
|
|
87
166
|
)
|
|
88
167
|
parser.add_argument(
|
|
89
168
|
"--ignore",
|
|
@@ -93,13 +172,17 @@ def main():
|
|
|
93
172
|
help="Vulnerability IDs to ignore (can be specified multiple times)",
|
|
94
173
|
)
|
|
95
174
|
parser.add_argument(
|
|
96
|
-
"
|
|
175
|
+
"-o", "--output", metavar="FILE", help="Output file path (defaults to stdout)"
|
|
97
176
|
)
|
|
98
177
|
parser.add_argument(
|
|
99
|
-
"--
|
|
178
|
+
"--all",
|
|
179
|
+
action="store_true",
|
|
180
|
+
help=argparse.SUPPRESS, # Hide deprecated flag from help
|
|
100
181
|
)
|
|
101
182
|
parser.add_argument(
|
|
102
|
-
"--
|
|
183
|
+
"--all-extras",
|
|
184
|
+
action="store_true",
|
|
185
|
+
help="Include ALL extra dependencies (main + dev, optional, etc)",
|
|
103
186
|
)
|
|
104
187
|
parser.add_argument(
|
|
105
188
|
"--direct-only",
|
|
@@ -112,13 +195,18 @@ def main():
|
|
|
112
195
|
"--source",
|
|
113
196
|
choices=["pypa", "pypi", "osv"],
|
|
114
197
|
default="pypa",
|
|
115
|
-
help="Vulnerability data source
|
|
198
|
+
help="Vulnerability data source [DEPRECATED: use --sources instead] [default: pypa] [possible values: pypa, pypi, osv]",
|
|
199
|
+
)
|
|
200
|
+
parser.add_argument(
|
|
201
|
+
"--sources",
|
|
202
|
+
action="append",
|
|
203
|
+
help="Vulnerability data sources (can be specified multiple times or comma-separated)",
|
|
116
204
|
)
|
|
117
205
|
parser.add_argument(
|
|
118
206
|
"--resolver",
|
|
119
207
|
choices=["uv", "pip-tools"],
|
|
120
208
|
default="uv",
|
|
121
|
-
help="Dependency resolver for requirements.txt files
|
|
209
|
+
help="Dependency resolver for requirements.txt files [default: uv] [possible values: uv, pip-tools]",
|
|
122
210
|
)
|
|
123
211
|
parser.add_argument(
|
|
124
212
|
"--requirements-files",
|
|
@@ -127,25 +215,41 @@ def main():
|
|
|
127
215
|
help="Specific requirements files to audit (disables auto-discovery)",
|
|
128
216
|
)
|
|
129
217
|
parser.add_argument(
|
|
130
|
-
"
|
|
218
|
+
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
131
219
|
)
|
|
132
220
|
parser.add_argument(
|
|
133
|
-
"
|
|
221
|
+
"-q", "--quiet", action="store_true", help="Suppress non-error output"
|
|
134
222
|
)
|
|
135
223
|
|
|
224
|
+
# Add custom help text for commands
|
|
225
|
+
parser.epilog = """
|
|
226
|
+
Commands:
|
|
227
|
+
resolvers Check available dependency resolvers
|
|
228
|
+
check-version Check if a newer version is available
|
|
229
|
+
help Print this message or the help of the given subcommand(s)
|
|
230
|
+
"""
|
|
231
|
+
|
|
136
232
|
args = parser.parse_args()
|
|
137
233
|
|
|
138
234
|
try:
|
|
139
|
-
# Main audit functionality
|
|
235
|
+
# Main audit functionality - handle deprecated --all flag and new --all-extras flag
|
|
236
|
+
include_all = handle_all_flags(args)
|
|
237
|
+
dev = include_all
|
|
238
|
+
optional = include_all
|
|
239
|
+
|
|
240
|
+
resolved_sources = resolve_sources(
|
|
241
|
+
args.source, getattr(args, "sources", None) or []
|
|
242
|
+
)
|
|
243
|
+
|
|
140
244
|
result = audit_with_options(
|
|
141
245
|
path=args.path,
|
|
142
246
|
format=args.format,
|
|
143
|
-
|
|
247
|
+
sources=resolved_sources,
|
|
144
248
|
min_severity=args.severity,
|
|
145
249
|
ignore_ids=args.ignore_ids,
|
|
146
250
|
output=args.output,
|
|
147
|
-
dev=
|
|
148
|
-
optional=
|
|
251
|
+
dev=dev,
|
|
252
|
+
optional=optional,
|
|
149
253
|
direct_only=args.direct_only,
|
|
150
254
|
no_cache=args.no_cache,
|
|
151
255
|
cache_dir=args.cache_dir,
|
|
@@ -158,6 +262,27 @@ def main():
|
|
|
158
262
|
if not args.output:
|
|
159
263
|
print(result)
|
|
160
264
|
|
|
265
|
+
if args.format == "json":
|
|
266
|
+
import json
|
|
267
|
+
|
|
268
|
+
try:
|
|
269
|
+
report_data = json.loads(result)
|
|
270
|
+
vulnerabilities = report_data.get("vulnerabilities", [])
|
|
271
|
+
|
|
272
|
+
severity_levels = {"low": 1, "medium": 2, "high": 3, "critical": 4}
|
|
273
|
+
fail_on_level = severity_levels.get(args.fail_on, 2) # default medium
|
|
274
|
+
|
|
275
|
+
for vuln in vulnerabilities:
|
|
276
|
+
vuln_severity = vuln.get("severity", "low").lower()
|
|
277
|
+
vuln_level = severity_levels.get(vuln_severity, 1)
|
|
278
|
+
if vuln_level >= fail_on_level:
|
|
279
|
+
sys.exit(1)
|
|
280
|
+
|
|
281
|
+
except (json.JSONDecodeError, KeyError):
|
|
282
|
+
pass
|
|
283
|
+
else:
|
|
284
|
+
pass
|
|
285
|
+
|
|
161
286
|
except Exception as e:
|
|
162
287
|
print(f"Error: {e}", file=sys.stderr)
|
|
163
288
|
sys.exit(1)
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pysentry-rs
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
@@ -26,30 +26,32 @@ Project-URL: Issues, https://github.com/nyudenkov/pysentry/issues
|
|
|
26
26
|
|
|
27
27
|
# 🐍 PySentry
|
|
28
28
|
|
|
29
|
+
[](https://google.github.io/osv.dev/)
|
|
30
|
+
|
|
29
31
|
[Help to test and improve](https://github.com/nyudenkov/pysentry/issues/12)
|
|
30
32
|
|
|
31
33
|
A fast, reliable security vulnerability scanner for Python projects, written in Rust.
|
|
32
34
|
|
|
33
35
|
## Overview
|
|
34
36
|
|
|
35
|
-
PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `pyproject.toml`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
|
|
37
|
+
PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `pyproject.toml`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
|
|
36
38
|
|
|
37
39
|
## Key Features
|
|
38
40
|
|
|
39
|
-
- **Multiple Project Formats**: Supports `uv.lock`, `pyproject.toml`, and `requirements.txt` files
|
|
41
|
+
- **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `pyproject.toml`, and `requirements.txt` files
|
|
40
42
|
- **External Resolver Integration**: Leverages `uv` and `pip-tools` for accurate requirements.txt constraint solving
|
|
41
43
|
- **Multiple Data Sources**:
|
|
42
44
|
- PyPA Advisory Database (default)
|
|
43
45
|
- PyPI JSON API
|
|
44
46
|
- OSV.dev (Open Source Vulnerabilities)
|
|
45
|
-
- **Flexible Output**: Human-readable, JSON, and
|
|
47
|
+
- **Flexible Output for different workflows**: Human-readable, JSON, SARIF, and Markdown formats
|
|
46
48
|
- **Performance Focused**:
|
|
47
49
|
- Written in Rust for speed
|
|
48
50
|
- Async/concurrent processing
|
|
49
51
|
- Intelligent caching system
|
|
50
52
|
- **Comprehensive Filtering**:
|
|
51
53
|
- Severity levels (low, medium, high, critical)
|
|
52
|
-
- Dependency
|
|
54
|
+
- Dependency scopes (main only vs all [optional, dev, prod, etc] dependencies)
|
|
53
55
|
- Direct vs. transitive dependencies
|
|
54
56
|
- **Enterprise Ready**: SARIF output for IDE/CI integration
|
|
55
57
|
|
|
@@ -174,7 +176,7 @@ pip install pip-tools
|
|
|
174
176
|
```
|
|
175
177
|
- Alternatively, install resolvers globally for system-wide availability
|
|
176
178
|
|
|
177
|
-
**Auto-detection:** PySentry automatically detects and prefers: `uv` > `pip-tools`. Without a resolver, only `uv.lock` and `
|
|
179
|
+
**Auto-detection:** PySentry automatically detects and prefers: `uv` > `pip-tools`. Without a resolver, only `uv.lock` and `poetry.lock` files can be scanned.
|
|
178
180
|
|
|
179
181
|
## Quick Start
|
|
180
182
|
|
|
@@ -189,15 +191,15 @@ uvx pysentry-rs /path/to/python/project
|
|
|
189
191
|
pysentry
|
|
190
192
|
pysentry /path/to/python/project
|
|
191
193
|
|
|
192
|
-
#
|
|
194
|
+
# Automatically detects project type (uv.lock, poetry.lock, pyproject.toml, requirements.txt)
|
|
193
195
|
pysentry /path/to/project
|
|
194
196
|
|
|
195
197
|
# Force specific resolver
|
|
196
198
|
pysentry --resolver uv /path/to/project
|
|
197
199
|
pysentry --resolver pip-tools /path/to/project
|
|
198
200
|
|
|
199
|
-
# Include
|
|
200
|
-
pysentry --
|
|
201
|
+
# Include all dependencies (main + dev + optional)
|
|
202
|
+
pysentry --all-extras
|
|
201
203
|
|
|
202
204
|
# Filter by severity (only show high and critical)
|
|
203
205
|
pysentry --severity high
|
|
@@ -210,14 +212,22 @@ pysentry --format json --output audit-results.json
|
|
|
210
212
|
|
|
211
213
|
```bash
|
|
212
214
|
# Using uvx for comprehensive audit
|
|
213
|
-
uvx pysentry-rs --
|
|
215
|
+
uvx pysentry-rs --all-extras --format sarif --output security-report.sarif
|
|
216
|
+
|
|
217
|
+
# Check multiple vulnerability sources concurrently
|
|
218
|
+
uvx pysentry-rs --sources pypa,osv,pypi /path/to/project
|
|
219
|
+
uvx pysentry-rs --sources pypa --sources osv --sources pypi
|
|
220
|
+
|
|
221
|
+
# Generate markdown report
|
|
222
|
+
uvx pysentry-rs --format markdown --output security-report.md
|
|
214
223
|
|
|
215
|
-
#
|
|
216
|
-
uvx pysentry-rs --
|
|
224
|
+
# Control CI exit codes - only fail on critical vulnerabilities
|
|
225
|
+
uvx pysentry-rs --fail-on critical
|
|
217
226
|
|
|
218
227
|
# Or with installed binary
|
|
219
|
-
pysentry --
|
|
220
|
-
pysentry --direct-only
|
|
228
|
+
pysentry --all-extras --format sarif --output security-report.sarif
|
|
229
|
+
pysentry --sources pypa,osv --direct-only
|
|
230
|
+
pysentry --format markdown --output security-report.md
|
|
221
231
|
|
|
222
232
|
# Ignore specific vulnerabilities
|
|
223
233
|
pysentry --ignore CVE-2023-12345 --ignore GHSA-xxxx-yyyy-zzzz
|
|
@@ -246,26 +256,45 @@ pysentry /path/to/project
|
|
|
246
256
|
pysentry --verbose --resolver uv /path/to/project
|
|
247
257
|
```
|
|
248
258
|
|
|
259
|
+
### CI/CD Integration Examples
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Development environment - only fail on critical vulnerabilities
|
|
263
|
+
pysentry --fail-on critical --format json --output security-report.json
|
|
264
|
+
|
|
265
|
+
# Staging environment - fail on high+ vulnerabilities
|
|
266
|
+
pysentry --fail-on high --sources pypa,osv --format sarif --output security.sarif
|
|
267
|
+
|
|
268
|
+
# Production deployment - strict security (fail on medium+, default)
|
|
269
|
+
pysentry --sources pypa,pypi,osv --format json --output prod-security.json
|
|
270
|
+
|
|
271
|
+
# Generate markdown report for GitHub issues/PRs
|
|
272
|
+
pysentry --format markdown --output SECURITY-REPORT.md
|
|
273
|
+
|
|
274
|
+
# Comprehensive audit with all sources and full reporting
|
|
275
|
+
pysentry --sources pypa,pypi,osv --all-extras --format json --fail-on low
|
|
276
|
+
```
|
|
277
|
+
|
|
249
278
|
## Configuration
|
|
250
279
|
|
|
251
280
|
### Command Line Options
|
|
252
281
|
|
|
253
|
-
| Option | Description
|
|
254
|
-
| ---------------- |
|
|
255
|
-
| `--format` | Output format: `human`, `json`, `sarif`
|
|
256
|
-
| `--severity` | Minimum severity: `low`, `medium`, `high`, `critical`
|
|
257
|
-
| `--
|
|
258
|
-
| `--
|
|
259
|
-
| `--
|
|
260
|
-
| `--direct-only` | Check only direct dependencies
|
|
261
|
-
| `--ignore` | Vulnerability IDs to ignore (repeatable)
|
|
262
|
-
| `--output` | Output file path
|
|
263
|
-
| `--no-cache` | Disable caching
|
|
264
|
-
| `--cache-dir` | Custom cache directory
|
|
265
|
-
| `--verbose` | Enable verbose output
|
|
266
|
-
| `--quiet` | Suppress non-error output
|
|
267
|
-
| `--resolver` | Dependency resolver: `auto`, `uv`, `pip-tools`
|
|
268
|
-
| `--requirements` | Additional requirements files (repeatable)
|
|
282
|
+
| Option | Description | Default |
|
|
283
|
+
| ---------------- | ------------------------------------------------------- | ------------------- |
|
|
284
|
+
| `--format` | Output format: `human`, `json`, `sarif`, `markdown` | `human` |
|
|
285
|
+
| `--severity` | Minimum severity: `low`, `medium`, `high`, `critical` | `low` |
|
|
286
|
+
| `--fail-on` | Fail (exit non-zero) on vulnerabilities ≥ severity | `medium` |
|
|
287
|
+
| `--sources` | Vulnerability sources: `pypa`, `pypi`, `osv` (multiple) | `pypa` |
|
|
288
|
+
| `--all-extras` | Include all dependencies (main + dev + optional) | `false` |
|
|
289
|
+
| `--direct-only` | Check only direct dependencies | `false` |
|
|
290
|
+
| `--ignore` | Vulnerability IDs to ignore (repeatable) | `[]` |
|
|
291
|
+
| `--output` | Output file path | `stdout` |
|
|
292
|
+
| `--no-cache` | Disable caching | `false` |
|
|
293
|
+
| `--cache-dir` | Custom cache directory | `~/.cache/pysentry` |
|
|
294
|
+
| `--verbose` | Enable verbose output | `false` |
|
|
295
|
+
| `--quiet` | Suppress non-error output | `false` |
|
|
296
|
+
| `--resolver` | Dependency resolver: `auto`, `uv`, `pip-tools` | `auto` |
|
|
297
|
+
| `--requirements` | Additional requirements files (repeatable) | `[]` |
|
|
269
298
|
|
|
270
299
|
### Cache Management
|
|
271
300
|
|
|
@@ -293,6 +322,23 @@ PySentry has support for `uv.lock` files:
|
|
|
293
322
|
- Source tracking
|
|
294
323
|
- Dependency classification (main, dev, optional) including transitive dependencies
|
|
295
324
|
|
|
325
|
+
### poetry.lock Files
|
|
326
|
+
|
|
327
|
+
Full support for Poetry lock files:
|
|
328
|
+
|
|
329
|
+
- **Exact Version Resolution**: Scans exact dependency versions locked by Poetry
|
|
330
|
+
- **Lock-File Only Analysis**: Relies purely on the lock file structure, no pyproject.toml parsing needed
|
|
331
|
+
- **Complete Dependency Tree**: Analyzes all resolved dependencies including transitive ones
|
|
332
|
+
- **Dependency Classification**: Distinguishes between main dependencies and optional groups (dev, test, etc.)
|
|
333
|
+
- **Source Tracking**: Supports PyPI registry, Git repositories, local paths, and direct URLs
|
|
334
|
+
|
|
335
|
+
**Key Features:**
|
|
336
|
+
|
|
337
|
+
- No external tools required
|
|
338
|
+
- Fast parsing with exact version information
|
|
339
|
+
- Handles Poetry's dependency groups and optional dependencies
|
|
340
|
+
- Perfect for Poetry-managed projects with established lock files
|
|
341
|
+
|
|
296
342
|
### requirements.txt Files (External Resolution)
|
|
297
343
|
|
|
298
344
|
Advanced support for `requirements.txt` files using external dependency resolvers:
|
|
@@ -360,6 +406,10 @@ Support for projects without lock files:
|
|
|
360
406
|
|
|
361
407
|
Most comfortable to read.
|
|
362
408
|
|
|
409
|
+
### Markdown
|
|
410
|
+
|
|
411
|
+
GitHub-friendly format with structured sections and severity indicators. Perfect for documentation, GitHub issues, and security reports.
|
|
412
|
+
|
|
363
413
|
### JSON
|
|
364
414
|
|
|
365
415
|
```json
|
|
@@ -447,7 +497,7 @@ src/
|
|
|
447
497
|
|
|
448
498
|
```bash
|
|
449
499
|
# Ensure you're in a Python project directory
|
|
450
|
-
ls pyproject.toml uv.lock requirements.txt
|
|
500
|
+
ls pyproject.toml uv.lock poetry.lock requirements.txt
|
|
451
501
|
|
|
452
502
|
# Or specify the path explicitly
|
|
453
503
|
pysentry /path/to/python/project
|
|
@@ -494,8 +544,9 @@ pysentry --verbose /path/to/project
|
|
|
494
544
|
# Check network connectivity
|
|
495
545
|
curl -I https://osv-vulnerabilities.storage.googleapis.com/
|
|
496
546
|
|
|
497
|
-
# Try with different
|
|
498
|
-
pysentry --
|
|
547
|
+
# Try with different or multiple sources
|
|
548
|
+
pysentry --sources pypi
|
|
549
|
+
pysentry --sources pypa,osv
|
|
499
550
|
```
|
|
500
551
|
|
|
501
552
|
**Slow requirements.txt resolution**
|
|
@@ -524,7 +575,7 @@ pysentry /path/to/python/project
|
|
|
524
575
|
pysentry --requirements requirements-dev.txt --requirements requirements-test.txt
|
|
525
576
|
|
|
526
577
|
# Check if higher-priority files exist (they take precedence)
|
|
527
|
-
ls uv.lock pyproject.toml
|
|
578
|
+
ls uv.lock poetry.lock pyproject.toml
|
|
528
579
|
```
|
|
529
580
|
|
|
530
581
|
**Performance Issues**
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
pysentry/__init__.py,sha256=7j3_zsnLLnKCaLgYXDrW3xm4AkmbE-ofoa5PX-79rGY,9792
|
|
2
|
+
pysentry/__main__.py,sha256=FJdFFQuSE8TYsZtY_vb00oCE2nvq9hB6MhMLBxnn7Ns,117
|
|
3
|
+
pysentry/_internal.cpython-39-darwin.so,sha256=IiQAoVDgDhvpe_Kqo4tOt1QVyRl3pkPMeBLbVSVHO_c,6395008
|
|
4
|
+
pysentry_rs-0.2.1.dist-info/METADATA,sha256=4_2U3eoQuhETKDwaZVXbCqW9OGpUmzWhDTx2ppNn-Vw,19333
|
|
5
|
+
pysentry_rs-0.2.1.dist-info/WHEEL,sha256=XNDUDUieSorG-Y7wZ8qiKEUDK0umKv3PscUlyjQeFKE,102
|
|
6
|
+
pysentry_rs-0.2.1.dist-info/entry_points.txt,sha256=3bJguekVEbXTn-ceDCWJaSIZScquPPP1Ux9TPVHHanE,44
|
|
7
|
+
pysentry_rs-0.2.1.dist-info/licenses/LICENSE,sha256=TAMtDCoJuavXz7pCEklrzjH55sdvsy5gKsXY9NsImwY,34878
|
|
8
|
+
pysentry_rs-0.2.1.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
pysentry/__init__.py,sha256=t1lvpozrRrRipRHMSTK28BcMgkCXJNhpGVwi0GkjY8c,5089
|
|
2
|
-
pysentry/__main__.py,sha256=FJdFFQuSE8TYsZtY_vb00oCE2nvq9hB6MhMLBxnn7Ns,117
|
|
3
|
-
pysentry/_internal.cpython-39-darwin.so,sha256=XQwsz9kuj1ggKF3RQdDkTyEQqpfbhSC2Xzt_CQ2CSSA,6156016
|
|
4
|
-
pysentry_rs-0.1.5.dist-info/METADATA,sha256=VVt36MRhL3evoIIFKxL0Cw-TVNwyLQO_QMx0URpGGJc,17030
|
|
5
|
-
pysentry_rs-0.1.5.dist-info/WHEEL,sha256=XNDUDUieSorG-Y7wZ8qiKEUDK0umKv3PscUlyjQeFKE,102
|
|
6
|
-
pysentry_rs-0.1.5.dist-info/entry_points.txt,sha256=3bJguekVEbXTn-ceDCWJaSIZScquPPP1Ux9TPVHHanE,44
|
|
7
|
-
pysentry_rs-0.1.5.dist-info/licenses/LICENSE,sha256=TAMtDCoJuavXz7pCEklrzjH55sdvsy5gKsXY9NsImwY,34878
|
|
8
|
-
pysentry_rs-0.1.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|