fastrag.ingestion.steps.fetching#
Fetching: locations in, Source objects out.
Fetcher is the abstract leaf-level SourceStep concrete fetchers
extend; Sources aggregates several of them (or other SourceSteps)
into one stream; SitemapCrawler, WebCrawler, FileSource, and
LocalFileFetcher are the concrete fetchers this package ships —
FileSource for exactly one URL, LocalFileFetcher for local files
matched by glob, the other two for discovering many pages over HTTP.
S3Fetcher is named in docs/specification/API.md but has no old
counterpart to port and is a later plan’s territory.
- class fastrag.ingestion.steps.fetching.Renderer[source]#
Bases:
ABCTurn an HTTP response into raw content before hashing and caching.
- abstractmethod async render(page)[source]#
Return raw rendered content with response provenance preserved.
- Parameters:
page (FetchedPage)
- Return type:
- class fastrag.ingestion.steps.fetching.HttpRenderer[source]#
Bases:
RendererKeep the HTTP response unchanged; perform no browser work.
- async render(page)[source]#
Return the response unchanged.
- Parameters:
page (FetchedPage)
- Return type:
- async aclose()#
Release any long-lived resources. Idempotent; a no-op by default.
- Return type:
None
- class fastrag.ingestion.steps.fetching.PlaywrightRenderer(*, timeout=30, wait_selector=None, browser=None, wait_until='networkidle')[source]#
Bases:
RendererExecute JavaScript and hydrate HTML without model-driven interaction.
- Parameters:
- async render(page)[source]#
Hydrate HTML; leave non-HTML responses untouched.
- Parameters:
page (FetchedPage)
- Return type:
- async aclose()#
Release any long-lived resources. Idempotent; a no-op by default.
- Return type:
None
- class fastrag.ingestion.steps.fetching.ChatRenderer(*, model, api_key, base_url, goal='Extract all useful page content for a searchable knowledge base.', max_steps=32, max_snapshot_chars=24000, timeout=600, request_timeout=120, render_timeout=30, settle_seconds=0.5, wait_selector=None, extra_body=None, fallback=None, http_renderer=None, dynamic_renderer=None)[source]#
Bases:
RendererReveal dynamic content using an OpenAI-compatible chat model.
- Parameters:
model (str)
api_key (str)
base_url (str)
goal (str)
max_steps (int)
max_snapshot_chars (int)
timeout (float)
request_timeout (float)
render_timeout (float)
settle_seconds (float)
wait_selector (str | None)
fallback (_AIRenderer | None)
http_renderer (Renderer | None)
dynamic_renderer (Renderer | None)
- async aclose()#
Close the shared model client, browser and any fallback.
- Return type:
None
- async render(page)#
Reveal same-page content, preserving HTML across replacement states.
- Parameters:
page (FetchedPage)
- Return type:
- class fastrag.ingestion.steps.fetching.DecisionsRenderer(*, api_format='decisions', **kwargs)[source]#
Bases:
RendererReveal dynamic content using typed Decisions/System One model choices.
api_formatpicks the wire format:"decisions"(OpenAI Decisions,/decisions) or"systemone"(TypeSafe System One,/systemone).- Parameters:
api_format (Literal['decisions', 'systemone'])
kwargs (Any)
- async aclose()#
Close the shared model client, browser and any fallback.
- Return type:
None
- async render(page)#
Reveal same-page content, preserving HTML across replacement states.
- Parameters:
page (FetchedPage)
- Return type:
- class fastrag.ingestion.steps.fetching.Fetcher(*args, **kwargs)[source]#
Bases:
SourceStep,ABCBase class for leaf-level data fetchers that extract raw content from a single protocol/medium.
Every event a fetcher emits is labelled
"Fetching"— restated here rather than only inherited fromSourceStepso the family’s own module states the stage it belongs to.Fetchers that discover URLs (crawlers) can delegate specific ones to other fetchers with
route(), e.g. YouTube links to aYouTubeFetcher.- Parameters:
args (Any)
kwargs (Any)
- event_name: str = 'Fetching'#
The stage this step’s work belongs to, e.g.
"Chunking".Declared as a plain class attribute by a family base class, and inherited by every concrete step in that family:
class Chunker(DocumentStep, ABC): event_name = "Chunking" class ChunkerRouter(RoutedStep[Document], Chunker): ... # -> "Chunking", inherited from `Chunker`
A concrete step overrides it to opt out of its family’s label:
class ChunkerRouter(RoutedStep[Document], Chunker): event_name = "ChunkerRouter" # -> "ChunkerRouter"
Resolution walks the MRO for the first class that declares it in its own class body (so a mixin listed first, e.g.
RoutedStep, contributes nothing unless it declares one itself), and falls back to the class’s own name when nothing in the MRO does — a step family that never declares anevent_namestill labels each of its steps distinctly rather than collapsing them under one blank heading. That fallback is computed per instance rather than assigned onto the class: assigning it would make it look “declared” to every subclass, which would then inherit their base’s name instead of getting their own.
- route(filter_rule, fetcher)[source]#
Delegate the URLs matching
filter_ruletofetcher.The filter sees a content-less
Sourcecarrying only the URL, so URL-based filters such asURLFilterapply. Routes are tried in registration order, and the first match wins.
- canonical_uri(uri)[source]#
Identity under which
uriis fetched, to deduplicate equivalent spellings.
- async fetch(uri)[source]#
Fetch one URL in-process, uncached. Needed to be a
route()target.- Raises:
fastrag.exceptions.ConfigurationError – This fetcher cannot fetch an arbitrary URL.
- Parameters:
uri (str)
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- abstractmethod config()#
Return this step’s own configuration, for cache-identity hashing.
Every concrete step declares this explicitly — steps are plain classes, not dataclasses, so there is no automatic field introspection. A step that forgets it cannot be instantiated:
configis abstract, so construction itself fails loudly rather thanconfig_hashsilently collapsing to a constant.
- property config_hash: str#
A stable hash of this step’s class name and
config().Two identically configured steps of the same class hash equal; changing any declared config value changes the hash; the hash is stable across processes. Used as part of every cache id this step’s evaluation reads or writes.
- effective_policy(context)#
Resolve this step’s policy over the one inherited from
context.The step’s own explicitly-set fields take priority; everything else falls through to the pipeline (or enclosing router/aggregator) policy.
- Parameters:
context (ExecutionContext)
- Return type:
- abstractmethod evaluate(context)#
Lazily evaluate the step within an execution context.
- Parameters:
context (ExecutionContext) – Execution-scoped state and services.
- Yields:
Values produced by the step.
- Return type:
- async run()#
Execute this step independently and collect every item.
Builds a default
ExecutionContextwhen none is installed (this step’s ownpolicy, or a freshPolicy). Intended primarily for testing and standalone use — pipeline-wide event observation isPipeline’s job.- Return type:
list[T]
- property upstream: PipelineStep[Any] | None#
Return the upstream step bound via
__call__, orNone.Read-only counterpart to
__call__’sself._upstreamassignment — lets external code (e.g.Pipeline, walking a graph from its root to classify each step by position) introspect composition without reaching into a private attribute.
- class fastrag.ingestion.steps.fetching.FileSource(*, url, renderer=None, headers=None, timeout=30.0, follow_redirects=True, user_agent='fastrag/0.1 (+https://github.com/AgrospAI/fastrag)', cache=None, policy=None, cache_validation_interval=None)[source]#
Bases:
FetcherFetch exactly one URL, yielding exactly one
Source.from fastrag.ingestion.steps.fetching import FileSource source = FileSource( url="https://example.com/report.xlsx", cache=cache, )
- Parameters:
- config()[source]#
This fetcher’s cache fingerprint: only what changes the fetched bytes.
urlis deliberately excluded, exactly asconfig()excludes the pages it discovers — the URL is already encoded in the per-target cache id (seetargets()), so including it here too would only make the fingerprint redundant, not more correct.
- async targets(context)[source]#
Return the one normalized URL this fetcher targets.
Called by the base class’s per-target cache wrap before deciding whether
evaluate_target()needs to run.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_target(target, context)[source]#
Fetch the URL, yielding the single
Sourceit produces.- Parameters:
target (str)
context (ExecutionContext)
- Return type:
- async evaluate(context)[source]#
Fetch the URL, uncached.
Used directly when no cache is in effect — the per-target cache wrap (
targets()/evaluate_target()) is what applies when one is.- Parameters:
context (ExecutionContext)
- Return type:
- async is_source_modified(source_id, cached_etag, cached_last_modified, cached_content_hash)[source]#
Conditional freshness check: ETag, then Last-Modified, then content hash.
Identical ladder to
is_source_modified():source_idis the cached entry’s normalized id, still carrying a scheme, so it is directly usable as a fetchable URI here. A server that answers none of the three (refusesHEADand gives no reusable validator) reads as modified only implicitly: the refetch-and-compare fallback below always produces a definite answer.
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- canonical_uri(uri)#
Identity under which
uriis fetched, to deduplicate equivalent spellings.
- property config_hash: str#
A stable hash of this step’s class name and
config().Two identically configured steps of the same class hash equal; changing any declared config value changes the hash; the hash is stable across processes. Used as part of every cache id this step’s evaluation reads or writes.
- effective_policy(context)#
Resolve this step’s policy over the one inherited from
context.The step’s own explicitly-set fields take priority; everything else falls through to the pipeline (or enclosing router/aggregator) policy.
- Parameters:
context (ExecutionContext)
- Return type:
- event_name: str = 'Fetching'#
The stage this step’s work belongs to, e.g.
"Chunking".Declared as a plain class attribute by a family base class, and inherited by every concrete step in that family:
class Chunker(DocumentStep, ABC): event_name = "Chunking" class ChunkerRouter(RoutedStep[Document], Chunker): ... # -> "Chunking", inherited from `Chunker`
A concrete step overrides it to opt out of its family’s label:
class ChunkerRouter(RoutedStep[Document], Chunker): event_name = "ChunkerRouter" # -> "ChunkerRouter"
Resolution walks the MRO for the first class that declares it in its own class body (so a mixin listed first, e.g.
RoutedStep, contributes nothing unless it declares one itself), and falls back to the class’s own name when nothing in the MRO does — a step family that never declares anevent_namestill labels each of its steps distinctly rather than collapsing them under one blank heading. That fallback is computed per instance rather than assigned onto the class: assigning it would make it look “declared” to every subclass, which would then inherit their base’s name instead of getting their own.
- async fetch(uri)#
Fetch one URL in-process, uncached. Needed to be a
route()target.- Raises:
fastrag.exceptions.ConfigurationError – This fetcher cannot fetch an arbitrary URL.
- Parameters:
uri (str)
- Return type:
- route(filter_rule, fetcher)#
Delegate the URLs matching
filter_ruletofetcher.The filter sees a content-less
Sourcecarrying only the URL, so URL-based filters such asURLFilterapply. Routes are tried in registration order, and the first match wins.
- route_for(uri)#
The fetcher routed to
uri, orNoneto fetch it normally.
- routes_config()#
Routed fetchers’ fingerprints, for inclusion in a crawler’s
config().
- async run()#
Execute this step independently and collect every item.
Builds a default
ExecutionContextwhen none is installed (this step’s ownpolicy, or a freshPolicy). Intended primarily for testing and standalone use — pipeline-wide event observation isPipeline’s job.- Return type:
list[T]
- property upstream: PipelineStep[Any] | None#
Return the upstream step bound via
__call__, orNone.Read-only counterpart to
__call__’sself._upstreamassignment — lets external code (e.g.Pipeline, walking a graph from its root to classify each step by position) introspect composition without reaching into a private attribute.
- class fastrag.ingestion.steps.fetching.LocalFileFetcher(*, patterns, include=None, exclude=None, max_files=None, cache=None, policy=None, cache_validation_interval=None)[source]#
Bases:
FetcherFetch local files matched by glob, yielding one
Sourceper file.from fastrag.ingestion.steps.fetching import LocalFileFetcher fetcher = LocalFileFetcher( patterns=["data/**/*.xlsx"], exclude=["data/**/~$*"], cache=cache, )
Each element of
patternsmay be a plain file path, a directory path (every file under it, recursively), or a glob pattern (*,?,[...], and**when used with a directory-spanning segment — seeglob.glob()). A pattern that matches no files is an error, not a silent no-op: a typo’d path should fail loudly rather than quietly ingest nothing.- Parameters:
- config()[source]#
This fetcher’s cache fingerprint.
Empty: unlike the HTTP-speaking fetchers, nothing here changes what bytes a given file returns — that is entirely up to the filesystem.
patterns/include/exclude/max_filesdecide which files are discovered, not what a given file’s bytes are, the same reasoningconfig()documents for its own URL selection — so they are deliberately excluded here too. Per-file cache ids already encode the file’s own URI as theirtarget.
- async targets(context)[source]#
Return the filtered, deduplicated
file://URIs this fetcher targets.Called by the base class’s per-target cache wrap before deciding which files need
evaluate_target(). Expansion (globbing, directory walks, and thestatcalls needed to tell a file from a directory) runs in a worker thread so it never blocks the event loop.- Raises:
fastrag.exceptions.FetchError – A pattern in
patternsmatched no files.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_target(target, context)[source]#
Read one file, yielding the single
Sourceit produces.- Parameters:
target (str)
context (ExecutionContext)
- Return type:
- async evaluate(context)[source]#
Read every matched file, uncached, bounded by
policy.concurrency.Used directly when no cache is in effect — the per-target cache wrap (
targets()/evaluate_target()) is what applies when one is.- Parameters:
context (ExecutionContext)
- Return type:
- async is_source_modified(source_id, cached_etag, cached_last_modified, cached_content_hash)[source]#
Conditional freshness check: file size, then mtime — never rereading bytes.
cached_etagholds the file’s size at the time it was cached (this fetcher’s stand-in for an HTTPETag, an opaque origin validator, populated the same way by_fetch_source) andcached_last_modifiedits mtime. A file that no longer exists, or can no longer bestat-ed, reads as modified — the same “unanswerable freshness question” logicis_source_modified()applies to a server that refusesHEAD: an attempted refetch always produces a definite answer (here, aFetchError), rather than silently keeping stale bytes.
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- canonical_uri(uri)#
Identity under which
uriis fetched, to deduplicate equivalent spellings.
- property config_hash: str#
A stable hash of this step’s class name and
config().Two identically configured steps of the same class hash equal; changing any declared config value changes the hash; the hash is stable across processes. Used as part of every cache id this step’s evaluation reads or writes.
- effective_policy(context)#
Resolve this step’s policy over the one inherited from
context.The step’s own explicitly-set fields take priority; everything else falls through to the pipeline (or enclosing router/aggregator) policy.
- Parameters:
context (ExecutionContext)
- Return type:
- event_name: str = 'Fetching'#
The stage this step’s work belongs to, e.g.
"Chunking".Declared as a plain class attribute by a family base class, and inherited by every concrete step in that family:
class Chunker(DocumentStep, ABC): event_name = "Chunking" class ChunkerRouter(RoutedStep[Document], Chunker): ... # -> "Chunking", inherited from `Chunker`
A concrete step overrides it to opt out of its family’s label:
class ChunkerRouter(RoutedStep[Document], Chunker): event_name = "ChunkerRouter" # -> "ChunkerRouter"
Resolution walks the MRO for the first class that declares it in its own class body (so a mixin listed first, e.g.
RoutedStep, contributes nothing unless it declares one itself), and falls back to the class’s own name when nothing in the MRO does — a step family that never declares anevent_namestill labels each of its steps distinctly rather than collapsing them under one blank heading. That fallback is computed per instance rather than assigned onto the class: assigning it would make it look “declared” to every subclass, which would then inherit their base’s name instead of getting their own.
- async fetch(uri)#
Fetch one URL in-process, uncached. Needed to be a
route()target.- Raises:
fastrag.exceptions.ConfigurationError – This fetcher cannot fetch an arbitrary URL.
- Parameters:
uri (str)
- Return type:
- route(filter_rule, fetcher)#
Delegate the URLs matching
filter_ruletofetcher.The filter sees a content-less
Sourcecarrying only the URL, so URL-based filters such asURLFilterapply. Routes are tried in registration order, and the first match wins.
- route_for(uri)#
The fetcher routed to
uri, orNoneto fetch it normally.
- routes_config()#
Routed fetchers’ fingerprints, for inclusion in a crawler’s
config().
- async run()#
Execute this step independently and collect every item.
Builds a default
ExecutionContextwhen none is installed (this step’s ownpolicy, or a freshPolicy). Intended primarily for testing and standalone use — pipeline-wide event observation isPipeline’s job.- Return type:
list[T]
- property upstream: PipelineStep[Any] | None#
Return the upstream step bound via
__call__, orNone.Read-only counterpart to
__call__’sself._upstreamassignment — lets external code (e.g.Pipeline, walking a graph from its root to classify each step by position) introspect composition without reaching into a private attribute.
- class fastrag.ingestion.steps.fetching.SitemapCrawler(*, url, include=None, exclude=None, max_urls=None, renderer=None, extract_pdfs=True, headers=None, timeout=30.0, follow_redirects=True, user_agent='fastrag/0.1 (+https://github.com/AgrospAI/fastrag)', cache=None, policy=None, cache_validation_interval=None)[source]#
Bases:
FetcherExpand
sitemap.xml, then fetch what it lists.The right default for a website: the site itself publishes the canonical page list, so a rerun picks up new pages without editing any code. Nested
<sitemapindex>documents are followed.from fastrag.ingestion.steps.fetching import SitemapCrawler crawler = SitemapCrawler( url="https://example.com/sitemap.xml", include=["https://example.com/docs/*"], cache=cache, )
- Parameters:
- config()[source]#
This crawler’s cache fingerprint: only what changes a page’s bytes.
url,include,exclude, andmax_urlsdecide which pages are discovered, not what a given page returns, so they are deliberately excluded here — otherwise raisingmax_urlswould invalidate every already-cached page’s bucket for no reason. Per-page cache ids already encode the page’s own URL as theirtarget.
- async targets(context)[source]#
Return the filtered page URLs the sitemap lists, normalized and deduplicated.
Costs one request per sitemap document, and no page downloads. Called by the base class’s per-target cache wrap before deciding which pages need
evaluate_target().Sitemaps routinely list one page under several spellings (
/auditand/audit/, a stray#fragment, an explicit:443). Those all collapse to onenormalize_uri(), and so to oneSource.id, so they are collapsed here too — into a single target and a single cache bucket, rather than fetched repeatedly and written over each other.include/excludestill see the sitemap’s own spelling for glob patterns; exact URLs match normalized spellings too.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_target(target, context)[source]#
Fetch one page URL, yielding its
Sourcethen one per routed embed.- Parameters:
target (str)
context (ExecutionContext)
- Return type:
- async evaluate(context)[source]#
Fetch every listed page, uncached, bounded by
policy.concurrency.Used directly when no cache is in effect — the per-target cache wrap (
targets()/evaluate_target()) is what applies when one is.- Parameters:
context (ExecutionContext)
- Return type:
- async is_source_modified(source_id, cached_etag, cached_last_modified, cached_content_hash)[source]#
Conditional freshness check: ETag, then Last-Modified, then content hash.
source_idis the cached entry’s normalized id, which — unlikeAPI.md’s illustrative example — still carries a scheme, so it is directly usable as a fetchable URI here. A server that answers none of the three (refusesHEADand gives no reusable validator) reads as modified only implicitly: the refetch-and-compare fallback below always produces a definite answer.
- async aclose()[source]#
Release the shared HTTP client and renderer resources. Idempotent.
- Return type:
None
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- canonical_uri(uri)#
Identity under which
uriis fetched, to deduplicate equivalent spellings.
- property config_hash: str#
A stable hash of this step’s class name and
config().Two identically configured steps of the same class hash equal; changing any declared config value changes the hash; the hash is stable across processes. Used as part of every cache id this step’s evaluation reads or writes.
- effective_policy(context)#
Resolve this step’s policy over the one inherited from
context.The step’s own explicitly-set fields take priority; everything else falls through to the pipeline (or enclosing router/aggregator) policy.
- Parameters:
context (ExecutionContext)
- Return type:
- event_name: str = 'Fetching'#
The stage this step’s work belongs to, e.g.
"Chunking".Declared as a plain class attribute by a family base class, and inherited by every concrete step in that family:
class Chunker(DocumentStep, ABC): event_name = "Chunking" class ChunkerRouter(RoutedStep[Document], Chunker): ... # -> "Chunking", inherited from `Chunker`
A concrete step overrides it to opt out of its family’s label:
class ChunkerRouter(RoutedStep[Document], Chunker): event_name = "ChunkerRouter" # -> "ChunkerRouter"
Resolution walks the MRO for the first class that declares it in its own class body (so a mixin listed first, e.g.
RoutedStep, contributes nothing unless it declares one itself), and falls back to the class’s own name when nothing in the MRO does — a step family that never declares anevent_namestill labels each of its steps distinctly rather than collapsing them under one blank heading. That fallback is computed per instance rather than assigned onto the class: assigning it would make it look “declared” to every subclass, which would then inherit their base’s name instead of getting their own.
- async fetch(uri)#
Fetch one URL in-process, uncached. Needed to be a
route()target.- Raises:
fastrag.exceptions.ConfigurationError – This fetcher cannot fetch an arbitrary URL.
- Parameters:
uri (str)
- Return type:
- route(filter_rule, fetcher)#
Delegate the URLs matching
filter_ruletofetcher.The filter sees a content-less
Sourcecarrying only the URL, so URL-based filters such asURLFilterapply. Routes are tried in registration order, and the first match wins.
- route_for(uri)#
The fetcher routed to
uri, orNoneto fetch it normally.
- routes_config()#
Routed fetchers’ fingerprints, for inclusion in a crawler’s
config().
- async run()#
Execute this step independently and collect every item.
Builds a default
ExecutionContextwhen none is installed (this step’s ownpolicy, or a freshPolicy). Intended primarily for testing and standalone use — pipeline-wide event observation isPipeline’s job.- Return type:
list[T]
- property upstream: PipelineStep[Any] | None#
Return the upstream step bound via
__call__, orNone.Read-only counterpart to
__call__’sself._upstreamassignment — lets external code (e.g.Pipeline, walking a graph from its root to classify each step by position) introspect composition without reaching into a private attribute.
- class fastrag.ingestion.steps.fetching.Sources(sources, cache=None, policy=None, *, filter=None, max_sources=None)[source]#
Bases:
SourceStepAggregator step combining multiple
Fetchers orSourceSteps into one stream.sources = Sources( sources=[LocalFileFetcher(...), SitemapCrawler(...)], cache=cache, # default cache for all sources policy=policy, # default policy for all sources )
- Parameters:
sources (Sequence[SourceStep])
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
max_sources (int | None)
- config()[source]#
No identity-affecting configuration of its own.
Sources is never cached as a single bucket (see
__init__) so this only exists to satisfy PipelineStep.config’s abstract contract; nothing consults it.
- async aclose()[source]#
Release resources held by children that expose an async close hook.
- Return type:
None
- async evaluate(context)[source]#
Merge every child’s stream, each cached under its own resolution.
Each child is driven through
run_source_step()— the same caching + lifecycle wrap everySourceStepgets — under a context whosecache/policyare resolved once here: a child with its own explicitcache/policykeeps them (resolution happens again, inside the child’s own wrap, against whatever this context carries); a child with neither inherits this aggregator’s.- Parameters:
context (ExecutionContext)
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- property config_hash: str#
A stable hash of this step’s class name and
config().Two identically configured steps of the same class hash equal; changing any declared config value changes the hash; the hash is stable across processes. Used as part of every cache id this step’s evaluation reads or writes.
- effective_policy(context)#
Resolve this step’s policy over the one inherited from
context.The step’s own explicitly-set fields take priority; everything else falls through to the pipeline (or enclosing router/aggregator) policy.
- Parameters:
context (ExecutionContext)
- Return type:
- event_name: str = 'Fetching'#
The stage this step’s work belongs to, e.g.
"Chunking".Declared as a plain class attribute by a family base class, and inherited by every concrete step in that family:
class Chunker(DocumentStep, ABC): event_name = "Chunking" class ChunkerRouter(RoutedStep[Document], Chunker): ... # -> "Chunking", inherited from `Chunker`
A concrete step overrides it to opt out of its family’s label:
class ChunkerRouter(RoutedStep[Document], Chunker): event_name = "ChunkerRouter" # -> "ChunkerRouter"
Resolution walks the MRO for the first class that declares it in its own class body (so a mixin listed first, e.g.
RoutedStep, contributes nothing unless it declares one itself), and falls back to the class’s own name when nothing in the MRO does — a step family that never declares anevent_namestill labels each of its steps distinctly rather than collapsing them under one blank heading. That fallback is computed per instance rather than assigned onto the class: assigning it would make it look “declared” to every subclass, which would then inherit their base’s name instead of getting their own.
- async run()#
Execute this step independently and collect every item.
Builds a default
ExecutionContextwhen none is installed (this step’s ownpolicy, or a freshPolicy). Intended primarily for testing and standalone use — pipeline-wide event observation isPipeline’s job.- Return type:
list[T]
- property upstream: PipelineStep[Any] | None#
Return the upstream step bound via
__call__, orNone.Read-only counterpart to
__call__’sself._upstreamassignment — lets external code (e.g.Pipeline, walking a graph from its root to classify each step by position) introspect composition without reaching into a private attribute.
- class fastrag.ingestion.steps.fetching.WebCrawler(*, url=None, start_urls=None, max_urls=None, max_depth=None, include=None, exclude=None, same_origin=True, renderer=None, headers=None, timeout=30.0, follow_redirects=True, user_agent='fastrag/0.1 (+https://github.com/AgrospAI/fastrag)', cache=None, policy=None, cache_validation_interval=None)[source]#
Bases:
FetcherFollow links from one or more start URLs, within configured bounds.
Accepts either a single
url=(the formexamples/08_sources.py/09_filters.pyuse) or severalstart_urls=(docs/specification/API.md’s multi-start form) — exactly one of the two must be given. Both are stored the same way internally (self.start_urls), so the rest of this class does not distinguish them.from fastrag.ingestion.steps.fetching import WebCrawler crawler = WebCrawler(url="https://docs.pontus-x.eu/", max_urls=200) crawler = WebCrawler(start_urls=["a.com", "https://b.com/"], max_depth=3)
- Parameters:
url (str | None)
start_urls (Sequence[str] | None)
max_urls (int | None)
max_depth (int | None)
same_origin (bool)
renderer (Renderer | None)
timeout (float)
follow_redirects (bool)
user_agent (str)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
cache_validation_interval (float | None)
- streams_targets = True#
A start URL’s crawl bounds, retries and times out each page itself, so the cache wrap streams it rather than running it as one timed item.
- config()[source]#
This crawler’s cache fingerprint: only what changes a page’s bytes.
start_urls,max_urls,max_depth,include,exclude, andsame_origindecide which pages are discovered, not what a given page returns, so they are deliberately excluded here — the same principleconfig()follows, for the same reason. Per-start-URL cache ids already encode the start URL itself as theirtarget.
- async targets(context)[source]#
Return the normalized start URLs — one independent cache bucket each.
- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_target(target, context)[source]#
Crawl the subtree reachable from one start URL, within bounds.
Fetches breadth-first, one level of link depth at a time, each level’s pages fetched concurrently (bounded by
policy.concurrency) viarun_concurrently()— so a page that fails to fetch after retries emits an attributedItemFailedand is skipped (policy.on_error == "skip") rather than aborting the whole crawl. Avisitedset, seeded withtargetitself, guarantees every URL is fetched at most once per call even when several pages link to it, and pages are deduplicated again by theSource.idthey actually resolve to, so two URLs that redirect to one page are yielded (and cached) once.- Parameters:
target (str)
context (ExecutionContext)
- Return type:
- async evaluate(context)[source]#
Crawl every start URL, uncached, bounded by
policy.concurrency.Used directly when no cache is in effect — the per-target cache wrap (
targets()/evaluate_target()) is what applies when one is. Start URLs are themselves fetched concurrently, mirroringevaluate_target()’s own per-level concurrency.- Parameters:
context (ExecutionContext)
- Return type:
- async is_source_modified(source_id, cached_etag, cached_last_modified, cached_content_hash)[source]#
Conditional freshness check: ETag, then Last-Modified, then content hash.
Identical ladder to
is_source_modified(), applied here to one page within a start URL’s cached bucket — the base class’s_any_modifiedcalls this once per cached page, and treats the whole bucket as stale (recrawling the entire start URL viaevaluate_target()) if any one page reports modified.
- async aclose()[source]#
Release the shared HTTP client and renderer resources. Idempotent.
- Return type:
None
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- canonical_uri(uri)#
Identity under which
uriis fetched, to deduplicate equivalent spellings.
- property config_hash: str#
A stable hash of this step’s class name and
config().Two identically configured steps of the same class hash equal; changing any declared config value changes the hash; the hash is stable across processes. Used as part of every cache id this step’s evaluation reads or writes.
- effective_policy(context)#
Resolve this step’s policy over the one inherited from
context.The step’s own explicitly-set fields take priority; everything else falls through to the pipeline (or enclosing router/aggregator) policy.
- Parameters:
context (ExecutionContext)
- Return type:
- event_name: str = 'Fetching'#
The stage this step’s work belongs to, e.g.
"Chunking".Declared as a plain class attribute by a family base class, and inherited by every concrete step in that family:
class Chunker(DocumentStep, ABC): event_name = "Chunking" class ChunkerRouter(RoutedStep[Document], Chunker): ... # -> "Chunking", inherited from `Chunker`
A concrete step overrides it to opt out of its family’s label:
class ChunkerRouter(RoutedStep[Document], Chunker): event_name = "ChunkerRouter" # -> "ChunkerRouter"
Resolution walks the MRO for the first class that declares it in its own class body (so a mixin listed first, e.g.
RoutedStep, contributes nothing unless it declares one itself), and falls back to the class’s own name when nothing in the MRO does — a step family that never declares anevent_namestill labels each of its steps distinctly rather than collapsing them under one blank heading. That fallback is computed per instance rather than assigned onto the class: assigning it would make it look “declared” to every subclass, which would then inherit their base’s name instead of getting their own.
- async fetch(uri)#
Fetch one URL in-process, uncached. Needed to be a
route()target.- Raises:
fastrag.exceptions.ConfigurationError – This fetcher cannot fetch an arbitrary URL.
- Parameters:
uri (str)
- Return type:
- route(filter_rule, fetcher)#
Delegate the URLs matching
filter_ruletofetcher.The filter sees a content-less
Sourcecarrying only the URL, so URL-based filters such asURLFilterapply. Routes are tried in registration order, and the first match wins.
- route_for(uri)#
The fetcher routed to
uri, orNoneto fetch it normally.
- routes_config()#
Routed fetchers’ fingerprints, for inclusion in a crawler’s
config().
- async run()#
Execute this step independently and collect every item.
Builds a default
ExecutionContextwhen none is installed (this step’s ownpolicy, or a freshPolicy). Intended primarily for testing and standalone use — pipeline-wide event observation isPipeline’s job.- Return type:
list[T]
- property upstream: PipelineStep[Any] | None#
Return the upstream step bound via
__call__, orNone.Read-only counterpart to
__call__’sself._upstreamassignment — lets external code (e.g.Pipeline, walking a graph from its root to classify each step by position) introspect composition without reaching into a private attribute.
- class fastrag.ingestion.steps.fetching.YouTubeFetcher(*, url=None, audio_only=False, cache=None, policy=None, cache_validation_interval=None)[source]#
Bases:
FetcherDownload one YouTube video, yielding its media bytes as a
Source.Needs the “video” extra (
yt-dlp).- Parameters:
url (str | None)
audio_only (bool)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
cache_validation_interval (float | None)
- async targets(context)[source]#
The one video this fetcher targets.
- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_target(target, context)[source]#
Download the video, yielding its
Source.- Parameters:
target (str)
context (ExecutionContext)
- Return type:
- async evaluate(context)[source]#
Download the video, uncached.
- Parameters:
context (ExecutionContext)
- Return type:
- async is_source_modified(source_id, cached_etag, cached_last_modified, cached_content_hash)[source]#
Never: a video’s bytes are keyed by its id and do not change.
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- property config_hash: str#
A stable hash of this step’s class name and
config().Two identically configured steps of the same class hash equal; changing any declared config value changes the hash; the hash is stable across processes. Used as part of every cache id this step’s evaluation reads or writes.
- effective_policy(context)#
Resolve this step’s policy over the one inherited from
context.The step’s own explicitly-set fields take priority; everything else falls through to the pipeline (or enclosing router/aggregator) policy.
- Parameters:
context (ExecutionContext)
- Return type:
- event_name: str = 'Fetching'#
The stage this step’s work belongs to, e.g.
"Chunking".Declared as a plain class attribute by a family base class, and inherited by every concrete step in that family:
class Chunker(DocumentStep, ABC): event_name = "Chunking" class ChunkerRouter(RoutedStep[Document], Chunker): ... # -> "Chunking", inherited from `Chunker`
A concrete step overrides it to opt out of its family’s label:
class ChunkerRouter(RoutedStep[Document], Chunker): event_name = "ChunkerRouter" # -> "ChunkerRouter"
Resolution walks the MRO for the first class that declares it in its own class body (so a mixin listed first, e.g.
RoutedStep, contributes nothing unless it declares one itself), and falls back to the class’s own name when nothing in the MRO does — a step family that never declares anevent_namestill labels each of its steps distinctly rather than collapsing them under one blank heading. That fallback is computed per instance rather than assigned onto the class: assigning it would make it look “declared” to every subclass, which would then inherit their base’s name instead of getting their own.
- route(filter_rule, fetcher)#
Delegate the URLs matching
filter_ruletofetcher.The filter sees a content-less
Sourcecarrying only the URL, so URL-based filters such asURLFilterapply. Routes are tried in registration order, and the first match wins.
- route_for(uri)#
The fetcher routed to
uri, orNoneto fetch it normally.
- routes_config()#
Routed fetchers’ fingerprints, for inclusion in a crawler’s
config().
- async run()#
Execute this step independently and collect every item.
Builds a default
ExecutionContextwhen none is installed (this step’s ownpolicy, or a freshPolicy). Intended primarily for testing and standalone use — pipeline-wide event observation isPipeline’s job.- Return type:
list[T]
- property upstream: PipelineStep[Any] | None#
Return the upstream step bound via
__call__, orNone.Read-only counterpart to
__call__’sself._upstreamassignment — lets external code (e.g.Pipeline, walking a graph from its root to classify each step by position) introspect composition without reaching into a private attribute.
Modules
The |
|
Single-URL fetching: exactly one file at exactly one URL. |
|
Shared HTTP transport for the fetching steps that speak HTTP. |
|
Local-disk fetching: files matched by glob, one |
|
Pluggable raw-content renderers, owned by the fetching stage. |
|
Sitemap-driven fetching: expand |
|
|
|
Link-following crawling: start from one or more URLs, follow what they link to. |
|
YouTube video fetching, and the iframe-embed discovery crawlers route through it. |