fastrag.ingestion.steps.fetching.local#
Local-disk fetching: files matched by glob, one Source per file.
Where FileSource fetches one
URL and the crawlers discover pages over HTTP, LocalFileFetcher reads
whatever a corpus that already lives on disk needs — “every spreadsheet
under data/” — without publishing it over HTTP first. A pattern is a
plain file path, a directory path (expanded to the files under it,
recursively), or a glob (including **); several patterns may be given at
once and their results are deduplicated.
Caching is one bucket per file, via the same targets/evaluate_target
hooks SitemapCrawler uses
for its per-page buckets — one new file appearing under a watched directory
never invalidates the files already cached. Freshness is checked cheaply,
without rereading a file’s bytes: a file’s size doubles as its “ETag” (an
opaque validator, same slot HTTP’s ETag occupies) and its mtime as its
“Last-Modified” — both available from a single stat() call. Content is
only reread when either changes.
Classes
|
Fetch local files matched by glob, yielding one |
- class fastrag.ingestion.steps.fetching.local.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.