pysentry-rs 0.2.0__cp311-cp311-macosx_11_0_arm64.whl → 0.2.1__cp311-cp311-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 +114 -9
- pysentry/_internal.cpython-311-darwin.so +0 -0
- {pysentry_rs-0.2.0.dist-info → pysentry_rs-0.2.1.dist-info}/METADATA +60 -25
- pysentry_rs-0.2.1.dist-info/RECORD +8 -0
- pysentry_rs-0.2.0.dist-info/RECORD +0 -8
- {pysentry_rs-0.2.0.dist-info → pysentry_rs-0.2.1.dist-info}/WHEEL +0 -0
- {pysentry_rs-0.2.0.dist-info → pysentry_rs-0.2.1.dist-info}/entry_points.txt +0 -0
- {pysentry_rs-0.2.0.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.2.
|
|
5
|
+
__version__ = "0.2.1"
|
|
6
6
|
__all__ = [
|
|
7
7
|
"audit_python",
|
|
8
8
|
"audit_with_options",
|
|
@@ -12,11 +12,74 @@ __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
|
|
|
57
|
+
# Global flag to track if deprecation warning has been shown
|
|
58
|
+
_deprecation_warning_shown = False
|
|
59
|
+
|
|
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
|
|
63
|
+
|
|
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)
|
|
82
|
+
|
|
20
83
|
# Handle subcommands manually to match Rust CLI structure exactly
|
|
21
84
|
if len(sys.argv) > 1:
|
|
22
85
|
if sys.argv[1] == "resolvers":
|
|
@@ -85,9 +148,9 @@ def main():
|
|
|
85
148
|
)
|
|
86
149
|
parser.add_argument(
|
|
87
150
|
"--format",
|
|
88
|
-
choices=["human", "json", "sarif"],
|
|
151
|
+
choices=["human", "json", "sarif", "markdown"],
|
|
89
152
|
default="human",
|
|
90
|
-
help="Output format [default: human] [possible values: human, json, sarif]",
|
|
153
|
+
help="Output format [default: human] [possible values: human, json, sarif, markdown]",
|
|
91
154
|
)
|
|
92
155
|
parser.add_argument(
|
|
93
156
|
"--severity",
|
|
@@ -95,6 +158,12 @@ def main():
|
|
|
95
158
|
default="low",
|
|
96
159
|
help="Minimum severity level to report [default: low] [possible values: low, medium, high, critical]",
|
|
97
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]",
|
|
166
|
+
)
|
|
98
167
|
parser.add_argument(
|
|
99
168
|
"--ignore",
|
|
100
169
|
action="append",
|
|
@@ -108,7 +177,12 @@ def main():
|
|
|
108
177
|
parser.add_argument(
|
|
109
178
|
"--all",
|
|
110
179
|
action="store_true",
|
|
111
|
-
help=
|
|
180
|
+
help=argparse.SUPPRESS, # Hide deprecated flag from help
|
|
181
|
+
)
|
|
182
|
+
parser.add_argument(
|
|
183
|
+
"--all-extras",
|
|
184
|
+
action="store_true",
|
|
185
|
+
help="Include ALL extra dependencies (main + dev, optional, etc)",
|
|
112
186
|
)
|
|
113
187
|
parser.add_argument(
|
|
114
188
|
"--direct-only",
|
|
@@ -121,7 +195,12 @@ def main():
|
|
|
121
195
|
"--source",
|
|
122
196
|
choices=["pypa", "pypi", "osv"],
|
|
123
197
|
default="pypa",
|
|
124
|
-
help="Vulnerability data source [default: pypa] [possible values: pypa, pypi, osv]",
|
|
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)",
|
|
125
204
|
)
|
|
126
205
|
parser.add_argument(
|
|
127
206
|
"--resolver",
|
|
@@ -153,14 +232,19 @@ Commands:
|
|
|
153
232
|
args = parser.parse_args()
|
|
154
233
|
|
|
155
234
|
try:
|
|
156
|
-
# Main audit functionality -
|
|
157
|
-
|
|
158
|
-
|
|
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
|
+
)
|
|
159
243
|
|
|
160
244
|
result = audit_with_options(
|
|
161
245
|
path=args.path,
|
|
162
246
|
format=args.format,
|
|
163
|
-
|
|
247
|
+
sources=resolved_sources,
|
|
164
248
|
min_severity=args.severity,
|
|
165
249
|
ignore_ids=args.ignore_ids,
|
|
166
250
|
output=args.output,
|
|
@@ -178,6 +262,27 @@ Commands:
|
|
|
178
262
|
if not args.output:
|
|
179
263
|
print(result)
|
|
180
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
|
+
|
|
181
286
|
except Exception as e:
|
|
182
287
|
print(f"Error: {e}", file=sys.stderr)
|
|
183
288
|
sys.exit(1)
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pysentry-rs
|
|
3
|
-
Version: 0.2.
|
|
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,6 +26,8 @@ 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.
|
|
@@ -42,7 +44,7 @@ PySentry audits Python projects for known security vulnerabilities by analyzing
|
|
|
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
|
|
@@ -197,7 +199,7 @@ pysentry --resolver uv /path/to/project
|
|
|
197
199
|
pysentry --resolver pip-tools /path/to/project
|
|
198
200
|
|
|
199
201
|
# Include all dependencies (main + dev + optional)
|
|
200
|
-
pysentry --all
|
|
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 --all --format sarif --output security-report.sarif
|
|
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
|
|
214
220
|
|
|
215
|
-
#
|
|
216
|
-
uvx pysentry-rs --
|
|
221
|
+
# Generate markdown report
|
|
222
|
+
uvx pysentry-rs --format markdown --output security-report.md
|
|
223
|
+
|
|
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 --all --format sarif --output security-report.sarif
|
|
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,25 +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
|
-
| `--
|
|
261
|
-
| `--
|
|
262
|
-
| `--
|
|
263
|
-
| `--cache
|
|
264
|
-
| `--
|
|
265
|
-
| `--
|
|
266
|
-
| `--
|
|
267
|
-
| `--
|
|
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) | `[]` |
|
|
268
298
|
|
|
269
299
|
### Cache Management
|
|
270
300
|
|
|
@@ -376,6 +406,10 @@ Support for projects without lock files:
|
|
|
376
406
|
|
|
377
407
|
Most comfortable to read.
|
|
378
408
|
|
|
409
|
+
### Markdown
|
|
410
|
+
|
|
411
|
+
GitHub-friendly format with structured sections and severity indicators. Perfect for documentation, GitHub issues, and security reports.
|
|
412
|
+
|
|
379
413
|
### JSON
|
|
380
414
|
|
|
381
415
|
```json
|
|
@@ -510,8 +544,9 @@ pysentry --verbose /path/to/project
|
|
|
510
544
|
# Check network connectivity
|
|
511
545
|
curl -I https://osv-vulnerabilities.storage.googleapis.com/
|
|
512
546
|
|
|
513
|
-
# Try with different
|
|
514
|
-
pysentry --
|
|
547
|
+
# Try with different or multiple sources
|
|
548
|
+
pysentry --sources pypi
|
|
549
|
+
pysentry --sources pypa,osv
|
|
515
550
|
```
|
|
516
551
|
|
|
517
552
|
**Slow requirements.txt resolution**
|
|
@@ -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-311-darwin.so,sha256=VEioIE0totieeD3qY30ZkY4wSuz6jMy_NYLT-c9n7HY,6378208
|
|
4
|
+
pysentry_rs-0.2.1.dist-info/METADATA,sha256=4_2U3eoQuhETKDwaZVXbCqW9OGpUmzWhDTx2ppNn-Vw,19333
|
|
5
|
+
pysentry_rs-0.2.1.dist-info/WHEEL,sha256=FQD2wNSk7QdKfwuvlrA52DGgdDYb2Xq1PtLwlu6bv-w,104
|
|
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=kDa2q8nWFR120mhgRaTBxmI8Yxf26tsE5Pdk8tg35VI,5898
|
|
2
|
-
pysentry/__main__.py,sha256=FJdFFQuSE8TYsZtY_vb00oCE2nvq9hB6MhMLBxnn7Ns,117
|
|
3
|
-
pysentry/_internal.cpython-311-darwin.so,sha256=oYdFSeH2jPPeRv93g5N8j8LQMJLBYVvVm0ks7uy4rRg,6240640
|
|
4
|
-
pysentry_rs-0.2.0.dist-info/METADATA,sha256=JAISzKEXYsg9sS29nTxu1NwyVZVZp1_vCKpxdQ2jLhE,17816
|
|
5
|
-
pysentry_rs-0.2.0.dist-info/WHEEL,sha256=FQD2wNSk7QdKfwuvlrA52DGgdDYb2Xq1PtLwlu6bv-w,104
|
|
6
|
-
pysentry_rs-0.2.0.dist-info/entry_points.txt,sha256=3bJguekVEbXTn-ceDCWJaSIZScquPPP1Ux9TPVHHanE,44
|
|
7
|
-
pysentry_rs-0.2.0.dist-info/licenses/LICENSE,sha256=TAMtDCoJuavXz7pCEklrzjH55sdvsy5gKsXY9NsImwY,34878
|
|
8
|
-
pysentry_rs-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|