Edit on GitHub

agent_search_gateway.url_store

In-memory five-field URL state machine.

 1"""In-memory five-field URL state machine."""
 2
 3from dataclasses import replace
 4
 5from .models import URLRecord
 6from .url_normalization import NormalizedURL
 7
 8
 9def _first_non_empty(existing: str, candidate: str) -> str:
10    return existing if existing else candidate
11
12
13class URLStore:
14    def __init__(self) -> None:
15        self._records: dict[NormalizedURL, URLRecord] = {}
16
17    def admit(
18        self,
19        url: NormalizedURL,
20        abstract: str,
21        *,
22        raw_content: str = "",
23        content: str = "",
24    ) -> URLRecord:
25        normalized_abstract = abstract.strip()
26        if not normalized_abstract:
27            raise ValueError("URL records require a non-empty abstract")
28
29        existing = self._records.get(url)
30        if existing is None:
31            record = URLRecord(
32                url=url,
33                raw_content=raw_content,
34                content=content,
35                abstract=normalized_abstract,
36            )
37        else:
38            record = replace(
39                existing,
40                raw_content=_first_non_empty(existing.raw_content, raw_content),
41                content=_first_non_empty(existing.content, content),
42                abstract=_first_non_empty(existing.abstract, normalized_abstract),
43            )
44        self._records[url] = record
45        return record
46
47    def merge_body(
48        self,
49        url: NormalizedURL,
50        *,
51        raw_content: str = "",
52        content: str = "",
53    ) -> URLRecord:
54        existing = self._require(url)
55        record = replace(
56            existing,
57            raw_content=_first_non_empty(existing.raw_content, raw_content),
58            content=_first_non_empty(existing.content, content),
59        )
60        self._records[url] = record
61        return record
62
63    def mark_unavailable(self, url: NormalizedURL) -> URLRecord:
64        existing = self._require(url)
65        if not existing.available:
66            return existing
67        record = replace(existing, available=False)
68        self._records[url] = record
69        return record
70
71    def get(self, url: NormalizedURL) -> URLRecord | None:
72        return self._records.get(url)
73
74    def _require(self, url: NormalizedURL) -> URLRecord:
75        record = self._records.get(url)
76        if record is None:
77            raise KeyError(str(url))
78        return record
class URLStore:
14class URLStore:
15    def __init__(self) -> None:
16        self._records: dict[NormalizedURL, URLRecord] = {}
17
18    def admit(
19        self,
20        url: NormalizedURL,
21        abstract: str,
22        *,
23        raw_content: str = "",
24        content: str = "",
25    ) -> URLRecord:
26        normalized_abstract = abstract.strip()
27        if not normalized_abstract:
28            raise ValueError("URL records require a non-empty abstract")
29
30        existing = self._records.get(url)
31        if existing is None:
32            record = URLRecord(
33                url=url,
34                raw_content=raw_content,
35                content=content,
36                abstract=normalized_abstract,
37            )
38        else:
39            record = replace(
40                existing,
41                raw_content=_first_non_empty(existing.raw_content, raw_content),
42                content=_first_non_empty(existing.content, content),
43                abstract=_first_non_empty(existing.abstract, normalized_abstract),
44            )
45        self._records[url] = record
46        return record
47
48    def merge_body(
49        self,
50        url: NormalizedURL,
51        *,
52        raw_content: str = "",
53        content: str = "",
54    ) -> URLRecord:
55        existing = self._require(url)
56        record = replace(
57            existing,
58            raw_content=_first_non_empty(existing.raw_content, raw_content),
59            content=_first_non_empty(existing.content, content),
60        )
61        self._records[url] = record
62        return record
63
64    def mark_unavailable(self, url: NormalizedURL) -> URLRecord:
65        existing = self._require(url)
66        if not existing.available:
67            return existing
68        record = replace(existing, available=False)
69        self._records[url] = record
70        return record
71
72    def get(self, url: NormalizedURL) -> URLRecord | None:
73        return self._records.get(url)
74
75    def _require(self, url: NormalizedURL) -> URLRecord:
76        record = self._records.get(url)
77        if record is None:
78            raise KeyError(str(url))
79        return record
def admit( self, url: agent_search_gateway.url_normalization.NormalizedURL, abstract: str, *, raw_content: str = '', content: str = '') -> agent_search_gateway.models.URLRecord:
18    def admit(
19        self,
20        url: NormalizedURL,
21        abstract: str,
22        *,
23        raw_content: str = "",
24        content: str = "",
25    ) -> URLRecord:
26        normalized_abstract = abstract.strip()
27        if not normalized_abstract:
28            raise ValueError("URL records require a non-empty abstract")
29
30        existing = self._records.get(url)
31        if existing is None:
32            record = URLRecord(
33                url=url,
34                raw_content=raw_content,
35                content=content,
36                abstract=normalized_abstract,
37            )
38        else:
39            record = replace(
40                existing,
41                raw_content=_first_non_empty(existing.raw_content, raw_content),
42                content=_first_non_empty(existing.content, content),
43                abstract=_first_non_empty(existing.abstract, normalized_abstract),
44            )
45        self._records[url] = record
46        return record
def merge_body( self, url: agent_search_gateway.url_normalization.NormalizedURL, *, raw_content: str = '', content: str = '') -> agent_search_gateway.models.URLRecord:
48    def merge_body(
49        self,
50        url: NormalizedURL,
51        *,
52        raw_content: str = "",
53        content: str = "",
54    ) -> URLRecord:
55        existing = self._require(url)
56        record = replace(
57            existing,
58            raw_content=_first_non_empty(existing.raw_content, raw_content),
59            content=_first_non_empty(existing.content, content),
60        )
61        self._records[url] = record
62        return record
64    def mark_unavailable(self, url: NormalizedURL) -> URLRecord:
65        existing = self._require(url)
66        if not existing.available:
67            return existing
68        record = replace(existing, available=False)
69        self._records[url] = record
70        return record
72    def get(self, url: NormalizedURL) -> URLRecord | None:
73        return self._records.get(url)