Coverage for src/usaspending/models/spending.py: 100%
33 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-03 17:15 -0700
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-03 17:15 -0700
1"""Base spending model for USASpending spending by category data."""
3from __future__ import annotations
5from typing import Optional, TYPE_CHECKING
6from ..utils.formatter import to_float
7from .base_model import BaseModel
9if TYPE_CHECKING:
10 from ..client import USASpending
13class Spending(BaseModel):
14 """Base model for spending by category data.
16 Represents common fields across spending by recipient and district categories.
17 This model provides access to spending data with amounts, names, codes, and outlays.
18 """
20 def __init__(self, data: dict, client: Optional["USASpending"] = None):
21 """Initialize Spending model.
23 Args:
24 data: Raw spending data from API
25 client: USASpending client instance
26 """
27 super().__init__(data)
28 self._client = client
30 @property
31 def id(self) -> Optional[int]:
32 """Database ID for the spending record."""
33 return self.get_value(["id"])
35 @property
36 def name(self) -> Optional[str]:
37 """Display name for the spending category (recipient name or district name)."""
38 return self.get_value(["name"])
40 @property
41 def code(self) -> Optional[str]:
42 """Code associated with the spending record (DUNS, district code, etc.)."""
43 return self.get_value(["code"])
45 @property
46 def amount(self) -> Optional[float]:
47 """Total spending amount for this record."""
48 return to_float(self.get_value(["amount"]))
50 @property
51 def total_outlays(self) -> Optional[float]:
52 """Total outlays for this spending record."""
53 return to_float(self.get_value(["total_outlays"]))
55 @property
56 def spending_level(self) -> Optional[str]:
57 """The spending level used for this data (transactions, awards, subawards)."""
58 return self.get_value(["spending_level"])
60 @property
61 def category(self) -> Optional[str]:
62 """The category type (recipient or district)."""
63 return self.get_value(["category"])
65 def __repr__(self) -> str:
66 """String representation of Spending."""
67 name = self.name or "Unknown"
68 amount = self.amount or 0
69 return f"<Spending {name}: ${amount:,.2f}>"