0
# Dependency Sources
1
2
Various sources of Python dependencies including pip environments, requirements files, pyproject.toml files, and lock files. Dependency sources provide the packages to be audited and can optionally apply fixes.
3
4
## Capabilities
5
6
### Base Interface
7
8
Abstract base class for all dependency sources.
9
10
```python { .api }
11
class DependencySource(ABC):
12
"""
13
Represents an abstract source of fully-resolved Python dependencies.
14
15
Individual concrete dependency sources are expected to subclass DependencySource
16
and implement it in their terms.
17
"""
18
19
@abstractmethod
20
def collect(self) -> Iterator[Dependency]:
21
"""
22
Yield the dependencies in this source.
23
24
Returns:
25
Iterator of Dependency objects
26
"""
27
28
@abstractmethod
29
def fix(self, fix_version: ResolvedFixVersion) -> None:
30
"""
31
Upgrade a dependency to the given fix version.
32
33
Parameters:
34
- fix_version: ResolvedFixVersion, the version to upgrade to
35
"""
36
```
37
38
### Pip Environment Source
39
40
Source that collects dependencies from the current pip environment.
41
42
```python { .api }
43
class PipSource(DependencySource):
44
"""
45
Wraps pip (specifically pip list) as a dependency source.
46
"""
47
48
def __init__(
49
self,
50
*,
51
local: bool = False,
52
paths: Sequence[Path] = [],
53
skip_editable: bool = False,
54
state: AuditState = AuditState(),
55
):
56
"""
57
Create a new PipSource.
58
59
Parameters:
60
- local: bool, whether to include only local packages
61
- paths: Sequence[Path], additional paths to include
62
- skip_editable: bool, whether to skip editable packages
63
- state: AuditState, state tracker for progress updates
64
"""
65
66
def collect(self) -> Iterator[Dependency]:
67
"""Collect dependencies from pip list."""
68
69
def fix(self, fix_version: ResolvedFixVersion) -> None:
70
"""Fix a dependency by upgrading via pip install."""
71
```
72
73
### Requirements File Source
74
75
Source that reads dependencies from requirements.txt files.
76
77
```python { .api }
78
class RequirementSource(DependencySource):
79
"""
80
Dependency source for requirements.txt style files.
81
"""
82
83
def __init__(
84
self,
85
filenames: list[Path],
86
*,
87
require_hashes: bool = False,
88
no_deps: bool = False,
89
disable_pip: bool = False,
90
skip_editable: bool = False,
91
index_url: str | None = None,
92
extra_index_urls: list[str] = [],
93
state: AuditState = AuditState(),
94
) -> None:
95
"""
96
Create a new RequirementSource.
97
98
Parameters:
99
- filenames: list[Path], list of filepaths to parse
100
- require_hashes: bool, controls the hash policy
101
- no_deps: bool, whether to skip dependency resolution
102
- disable_pip: bool, whether to disable pip for resolution
103
- skip_editable: bool, whether to skip editable packages
104
- index_url: str | None, custom index URL
105
- extra_index_urls: list[str], additional index URLs
106
- state: AuditState, state tracker for progress updates
107
"""
108
109
def collect(self) -> Iterator[Dependency]:
110
"""Collect dependencies from requirements file."""
111
112
def fix(self, fix_version: ResolvedFixVersion) -> None:
113
"""Fix a dependency by updating the requirements file."""
114
```
115
116
### PyProject Source
117
118
Source that reads dependencies from pyproject.toml files.
119
120
```python { .api }
121
class PyProjectSource(DependencySource):
122
"""
123
Dependency source for pyproject.toml files.
124
"""
125
126
def __init__(
127
self,
128
filename: Path,
129
index_url: str | None = None,
130
extra_index_urls: list[str] = [],
131
state: AuditState = AuditState(),
132
) -> None:
133
"""
134
Create a new PyProjectSource.
135
136
Parameters:
137
- filename: Path, path to a pyproject.toml file
138
- index_url: str | None, base URL of the package index
139
- extra_index_urls: list[str], extra URLs of package indexes
140
- state: AuditState, state tracker for progress updates
141
"""
142
143
def collect(self) -> Iterator[Dependency]:
144
"""Collect dependencies from pyproject.toml."""
145
146
def fix(self, fix_version: ResolvedFixVersion) -> None:
147
"""Fix a dependency by updating pyproject.toml."""
148
```
149
150
### Lock File Source
151
152
Source that reads dependencies from Python lock files.
153
154
```python { .api }
155
class PyLockSource(DependencySource):
156
"""
157
Dependency source for Python lock files (poetry.lock, Pipfile.lock, etc.).
158
"""
159
160
def __init__(self, filenames: list[Path]) -> None:
161
"""
162
Create a new PyLockSource.
163
164
Parameters:
165
- filenames: list[Path], list of pylock.*.toml files to parse
166
"""
167
168
def collect(self) -> Iterator[Dependency]:
169
"""Collect dependencies from lock file."""
170
171
def fix(self, fix_version: ResolvedFixVersion) -> None:
172
"""Fix a dependency by updating the lock file."""
173
```
174
175
### Exceptions
176
177
Exceptions raised by dependency sources.
178
179
```python { .api }
180
class DependencySourceError(Exception):
181
"""
182
Raised when a DependencySource fails to provide its dependencies.
183
"""
184
185
class DependencyFixError(Exception):
186
"""
187
Raised when a DependencySource fails to perform a fix operation.
188
"""
189
190
class InvalidRequirementSpecifier(DependencySourceError):
191
"""
192
A DependencySourceError specialized for non-PEP 440 requirements specifiers.
193
"""
194
195
class PipSourceError(DependencySourceError):
196
"""
197
Pip-specific dependency source errors.
198
"""
199
200
class PipFixError(DependencyFixError):
201
"""
202
Pip-specific dependency fix errors.
203
"""
204
205
class RequirementSourceError(DependencySourceError):
206
"""
207
Requirements file-specific dependency source errors.
208
"""
209
210
class RequirementFixError(DependencyFixError):
211
"""
212
Requirements file-specific dependency fix errors.
213
"""
214
215
class PyProjectSourceError(DependencySourceError):
216
"""
217
PyProject-specific dependency source errors.
218
"""
219
220
class PyProjectFixError(DependencyFixError):
221
"""
222
PyProject-specific dependency fix errors.
223
"""
224
225
class PyLockSourceError(DependencySourceError):
226
"""
227
Lock file-specific dependency source errors.
228
"""
229
230
class PyLockFixError(DependencyFixError):
231
"""
232
Lock file-specific dependency fix errors.
233
"""
234
```
235
236
### Constants
237
238
```python { .api }
239
PYPI_URL: str = "https://pypi.org/simple/"
240
"""Default PyPI simple index URL."""
241
```
242
243
## Usage Examples
244
245
### Audit Current Environment
246
247
```python
248
from pip_audit._dependency_source import PipSource
249
250
# Audit current pip environment
251
source = PipSource()
252
dependencies = list(source.collect())
253
print(f"Found {len(dependencies)} packages in environment")
254
```
255
256
### Audit Requirements File
257
258
```python
259
from pip_audit._dependency_source import RequirementSource
260
261
# Audit a requirements file
262
source = RequirementSource("requirements.txt")
263
dependencies = list(source.collect())
264
print(f"Found {len(dependencies)} packages in requirements.txt")
265
```
266
267
### Audit with Different Sources
268
269
```python
270
from pip_audit._dependency_source import PipSource, PyProjectSource
271
from pip_audit._audit import Auditor
272
from pip_audit._service import PyPIService
273
274
service = PyPIService()
275
auditor = Auditor(service=service)
276
277
# Audit multiple sources
278
sources = [
279
PipSource(local=True),
280
PyProjectSource("pyproject.toml"),
281
]
282
283
for i, source in enumerate(sources):
284
print(f"Auditing source {i+1}:")
285
for dependency, vulns in auditor.audit(source):
286
if vulns:
287
print(f" {dependency.name}: {len(vulns)} vulnerabilities")
288
```