pysentry-rs 0.2.0__cp38-cp38-macosx_11_0_arm64.whl → 0.2.2__cp38-cp38-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 +8 -171
- pysentry/_internal.cpython-38-darwin.so +0 -0
- {pysentry_rs-0.2.0.dist-info → pysentry_rs-0.2.2.dist-info}/METADATA +190 -43
- pysentry_rs-0.2.2.dist-info/RECORD +7 -0
- pysentry/__main__.py +0 -6
- pysentry_rs-0.2.0.dist-info/RECORD +0 -8
- {pysentry_rs-0.2.0.dist-info → pysentry_rs-0.2.2.dist-info}/WHEEL +0 -0
- {pysentry_rs-0.2.0.dist-info → pysentry_rs-0.2.2.dist-info}/entry_points.txt +0 -0
- {pysentry_rs-0.2.0.dist-info → pysentry_rs-0.2.2.dist-info}/licenses/LICENSE +0 -0
pysentry/__init__.py
CHANGED
|
@@ -1,182 +1,19 @@
|
|
|
1
|
-
"""pysentry: Security vulnerability auditing tool for Python packages."""
|
|
1
|
+
"""pysentry-rs: Security vulnerability auditing tool for Python packages."""
|
|
2
2
|
|
|
3
|
-
from ._internal import
|
|
3
|
+
from ._internal import get_version, run_cli
|
|
4
4
|
|
|
5
|
-
__version__ =
|
|
6
|
-
__all__ = [
|
|
7
|
-
"audit_python",
|
|
8
|
-
"audit_with_options",
|
|
9
|
-
"check_resolvers",
|
|
10
|
-
"check_version",
|
|
11
|
-
"main",
|
|
12
|
-
]
|
|
5
|
+
__version__ = get_version()
|
|
6
|
+
__all__ = ["get_version", "run_cli", "main"]
|
|
13
7
|
|
|
14
8
|
|
|
15
9
|
def main():
|
|
16
|
-
"""CLI entry point."""
|
|
10
|
+
"""CLI entry point that provides the exact same interface as the Rust binary."""
|
|
17
11
|
import sys
|
|
18
|
-
import argparse
|
|
19
|
-
|
|
20
|
-
# Handle subcommands manually to match Rust CLI structure exactly
|
|
21
|
-
if len(sys.argv) > 1:
|
|
22
|
-
if sys.argv[1] == "resolvers":
|
|
23
|
-
# Resolvers subcommand
|
|
24
|
-
parser = argparse.ArgumentParser(
|
|
25
|
-
prog="pysentry resolvers",
|
|
26
|
-
description="Check available dependency resolvers",
|
|
27
|
-
)
|
|
28
|
-
parser.add_argument(
|
|
29
|
-
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
args = parser.parse_args(sys.argv[2:])
|
|
33
|
-
try:
|
|
34
|
-
result = check_resolvers(args.verbose)
|
|
35
|
-
print(result)
|
|
36
|
-
except Exception as e:
|
|
37
|
-
print(f"Error: {e}", file=sys.stderr)
|
|
38
|
-
sys.exit(1)
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
elif sys.argv[1] == "check-version":
|
|
42
|
-
# Check-version subcommand
|
|
43
|
-
parser = argparse.ArgumentParser(
|
|
44
|
-
prog="pysentry-rs check-version",
|
|
45
|
-
description="Check if a newer version is available",
|
|
46
|
-
)
|
|
47
|
-
parser.add_argument(
|
|
48
|
-
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
args = parser.parse_args(sys.argv[2:])
|
|
52
|
-
try:
|
|
53
|
-
result = check_version(args.verbose)
|
|
54
|
-
print(result)
|
|
55
|
-
except Exception as e:
|
|
56
|
-
print(f"Error: {e}", file=sys.stderr)
|
|
57
|
-
sys.exit(1)
|
|
58
|
-
return
|
|
59
|
-
elif sys.argv[1] in ["-h", "--help"]:
|
|
60
|
-
# Show main help
|
|
61
|
-
pass
|
|
62
|
-
elif sys.argv[1] in ["-V", "--version"]:
|
|
63
|
-
print(f"pysentry-rs {__version__}")
|
|
64
|
-
return
|
|
65
|
-
|
|
66
|
-
# Main parser for audit command (default) and help
|
|
67
|
-
parser = argparse.ArgumentParser(
|
|
68
|
-
prog="pysentry-rs",
|
|
69
|
-
description="Security vulnerability auditing for Python packages",
|
|
70
|
-
usage="pysentry-rs [OPTIONS] [PATH] [COMMAND]",
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
# Add version argument
|
|
74
|
-
parser.add_argument(
|
|
75
|
-
"-V", "--version", action="version", version=f"pysentry-rs {__version__}"
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
# Main audit arguments
|
|
79
|
-
parser.add_argument(
|
|
80
|
-
"path",
|
|
81
|
-
nargs="?",
|
|
82
|
-
default=".",
|
|
83
|
-
metavar="PATH",
|
|
84
|
-
help="Path to the project directory to audit [default: .]",
|
|
85
|
-
)
|
|
86
|
-
parser.add_argument(
|
|
87
|
-
"--format",
|
|
88
|
-
choices=["human", "json", "sarif"],
|
|
89
|
-
default="human",
|
|
90
|
-
help="Output format [default: human] [possible values: human, json, sarif]",
|
|
91
|
-
)
|
|
92
|
-
parser.add_argument(
|
|
93
|
-
"--severity",
|
|
94
|
-
choices=["low", "medium", "high", "critical"],
|
|
95
|
-
default="low",
|
|
96
|
-
help="Minimum severity level to report [default: low] [possible values: low, medium, high, critical]",
|
|
97
|
-
)
|
|
98
|
-
parser.add_argument(
|
|
99
|
-
"--ignore",
|
|
100
|
-
action="append",
|
|
101
|
-
dest="ignore_ids",
|
|
102
|
-
metavar="ID",
|
|
103
|
-
help="Vulnerability IDs to ignore (can be specified multiple times)",
|
|
104
|
-
)
|
|
105
|
-
parser.add_argument(
|
|
106
|
-
"-o", "--output", metavar="FILE", help="Output file path (defaults to stdout)"
|
|
107
|
-
)
|
|
108
|
-
parser.add_argument(
|
|
109
|
-
"--all",
|
|
110
|
-
action="store_true",
|
|
111
|
-
help="Include ALL dependencies (main + dev, optional, etc)",
|
|
112
|
-
)
|
|
113
|
-
parser.add_argument(
|
|
114
|
-
"--direct-only",
|
|
115
|
-
action="store_true",
|
|
116
|
-
help="Only check direct dependencies (exclude transitive)",
|
|
117
|
-
)
|
|
118
|
-
parser.add_argument("--no-cache", action="store_true", help="Disable caching")
|
|
119
|
-
parser.add_argument("--cache-dir", metavar="DIR", help="Custom cache directory")
|
|
120
|
-
parser.add_argument(
|
|
121
|
-
"--source",
|
|
122
|
-
choices=["pypa", "pypi", "osv"],
|
|
123
|
-
default="pypa",
|
|
124
|
-
help="Vulnerability data source [default: pypa] [possible values: pypa, pypi, osv]",
|
|
125
|
-
)
|
|
126
|
-
parser.add_argument(
|
|
127
|
-
"--resolver",
|
|
128
|
-
choices=["uv", "pip-tools"],
|
|
129
|
-
default="uv",
|
|
130
|
-
help="Dependency resolver for requirements.txt files [default: uv] [possible values: uv, pip-tools]",
|
|
131
|
-
)
|
|
132
|
-
parser.add_argument(
|
|
133
|
-
"--requirements-files",
|
|
134
|
-
nargs="+",
|
|
135
|
-
metavar="FILE",
|
|
136
|
-
help="Specific requirements files to audit (disables auto-discovery)",
|
|
137
|
-
)
|
|
138
|
-
parser.add_argument(
|
|
139
|
-
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
140
|
-
)
|
|
141
|
-
parser.add_argument(
|
|
142
|
-
"-q", "--quiet", action="store_true", help="Suppress non-error output"
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
# Add custom help text for commands
|
|
146
|
-
parser.epilog = """
|
|
147
|
-
Commands:
|
|
148
|
-
resolvers Check available dependency resolvers
|
|
149
|
-
check-version Check if a newer version is available
|
|
150
|
-
help Print this message or the help of the given subcommand(s)
|
|
151
|
-
"""
|
|
152
|
-
|
|
153
|
-
args = parser.parse_args()
|
|
154
12
|
|
|
155
13
|
try:
|
|
156
|
-
#
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
result = audit_with_options(
|
|
161
|
-
path=args.path,
|
|
162
|
-
format=args.format,
|
|
163
|
-
source=args.source,
|
|
164
|
-
min_severity=args.severity,
|
|
165
|
-
ignore_ids=args.ignore_ids,
|
|
166
|
-
output=args.output,
|
|
167
|
-
dev=dev,
|
|
168
|
-
optional=optional,
|
|
169
|
-
direct_only=args.direct_only,
|
|
170
|
-
no_cache=args.no_cache,
|
|
171
|
-
cache_dir=args.cache_dir,
|
|
172
|
-
resolver=args.resolver,
|
|
173
|
-
requirements_files=args.requirements_files,
|
|
174
|
-
verbose=args.verbose,
|
|
175
|
-
quiet=args.quiet,
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
if not args.output:
|
|
179
|
-
print(result)
|
|
14
|
+
# Pass all arguments directly to the Rust CLI - this ensures perfect compatibility
|
|
15
|
+
exit_code = run_cli(sys.argv)
|
|
16
|
+
sys.exit(exit_code)
|
|
180
17
|
|
|
181
18
|
except Exception as e:
|
|
182
19
|
print(f"Error: {e}", file=sys.stderr)
|
|
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.2
|
|
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,11 +44,11 @@ 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
|
|
49
|
-
-
|
|
51
|
+
- Multi-tier intelligent caching (vulnerability data + resolved dependencies)
|
|
50
52
|
- **Comprehensive Filtering**:
|
|
51
53
|
- Severity levels (low, medium, high, critical)
|
|
52
54
|
- Dependency scopes (main only vs all [optional, dev, prod, etc] dependencies)
|
|
@@ -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
|
|
@@ -244,41 +254,140 @@ pysentry /path/to/project
|
|
|
244
254
|
|
|
245
255
|
# Debug requirements.txt resolution
|
|
246
256
|
pysentry --verbose --resolver uv /path/to/project
|
|
257
|
+
|
|
258
|
+
# Use longer resolution cache TTL (48 hours)
|
|
259
|
+
pysentry --resolution-cache-ttl 48 /path/to/project
|
|
260
|
+
|
|
261
|
+
# Clear resolution cache before scanning
|
|
262
|
+
pysentry --clear-resolution-cache /path/to/project
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### CI/CD Integration Examples
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# Development environment - only fail on critical vulnerabilities
|
|
269
|
+
pysentry --fail-on critical --format json --output security-report.json
|
|
270
|
+
|
|
271
|
+
# Staging environment - fail on high+ vulnerabilities
|
|
272
|
+
pysentry --fail-on high --sources pypa,osv --format sarif --output security.sarif
|
|
273
|
+
|
|
274
|
+
# Production deployment - strict security (fail on medium+, default)
|
|
275
|
+
pysentry --sources pypa,pypi,osv --format json --output prod-security.json
|
|
276
|
+
|
|
277
|
+
# Generate markdown report for GitHub issues/PRs
|
|
278
|
+
pysentry --format markdown --output SECURITY-REPORT.md
|
|
279
|
+
|
|
280
|
+
# Comprehensive audit with all sources and full reporting
|
|
281
|
+
pysentry --sources pypa,pypi,osv --all-extras --format json --fail-on low
|
|
282
|
+
|
|
283
|
+
# CI environment with fresh resolution cache
|
|
284
|
+
pysentry --clear-resolution-cache --sources pypa,osv --format sarif
|
|
285
|
+
|
|
286
|
+
# CI with resolution cache disabled
|
|
287
|
+
pysentry --no-resolution-cache --format json --output security-report.json
|
|
247
288
|
```
|
|
248
289
|
|
|
249
290
|
## Configuration
|
|
250
291
|
|
|
251
292
|
### Command Line Options
|
|
252
293
|
|
|
253
|
-
| Option
|
|
254
|
-
|
|
|
255
|
-
| `--format`
|
|
256
|
-
| `--severity`
|
|
257
|
-
| `--
|
|
258
|
-
| `--
|
|
259
|
-
| `--
|
|
260
|
-
| `--
|
|
261
|
-
| `--
|
|
262
|
-
| `--
|
|
263
|
-
| `--cache
|
|
264
|
-
| `--
|
|
265
|
-
| `--
|
|
266
|
-
| `--
|
|
267
|
-
| `--
|
|
294
|
+
| Option | Description | Default |
|
|
295
|
+
| -------------------------- | ------------------------------------------------------- | ----------------- |
|
|
296
|
+
| `--format` | Output format: `human`, `json`, `sarif`, `markdown` | `human` |
|
|
297
|
+
| `--severity` | Minimum severity: `low`, `medium`, `high`, `critical` | `low` |
|
|
298
|
+
| `--fail-on` | Fail (exit non-zero) on vulnerabilities ≥ severity | `medium` |
|
|
299
|
+
| `--sources` | Vulnerability sources: `pypa`, `pypi`, `osv` (multiple) | `pypa` |
|
|
300
|
+
| `--all-extras` | Include all dependencies (main + dev + optional) | `false` |
|
|
301
|
+
| `--direct-only` | Check only direct dependencies | `false` |
|
|
302
|
+
| `--ignore` | Vulnerability IDs to ignore (repeatable) | `[]` |
|
|
303
|
+
| `--output` | Output file path | `stdout` |
|
|
304
|
+
| `--no-cache` | Disable all caching | `false` |
|
|
305
|
+
| `--cache-dir` | Custom cache directory | Platform-specific |
|
|
306
|
+
| `--resolution-cache-ttl` | Resolution cache TTL in hours | `24` |
|
|
307
|
+
| `--no-resolution-cache` | Disable resolution caching only | `false` |
|
|
308
|
+
| `--clear-resolution-cache` | Clear resolution cache on startup | `false` |
|
|
309
|
+
| `--verbose` | Enable verbose output | `false` |
|
|
310
|
+
| `--quiet` | Suppress non-error output | `false` |
|
|
311
|
+
| `--resolver` | Dependency resolver: `auto`, `uv`, `pip-tools` | `auto` |
|
|
312
|
+
| `--requirements` | Additional requirements files (repeatable) | `[]` |
|
|
268
313
|
|
|
269
314
|
### Cache Management
|
|
270
315
|
|
|
271
|
-
PySentry uses an intelligent caching system
|
|
316
|
+
PySentry uses an intelligent multi-tier caching system for optimal performance:
|
|
317
|
+
|
|
318
|
+
#### Vulnerability Data Cache
|
|
319
|
+
|
|
320
|
+
- **Location**: `{CACHE_DIR}/pysentry/vulnerability-db/`
|
|
321
|
+
- **Purpose**: Caches vulnerability databases from PyPA, PyPI, OSV
|
|
322
|
+
- **TTL**: 24 hours (configurable per source)
|
|
323
|
+
- **Benefits**: Avoids redundant API calls and downloads
|
|
324
|
+
|
|
325
|
+
#### Resolution Cache
|
|
326
|
+
|
|
327
|
+
- **Location**: `{CACHE_DIR}/pysentry/dependency-resolution/`
|
|
328
|
+
- **Purpose**: Caches resolved dependencies from `uv`/`pip-tools`
|
|
329
|
+
- **TTL**: 24 hours (configurable via `--resolution-cache-ttl`)
|
|
330
|
+
- **Benefits**: Dramatically speeds up repeated scans of requirements.txt files
|
|
331
|
+
- **Cache Key**: Based on requirements content, resolver version, Python version, platform
|
|
332
|
+
|
|
333
|
+
#### Platform-Specific Cache Locations
|
|
334
|
+
|
|
335
|
+
- **Linux**: `~/.cache/pysentry/`
|
|
336
|
+
- **macOS**: `~/Library/Caches/pysentry/`
|
|
337
|
+
- **Windows**: `%LOCALAPPDATA%\pysentry\`
|
|
338
|
+
|
|
339
|
+
**Finding Your Cache Location**: Run with `--verbose` to see the actual cache directory path being used.
|
|
340
|
+
|
|
341
|
+
#### Cache Features
|
|
272
342
|
|
|
273
|
-
- **Default Location**: `~/.cache/pysentry/` (or system temp directory)
|
|
274
|
-
- **TTL-based Expiration**: Separate expiration for each vulnerability source
|
|
275
343
|
- **Atomic Updates**: Prevents cache corruption during concurrent access
|
|
276
344
|
- **Custom Location**: Use `--cache-dir` to specify alternative location
|
|
345
|
+
- **Selective Clearing**: Control caching behavior per cache type
|
|
346
|
+
- **Content-based Invalidation**: Automatic cache invalidation on content changes
|
|
277
347
|
|
|
278
|
-
|
|
348
|
+
#### Cache Control Examples
|
|
279
349
|
|
|
280
350
|
```bash
|
|
351
|
+
# Disable all caching
|
|
352
|
+
pysentry --no-cache
|
|
353
|
+
|
|
354
|
+
# Disable only resolution caching (keep vulnerability cache)
|
|
355
|
+
pysentry --no-resolution-cache
|
|
356
|
+
|
|
357
|
+
# Set resolution cache TTL to 48 hours
|
|
358
|
+
pysentry --resolution-cache-ttl 48
|
|
359
|
+
|
|
360
|
+
# Clear resolution cache on startup (useful for CI)
|
|
361
|
+
pysentry --clear-resolution-cache
|
|
362
|
+
|
|
363
|
+
# Custom cache directory
|
|
364
|
+
pysentry --cache-dir /tmp/my-pysentry-cache
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
To manually clear all caches:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
# Linux
|
|
281
371
|
rm -rf ~/.cache/pysentry/
|
|
372
|
+
|
|
373
|
+
# macOS
|
|
374
|
+
rm -rf ~/Library/Caches/pysentry/
|
|
375
|
+
|
|
376
|
+
# Windows (PowerShell)
|
|
377
|
+
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\pysentry"
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
To clear only resolution cache:
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
# Linux
|
|
384
|
+
rm -rf ~/.cache/pysentry/dependency-resolution/
|
|
385
|
+
|
|
386
|
+
# macOS
|
|
387
|
+
rm -rf ~/Library/Caches/pysentry/dependency-resolution/
|
|
388
|
+
|
|
389
|
+
# Windows (PowerShell)
|
|
390
|
+
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\pysentry\dependency-resolution"
|
|
282
391
|
```
|
|
283
392
|
|
|
284
393
|
## Supported Project Formats
|
|
@@ -376,6 +485,10 @@ Support for projects without lock files:
|
|
|
376
485
|
|
|
377
486
|
Most comfortable to read.
|
|
378
487
|
|
|
488
|
+
### Markdown
|
|
489
|
+
|
|
490
|
+
GitHub-friendly format with structured sections and severity indicators. Perfect for documentation, GitHub issues, and security reports.
|
|
491
|
+
|
|
379
492
|
### JSON
|
|
380
493
|
|
|
381
494
|
```json
|
|
@@ -403,26 +516,28 @@ Compatible with GitHub Security tab, VS Code, and other security tools.
|
|
|
403
516
|
|
|
404
517
|
PySentry is designed for speed and efficiency:
|
|
405
518
|
|
|
406
|
-
- **Concurrent Processing**: Vulnerability data fetched in parallel
|
|
407
|
-
- **
|
|
519
|
+
- **Concurrent Processing**: Vulnerability data fetched in parallel from multiple sources
|
|
520
|
+
- **Multi-tier Caching**: Intelligent caching for both vulnerability data and resolved dependencies
|
|
408
521
|
- **Efficient Matching**: In-memory indexing for fast vulnerability lookups
|
|
409
522
|
- **Streaming**: Large databases processed without excessive memory usage
|
|
410
523
|
|
|
524
|
+
### Resolution Cache Performance
|
|
525
|
+
|
|
526
|
+
The resolution cache provides dramatic performance improvements for requirements.txt files:
|
|
527
|
+
|
|
528
|
+
- **First scan**: Standard resolution time using `uv` or `pip-tools`
|
|
529
|
+
- **Subsequent scans**: Near-instantaneous when cache is fresh (>90% time savings)
|
|
530
|
+
- **Cache invalidation**: Automatic when requirements content, resolver, or environment changes
|
|
531
|
+
- **Content-aware**: Different cache entries for different Python versions and platforms
|
|
532
|
+
|
|
411
533
|
### Requirements.txt Resolution Performance
|
|
412
534
|
|
|
413
|
-
PySentry leverages external resolvers
|
|
535
|
+
PySentry leverages external resolvers with intelligent caching:
|
|
414
536
|
|
|
415
537
|
- **uv resolver**: 2-10x faster than pip-tools, handles large dependency trees efficiently
|
|
416
538
|
- **pip-tools resolver**: Reliable fallback, slower but widely compatible
|
|
417
539
|
- **Isolated execution**: Prevents project pollution while maintaining security
|
|
418
|
-
|
|
419
|
-
### Benchmarks
|
|
420
|
-
|
|
421
|
-
Typical performance on a project with 100+ dependencies:
|
|
422
|
-
|
|
423
|
-
- **Cold cache**: 15-30 seconds
|
|
424
|
-
- **Warm cache**: 2-5 seconds
|
|
425
|
-
- **Memory usage**: ~50MB peak
|
|
540
|
+
- **Resolution caching**: Eliminates repeated resolver calls for unchanged requirements
|
|
426
541
|
|
|
427
542
|
## Development
|
|
428
543
|
|
|
@@ -510,8 +625,9 @@ pysentry --verbose /path/to/project
|
|
|
510
625
|
# Check network connectivity
|
|
511
626
|
curl -I https://osv-vulnerabilities.storage.googleapis.com/
|
|
512
627
|
|
|
513
|
-
# Try with different
|
|
514
|
-
pysentry --
|
|
628
|
+
# Try with different or multiple sources
|
|
629
|
+
pysentry --sources pypi
|
|
630
|
+
pysentry --sources pypa,osv
|
|
515
631
|
```
|
|
516
632
|
|
|
517
633
|
**Slow requirements.txt resolution**
|
|
@@ -546,12 +662,43 @@ ls uv.lock poetry.lock pyproject.toml
|
|
|
546
662
|
**Performance Issues**
|
|
547
663
|
|
|
548
664
|
```bash
|
|
549
|
-
# Clear
|
|
550
|
-
rm -rf ~/.cache/pysentry
|
|
665
|
+
# Clear all caches and retry
|
|
666
|
+
rm -rf ~/.cache/pysentry # Linux
|
|
667
|
+
rm -rf ~/Library/Caches/pysentry # macOS
|
|
668
|
+
pysentry
|
|
669
|
+
|
|
670
|
+
# Clear only resolution cache (if vulnerability cache is working)
|
|
671
|
+
rm -rf ~/.cache/pysentry/dependency-resolution/ # Linux
|
|
672
|
+
rm -rf ~/Library/Caches/pysentry/dependency-resolution/ # macOS
|
|
551
673
|
pysentry
|
|
552
674
|
|
|
675
|
+
# Clear resolution cache via CLI
|
|
676
|
+
pysentry --clear-resolution-cache
|
|
677
|
+
|
|
553
678
|
# Use verbose mode to identify bottlenecks
|
|
554
679
|
pysentry --verbose
|
|
680
|
+
|
|
681
|
+
# Disable caching to isolate issues
|
|
682
|
+
pysentry --no-cache
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
**Resolution Cache Issues**
|
|
686
|
+
|
|
687
|
+
```bash
|
|
688
|
+
# Clear stale resolution cache after environment changes
|
|
689
|
+
pysentry --clear-resolution-cache
|
|
690
|
+
|
|
691
|
+
# Disable resolution cache if causing issues
|
|
692
|
+
pysentry --no-resolution-cache
|
|
693
|
+
|
|
694
|
+
# Extend cache TTL for stable environments
|
|
695
|
+
pysentry --resolution-cache-ttl 168 # 1 week
|
|
696
|
+
|
|
697
|
+
# Check cache usage with verbose output
|
|
698
|
+
pysentry --verbose # Shows cache hits/misses
|
|
699
|
+
|
|
700
|
+
# Force fresh resolution (ignores cache)
|
|
701
|
+
pysentry --clear-resolution-cache --no-resolution-cache
|
|
555
702
|
```
|
|
556
703
|
|
|
557
704
|
## Acknowledgments
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
pysentry/__init__.py,sha256=uSo2bKZNbcRd1bEXOzF3MuxrEapECowrIHG0t_DERa8,611
|
|
2
|
+
pysentry/_internal.cpython-38-darwin.so,sha256=_hv1FC4gV0-DVnxKlOjsbxUxurMxLwmZHuGMYPfxhmI,9935136
|
|
3
|
+
pysentry_rs-0.2.2.dist-info/METADATA,sha256=q5sPtpWGSajB12VZieJeNdCuLctHUe-fx9MZw-cQG8U,23331
|
|
4
|
+
pysentry_rs-0.2.2.dist-info/WHEEL,sha256=uCxAYGR8mh7ybiMWkA6Fu-BNUURLCTLWDXY7SKDjVCA,102
|
|
5
|
+
pysentry_rs-0.2.2.dist-info/entry_points.txt,sha256=3bJguekVEbXTn-ceDCWJaSIZScquPPP1Ux9TPVHHanE,44
|
|
6
|
+
pysentry_rs-0.2.2.dist-info/licenses/LICENSE,sha256=TAMtDCoJuavXz7pCEklrzjH55sdvsy5gKsXY9NsImwY,34878
|
|
7
|
+
pysentry_rs-0.2.2.dist-info/RECORD,,
|
pysentry/__main__.py
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
pysentry/__init__.py,sha256=kDa2q8nWFR120mhgRaTBxmI8Yxf26tsE5Pdk8tg35VI,5898
|
|
2
|
-
pysentry/__main__.py,sha256=FJdFFQuSE8TYsZtY_vb00oCE2nvq9hB6MhMLBxnn7Ns,117
|
|
3
|
-
pysentry/_internal.cpython-38-darwin.so,sha256=eKXsRzhbPWkYH8mo-hLrKE6Youz0cDuT9xWL6XSn-4w,6240736
|
|
4
|
-
pysentry_rs-0.2.0.dist-info/METADATA,sha256=JAISzKEXYsg9sS29nTxu1NwyVZVZp1_vCKpxdQ2jLhE,17816
|
|
5
|
-
pysentry_rs-0.2.0.dist-info/WHEEL,sha256=uCxAYGR8mh7ybiMWkA6Fu-BNUURLCTLWDXY7SKDjVCA,102
|
|
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
|