pysentry-rs 0.2.1__cp312-cp312-macosx_11_0_arm64.whl → 0.2.3__cp312-cp312-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 -276
- pysentry/_internal.cpython-312-darwin.so +0 -0
- {pysentry_rs-0.2.1.dist-info → pysentry_rs-0.2.3.dist-info}/METADATA +147 -35
- pysentry_rs-0.2.3.dist-info/RECORD +7 -0
- pysentry/__main__.py +0 -6
- pysentry_rs-0.2.1.dist-info/RECORD +0 -8
- {pysentry_rs-0.2.1.dist-info → pysentry_rs-0.2.3.dist-info}/WHEEL +0 -0
- {pysentry_rs-0.2.1.dist-info → pysentry_rs-0.2.3.dist-info}/entry_points.txt +0 -0
- {pysentry_rs-0.2.1.dist-info → pysentry_rs-0.2.3.dist-info}/licenses/LICENSE +0 -0
pysentry/__init__.py
CHANGED
|
@@ -1,287 +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
|
-
]
|
|
13
|
-
|
|
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
|
|
5
|
+
__version__ = get_version()
|
|
6
|
+
__all__ = ["get_version", "run_cli", "main"]
|
|
50
7
|
|
|
51
8
|
|
|
52
9
|
def main():
|
|
53
|
-
"""CLI entry point."""
|
|
10
|
+
"""CLI entry point that provides the exact same interface as the Rust binary."""
|
|
54
11
|
import sys
|
|
55
|
-
import argparse
|
|
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
|
-
|
|
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
|
-
)
|
|
94
|
-
|
|
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
|
|
103
|
-
|
|
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
|
|
130
|
-
parser = argparse.ArgumentParser(
|
|
131
|
-
prog="pysentry-rs",
|
|
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__}"
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
# Main audit arguments
|
|
142
|
-
parser.add_argument(
|
|
143
|
-
"path",
|
|
144
|
-
nargs="?",
|
|
145
|
-
default=".",
|
|
146
|
-
metavar="PATH",
|
|
147
|
-
help="Path to the project directory to audit [default: .]",
|
|
148
|
-
)
|
|
149
|
-
parser.add_argument(
|
|
150
|
-
"--format",
|
|
151
|
-
choices=["human", "json", "sarif", "markdown"],
|
|
152
|
-
default="human",
|
|
153
|
-
help="Output format [default: human] [possible values: human, json, sarif, markdown]",
|
|
154
|
-
)
|
|
155
|
-
parser.add_argument(
|
|
156
|
-
"--severity",
|
|
157
|
-
choices=["low", "medium", "high", "critical"],
|
|
158
|
-
default="low",
|
|
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]",
|
|
166
|
-
)
|
|
167
|
-
parser.add_argument(
|
|
168
|
-
"--ignore",
|
|
169
|
-
action="append",
|
|
170
|
-
dest="ignore_ids",
|
|
171
|
-
metavar="ID",
|
|
172
|
-
help="Vulnerability IDs to ignore (can be specified multiple times)",
|
|
173
|
-
)
|
|
174
|
-
parser.add_argument(
|
|
175
|
-
"-o", "--output", metavar="FILE", help="Output file path (defaults to stdout)"
|
|
176
|
-
)
|
|
177
|
-
parser.add_argument(
|
|
178
|
-
"--all",
|
|
179
|
-
action="store_true",
|
|
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)",
|
|
186
|
-
)
|
|
187
|
-
parser.add_argument(
|
|
188
|
-
"--direct-only",
|
|
189
|
-
action="store_true",
|
|
190
|
-
help="Only check direct dependencies (exclude transitive)",
|
|
191
|
-
)
|
|
192
|
-
parser.add_argument("--no-cache", action="store_true", help="Disable caching")
|
|
193
|
-
parser.add_argument("--cache-dir", metavar="DIR", help="Custom cache directory")
|
|
194
|
-
parser.add_argument(
|
|
195
|
-
"--source",
|
|
196
|
-
choices=["pypa", "pypi", "osv"],
|
|
197
|
-
default="pypa",
|
|
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)",
|
|
204
|
-
)
|
|
205
|
-
parser.add_argument(
|
|
206
|
-
"--resolver",
|
|
207
|
-
choices=["uv", "pip-tools"],
|
|
208
|
-
default="uv",
|
|
209
|
-
help="Dependency resolver for requirements.txt files [default: uv] [possible values: uv, pip-tools]",
|
|
210
|
-
)
|
|
211
|
-
parser.add_argument(
|
|
212
|
-
"--requirements-files",
|
|
213
|
-
nargs="+",
|
|
214
|
-
metavar="FILE",
|
|
215
|
-
help="Specific requirements files to audit (disables auto-discovery)",
|
|
216
|
-
)
|
|
217
|
-
parser.add_argument(
|
|
218
|
-
"-v", "--verbose", action="store_true", help="Enable verbose output"
|
|
219
|
-
)
|
|
220
|
-
parser.add_argument(
|
|
221
|
-
"-q", "--quiet", action="store_true", help="Suppress non-error output"
|
|
222
|
-
)
|
|
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
|
-
|
|
232
|
-
args = parser.parse_args()
|
|
233
12
|
|
|
234
13
|
try:
|
|
235
|
-
#
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
optional = include_all
|
|
239
|
-
|
|
240
|
-
resolved_sources = resolve_sources(
|
|
241
|
-
args.source, getattr(args, "sources", None) or []
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
result = audit_with_options(
|
|
245
|
-
path=args.path,
|
|
246
|
-
format=args.format,
|
|
247
|
-
sources=resolved_sources,
|
|
248
|
-
min_severity=args.severity,
|
|
249
|
-
ignore_ids=args.ignore_ids,
|
|
250
|
-
output=args.output,
|
|
251
|
-
dev=dev,
|
|
252
|
-
optional=optional,
|
|
253
|
-
direct_only=args.direct_only,
|
|
254
|
-
no_cache=args.no_cache,
|
|
255
|
-
cache_dir=args.cache_dir,
|
|
256
|
-
resolver=args.resolver,
|
|
257
|
-
requirements_files=args.requirements_files,
|
|
258
|
-
verbose=args.verbose,
|
|
259
|
-
quiet=args.quiet,
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
if not args.output:
|
|
263
|
-
print(result)
|
|
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
|
|
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)
|
|
285
17
|
|
|
286
18
|
except Exception as e:
|
|
287
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.3
|
|
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)
|
|
@@ -48,7 +48,7 @@ PySentry audits Python projects for known security vulnerabilities by analyzing
|
|
|
48
48
|
- **Performance Focused**:
|
|
49
49
|
- Written in Rust for speed
|
|
50
50
|
- Async/concurrent processing
|
|
51
|
-
-
|
|
51
|
+
- Multi-tier intelligent caching (vulnerability data + resolved dependencies)
|
|
52
52
|
- **Comprehensive Filtering**:
|
|
53
53
|
- Severity levels (low, medium, high, critical)
|
|
54
54
|
- Dependency scopes (main only vs all [optional, dev, prod, etc] dependencies)
|
|
@@ -254,6 +254,12 @@ pysentry /path/to/project
|
|
|
254
254
|
|
|
255
255
|
# Debug requirements.txt resolution
|
|
256
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
|
|
257
263
|
```
|
|
258
264
|
|
|
259
265
|
### CI/CD Integration Examples
|
|
@@ -273,42 +279,115 @@ pysentry --format markdown --output SECURITY-REPORT.md
|
|
|
273
279
|
|
|
274
280
|
# Comprehensive audit with all sources and full reporting
|
|
275
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
|
|
276
288
|
```
|
|
277
289
|
|
|
278
290
|
## Configuration
|
|
279
291
|
|
|
280
292
|
### Command Line Options
|
|
281
293
|
|
|
282
|
-
| Option
|
|
283
|
-
|
|
|
284
|
-
| `--format`
|
|
285
|
-
| `--severity`
|
|
286
|
-
| `--fail-on`
|
|
287
|
-
| `--sources`
|
|
288
|
-
| `--all-extras`
|
|
289
|
-
| `--direct-only`
|
|
290
|
-
| `--ignore`
|
|
291
|
-
| `--output`
|
|
292
|
-
| `--no-cache`
|
|
293
|
-
| `--cache-dir`
|
|
294
|
-
| `--
|
|
295
|
-
| `--
|
|
296
|
-
| `--
|
|
297
|
-
| `--
|
|
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) | `[]` |
|
|
298
313
|
|
|
299
314
|
### Cache Management
|
|
300
315
|
|
|
301
|
-
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
|
|
302
342
|
|
|
303
|
-
- **Default Location**: `~/.cache/pysentry/` (or system temp directory)
|
|
304
|
-
- **TTL-based Expiration**: Separate expiration for each vulnerability source
|
|
305
343
|
- **Atomic Updates**: Prevents cache corruption during concurrent access
|
|
306
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
|
|
307
347
|
|
|
308
|
-
|
|
348
|
+
#### Cache Control Examples
|
|
309
349
|
|
|
310
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
|
|
311
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"
|
|
312
391
|
```
|
|
313
392
|
|
|
314
393
|
## Supported Project Formats
|
|
@@ -437,26 +516,28 @@ Compatible with GitHub Security tab, VS Code, and other security tools.
|
|
|
437
516
|
|
|
438
517
|
PySentry is designed for speed and efficiency:
|
|
439
518
|
|
|
440
|
-
- **Concurrent Processing**: Vulnerability data fetched in parallel
|
|
441
|
-
- **
|
|
519
|
+
- **Concurrent Processing**: Vulnerability data fetched in parallel from multiple sources
|
|
520
|
+
- **Multi-tier Caching**: Intelligent caching for both vulnerability data and resolved dependencies
|
|
442
521
|
- **Efficient Matching**: In-memory indexing for fast vulnerability lookups
|
|
443
522
|
- **Streaming**: Large databases processed without excessive memory usage
|
|
444
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
|
+
|
|
445
533
|
### Requirements.txt Resolution Performance
|
|
446
534
|
|
|
447
|
-
PySentry leverages external resolvers
|
|
535
|
+
PySentry leverages external resolvers with intelligent caching:
|
|
448
536
|
|
|
449
537
|
- **uv resolver**: 2-10x faster than pip-tools, handles large dependency trees efficiently
|
|
450
538
|
- **pip-tools resolver**: Reliable fallback, slower but widely compatible
|
|
451
539
|
- **Isolated execution**: Prevents project pollution while maintaining security
|
|
452
|
-
|
|
453
|
-
### Benchmarks
|
|
454
|
-
|
|
455
|
-
Typical performance on a project with 100+ dependencies:
|
|
456
|
-
|
|
457
|
-
- **Cold cache**: 15-30 seconds
|
|
458
|
-
- **Warm cache**: 2-5 seconds
|
|
459
|
-
- **Memory usage**: ~50MB peak
|
|
540
|
+
- **Resolution caching**: Eliminates repeated resolver calls for unchanged requirements
|
|
460
541
|
|
|
461
542
|
## Development
|
|
462
543
|
|
|
@@ -581,12 +662,43 @@ ls uv.lock poetry.lock pyproject.toml
|
|
|
581
662
|
**Performance Issues**
|
|
582
663
|
|
|
583
664
|
```bash
|
|
584
|
-
# Clear
|
|
585
|
-
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
|
|
586
673
|
pysentry
|
|
587
674
|
|
|
675
|
+
# Clear resolution cache via CLI
|
|
676
|
+
pysentry --clear-resolution-cache
|
|
677
|
+
|
|
588
678
|
# Use verbose mode to identify bottlenecks
|
|
589
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
|
|
590
702
|
```
|
|
591
703
|
|
|
592
704
|
## Acknowledgments
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
pysentry/__init__.py,sha256=uSo2bKZNbcRd1bEXOzF3MuxrEapECowrIHG0t_DERa8,611
|
|
2
|
+
pysentry/_internal.cpython-312-darwin.so,sha256=jT7E9SqV9s_203NLWxLQIE7nr6p1LjapKzuNRPfZzGY,9914288
|
|
3
|
+
pysentry_rs-0.2.3.dist-info/METADATA,sha256=M4mpNvGbc6jGKlNISGy8uSCNu6YP5Dhtj0zCqItW4XU,23331
|
|
4
|
+
pysentry_rs-0.2.3.dist-info/WHEEL,sha256=EhaWXx4fd8VOPM6W-6pxsePGk73OLk2gBi7fwS90pc8,104
|
|
5
|
+
pysentry_rs-0.2.3.dist-info/entry_points.txt,sha256=3bJguekVEbXTn-ceDCWJaSIZScquPPP1Ux9TPVHHanE,44
|
|
6
|
+
pysentry_rs-0.2.3.dist-info/licenses/LICENSE,sha256=TAMtDCoJuavXz7pCEklrzjH55sdvsy5gKsXY9NsImwY,34878
|
|
7
|
+
pysentry_rs-0.2.3.dist-info/RECORD,,
|
pysentry/__main__.py
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
pysentry/__init__.py,sha256=7j3_zsnLLnKCaLgYXDrW3xm4AkmbE-ofoa5PX-79rGY,9792
|
|
2
|
-
pysentry/__main__.py,sha256=FJdFFQuSE8TYsZtY_vb00oCE2nvq9hB6MhMLBxnn7Ns,117
|
|
3
|
-
pysentry/_internal.cpython-312-darwin.so,sha256=L3Wj75JqyRRyimBY1qOIIqvLaciC5Q2a9sr5-bCp7dM,6376080
|
|
4
|
-
pysentry_rs-0.2.1.dist-info/METADATA,sha256=4_2U3eoQuhETKDwaZVXbCqW9OGpUmzWhDTx2ppNn-Vw,19333
|
|
5
|
-
pysentry_rs-0.2.1.dist-info/WHEEL,sha256=EhaWXx4fd8VOPM6W-6pxsePGk73OLk2gBi7fwS90pc8,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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|