pysentry-rs 0.1.4__cp311-cp311-macosx_11_0_arm64.whl → 0.2.0__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 CHANGED
@@ -2,8 +2,14 @@
2
2
 
3
3
  from ._internal import audit_python, audit_with_options, check_resolvers, check_version
4
4
 
5
- __version__ = "0.1.4"
6
- __all__ = ["audit_python", "audit_with_options", "check_resolvers", "check_version", "main"]
5
+ __version__ = "0.2.0"
6
+ __all__ = [
7
+ "audit_python",
8
+ "audit_with_options",
9
+ "check_resolvers",
10
+ "check_version",
11
+ "main",
12
+ ]
7
13
 
8
14
 
9
15
  def main():
@@ -11,73 +17,83 @@ def main():
11
17
  import sys
12
18
  import argparse
13
19
 
14
- # Handle the case where first argument is 'resolvers'
15
- if len(sys.argv) > 1 and sys.argv[1] == "resolvers":
16
- # Parse resolvers subcommand
17
- parser = argparse.ArgumentParser(
18
- prog="pysentry-rs resolvers",
19
- description="Check available dependency resolvers",
20
- )
21
- parser.add_argument(
22
- "--verbose", "-v", action="store_true", help="Enable verbose output"
23
- )
24
-
25
- # Remove 'resolvers' from args and parse the rest
26
- args = parser.parse_args(sys.argv[2:])
27
-
28
- try:
29
- result = check_resolvers(args.verbose)
30
- print(result)
31
- except Exception as e:
32
- print(f"Error: {e}", file=sys.stderr)
33
- sys.exit(1)
34
- return
35
-
36
- # Handle the case where first argument is 'check-version'
37
- if len(sys.argv) > 1 and sys.argv[1] == "check-version":
38
- # Parse check-version subcommand
39
- parser = argparse.ArgumentParser(
40
- prog="pysentry-rs check-version",
41
- description="Check if a newer version is available",
42
- )
43
- parser.add_argument(
44
- "--verbose", "-v", action="store_true", help="Enable verbose output"
45
- )
46
-
47
- # Remove 'check-version' from args and parse the rest
48
- args = parser.parse_args(sys.argv[2:])
49
-
50
- try:
51
- result = check_version(args.verbose)
52
- print(result)
53
- except Exception as e:
54
- print(f"Error: {e}", file=sys.stderr)
55
- sys.exit(1)
56
- return
57
-
58
- # Default audit command parser
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
59
67
  parser = argparse.ArgumentParser(
60
68
  prog="pysentry-rs",
61
69
  description="Security vulnerability auditing for Python packages",
70
+ usage="pysentry-rs [OPTIONS] [PATH] [COMMAND]",
62
71
  )
63
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
64
79
  parser.add_argument(
65
80
  "path",
66
81
  nargs="?",
67
82
  default=".",
68
- help="Path to the project directory to audit (default: current directory)",
83
+ metavar="PATH",
84
+ help="Path to the project directory to audit [default: .]",
69
85
  )
70
86
  parser.add_argument(
71
87
  "--format",
72
88
  choices=["human", "json", "sarif"],
73
89
  default="human",
74
- help="Output format (default: human)",
90
+ help="Output format [default: human] [possible values: human, json, sarif]",
75
91
  )
76
92
  parser.add_argument(
77
93
  "--severity",
78
94
  choices=["low", "medium", "high", "critical"],
79
95
  default="low",
80
- help="Minimum severity level to report (default: low)",
96
+ help="Minimum severity level to report [default: low] [possible values: low, medium, high, critical]",
81
97
  )
82
98
  parser.add_argument(
83
99
  "--ignore",
@@ -87,13 +103,12 @@ def main():
87
103
  help="Vulnerability IDs to ignore (can be specified multiple times)",
88
104
  )
89
105
  parser.add_argument(
90
- "--output", "-o", metavar="FILE", help="Output file path (defaults to stdout)"
106
+ "-o", "--output", metavar="FILE", help="Output file path (defaults to stdout)"
91
107
  )
92
108
  parser.add_argument(
93
- "--dev", action="store_true", help="Include development dependencies"
94
- )
95
- parser.add_argument(
96
- "--optional", action="store_true", help="Include optional dependencies"
109
+ "--all",
110
+ action="store_true",
111
+ help="Include ALL dependencies (main + dev, optional, etc)",
97
112
  )
98
113
  parser.add_argument(
99
114
  "--direct-only",
@@ -106,13 +121,13 @@ def main():
106
121
  "--source",
107
122
  choices=["pypa", "pypi", "osv"],
108
123
  default="pypa",
109
- help="Vulnerability data source (default: pypa)",
124
+ help="Vulnerability data source [default: pypa] [possible values: pypa, pypi, osv]",
110
125
  )
111
126
  parser.add_argument(
112
127
  "--resolver",
113
128
  choices=["uv", "pip-tools"],
114
129
  default="uv",
115
- help="Dependency resolver for requirements.txt files (default: uv)",
130
+ help="Dependency resolver for requirements.txt files [default: uv] [possible values: uv, pip-tools]",
116
131
  )
117
132
  parser.add_argument(
118
133
  "--requirements-files",
@@ -121,16 +136,27 @@ def main():
121
136
  help="Specific requirements files to audit (disables auto-discovery)",
122
137
  )
123
138
  parser.add_argument(
124
- "--verbose", "-v", action="store_true", help="Enable verbose output"
139
+ "-v", "--verbose", action="store_true", help="Enable verbose output"
125
140
  )
126
141
  parser.add_argument(
127
- "--quiet", "-q", action="store_true", help="Suppress non-error output"
142
+ "-q", "--quiet", action="store_true", help="Suppress non-error output"
128
143
  )
129
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
+
130
153
  args = parser.parse_args()
131
154
 
132
155
  try:
133
- # Main audit functionality
156
+ # Main audit functionality - convert --all to dev/optional
157
+ dev = args.all
158
+ optional = args.all
159
+
134
160
  result = audit_with_options(
135
161
  path=args.path,
136
162
  format=args.format,
@@ -138,8 +164,8 @@ def main():
138
164
  min_severity=args.severity,
139
165
  ignore_ids=args.ignore_ids,
140
166
  output=args.output,
141
- dev=args.dev,
142
- optional=args.optional,
167
+ dev=dev,
168
+ optional=optional,
143
169
  direct_only=args.direct_only,
144
170
  no_cache=args.no_cache,
145
171
  cache_dir=args.cache_dir,
Binary file
@@ -0,0 +1,562 @@
1
+ Metadata-Version: 2.4
2
+ Name: pysentry-rs
3
+ Version: 0.2.0
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
7
+ Classifier: Programming Language :: Rust
8
+ Classifier: Programming Language :: Python :: Implementation :: CPython
9
+ Classifier: Programming Language :: Python :: 3.8
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Security
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ License-File: LICENSE
18
+ Summary: Security vulnerability auditing tool for Python packages
19
+ Author-email: nyudenkov <nyudenkov@pm.me>
20
+ License: GPL-3.0
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
23
+ Project-URL: Homepage, https://github.com/nyudenkov/pysentry
24
+ Project-URL: Repository, https://github.com/nyudenkov/pysentry
25
+ Project-URL: Issues, https://github.com/nyudenkov/pysentry/issues
26
+
27
+ # 🐍 PySentry
28
+
29
+ [Help to test and improve](https://github.com/nyudenkov/pysentry/issues/12)
30
+
31
+ A fast, reliable security vulnerability scanner for Python projects, written in Rust.
32
+
33
+ ## Overview
34
+
35
+ PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `pyproject.toml`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
36
+
37
+ ## Key Features
38
+
39
+ - **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `pyproject.toml`, and `requirements.txt` files
40
+ - **External Resolver Integration**: Leverages `uv` and `pip-tools` for accurate requirements.txt constraint solving
41
+ - **Multiple Data Sources**:
42
+ - PyPA Advisory Database (default)
43
+ - PyPI JSON API
44
+ - OSV.dev (Open Source Vulnerabilities)
45
+ - **Flexible Output**: Human-readable, JSON, and SARIF formats
46
+ - **Performance Focused**:
47
+ - Written in Rust for speed
48
+ - Async/concurrent processing
49
+ - Intelligent caching system
50
+ - **Comprehensive Filtering**:
51
+ - Severity levels (low, medium, high, critical)
52
+ - Dependency scopes (main only vs all [optional, dev, prod, etc] dependencies)
53
+ - Direct vs. transitive dependencies
54
+ - **Enterprise Ready**: SARIF output for IDE/CI integration
55
+
56
+ ## Installation
57
+
58
+ Choose the installation method that works best for you:
59
+
60
+ ### ⚡ Via uvx (Recommended for occasional use)
61
+
62
+ Run directly without installing (requires [uv](https://docs.astral.sh/uv/)):
63
+
64
+ ```bash
65
+ uvx pysentry-rs /path/to/project
66
+ ```
67
+
68
+ This method:
69
+
70
+ - Runs the latest version without installation
71
+ - Automatically manages Python environment
72
+ - Perfect for CI/CD or occasional security audits
73
+ - No need to manage package versions or updates
74
+
75
+ ### 📦 From PyPI (Python Package)
76
+
77
+ For Python 3.8+ on Linux and macOS:
78
+
79
+ ```bash
80
+ pip install pysentry-rs
81
+ ```
82
+
83
+ Then use it with Python:
84
+
85
+ ```bash
86
+ python -m pysentry /path/to/project
87
+ # or directly if scripts are in PATH
88
+ pysentry-rs /path/to/project
89
+ ```
90
+
91
+ ### ⚡ From Crates.io (Rust Package)
92
+
93
+ If you have Rust installed:
94
+
95
+ ```bash
96
+ cargo install pysentry
97
+ ```
98
+
99
+ ### 💾 From GitHub Releases (Pre-built Binaries)
100
+
101
+ Download the latest release for your platform:
102
+
103
+ - **Linux x64**: `pysentry-linux-x64.tar.gz`
104
+ - **Linux x64 (musl)**: `pysentry-linux-x64-musl.tar.gz`
105
+ - **Linux ARM64**: `pysentry-linux-arm64.tar.gz`
106
+ - **macOS x64**: `pysentry-macos-x64.tar.gz`
107
+ - **macOS ARM64**: `pysentry-macos-arm64.tar.gz`
108
+ - **Windows x64**: `pysentry-windows-x64.zip`
109
+
110
+ ```bash
111
+ # Example for Linux x64
112
+ curl -L https://github.com/nyudenkov/pysentry/releases/latest/download/pysentry-linux-x64.tar.gz | tar -xz
113
+ ./pysentry-linux-x64/pysentry --help
114
+ ```
115
+
116
+ ### 🔧 From Source
117
+
118
+ ```bash
119
+ git clone https://github.com/nyudenkov/pysentry
120
+ cd pysentry
121
+ cargo build --release
122
+ ```
123
+
124
+ The binary will be available at `target/release/pysentry`.
125
+
126
+ ### Requirements
127
+
128
+ - **For uvx**: Python 3.8+ and [uv](https://docs.astral.sh/uv/) installed (Linux/macOS only)
129
+ - **For binaries**: No additional dependencies
130
+ - **For Python package**: Python 3.8+ (Linux/macOS only)
131
+ - **For Rust package and source**: Rust 1.79+
132
+
133
+ ### Platform Support
134
+
135
+ | Installation Method | Linux | macOS | Windows |
136
+ | ------------------- | ----- | ----- | ------- |
137
+ | uvx | ✅ | ✅ | ❌ |
138
+ | PyPI (pip) | ✅ | ✅ | ❌ |
139
+ | Crates.io (cargo) | ✅ | ✅ | ✅ |
140
+ | GitHub Releases | ✅ | ✅ | ✅ |
141
+ | From Source | ✅ | ✅ | ✅ |
142
+
143
+ **Note**: Windows Python wheels are not available due to compilation complexity. Windows users should use the pre-built binary from GitHub releases, install via cargo and build from source.
144
+
145
+ ### CLI Command Names
146
+
147
+ - **Rust binary**: `pysentry` (when installed via cargo or binary releases)
148
+ - **Python package**: `pysentry-rs` (when installed via pip or uvx)
149
+
150
+ Both variants support identical functionality. The resolver tools (`uv`, `pip-tools`) must be available in your current environment regardless of which PySentry variant you use.
151
+
152
+ ### Requirements.txt Support Prerequisites
153
+
154
+ To scan `requirements.txt` files, PySentry requires an external dependency resolver to convert version constraints (e.g., `flask>=2.0,<3.0`) into exact versions for vulnerability scanning.
155
+
156
+ **Install a supported resolver:**
157
+
158
+ ```bash
159
+ # uv (recommended - fastest, Rust-based)
160
+ pip install uv
161
+
162
+ # pip-tools (widely compatible, Python-based)
163
+ pip install pip-tools
164
+ ```
165
+
166
+ **Environment Requirements:**
167
+
168
+ - Resolvers must be available in your current environment
169
+ - If using virtual environments, activate your venv before running PySentry:
170
+ ```bash
171
+ source venv/bin/activate # Linux/macOS
172
+ venv\Scripts\activate # Windows
173
+ pysentry /path/to/project
174
+ ```
175
+ - Alternatively, install resolvers globally for system-wide availability
176
+
177
+ **Auto-detection:** PySentry automatically detects and prefers: `uv` > `pip-tools`. Without a resolver, only `uv.lock` and `poetry.lock` files can be scanned.
178
+
179
+ ## Quick Start
180
+
181
+ ### Basic Usage
182
+
183
+ ```bash
184
+ # Using uvx (recommended for occasional use)
185
+ uvx pysentry-rs
186
+ uvx pysentry-rs /path/to/python/project
187
+
188
+ # Using installed binary
189
+ pysentry
190
+ pysentry /path/to/python/project
191
+
192
+ # Automatically detects project type (uv.lock, poetry.lock, pyproject.toml, requirements.txt)
193
+ pysentry /path/to/project
194
+
195
+ # Force specific resolver
196
+ pysentry --resolver uv /path/to/project
197
+ pysentry --resolver pip-tools /path/to/project
198
+
199
+ # Include all dependencies (main + dev + optional)
200
+ pysentry --all
201
+
202
+ # Filter by severity (only show high and critical)
203
+ pysentry --severity high
204
+
205
+ # Output to JSON file
206
+ pysentry --format json --output audit-results.json
207
+ ```
208
+
209
+ ### Advanced Usage
210
+
211
+ ```bash
212
+ # Using uvx for comprehensive audit
213
+ uvx pysentry-rs --all --format sarif --output security-report.sarif
214
+
215
+ # Check only direct dependencies using OSV database
216
+ uvx pysentry-rs --direct-only --source osv
217
+
218
+ # Or with installed binary
219
+ pysentry --all --format sarif --output security-report.sarif
220
+ pysentry --direct-only --source osv
221
+
222
+ # Ignore specific vulnerabilities
223
+ pysentry --ignore CVE-2023-12345 --ignore GHSA-xxxx-yyyy-zzzz
224
+
225
+ # Disable caching for CI environments
226
+ pysentry --no-cache
227
+
228
+ # Verbose output for debugging
229
+ pysentry --verbose
230
+ ```
231
+
232
+ ### Advanced Requirements.txt Usage
233
+
234
+ ```bash
235
+ # Scan multiple requirements files
236
+ pysentry --requirements requirements.txt --requirements requirements-dev.txt
237
+
238
+ # Check only direct dependencies from requirements.txt
239
+ pysentry --direct-only --resolver uv
240
+
241
+ # Ensure resolver is available in your environment
242
+ source venv/bin/activate # Activate your virtual environment first
243
+ pysentry /path/to/project
244
+
245
+ # Debug requirements.txt resolution
246
+ pysentry --verbose --resolver uv /path/to/project
247
+ ```
248
+
249
+ ## Configuration
250
+
251
+ ### Command Line Options
252
+
253
+ | Option | Description | Default |
254
+ | ---------------- | ----------------------------------------------------- | ------------------- |
255
+ | `--format` | Output format: `human`, `json`, `sarif` | `human` |
256
+ | `--severity` | Minimum severity: `low`, `medium`, `high`, `critical` | `low` |
257
+ | `--source` | Vulnerability source: `pypa`, `pypi`, `osv` | `pypa` |
258
+ | `--all` | Include all dependencies (main + dev + optional) | `false` |
259
+ | `--direct-only` | Check only direct dependencies | `false` |
260
+ | `--ignore` | Vulnerability IDs to ignore (repeatable) | `[]` |
261
+ | `--output` | Output file path | `stdout` |
262
+ | `--no-cache` | Disable caching | `false` |
263
+ | `--cache-dir` | Custom cache directory | `~/.cache/pysentry` |
264
+ | `--verbose` | Enable verbose output | `false` |
265
+ | `--quiet` | Suppress non-error output | `false` |
266
+ | `--resolver` | Dependency resolver: `auto`, `uv`, `pip-tools` | `auto` |
267
+ | `--requirements` | Additional requirements files (repeatable) | `[]` |
268
+
269
+ ### Cache Management
270
+
271
+ PySentry uses an intelligent caching system to avoid redundant API calls:
272
+
273
+ - **Default Location**: `~/.cache/pysentry/` (or system temp directory)
274
+ - **TTL-based Expiration**: Separate expiration for each vulnerability source
275
+ - **Atomic Updates**: Prevents cache corruption during concurrent access
276
+ - **Custom Location**: Use `--cache-dir` to specify alternative location
277
+
278
+ To clear the cache:
279
+
280
+ ```bash
281
+ rm -rf ~/.cache/pysentry/
282
+ ```
283
+
284
+ ## Supported Project Formats
285
+
286
+ ### uv.lock Files (Recommended)
287
+
288
+ PySentry has support for `uv.lock` files:
289
+
290
+ - Exact version resolution
291
+ - Complete dependency graph analysis
292
+ - Source tracking
293
+ - Dependency classification (main, dev, optional) including transitive dependencies
294
+
295
+ ### poetry.lock Files
296
+
297
+ Full support for Poetry lock files:
298
+
299
+ - **Exact Version Resolution**: Scans exact dependency versions locked by Poetry
300
+ - **Lock-File Only Analysis**: Relies purely on the lock file structure, no pyproject.toml parsing needed
301
+ - **Complete Dependency Tree**: Analyzes all resolved dependencies including transitive ones
302
+ - **Dependency Classification**: Distinguishes between main dependencies and optional groups (dev, test, etc.)
303
+ - **Source Tracking**: Supports PyPI registry, Git repositories, local paths, and direct URLs
304
+
305
+ **Key Features:**
306
+
307
+ - No external tools required
308
+ - Fast parsing with exact version information
309
+ - Handles Poetry's dependency groups and optional dependencies
310
+ - Perfect for Poetry-managed projects with established lock files
311
+
312
+ ### requirements.txt Files (External Resolution)
313
+
314
+ Advanced support for `requirements.txt` files using external dependency resolvers:
315
+
316
+ **Key Features:**
317
+
318
+ - **Dependencies Resolution**: Converts version constraints (e.g., `flask>=2.0,<3.0`) to exact versions using mature external tools
319
+ - **Multiple Resolver Support**:
320
+ - **uv**: Rust-based resolver, extremely fast and reliable (recommended)
321
+ - **pip-tools**: Python-based resolver using `pip-compile`, widely compatible
322
+ - **Auto-detection**: Automatically detects and uses the best available resolver in your environment
323
+ - **Multiple File Support**: Combines `requirements.txt`, `requirements-dev.txt`, `requirements-test.txt`, etc.
324
+ - **Dependency Classification**: Distinguishes between direct and transitive dependencies
325
+ - **Isolated Execution**: Resolvers run in temporary directories to prevent project pollution
326
+ - **Complex Constraint Handling**: Supports version ranges, extras, environment markers, and conflict resolution
327
+
328
+ **Resolution Workflow:**
329
+
330
+ 1. Detects `requirements.txt` files in your project
331
+ 2. Auto-detects available resolver (`uv` or `pip-tools`) in current environment
332
+ 3. Resolves version constraints to exact dependency versions
333
+ 4. Scans resolved dependencies for vulnerabilities
334
+ 5. Reports findings with direct vs. transitive classification
335
+
336
+ **Environment Setup:**
337
+
338
+ ```bash
339
+ # Ensure resolver is available in your environment
340
+ source venv/bin/activate # Activate virtual environment
341
+ pip install uv # Install preferred resolver
342
+ pysentry /path/to/project # Run security scan
343
+ ```
344
+
345
+ ### pyproject.toml Files (External Resolution)
346
+
347
+ Support for projects without lock files:
348
+
349
+ - Parses version constraints from `pyproject.toml`
350
+ - **Resolver Required**: Like requirements.txt, needs external resolvers (`uv` or `pip-tools`) to convert version constraints to exact versions for accurate vulnerability scanning
351
+ - Limited dependency graph information compared to lock files
352
+ - Works with both Poetry and PEP 621 formats
353
+
354
+ ## Vulnerability Data Sources
355
+
356
+ ### PyPA Advisory Database (Default)
357
+
358
+ - Comprehensive coverage of Python ecosystem
359
+ - Community-maintained vulnerability database
360
+ - Regular updates from security researchers
361
+
362
+ ### PyPI JSON API
363
+
364
+ - Official PyPI vulnerability data
365
+ - Real-time information
366
+ - Limited to packages hosted on PyPI
367
+
368
+ ### OSV.dev
369
+
370
+ - Cross-ecosystem vulnerability database
371
+ - Google-maintained infrastructure
372
+
373
+ ## Output Formats
374
+
375
+ ### Human-Readable (Default)
376
+
377
+ Most comfortable to read.
378
+
379
+ ### JSON
380
+
381
+ ```json
382
+ {
383
+ "summary": {
384
+ "total_dependencies": 245,
385
+ "vulnerable_packages": 2,
386
+ "total_vulnerabilities": 3,
387
+ "by_severity": {
388
+ "critical": 1,
389
+ "high": 1,
390
+ "medium": 1,
391
+ "low": 0
392
+ }
393
+ },
394
+ "vulnerabilities": [...]
395
+ }
396
+ ```
397
+
398
+ ### SARIF (Static Analysis Results Interchange Format)
399
+
400
+ Compatible with GitHub Security tab, VS Code, and other security tools.
401
+
402
+ ## Performance
403
+
404
+ PySentry is designed for speed and efficiency:
405
+
406
+ - **Concurrent Processing**: Vulnerability data fetched in parallel
407
+ - **Smart Caching**: Reduces API calls and parsing overhead
408
+ - **Efficient Matching**: In-memory indexing for fast vulnerability lookups
409
+ - **Streaming**: Large databases processed without excessive memory usage
410
+
411
+ ### Requirements.txt Resolution Performance
412
+
413
+ PySentry leverages external resolvers for optimal performance:
414
+
415
+ - **uv resolver**: 2-10x faster than pip-tools, handles large dependency trees efficiently
416
+ - **pip-tools resolver**: Reliable fallback, slower but widely compatible
417
+ - **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
426
+
427
+ ## Development
428
+
429
+ ### Building from Source
430
+
431
+ ```bash
432
+ git clone https://github.com/nyudenkov/pysentry
433
+ cd pysentry
434
+ cargo build --release
435
+ ```
436
+
437
+ ### Running Tests
438
+
439
+ ```bash
440
+ cargo test
441
+ ```
442
+
443
+ ### Project Structure
444
+
445
+ ```
446
+ src/
447
+ ├── main.rs # CLI interface
448
+ ├── lib.rs # Library API
449
+ ├── cache/ # Caching system
450
+ ├── dependency/ # Dependency scanning
451
+ ├── output/ # Report generation
452
+ ├── parsers/ # Project file parsers
453
+ ├── providers/ # Vulnerability data sources
454
+ ├── types.rs # Core type definitions
455
+ └── vulnerability/ # Vulnerability matching
456
+ ```
457
+
458
+ ## Troubleshooting
459
+
460
+ ### Common Issues
461
+
462
+ **Error: "No lock file or pyproject.toml found"**
463
+
464
+ ```bash
465
+ # Ensure you're in a Python project directory
466
+ ls pyproject.toml uv.lock poetry.lock requirements.txt
467
+
468
+ # Or specify the path explicitly
469
+ pysentry /path/to/python/project
470
+ ```
471
+
472
+ **Error: "No dependency resolver found" or "uv resolver not available"**
473
+
474
+ ```bash
475
+ # Install a supported resolver in your environment
476
+ pip install uv # Recommended - fastest
477
+ pip install pip-tools # Alternative
478
+
479
+ # Verify resolver is available
480
+ uv --version
481
+ pip-compile --version
482
+
483
+ # If using virtual environments, ensure resolver is installed there
484
+ source venv/bin/activate
485
+ pip install uv
486
+ pysentry /path/to/project
487
+ ```
488
+
489
+ **Error: "Failed to resolve requirements"**
490
+
491
+ ```bash
492
+ # Check your requirements.txt syntax
493
+ cat requirements.txt
494
+
495
+ # Try different resolver
496
+ pysentry --resolver pip-tools # if uv fails
497
+ pysentry --resolver uv # if pip-tools fails
498
+
499
+ # Ensure you're in correct environment
500
+ which python
501
+ which uv # or which pip-compile
502
+
503
+ # Debug with verbose output
504
+ pysentry --verbose /path/to/project
505
+ ```
506
+
507
+ **Error: "Failed to fetch vulnerability data"**
508
+
509
+ ```bash
510
+ # Check network connectivity
511
+ curl -I https://osv-vulnerabilities.storage.googleapis.com/
512
+
513
+ # Try with different source
514
+ pysentry --source pypi
515
+ ```
516
+
517
+ **Slow requirements.txt resolution**
518
+
519
+ ```bash
520
+ # Use faster uv resolver instead of pip-tools
521
+ pysentry --resolver uv
522
+
523
+ # Install uv for better performance (2-10x faster)
524
+ pip install uv
525
+
526
+ # Or use uvx for isolated execution
527
+ uvx pysentry-rs --resolver uv /path/to/project
528
+ ```
529
+
530
+ **Requirements.txt files not being detected**
531
+
532
+ ```bash
533
+ # Ensure requirements.txt exists
534
+ ls requirements.txt
535
+
536
+ # Specify path explicitly
537
+ pysentry /path/to/python/project
538
+
539
+ # Include additional requirements files
540
+ pysentry --requirements requirements-dev.txt --requirements requirements-test.txt
541
+
542
+ # Check if higher-priority files exist (they take precedence)
543
+ ls uv.lock poetry.lock pyproject.toml
544
+ ```
545
+
546
+ **Performance Issues**
547
+
548
+ ```bash
549
+ # Clear cache and retry
550
+ rm -rf ~/.cache/pysentry
551
+ pysentry
552
+
553
+ # Use verbose mode to identify bottlenecks
554
+ pysentry --verbose
555
+ ```
556
+
557
+ ## Acknowledgments
558
+
559
+ - Inspired by [pip-audit](https://github.com/pypa/pip-audit) and [uv #9189 issue](https://github.com/astral-sh/uv/issues/9189)
560
+ - Originally was a command for [uv](https://github.com/astral-sh/uv)
561
+ - Vulnerability data from [PyPA](https://github.com/pypa/advisory-database), [PyPI](https://pypi.org/), and [OSV.dev](https://osv.dev/)
562
+
@@ -0,0 +1,8 @@
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,,
@@ -1,376 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: pysentry-rs
3
- Version: 0.1.4
4
- Classifier: Development Status :: 4 - Beta
5
- Classifier: Intended Audience :: Developers
6
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
7
- Classifier: Programming Language :: Rust
8
- Classifier: Programming Language :: Python :: Implementation :: CPython
9
- Classifier: Programming Language :: Python :: 3.8
10
- Classifier: Programming Language :: Python :: 3.9
11
- Classifier: Programming Language :: Python :: 3.10
12
- Classifier: Programming Language :: Python :: 3.11
13
- Classifier: Programming Language :: Python :: 3.12
14
- Classifier: Programming Language :: Python :: 3.13
15
- Classifier: Topic :: Security
16
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
- License-File: LICENSE
18
- Summary: Security vulnerability auditing tool for Python packages
19
- Author-email: nyudenkov <nyudenkov@pm.me>
20
- License: GPL-3.0
21
- Requires-Python: >=3.8
22
- Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
23
- Project-URL: Homepage, https://github.com/nyudenkov/pysentry
24
- Project-URL: Repository, https://github.com/nyudenkov/pysentry
25
- Project-URL: Issues, https://github.com/nyudenkov/pysentry/issues
26
-
27
- # 🐍 PySentry
28
-
29
- A fast, reliable security vulnerability scanner for Python projects, written in Rust.
30
-
31
- ## Overview
32
-
33
- PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `pyproject.toml`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
34
-
35
- ## Key Features
36
-
37
- - **Multiple Project Formats**: Supports both `uv.lock` files (with exact versions) and `pyproject.toml` files
38
- - **Multiple Data Sources**:
39
- - PyPA Advisory Database (default)
40
- - PyPI JSON API
41
- - OSV.dev (Open Source Vulnerabilities)
42
- - **Flexible Output**: Human-readable, JSON, and SARIF formats
43
- - **Performance Focused**:
44
- - Written in Rust for speed
45
- - Async/concurrent processing
46
- - Intelligent caching system
47
- - **Comprehensive Filtering**:
48
- - Severity levels (low, medium, high, critical)
49
- - Dependency types (production, development, optional)
50
- - Direct vs. transitive dependencies
51
- - **Enterprise Ready**: SARIF output for IDE/CI integration
52
-
53
- ## Installation
54
-
55
- Choose the installation method that works best for you:
56
-
57
- ### ⚡ Via uvx (Recommended for occasional use)
58
-
59
- Run directly without installing (requires [uv](https://docs.astral.sh/uv/)):
60
-
61
- ```bash
62
- uvx pysentry-rs /path/to/project
63
- ```
64
-
65
- This method:
66
-
67
- - Runs the latest version without installation
68
- - Automatically manages Python environment
69
- - Perfect for CI/CD or occasional security audits
70
- - No need to manage package versions or updates
71
-
72
- ### 📦 From PyPI (Python Package)
73
-
74
- For Python 3.8+ on Linux and macOS:
75
-
76
- ```bash
77
- pip install pysentry-rs
78
- ```
79
-
80
- Then use it with Python:
81
-
82
- ```bash
83
- python -m pysentry /path/to/project
84
- # or directly if scripts are in PATH
85
- pysentry-rs /path/to/project
86
- ```
87
-
88
- ### ⚡ From Crates.io (Rust Package)
89
-
90
- If you have Rust installed:
91
-
92
- ```bash
93
- cargo install pysentry
94
- ```
95
-
96
- ### 💾 From GitHub Releases (Pre-built Binaries)
97
-
98
- Download the latest release for your platform:
99
-
100
- - **Linux x64**: `pysentry-linux-x64.tar.gz`
101
- - **Linux x64 (musl)**: `pysentry-linux-x64-musl.tar.gz`
102
- - **Linux ARM64**: `pysentry-linux-arm64.tar.gz`
103
- - **macOS x64**: `pysentry-macos-x64.tar.gz`
104
- - **macOS ARM64**: `pysentry-macos-arm64.tar.gz`
105
- - **Windows x64**: `pysentry-windows-x64.zip`
106
-
107
- ```bash
108
- # Example for Linux x64
109
- curl -L https://github.com/nyudenkov/pysentry/releases/latest/download/pysentry-linux-x64.tar.gz | tar -xz
110
- ./pysentry-linux-x64/pysentry --help
111
- ```
112
-
113
- ### 🔧 From Source
114
-
115
- ```bash
116
- git clone https://github.com/nyudenkov/pysentry
117
- cd pysentry
118
- cargo build --release
119
- ```
120
-
121
- The binary will be available at `target/release/pysentry`.
122
-
123
- ### Requirements
124
-
125
- - **For uvx**: Python 3.8+ and [uv](https://docs.astral.sh/uv/) installed (Linux/macOS only)
126
- - **For binaries**: No additional dependencies
127
- - **For Python package**: Python 3.8+ (Linux/macOS only)
128
- - **For Rust package and source**: Rust 1.79+
129
-
130
- ### Platform Support
131
-
132
- | Installation Method | Linux | macOS | Windows |
133
- | ------------------- | ----- | ----- | ------- |
134
- | uvx | ✅ | ✅ | ❌ |
135
- | PyPI (pip) | ✅ | ✅ | ❌ |
136
- | Crates.io (cargo) | ✅ | ✅ | ✅ |
137
- | GitHub Releases | ✅ | ✅ | ✅ |
138
- | From Source | ✅ | ✅ | ✅ |
139
-
140
- **Note**: Windows Python wheels are not available due to compilation complexity. Windows users should use the pre-built binary from GitHub releases, install via cargo and build from source.
141
-
142
- ## Quick Start
143
-
144
- ### Basic Usage
145
-
146
- ```bash
147
- # Using uvx (recommended for occasional use)
148
- uvx pysentry-rs
149
- uvx pysentry-rs /path/to/python/project
150
-
151
- # Using installed binary
152
- pysentry
153
- pysentry /path/to/python/project
154
-
155
- # Include development dependencies
156
- pysentry --dev
157
-
158
- # Filter by severity (only show high and critical)
159
- pysentry --severity high
160
-
161
- # Output to JSON file
162
- pysentry --format json --output audit-results.json
163
- ```
164
-
165
- ### Advanced Usage
166
-
167
- ```bash
168
- # Using uvx for comprehensive audit
169
- uvx pysentry-rs --dev --optional --format sarif --output security-report.sarif
170
-
171
- # Check only direct dependencies using OSV database
172
- uvx pysentry-rs --direct-only --source osv
173
-
174
- # Or with installed binary
175
- pysentry --dev --optional --format sarif --output security-report.sarif
176
- pysentry --direct-only --source osv
177
-
178
- # Ignore specific vulnerabilities
179
- pysentry --ignore CVE-2023-12345 --ignore GHSA-xxxx-yyyy-zzzz
180
-
181
- # Disable caching for CI environments
182
- pysentry --no-cache
183
-
184
- # Verbose output for debugging
185
- pysentry --verbose
186
- ```
187
-
188
- ## Configuration
189
-
190
- ### Command Line Options
191
-
192
- | Option | Description | Default |
193
- | --------------- | ----------------------------------------------------- | ------------------- |
194
- | `--format` | Output format: `human`, `json`, `sarif` | `human` |
195
- | `--severity` | Minimum severity: `low`, `medium`, `high`, `critical` | `low` |
196
- | `--source` | Vulnerability source: `pypa`, `pypi`, `osv` | `pypa` |
197
- | `--dev` | Include development dependencies | `false` |
198
- | `--optional` | Include optional dependencies | `false` |
199
- | `--direct-only` | Check only direct dependencies | `false` |
200
- | `--ignore` | Vulnerability IDs to ignore (repeatable) | `[]` |
201
- | `--output` | Output file path | `stdout` |
202
- | `--no-cache` | Disable caching | `false` |
203
- | `--cache-dir` | Custom cache directory | `~/.cache/pysentry` |
204
- | `--verbose` | Enable verbose output | `false` |
205
- | `--quiet` | Suppress non-error output | `false` |
206
-
207
- ### Cache Management
208
-
209
- PySentry uses an intelligent caching system to avoid redundant API calls:
210
-
211
- - **Default Location**: `~/.cache/pysentry/` (or system temp directory)
212
- - **TTL-based Expiration**: Separate expiration for each vulnerability source
213
- - **Atomic Updates**: Prevents cache corruption during concurrent access
214
- - **Custom Location**: Use `--cache-dir` to specify alternative location
215
-
216
- To clear the cache:
217
-
218
- ```bash
219
- rm -rf ~/.cache/pysentry/
220
- ```
221
-
222
- ## Supported Project Formats
223
-
224
- ### uv.lock Files (Recommended)
225
-
226
- PySentry has support for `uv.lock` files, providing:
227
-
228
- - Exact version resolution
229
- - Complete dependency graph analysis
230
- - Source tracking
231
- - Dependency classification (main, dev, optional) including transitioning dependencies
232
-
233
- ### pyproject.toml Files
234
-
235
- Fallback support for projects without lock files:
236
-
237
- - Parses version constraints from `pyproject.toml`
238
- - Limited dependency graph information
239
-
240
- ## Vulnerability Data Sources
241
-
242
- ### PyPA Advisory Database (Default)
243
-
244
- - Comprehensive coverage of Python ecosystem
245
- - Community-maintained vulnerability database
246
- - Regular updates from security researchers
247
-
248
- ### PyPI JSON API
249
-
250
- - Official PyPI vulnerability data
251
- - Real-time information
252
- - Limited to packages hosted on PyPI
253
-
254
- ### OSV.dev
255
-
256
- - Cross-ecosystem vulnerability database
257
- - Google-maintained infrastructure
258
-
259
- ## Output Formats
260
-
261
- ### Human-Readable (Default)
262
-
263
- Most comfortable to read.
264
-
265
- ### JSON
266
-
267
- ```json
268
- {
269
- "summary": {
270
- "total_dependencies": 245,
271
- "vulnerable_packages": 2,
272
- "total_vulnerabilities": 3,
273
- "by_severity": {
274
- "critical": 1,
275
- "high": 1,
276
- "medium": 1,
277
- "low": 0
278
- }
279
- },
280
- "vulnerabilities": [...]
281
- }
282
- ```
283
-
284
- ### SARIF (Static Analysis Results Interchange Format)
285
-
286
- Compatible with GitHub Security tab, VS Code, and other security tools.
287
-
288
- ## Performance
289
-
290
- PySentry is designed for speed and efficiency:
291
-
292
- - **Concurrent Processing**: Vulnerability data fetched in parallel
293
- - **Smart Caching**: Reduces API calls and parsing overhead
294
- - **Efficient Matching**: In-memory indexing for fast vulnerability lookups
295
- - **Streaming**: Large databases processed without excessive memory usage
296
-
297
- ### Benchmarks
298
-
299
- Typical performance on a project with 100+ dependencies:
300
-
301
- - **Cold cache**: 15-30 seconds
302
- - **Warm cache**: 2-5 seconds
303
- - **Memory usage**: ~50MB peak
304
-
305
- ## Development
306
-
307
- ### Building from Source
308
-
309
- ```bash
310
- git clone https://github.com/nyudenkov/pysentry
311
- cd pysentry
312
- cargo build --release
313
- ```
314
-
315
- ### Running Tests
316
-
317
- ```bash
318
- cargo test
319
- ```
320
-
321
- ### Project Structure
322
-
323
- ```
324
- src/
325
- ├── main.rs # CLI interface
326
- ├── lib.rs # Library API
327
- ├── cache/ # Caching system
328
- ├── dependency/ # Dependency scanning
329
- ├── output/ # Report generation
330
- ├── parsers/ # Project file parsers
331
- ├── providers/ # Vulnerability data sources
332
- ├── types.rs # Core type definitions
333
- └── vulnerability/ # Vulnerability matching
334
- ```
335
-
336
- ## Troubleshooting
337
-
338
- ### Common Issues
339
-
340
- **Error: "No lock file or pyproject.toml found"**
341
-
342
- ```bash
343
- # Ensure you're in a Python project directory
344
- ls pyproject.toml uv.lock
345
-
346
- # Or specify the path explicitly
347
- pysentry /path/to/python/project
348
- ```
349
-
350
- **Error: "Failed to fetch vulnerability data"**
351
-
352
- ```bash
353
- # Check network connectivity
354
- curl -I https://osv-vulnerabilities.storage.googleapis.com/
355
-
356
- # Try with different source
357
- pysentry --source pypi
358
- ```
359
-
360
- **Performance Issues**
361
-
362
- ```bash
363
- # Clear cache and retry
364
- rm -rf ~/.cache/pysentry
365
- pysentry
366
-
367
- # Use verbose mode to identify bottlenecks
368
- pysentry --verbose
369
- ```
370
-
371
- ## Acknowledgments
372
-
373
- - Inspired by [pip-audit](https://github.com/pypa/pip-audit) and [uv #9189 issue](https://github.com/astral-sh/uv/issues/9189)
374
- - Originally was a command for [uv](https://github.com/astral-sh/uv)
375
- - Vulnerability data from [PyPA](https://github.com/pypa/advisory-database), [PyPI](https://pypi.org/), and [OSV.dev](https://osv.dev/)
376
-
@@ -1,8 +0,0 @@
1
- pysentry/__init__.py,sha256=TcB6vZ9qN_6fa0HZnuiNiv7VQKwf6jA-kUdWP4ZSwho,5066
2
- pysentry/__main__.py,sha256=FJdFFQuSE8TYsZtY_vb00oCE2nvq9hB6MhMLBxnn7Ns,117
3
- pysentry/_internal.cpython-311-darwin.so,sha256=-WbuzvEYfOGXR3NmJ_n0Zx-eW0AXHujsoZODGJdUy4c,6137792
4
- pysentry_rs-0.1.4.dist-info/METADATA,sha256=vl4tTeCjqbM0zh8h-6Z1lfdwVmVfme57xTyeIqrhP20,10992
5
- pysentry_rs-0.1.4.dist-info/WHEEL,sha256=FQD2wNSk7QdKfwuvlrA52DGgdDYb2Xq1PtLwlu6bv-w,104
6
- pysentry_rs-0.1.4.dist-info/entry_points.txt,sha256=3bJguekVEbXTn-ceDCWJaSIZScquPPP1Ux9TPVHHanE,44
7
- pysentry_rs-0.1.4.dist-info/licenses/LICENSE,sha256=TAMtDCoJuavXz7pCEklrzjH55sdvsy5gKsXY9NsImwY,34878
8
- pysentry_rs-0.1.4.dist-info/RECORD,,