pysentry-rs 0.2.1__tar.gz → 0.2.3__tar.gz
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_rs-0.2.3/.github/workflows/benchmark.yml +156 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/Cargo.lock +75 -1
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/Cargo.toml +4 -1
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/PKG-INFO +147 -35
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/README.md +146 -34
- pysentry_rs-0.2.3/benchmarks/.gitignore +2 -0
- pysentry_rs-0.2.3/benchmarks/.python-version +1 -0
- pysentry_rs-0.2.3/benchmarks/README.md +3 -0
- pysentry_rs-0.2.3/benchmarks/main.py +111 -0
- pysentry_rs-0.2.3/benchmarks/pyproject.toml +12 -0
- pysentry_rs-0.2.3/benchmarks/src/benchmark_runner.py +364 -0
- pysentry_rs-0.2.3/benchmarks/src/performance_monitor.py +157 -0
- pysentry_rs-0.2.3/benchmarks/src/report_generator.py +222 -0
- pysentry_rs-0.2.3/benchmarks/src/tool_wrapper.py +347 -0
- pysentry_rs-0.2.3/benchmarks/test_data/large_requirements.txt +55 -0
- pysentry_rs-0.2.3/benchmarks/test_data/small_requirements.txt +10 -0
- pysentry_rs-0.2.3/benchmarks/uv.lock +1099 -0
- pysentry_rs-0.2.3/python/pysentry/__init__.py +24 -0
- pysentry_rs-0.2.3/src/cache/audit.rs +485 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/cache/storage.rs +5 -4
- pysentry_rs-0.2.1/src/main.rs → pysentry_rs-0.2.3/src/cli.rs +76 -378
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/dependency/resolvers/mod.rs +108 -29
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/dependency/resolvers/pip_tools.rs +187 -1
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/dependency/resolvers/uv.rs +211 -3
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/dependency/scanner.rs +1 -1
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/lib.rs +5 -1
- pysentry_rs-0.2.3/src/main.rs +67 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/parsers/mod.rs +1 -1
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/parsers/pyproject.rs +2 -2
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/parsers/requirements.rs +3 -3
- pysentry_rs-0.2.3/src/python.rs +87 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/types.rs +60 -0
- pysentry_rs-0.2.1/python/pysentry/__init__.py +0 -292
- pysentry_rs-0.2.1/python/pysentry/__main__.py +0 -6
- pysentry_rs-0.2.1/src/cache/audit.rs +0 -76
- pysentry_rs-0.2.1/src/python.rs +0 -486
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/.github/FUNDING.yml +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/.github/dependabot.yml +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/.github/workflows/ci.yml +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/.github/workflows/release.yml +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/.gitignore +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/.pre-commit-config.yaml +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/LICENSE +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/fixtures/requirements-tests/requirements-dev.txt +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/fixtures/requirements-tests/requirements.txt +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/fixtures/requirements-tests-vulnerable/requirements.txt +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/pyproject.toml +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/cache/mod.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/dependency/mod.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/error.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/output/mod.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/output/report.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/output/sarif.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/parsers/lock.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/parsers/poetry_lock.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/providers/mod.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/providers/osv.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/providers/pypa.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/providers/pypi.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/vulnerability/database.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/vulnerability/matcher.rs +0 -0
- {pysentry_rs-0.2.1 → pysentry_rs-0.2.3}/src/vulnerability/mod.rs +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
name: Benchmark Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
version:
|
|
10
|
+
description: "Version to benchmark (e.g., v0.2.3)"
|
|
11
|
+
required: true
|
|
12
|
+
default: "v0.2.3"
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
CARGO_TERM_COLOR: always
|
|
16
|
+
RUST_BACKTRACE: 1
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
benchmark:
|
|
20
|
+
name: Run Benchmarks
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
contents: write
|
|
24
|
+
pull-requests: write
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout code
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
|
|
32
|
+
- name: Extract version from tag
|
|
33
|
+
id: version
|
|
34
|
+
run: |
|
|
35
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
36
|
+
VERSION="${{ github.event.inputs.version }}"
|
|
37
|
+
else
|
|
38
|
+
VERSION="${{ github.ref_name }}"
|
|
39
|
+
fi
|
|
40
|
+
VERSION_CLEAN=${VERSION#v}
|
|
41
|
+
echo "version=${VERSION_CLEAN}" >> $GITHUB_OUTPUT
|
|
42
|
+
echo "version_with_v=${VERSION}" >> $GITHUB_OUTPUT
|
|
43
|
+
echo "branch_name=benchmark-${VERSION_CLEAN}" >> $GITHUB_OUTPUT
|
|
44
|
+
|
|
45
|
+
- name: Install system dependencies
|
|
46
|
+
run: |
|
|
47
|
+
sudo apt-get update
|
|
48
|
+
sudo apt-get install -y libssl-dev pkg-config
|
|
49
|
+
|
|
50
|
+
- name: Install Rust
|
|
51
|
+
uses: dtolnay/rust-toolchain@stable
|
|
52
|
+
|
|
53
|
+
- name: Cache cargo
|
|
54
|
+
uses: actions/cache@v4
|
|
55
|
+
with:
|
|
56
|
+
path: |
|
|
57
|
+
~/.cargo/registry/index/
|
|
58
|
+
~/.cargo/registry/cache/
|
|
59
|
+
~/.cargo/git/db/
|
|
60
|
+
target
|
|
61
|
+
key: ${{ runner.os }}-cargo-benchmark-${{ hashFiles('**/Cargo.lock') }}
|
|
62
|
+
restore-keys: |
|
|
63
|
+
${{ runner.os }}-cargo-benchmark-
|
|
64
|
+
${{ runner.os }}-cargo-build-
|
|
65
|
+
|
|
66
|
+
- name: Build PySentry
|
|
67
|
+
run: cargo build --release
|
|
68
|
+
|
|
69
|
+
- name: Set up Python
|
|
70
|
+
uses: actions/setup-python@v5
|
|
71
|
+
with:
|
|
72
|
+
python-version: "3.11"
|
|
73
|
+
|
|
74
|
+
- name: Install uv
|
|
75
|
+
run: |
|
|
76
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
77
|
+
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
78
|
+
|
|
79
|
+
- name: Install pip-audit for benchmark comparison
|
|
80
|
+
run: pip install pip-audit
|
|
81
|
+
|
|
82
|
+
- name: Install benchmark dependencies
|
|
83
|
+
run: |
|
|
84
|
+
cd benchmarks
|
|
85
|
+
uv sync
|
|
86
|
+
|
|
87
|
+
- name: Run benchmark suite
|
|
88
|
+
run: |
|
|
89
|
+
cd benchmarks
|
|
90
|
+
uv run python main.py --skip-build
|
|
91
|
+
|
|
92
|
+
ls -la results/
|
|
93
|
+
|
|
94
|
+
LATEST_FILE=$(ls results/*.md 2>/dev/null | sort -r | head -n 1)
|
|
95
|
+
if [ -f "$LATEST_FILE" ]; then
|
|
96
|
+
cp "$LATEST_FILE" results/latest.md
|
|
97
|
+
echo "Created latest.md from: $LATEST_FILE"
|
|
98
|
+
else
|
|
99
|
+
echo "Warning: No benchmark files found to create latest.md"
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
- name: Configure Git
|
|
103
|
+
run: |
|
|
104
|
+
git config --global user.name "github-actions[bot]"
|
|
105
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
106
|
+
|
|
107
|
+
- name: Create and switch to benchmark branch
|
|
108
|
+
run: |
|
|
109
|
+
BRANCH_NAME="${{ steps.version.outputs.branch_name }}"
|
|
110
|
+
git checkout -b $BRANCH_NAME
|
|
111
|
+
|
|
112
|
+
- name: Commit benchmark results
|
|
113
|
+
run: |
|
|
114
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
115
|
+
|
|
116
|
+
git add benchmarks/results/
|
|
117
|
+
|
|
118
|
+
if git diff --staged --quiet; then
|
|
119
|
+
echo "No changes to commit"
|
|
120
|
+
exit 0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
git commit -m "Add benchmark results for version ${VERSION}"
|
|
124
|
+
|
|
125
|
+
- name: Push benchmark branch
|
|
126
|
+
run: |
|
|
127
|
+
BRANCH_NAME="${{ steps.version.outputs.branch_name }}"
|
|
128
|
+
git push origin $BRANCH_NAME
|
|
129
|
+
|
|
130
|
+
- name: Create Pull Request
|
|
131
|
+
env:
|
|
132
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
133
|
+
run: |
|
|
134
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
135
|
+
BRANCH_NAME="${{ steps.version.outputs.branch_name }}"
|
|
136
|
+
|
|
137
|
+
PR_BODY="This PR contains automated benchmark results comparing PySentry v${VERSION} against pip-audit."
|
|
138
|
+
|
|
139
|
+
gh pr create \
|
|
140
|
+
--title "Benchmark results for v${VERSION}" \
|
|
141
|
+
--body "$PR_BODY" \
|
|
142
|
+
--base main \
|
|
143
|
+
--head $BRANCH_NAME \
|
|
144
|
+
--label "benchmark,automated"
|
|
145
|
+
|
|
146
|
+
- name: Summary
|
|
147
|
+
run: |
|
|
148
|
+
VERSION="${{ steps.version.outputs.version }}"
|
|
149
|
+
BRANCH_NAME="${{ steps.version.outputs.branch_name }}"
|
|
150
|
+
|
|
151
|
+
echo "Benchmark workflow completed successfully!"
|
|
152
|
+
echo ""
|
|
153
|
+
echo "Benchmarked version: v${VERSION}"
|
|
154
|
+
echo "Created branch: ${BRANCH_NAME}"
|
|
155
|
+
echo "Results location: benchmarks/results/"
|
|
156
|
+
echo "Pull request created automatically"
|
|
@@ -150,6 +150,15 @@ version = "2.9.1"
|
|
|
150
150
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
151
151
|
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
|
152
152
|
|
|
153
|
+
[[package]]
|
|
154
|
+
name = "block-buffer"
|
|
155
|
+
version = "0.10.4"
|
|
156
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
157
|
+
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
|
158
|
+
dependencies = [
|
|
159
|
+
"generic-array",
|
|
160
|
+
]
|
|
161
|
+
|
|
153
162
|
[[package]]
|
|
154
163
|
name = "bumpalo"
|
|
155
164
|
version = "3.19.0"
|
|
@@ -250,6 +259,15 @@ version = "0.8.7"
|
|
|
250
259
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
251
260
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|
252
261
|
|
|
262
|
+
[[package]]
|
|
263
|
+
name = "cpufeatures"
|
|
264
|
+
version = "0.2.17"
|
|
265
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
266
|
+
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
|
267
|
+
dependencies = [
|
|
268
|
+
"libc",
|
|
269
|
+
]
|
|
270
|
+
|
|
253
271
|
[[package]]
|
|
254
272
|
name = "crc32fast"
|
|
255
273
|
version = "1.5.0"
|
|
@@ -259,6 +277,16 @@ dependencies = [
|
|
|
259
277
|
"cfg-if",
|
|
260
278
|
]
|
|
261
279
|
|
|
280
|
+
[[package]]
|
|
281
|
+
name = "crypto-common"
|
|
282
|
+
version = "0.1.6"
|
|
283
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
284
|
+
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
|
285
|
+
dependencies = [
|
|
286
|
+
"generic-array",
|
|
287
|
+
"typenum",
|
|
288
|
+
]
|
|
289
|
+
|
|
262
290
|
[[package]]
|
|
263
291
|
name = "derive_arbitrary"
|
|
264
292
|
version = "1.4.1"
|
|
@@ -270,6 +298,16 @@ dependencies = [
|
|
|
270
298
|
"syn",
|
|
271
299
|
]
|
|
272
300
|
|
|
301
|
+
[[package]]
|
|
302
|
+
name = "digest"
|
|
303
|
+
version = "0.10.7"
|
|
304
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
305
|
+
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
|
306
|
+
dependencies = [
|
|
307
|
+
"block-buffer",
|
|
308
|
+
"crypto-common",
|
|
309
|
+
]
|
|
310
|
+
|
|
273
311
|
[[package]]
|
|
274
312
|
name = "dirs"
|
|
275
313
|
version = "6.0.0"
|
|
@@ -448,6 +486,16 @@ dependencies = [
|
|
|
448
486
|
"slab",
|
|
449
487
|
]
|
|
450
488
|
|
|
489
|
+
[[package]]
|
|
490
|
+
name = "generic-array"
|
|
491
|
+
version = "0.14.7"
|
|
492
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
493
|
+
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
|
494
|
+
dependencies = [
|
|
495
|
+
"typenum",
|
|
496
|
+
"version_check",
|
|
497
|
+
]
|
|
498
|
+
|
|
451
499
|
[[package]]
|
|
452
500
|
name = "getrandom"
|
|
453
501
|
version = "0.2.16"
|
|
@@ -1067,7 +1115,7 @@ dependencies = [
|
|
|
1067
1115
|
|
|
1068
1116
|
[[package]]
|
|
1069
1117
|
name = "pysentry"
|
|
1070
|
-
version = "0.2.
|
|
1118
|
+
version = "0.2.3"
|
|
1071
1119
|
dependencies = [
|
|
1072
1120
|
"anyhow",
|
|
1073
1121
|
"async-trait",
|
|
@@ -1078,10 +1126,13 @@ dependencies = [
|
|
|
1078
1126
|
"futures",
|
|
1079
1127
|
"pep440_rs",
|
|
1080
1128
|
"pyo3",
|
|
1129
|
+
"regex",
|
|
1081
1130
|
"reqwest",
|
|
1131
|
+
"rustc-hash",
|
|
1082
1132
|
"serde",
|
|
1083
1133
|
"serde_json",
|
|
1084
1134
|
"serde_yaml",
|
|
1135
|
+
"sha2",
|
|
1085
1136
|
"tempfile",
|
|
1086
1137
|
"thiserror",
|
|
1087
1138
|
"tokio",
|
|
@@ -1438,6 +1489,17 @@ dependencies = [
|
|
|
1438
1489
|
"unsafe-libyaml",
|
|
1439
1490
|
]
|
|
1440
1491
|
|
|
1492
|
+
[[package]]
|
|
1493
|
+
name = "sha2"
|
|
1494
|
+
version = "0.10.9"
|
|
1495
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1496
|
+
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
|
1497
|
+
dependencies = [
|
|
1498
|
+
"cfg-if",
|
|
1499
|
+
"cpufeatures",
|
|
1500
|
+
"digest",
|
|
1501
|
+
]
|
|
1502
|
+
|
|
1441
1503
|
[[package]]
|
|
1442
1504
|
name = "sharded-slab"
|
|
1443
1505
|
version = "0.1.7"
|
|
@@ -1826,6 +1888,12 @@ version = "0.2.5"
|
|
|
1826
1888
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1827
1889
|
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
|
1828
1890
|
|
|
1891
|
+
[[package]]
|
|
1892
|
+
name = "typenum"
|
|
1893
|
+
version = "1.18.0"
|
|
1894
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1895
|
+
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
|
1896
|
+
|
|
1829
1897
|
[[package]]
|
|
1830
1898
|
name = "unicode-ident"
|
|
1831
1899
|
version = "1.0.18"
|
|
@@ -1891,6 +1959,12 @@ version = "0.1.1"
|
|
|
1891
1959
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1892
1960
|
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
|
1893
1961
|
|
|
1962
|
+
[[package]]
|
|
1963
|
+
name = "version_check"
|
|
1964
|
+
version = "0.9.5"
|
|
1965
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1966
|
+
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|
1967
|
+
|
|
1894
1968
|
[[package]]
|
|
1895
1969
|
name = "want"
|
|
1896
1970
|
version = "0.3.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "pysentry"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
rust-version = "1.79"
|
|
6
6
|
description = "Security vulnerability auditing for Python packages"
|
|
@@ -31,10 +31,13 @@ fs-err = "3.1.1"
|
|
|
31
31
|
futures = "0.3.31"
|
|
32
32
|
pep440_rs = "0.7.3"
|
|
33
33
|
pyo3 = { version = "0.25.1", features = ["extension-module"], optional = true }
|
|
34
|
+
regex = "1.11.1"
|
|
34
35
|
reqwest = { version = "0.12.22", features = ["json", "stream", "rustls-tls"], default-features = false }
|
|
36
|
+
rustc-hash = "2.1.1"
|
|
35
37
|
serde = { version = "1.0.219", features = ["derive"] }
|
|
36
38
|
serde_json = "1.0.142"
|
|
37
39
|
serde_yaml = "0.9.34"
|
|
40
|
+
sha2 = "0.10.9"
|
|
38
41
|
tempfile = "3.20.0"
|
|
39
42
|
thiserror = "2.0.12"
|
|
40
43
|
tokio = { version = "1.47.1", features = ["fs", "io-util", "rt-multi-thread", "macros", "process"] }
|
|
@@ -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
|