or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-auditing.mddata-models.mddependency-sources.mdfix-resolution.mdindex.mdoutput-formats.mdvulnerability-services.md

data-models.mddocs/

0

# Data Models

1

2

Core data structures representing dependencies, vulnerabilities, and related information used throughout the pip-audit API.

3

4

## Capabilities

5

6

### Dependency Classes

7

8

Base classes representing Python packages and their states.

9

10

```python { .api }

11

@dataclass(frozen=True)

12

class Dependency:

13

"""

14

Represents an abstract Python package.

15

16

This class cannot be constructed directly.

17

"""

18

19

name: str

20

"""

21

The package's uncanonicalized name.

22

23

Use the canonical_name property when a canonicalized form is necessary.

24

"""

25

26

@property

27

def canonical_name(self) -> str:

28

"""

29

The Dependency's PEP-503 canonicalized name.

30

31

Returns:

32

Canonicalized package name according to PEP-503

33

"""

34

35

def is_skipped(self) -> bool:

36

"""

37

Check whether the Dependency was skipped by the audit.

38

39

Returns:

40

True if this is a SkippedDependency, False otherwise

41

"""

42

```

43

44

### Resolved Dependency

45

46

Represents a fully resolved Python package with a specific version.

47

48

```python { .api }

49

@dataclass(frozen=True)

50

class ResolvedDependency(Dependency):

51

"""

52

Represents a fully resolved Python package.

53

"""

54

55

version: Version

56

"""

57

The resolved version of the package.

58

"""

59

```

60

61

### Skipped Dependency

62

63

Represents a Python package that was unable to be audited.

64

65

```python { .api }

66

@dataclass(frozen=True)

67

class SkippedDependency(Dependency):

68

"""

69

Represents a Python package that was unable to be audited and therefore, skipped.

70

"""

71

72

skip_reason: str

73

"""

74

The reason why this package was skipped during audit.

75

"""

76

```

77

78

### Vulnerability Result

79

80

Represents vulnerability information for a package.

81

82

```python { .api }

83

@dataclass(frozen=True)

84

class VulnerabilityResult:

85

"""

86

Represents a vulnerability result from a vulnerability service.

87

"""

88

89

id: VulnerabilityID

90

"""

91

A service-provided identifier for the vulnerability.

92

"""

93

94

description: str

95

"""

96

A human-readable description of the vulnerability.

97

"""

98

99

fix_versions: list[Version]

100

"""

101

A list of versions that can be upgraded to that resolve the vulnerability.

102

"""

103

104

aliases: set[str]

105

"""

106

A set of aliases (alternative identifiers) for this result.

107

"""

108

109

published: datetime | None = None

110

"""

111

When the vulnerability was first published.

112

"""

113

114

def alias_of(self, other: VulnerabilityResult) -> bool:

115

"""

116

Returns whether this result is an alias of another result.

117

118

Two results are aliases if their respective sets of {id, *aliases} intersect.

119

120

Parameters:

121

- other: VulnerabilityResult, the other result to compare

122

123

Returns:

124

True if this result is an alias of the other result

125

"""

126

127

def merge_aliases(self, other: VulnerabilityResult) -> VulnerabilityResult:

128

"""

129

Merge other's aliases into this result, returning a new result.

130

131

Parameters:

132

- other: VulnerabilityResult, the result to merge aliases from

133

134

Returns:

135

New VulnerabilityResult with merged aliases

136

"""

137

138

def has_any_id(self, ids: set[str]) -> bool:

139

"""

140

Returns whether ids intersects with {id} | aliases.

141

142

Parameters:

143

- ids: set[str], set of IDs to check

144

145

Returns:

146

True if any of the IDs match this result's ID or aliases

147

"""

148

```

149

150

### Type Aliases

151

152

Type definitions used throughout the API.

153

154

```python { .api }

155

VulnerabilityID = NewType("VulnerabilityID", str)

156

"""

157

Type alias for vulnerability identifiers.

158

"""

159

```

160

161

## Usage Examples

162

163

### Working with Dependencies

164

165

```python

166

from pip_audit._service.interface import ResolvedDependency, SkippedDependency

167

from packaging.version import Version

168

169

# Create a resolved dependency

170

dependency = ResolvedDependency(name="requests", version=Version("2.28.0"))

171

print(f"Package: {dependency.name}")

172

print(f"Canonical: {dependency.canonical_name}")

173

print(f"Version: {dependency.version}")

174

print(f"Is skipped: {dependency.is_skipped()}")

175

176

# Create a skipped dependency

177

skipped = SkippedDependency(name="broken-package", skip_reason="Invalid version format")

178

print(f"Skipped: {skipped.name} - {skipped.skip_reason}")

179

print(f"Is skipped: {skipped.is_skipped()}")

180

```

181

182

### Working with Vulnerability Results

183

184

```python

185

from pip_audit._service.interface import VulnerabilityResult, VulnerabilityID

186

from packaging.version import Version

187

from datetime import datetime

188

189

# Create vulnerability result

190

vuln = VulnerabilityResult(

191

id=VulnerabilityID("GHSA-xxxx-yyyy-zzzz"),

192

description="Cross-site scripting vulnerability in user input handling",

193

fix_versions=[Version("2.28.1"), Version("2.29.0")],

194

aliases={"CVE-2022-12345", "SNYK-PYTHON-REQUESTS-12345"}

195

)

196

197

print(f"Vulnerability ID: {vuln.id}")

198

print(f"Description: {vuln.description}")

199

print(f"Fix versions: {[str(v) for v in vuln.fix_versions]}")

200

print(f"Aliases: {vuln.aliases}")

201

```

202

203

### Filtering Dependencies

204

205

```python

206

from pip_audit._service.interface import ResolvedDependency, SkippedDependency

207

208

def filter_resolved_dependencies(dependencies):

209

"""Filter out skipped dependencies and return only resolved ones."""

210

resolved = []

211

skipped = []

212

213

for dep in dependencies:

214

if dep.is_skipped():

215

skipped.append(dep)

216

else:

217

resolved.append(dep)

218

219

return resolved, skipped

220

221

# Example usage

222

dependencies = [

223

ResolvedDependency(name="requests", version=Version("2.28.0")),

224

SkippedDependency(name="broken-pkg", skip_reason="Parse error"),

225

ResolvedDependency(name="flask", version=Version("2.0.0")),

226

]

227

228

resolved, skipped = filter_resolved_dependencies(dependencies)

229

print(f"Resolved: {len(resolved)}, Skipped: {len(skipped)}")

230

```

231

232

### Canonical Name Handling

233

234

```python

235

from pip_audit._service.interface import ResolvedDependency

236

from packaging.version import Version

237

238

# Demonstrate canonical name handling

239

packages = [

240

ResolvedDependency(name="Django", version=Version("4.0.0")),

241

ResolvedDependency(name="PILLOW", version=Version("9.0.0")),

242

ResolvedDependency(name="beautifulsoup4", version=Version("4.10.0")),

243

]

244

245

for pkg in packages:

246

print(f"Original: {pkg.name}")

247

print(f"Canonical: {pkg.canonical_name}")

248

print("---")

249

```