or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcli-commands.mdconfiguration.mderrors.mdformatters.mdindex.mdmodels.mdprogrammatic.mdscanning.md

models.mddocs/

0

# Data Models and Types

1

2

Safety CLI uses a comprehensive set of data models and types to represent vulnerabilities, packages, requirements, and other security-related information. These models provide structured data access and serialization capabilities.

3

4

## Core Data Models

5

6

### Import Statements { .api }

7

8

```python

9

from safety.models import (

10

# Core models

11

Vulnerability, CVE, Severity, Fix, Package,

12

SafetyRequirement, RequirementFile,

13

14

# Utilities and encoders

15

SafetyEncoder, is_pinned_requirement, SafetyCLI, ToolResult

16

)

17

18

# Note: Announcement and Remediation must be imported directly from vulnerabilities module

19

from safety.models.vulnerabilities import Announcement, Remediation

20

from safety.errors import (

21

SafetyError, SafetyException, InvalidRequirementError,

22

InvalidCredentialError, NetworkConnectionError

23

)

24

from safety_schemas.models import (

25

ConfigModel, Ecosystem, FileType, Stage,

26

PolicyFileModel, DependencyResultModel

27

)

28

```

29

30

## Vulnerability Models

31

32

### Vulnerability Class { .api }

33

34

**Description**: Represents a security vulnerability found in a package dependency.

35

36

```python

37

# Note: Vulnerability is a named tuple with these fields (in order)

38

Vulnerability = namedtuple('Vulnerability', [

39

'vulnerability_id', # str: Unique vulnerability identifier

40

'package_name', # str: Affected package name

41

'pkg', # Package: Package object reference

42

'ignored', # bool: Whether vulnerability is ignored

43

'ignored_reason', # Optional[str]: Reason for ignoring

44

'ignored_expires', # Optional[datetime]: Ignore expiration date

45

'vulnerable_spec', # SpecifierSet: Vulnerable version specifiers

46

'all_vulnerable_specs', # List[str]: All vulnerable version patterns

47

'analyzed_version', # str: Currently installed version

48

'analyzed_requirement', # SafetyRequirement: Analyzed requirement object

49

'advisory', # str: Vulnerability description

50

'is_transitive', # bool: Is transitive dependency

51

'published_date', # datetime: Publication date

52

'fixed_versions', # List[str]: Versions with fixes

53

'closest_versions_without_known_vulnerabilities', # List[str]: Safe alternatives

54

'resources', # List[str]: Additional resources

55

'CVE', # CVE: CVE information

56

'severity', # Severity: Severity assessment

57

'affected_versions', # str: Affected version range

58

'more_info_url' # str: Additional information URL

59

])

60

61

class Vulnerability(vulnerability_nmt):

62

"""Core vulnerability information with comprehensive metadata."""

63

```

64

65

**Methods:**

66

67

```python

68

def to_dict(self) -> Dict[str, Any]:

69

"""

70

Convert vulnerability to dictionary format.

71

72

Returns:

73

Dict[str, Any]: Dictionary representation suitable for JSON serialization

74

"""

75

76

def get_advisory(self) -> str:

77

"""

78

Get cleaned advisory text.

79

80

Returns:

81

str: Advisory text with formatting cleaned

82

"""

83

84

def to_model_dict(self) -> Dict[str, Any]:

85

"""

86

Convert to model dictionary format for API communication.

87

88

Returns:

89

Dict[str, Any]: Structured model representation

90

"""

91

```

92

93

**Example Usage:**

94

95

```python

96

from safety.models import Vulnerability, CVE, Severity

97

from datetime import datetime

98

99

# Access vulnerability properties

100

vuln = Vulnerability(...) # From scan results

101

102

print(f"Vulnerability: {vuln.vulnerability_id}")

103

print(f"Package: {vuln.package_name} v{vuln.analyzed_version}")

104

print(f"Severity: {vuln.severity.cvssv3}")

105

print(f"Advisory: {vuln.get_advisory()}")

106

107

# Check if ignored

108

if vuln.ignored:

109

print(f"Ignored: {vuln.ignored_reason}")

110

if vuln.ignored_expires:

111

print(f"Expires: {vuln.ignored_expires}")

112

113

# Get remediation options

114

if vuln.fixed_versions:

115

print(f"Fixed in: {', '.join(vuln.fixed_versions)}")

116

117

# Convert to dictionary for serialization

118

vuln_dict = vuln.to_dict()

119

```

120

121

### CVE Class { .api }

122

123

**Description**: Common Vulnerabilities and Exposures (CVE) information.

124

125

```python

126

class CVE(NamedTuple):

127

"""CVE identification and scoring information."""

128

129

name: str # CVE identifier (e.g., "CVE-2023-12345")

130

cvssv2: Optional[float] # CVSS v2.0 score

131

cvssv3: Optional[float] # CVSS v3.x score

132

133

def to_dict(self) -> Dict[str, Any]:

134

"""

135

Convert CVE to dictionary format.

136

137

Returns:

138

Dict[str, Any]: CVE information as dictionary

139

"""

140

```

141

142

**Example Usage:**

143

144

```python

145

from safety.models import CVE

146

147

# CVE with scoring information

148

cve = CVE(

149

name="CVE-2023-12345",

150

cvssv2=7.5,

151

cvssv3=8.1

152

)

153

154

# Access properties

155

print(f"CVE: {cve.name}")

156

print(f"CVSS v3 Score: {cve.cvssv3}")

157

158

# Severity classification based on CVSS score

159

if cve.cvssv3 >= 9.0:

160

severity_level = "Critical"

161

elif cve.cvssv3 >= 7.0:

162

severity_level = "High"

163

elif cve.cvssv3 >= 4.0:

164

severity_level = "Medium"

165

else:

166

severity_level = "Low"

167

```

168

169

### Severity Class { .api }

170

171

**Description**: Vulnerability severity assessment from multiple sources.

172

173

```python

174

class Severity(NamedTuple):

175

"""Vulnerability severity with source attribution."""

176

177

source: str # Severity source (e.g., "safety", "nvd")

178

cvssv2: Optional[float] # CVSS v2.0 score

179

cvssv3: Optional[float] # CVSS v3.x score

180

181

def to_dict(self) -> Dict[str, Any]:

182

"""

183

Convert severity to dictionary format.

184

185

Returns:

186

Dict[str, Any]: Structured severity information

187

"""

188

```

189

190

## Package and Requirement Models

191

192

### Package Class { .api }

193

194

**Description**: Represents a Python package with version and dependency information.

195

196

```python

197

@dataclass

198

class Package:

199

"""Python package with comprehensive metadata and version information."""

200

201

# Basic package information

202

name: str # Package name (normalized)

203

version: Optional[str] # Installed version

204

requirements: List[SafetyRequirement] # Package requirements

205

206

# Location information

207

found: Optional[str] = None # Where package was found

208

absolute_path: Optional[str] = None # Absolute path to package

209

210

# Version metadata

211

insecure_versions: List[str] = field(default_factory=list) # Known insecure versions

212

secure_versions: List[str] = field(default_factory=list) # Known secure versions

213

latest_version_without_known_vulnerabilities: Optional[str] = None # Latest safe version

214

latest_version: Optional[str] = None # Latest available version

215

more_info_url: Optional[str] = None # Package information URL

216

```

217

218

**Methods:**

219

220

```python

221

def has_unpinned_req(self) -> bool:

222

"""

223

Check if package has unpinned requirements.

224

225

Returns:

226

bool: True if any requirements are unpinned

227

"""

228

229

def get_unpinned_req(self) -> filter:

230

"""

231

Get unpinned requirements.

232

233

Returns:

234

filter: Filter object containing unpinned requirements

235

"""

236

237

def filter_by_supported_versions(self, versions: List[str]) -> List[str]:

238

"""

239

Filter versions by parsing support.

240

241

Args:

242

versions (List[str]): Version strings to filter

243

244

Returns:

245

List[str]: Valid, parseable version strings

246

"""

247

248

def get_versions(self, db_full: Dict) -> Set[str]:

249

"""

250

Get all versions from vulnerability database.

251

252

Args:

253

db_full (Dict): Complete vulnerability database

254

255

Returns:

256

Set[str]: All known versions for package

257

"""

258

259

def refresh_from(self, db_full: Dict) -> None:

260

"""

261

Refresh package metadata from database.

262

263

Args:

264

db_full (Dict): Complete vulnerability database

265

"""

266

267

def to_dict(self) -> Dict[str, Any]:

268

"""

269

Convert package to dictionary format.

270

271

Returns:

272

Dict[str, Any]: Package information as dictionary

273

"""

274

```

275

276

**Example Usage:**

277

278

```python

279

from safety.models import Package, SafetyRequirement

280

281

# Create package instance

282

package = Package(

283

name="requests",

284

version="2.28.1",

285

requirements=[

286

SafetyRequirement("urllib3>=1.21.1,<1.27"),

287

SafetyRequirement("certifi>=2017.4.17")

288

],

289

found="requirements.txt"

290

)

291

292

# Check for unpinned requirements

293

if package.has_unpinned_req():

294

unpinned = list(package.get_unpinned_req())

295

print(f"Unpinned requirements: {[req.name for req in unpinned]}")

296

297

# Package metadata access

298

print(f"Package: {package.name} v{package.version}")

299

print(f"Found in: {package.found}")

300

print(f"Latest safe version: {package.latest_version_without_known_vulnerabilities}")

301

```

302

303

### SafetyRequirement Class { .api }

304

305

**Description**: Enhanced version of packaging.requirements.Requirement with Safety-specific features.

306

307

```python

308

class SafetyRequirement(Requirement):

309

"""Enhanced requirement with Safety-specific metadata and methods."""

310

311

def __init__(self,

312

requirement: Union[str, Dependency],

313

found: Optional[str] = None) -> None:

314

"""

315

Initialize Safety requirement.

316

317

Args:

318

requirement: Requirement string or Dependency object

319

found: Location where requirement was found

320

321

Raises:

322

InvalidRequirementError: If requirement cannot be parsed

323

"""

324

325

# Additional properties

326

raw: str # Original requirement line

327

found: Optional[str] # Source location

328

```

329

330

**Methods:**

331

332

```python

333

def to_dict(self, **kwargs: Any) -> Dict[str, Any]:

334

"""

335

Convert requirement to dictionary format.

336

337

Args:

338

**kwargs: Additional options (e.g., specifier_obj format)

339

340

Returns:

341

Dict[str, Any]: Requirement information as dictionary

342

"""

343

344

def __eq__(self, other: Any) -> bool:

345

"""

346

Compare requirements for equality.

347

348

Args:

349

other: Other requirement to compare

350

351

Returns:

352

bool: True if requirements are equal

353

"""

354

```

355

356

**Dictionary Format:**

357

358

```python

359

requirement_dict = {

360

'raw': 'requests>=2.20.0,<3.0.0', # Original requirement line

361

'name': 'requests', # Package name

362

'specifier': '>=2.20.0,<3.0.0', # Version specifiers

363

'extras': ['security'], # Optional extras

364

'marker': 'python_version >= "3.8"', # Environment markers

365

'url': None, # Direct URL (if any)

366

'found': 'requirements.txt' # Source location

367

}

368

```

369

370

### RequirementFile { .api }

371

372

**Description**: Named tuple representing a requirements file location.

373

374

```python

375

RequirementFile = namedtuple('RequirementFile', ['path'])

376

377

# Usage

378

req_file = RequirementFile(path="requirements.txt")

379

print(f"Requirements file: {req_file.path}")

380

```

381

382

## Remediation and Fix Models

383

384

### Fix Class { .api }

385

386

**Description**: Represents an applied or available security fix for a vulnerability.

387

388

```python

389

@dataclass

390

class Fix:

391

"""Security fix information and metadata."""

392

393

# Dependency information

394

dependency: Any = None # Dependency object

395

package: str = "" # Package name

396

397

# Version changes

398

previous_version: Any = None # Version before fix

399

updated_version: Any = None # Version after fix

400

previous_spec: Optional[str] = None # Previous version specifier

401

other_options: List[str] = field(default_factory=list) # Alternative versions

402

403

# Fix metadata

404

update_type: str = "" # Type of update (major, minor, patch)

405

status: str = "" # Fix application status

406

applied_at: str = "" # When fix was applied

407

fix_type: str = "" # Fix type classification

408

more_info_url: str = "" # Additional information URL

409

```

410

411

**Example Usage:**

412

413

```python

414

from safety.models import Fix

415

416

# Applied security fix

417

fix = Fix(

418

package="requests",

419

previous_version="2.20.0",

420

updated_version="2.28.1",

421

update_type="minor",

422

status="applied",

423

applied_at="2024-01-15T10:30:00Z",

424

fix_type="security_update"

425

)

426

427

print(f"Fixed {fix.package}: {fix.previous_version} → {fix.updated_version}")

428

print(f"Update type: {fix.update_type}")

429

print(f"Applied: {fix.applied_at}")

430

```

431

432

### Remediation Class { .api }

433

434

**Description**: Remediation suggestion for vulnerable packages.

435

436

```python

437

class Remediation(NamedTuple):

438

"""Remediation suggestion with version recommendations."""

439

440

Package: Package # Affected package

441

closest_secure_version: str # Nearest secure version

442

secure_versions: List[str] # All secure versions

443

latest_package_version: str # Latest available version

444

445

def to_dict(self) -> Dict[str, Any]:

446

"""

447

Convert remediation to dictionary format.

448

449

Returns:

450

Dict[str, Any]: Remediation information

451

"""

452

```

453

454

## Utility Models and Types

455

456

### Announcement Class { .api }

457

458

**Description**: Platform announcements and notices.

459

460

```python

461

class Announcement(NamedTuple):

462

"""Platform announcement information."""

463

464

type: str # Announcement type

465

message: str # Announcement content

466

```

467

468

### DictConverter Base Class { .api }

469

470

**Description**: Abstract base class for objects that can be converted to dictionaries.

471

472

```python

473

class DictConverter:

474

"""Base class for dictionary serialization."""

475

476

@abstractmethod

477

def to_dict(self, **kwargs: Any) -> Dict[str, Any]:

478

"""

479

Convert object to dictionary format.

480

481

Args:

482

**kwargs: Additional conversion options

483

484

Returns:

485

Dict[str, Any]: Dictionary representation

486

"""

487

```

488

489

### SafetyCLI Model { .api }

490

491

**Description**: Represents Safety CLI instance metadata.

492

493

```python

494

from safety.models import SafetyCLI

495

496

class SafetyCLI:

497

"""Safety CLI instance information and metadata."""

498

499

# CLI version and environment information

500

version: str # Safety CLI version

501

python_version: str # Python version

502

platform: str # Operating system platform

503

504

# Usage and telemetry data

505

command: str # Executed command

506

options: Dict[str, Any] # Command options

507

execution_time: float # Execution duration

508

```

509

510

### ToolResult Model { .api }

511

512

**Description**: Results from integrated security tools.

513

514

```python

515

from safety.models import ToolResult

516

517

class ToolResult:

518

"""Results from integrated security analysis tools."""

519

520

tool_name: str # Tool identifier

521

exit_code: int # Tool exit code

522

output: str # Tool output

523

errors: List[str] # Error messages

524

metadata: Dict[str, Any] # Additional metadata

525

```

526

527

## Serialization and Encoding

528

529

### SafetyEncoder { .api }

530

531

**Description**: Custom JSON encoder for Safety-specific data types.

532

533

```python

534

class SafetyEncoder(json.JSONEncoder):

535

"""Custom JSON encoder for Safety objects."""

536

537

def default(self, value: Any) -> Any:

538

"""

539

Serialize Safety objects to JSON-compatible formats.

540

541

Handles:

542

- SafetyRequirement objects

543

- packaging.version.Version objects

544

- packaging.version.LegacyVersion objects

545

- Custom data classes

546

547

Args:

548

value: Object to serialize

549

550

Returns:

551

Any: JSON-serializable representation

552

553

Raises:

554

TypeError: If object type is not supported

555

"""

556

```

557

558

**Example Usage:**

559

560

```python

561

import json

562

from safety.models import SafetyEncoder

563

564

# Serialize complex Safety data structures

565

data = {

566

'vulnerabilities': vulnerability_list, # Contains Vulnerability objects

567

'packages': package_list, # Contains Package objects

568

'requirements': requirement_list # Contains SafetyRequirement objects

569

}

570

571

json_output = json.dumps(data, cls=SafetyEncoder, indent=2)

572

```

573

574

## Configuration Models

575

576

### Schema Models { .api }

577

578

These models are imported from `safety_schemas.models`:

579

580

```python

581

from safety_schemas.models import (

582

ConfigModel, Ecosystem, FileType, Stage,

583

PolicyFileModel, DependencyResultModel

584

)

585

586

class ConfigModel:

587

"""Central configuration for Safety CLI operations."""

588

589

telemetry_enabled: bool # Enable telemetry collection

590

591

class Ecosystem(Enum):

592

"""Supported package ecosystems."""

593

PYTHON = "python"

594

595

class FileType(Enum):

596

"""Supported dependency file types."""

597

REQUIREMENTS_TXT = "requirements.txt"

598

PIPFILE = "Pipfile"

599

PYPROJECT_TOML = "pyproject.toml"

600

# ... additional file types

601

602

class Stage(Enum):

603

"""Development lifecycle stages."""

604

DEVELOPMENT = "development"

605

TESTING = "testing"

606

STAGING = "staging"

607

PRODUCTION = "production"

608

```

609

610

## Error and Exception Models

611

612

### Core Exception Classes { .api }

613

614

```python

615

from safety.errors import (

616

SafetyError, SafetyException, InvalidRequirementError,

617

InvalidCredentialError, NetworkConnectionError

618

)

619

620

class SafetyException(Exception):

621

"""Base exception for Safety CLI errors."""

622

623

def __init__(self, message: str = "Unhandled exception: {info}", info: str = ""):

624

"""Initialize with formatted message."""

625

626

def get_exit_code(self) -> int:

627

"""Get associated exit code."""

628

629

class SafetyError(Exception):

630

"""Generic Safety CLI error."""

631

632

def __init__(self, message: str = "Unhandled Safety error",

633

error_code: Optional[int] = None):

634

"""Initialize with message and optional error code."""

635

636

class InvalidRequirementError(SafetyError):

637

"""Error parsing requirement specifications."""

638

639

class InvalidCredentialError(SafetyError):

640

"""Authentication credential validation error."""

641

642

class NetworkConnectionError(SafetyError):

643

"""Network connectivity error."""

644

```

645

646

## Usage Examples

647

648

### Working with Vulnerabilities

649

650

```python

651

from safety.models import Vulnerability, Package, SafetyRequirement

652

653

# Process scan results

654

for vulnerability in scan_results.vulnerabilities:

655

print(f"🚨 {vulnerability.vulnerability_id}")

656

print(f" Package: {vulnerability.package_name}")

657

print(f" Version: {vulnerability.analyzed_version}")

658

print(f" Severity: {vulnerability.severity.cvssv3}")

659

660

if vulnerability.fixed_versions:

661

print(f" Fixed in: {', '.join(vulnerability.fixed_versions[:3])}")

662

663

# Check if vulnerability is ignored

664

if vulnerability.ignored:

665

print(f" ⚠️ Ignored: {vulnerability.ignored_reason}")

666

```

667

668

### Package Analysis

669

670

```python

671

from safety.models import Package, is_pinned_requirement

672

673

# Analyze package requirements

674

for package in discovered_packages:

675

print(f"📦 {package.name} v{package.version}")

676

677

# Check for unpinned requirements

678

if package.has_unpinned_req():

679

unpinned = list(package.get_unpinned_req())

680

for req in unpinned:

681

print(f" ⚠️ Unpinned: {req.name} {req.specifier}")

682

683

# Show latest safe version

684

if package.latest_version_without_known_vulnerabilities:

685

print(f" ✅ Latest safe: {package.latest_version_without_known_vulnerabilities}")

686

```

687

688

### Custom Serialization

689

690

```python

691

import json

692

from safety.models import SafetyEncoder

693

694

# Create custom report format

695

report = {

696

'scan_metadata': {

697

'timestamp': datetime.now(),

698

'target': '/path/to/project'

699

},

700

'findings': {

701

'vulnerabilities': vulnerability_list,

702

'packages': package_list

703

}

704

}

705

706

# Serialize with Safety encoder

707

json_report = json.dumps(report, cls=SafetyEncoder, indent=2)

708

709

# Save to file

710

with open('security_report.json', 'w') as f:

711

f.write(json_report)

712

```

713

714

This comprehensive data models documentation covers all core types and structures used throughout Safety CLI, enabling developers to understand and work with vulnerability data, package information, and security analysis results programmatically.