From 7954b7c22d4ac33ffab904b853313217496c1ab7 Mon Sep 17 00:00:00 2001 From: kasparasizi1 <132673909+kasparasizi1@users.noreply.github.com> Date: Fri, 17 Jul 2026 23:07:51 +0300 Subject: [PATCH] feat: add is_ended to eBay Item, broaden end_time to sold time (SCR-122) is_ended: bool (default False) - listing has closed (sold / ended), any buying format. end_time_utc/end_time_at now also set for ended/sold listings of any format (the exact sold time), not just active auctions; still None for active fixed-price listings. Rides along with unreleased 0.21.0. --- CHANGELOG.md | 1 + src/scrapebadger/ebay/models.py | 5 +++-- tests/test_ebay.py | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a42a560..af05dc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - **eBay completed-search sold dates** — `SearchResult` now exposes `sold_date` (sale date text as rendered by eBay, e.g. "2 Jul 2026"; localized on non-English markets) and `sold_date_at` (best-effort ISO date "2026-07-02", `None` when the market's format isn't English) on `client.ebay` completed/sold result cards. (SCR-122) +- **eBay item `is_ended`** — `Item` now exposes `is_ended` (`True` when the listing has closed — sold or ended — any buying format, default `False`). `end_time_utc`/`end_time_at` broaden from auction-only to the listing end: auction close or sold time for ended listings of any format; still `None` for active fixed-price listings. (SCR-122) ## [0.20.0] - 2026-07-13 diff --git a/src/scrapebadger/ebay/models.py b/src/scrapebadger/ebay/models.py index d83e189..19ee65e 100644 --- a/src/scrapebadger/ebay/models.py +++ b/src/scrapebadger/ebay/models.py @@ -180,8 +180,9 @@ class Item(_BaseModel): bids: int | None = None current_bid: EbayPrice | None = None # auctions: the current high bid (mirrors ``price``) time_left: str | None = None # relative remaining, e.g. "12h 16m" - end_time_utc: float | None = None # absolute auction end (Unix float) - end_time_at: str | None = None # absolute auction end (ISO-8601 Z) + is_ended: bool = False # listing has closed (sold / ended), any buying format + end_time_utc: float | None = None # listing end: auction close / sold time (Unix float) + end_time_at: str | None = None # listing end: auction close / sold time (ISO-8601 Z) buy_it_now_price: EbayPrice | None = None # BIN price (fixed-price, or auction-with-BIN) best_offer_enabled: bool | None = None brand: str | None = None diff --git a/tests/test_ebay.py b/tests/test_ebay.py index e982ce6..1156d29 100644 --- a/tests/test_ebay.py +++ b/tests/test_ebay.py @@ -164,6 +164,7 @@ "bids": 19, "current_bid": SAMPLE_AUCTION_BID, "time_left": "12h 5m", + "is_ended": False, "end_time_utc": 1782157851.0, "end_time_at": "2026-06-22T19:50:51Z", "buy_it_now_price": None, @@ -419,13 +420,19 @@ def test_item_auction(self) -> None: assert item.current_bid is not None assert item.current_bid.value == 1430.0 assert item.time_left == "12h 5m" + assert item.is_ended is False assert item.end_time_utc == 1782157851.0 assert item.end_time_at == "2026-06-22T19:50:51Z" assert item.buy_it_now_price is None + def test_item_ended(self) -> None: + item = Item.model_validate({**SAMPLE_AUCTION_ITEM, "is_ended": True, "time_left": None}) + assert item.is_ended is True + def test_item_non_auction_has_no_auction_fields(self) -> None: item = Item.model_validate(SAMPLE_ITEM) assert item.is_auction is False + assert item.is_ended is False assert item.current_bid is None assert item.end_time_utc is None assert item.end_time_at is None