fastrag.ingestion.steps.parsing#
Source parsing: raw bytes in, documents out.
HTML parsers preserve hidden content and SVG labels by default. JavaScript
rendering and vision descriptions are optional. ParserRouter dispatches
each source to a parser by filter, e.g. html_filter to HtmlParser.
- class fastrag.ingestion.steps.parsing.AudioParser(*, model, api_key, base_url, language=None, prompt=None, timeout=600, extra_body=None, cache=None, policy=None)[source]#
Bases:
ParserTranscribe audio sources to text with an OpenAI-compatible Whisper endpoint.
base_urlis the API root (e.g.https://host/v1); the request goes to{base_url}/audio/transcriptionsas multipart form data. Credentials are excluded from cache identity; model, endpoint, language, prompt and extra form fields are included.- Parameters:
- accepted_media_types: frozenset[str] | None = frozenset({'audio/*', 'video/mp4', 'video/webm'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- async transcribe(content, filename, content_type)[source]#
POST audio bytes to the transcription endpoint and return the text.
- async transform(item, context)[source]#
Yield one transcript document for an audio source.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- content_format: ContentFormat = 'text'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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.parsing.ChandraParser(*, api_key, base_url='https://chandra.agrospai.udl.cat', output_format='markdown', timeout=900, pages=None, cache=None, policy=None)[source]#
Bases:
PDFParserOCR PDFs with Chandra; one Markdown (or HTML) document per page.
parser = ChandraParser(api_key=CHANDRA_API_KEY, base_url=CHANDRA_URL) parser = ChandraParser(..., output_format="html")
- Parameters:
api_key (str)
base_url (str)
output_format (OutputFormat)
timeout (float)
pages (Pages | None)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- content_format: ContentFormat = 'text'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- async parse_pdf(content, filename, pages)[source]#
OCR the PDF and map Chandra’s per-page results.
- Parameters:
- Return type:
- accepted_media_types: frozenset[str] | None = frozenset({'application/pdf'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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]
- async transform(item, context)#
Yield one document per non-empty PDF page, in page order.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- 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.parsing.DecisionsParser(*, api_format='decisions', **kwargs)[source]#
Bases:
ParserSelect useful source content with typed Decisions/JEV choices.
api_formatpicks the wire format:"decisions"(OpenAI Decisions,/decisions) or"systemone"(TypeSafe System One,/systemone).- Parameters:
api_format (Literal['decisions', 'systemone'])
kwargs (Any)
- accepted_media_types: frozenset[str] | None = frozenset({'application/xhtml+xml', 'text/html'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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]
- async transform(item, context)#
Yield useful Markdown from supplied source bytes without browser or page requests.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- 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.parsing.OpenAIParser(*, model, api_key, base_url, goal='Extract all useful page content for a searchable knowledge base.', timeout=600, max_snapshot_chars=24000, request_timeout=120, extra_body=None, fallback=None, cache=None, policy=None)[source]#
Bases:
ParserSelect useful source content with an OpenAI-compatible model.
- Parameters:
- accepted_media_types: frozenset[str] | None = frozenset({'application/xhtml+xml', 'text/html'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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]
- async transform(item, context)#
Yield useful Markdown from supplied source bytes without browser or page requests.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- 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.parsing.DefaultParser(*, encoding='utf-8', cache=None, policy=None)[source]#
Bases:
ParserDecode the bytes as text, without any parsing.
The text-only fallback parser
ParserRouterfalls back to for text that has no more specific route.from fastrag.ingestion.steps.parsing import DefaultParser parser = DefaultParser(encoding="latin-1")
- Parameters:
encoding (str)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- content_format: ContentFormat = 'text'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- accepted_media_types: frozenset[str] | None = frozenset({'application/javascript', 'application/json', 'application/octet-stream', 'application/x-yaml', 'application/xhtml+xml', 'application/xml', 'application/yaml', 'text/*'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- config()[source]#
This parser’s cache-identity configuration.
encodingis part of the fingerprint: decoding the same bytes differently is a different parse.
- async transform(item, context)[source]#
Yield one document holding the decoded text, or nothing if blank.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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.parsing.DoclingParser(*, output_format='markdown', describe_images=False, picture_description_options=None, allowed_formats=None, format_options=None, cache=None, policy=None)[source]#
Bases:
ParserConvert a binary document to Markdown or a serialized
DoclingDocument.Hands a
Source’s bytes to Docling’sDocumentConverter, entirely from memory (never a temporary file): Docling infers the source format from a filename derived from the source’s URI, not from anything written to disk.from fastrag.ingestion.steps.parsing import DoclingParser # Markdown, chunked by whatever chunker the caller already uses. parser = DoclingParser() # The structured document itself, for a Docling-native chunker. parser = DoclingParser(output_format="docling") # Describe the pictures found in PDFs (runs a vision model). parser = DoclingParser(describe_images=True)
In
"markdown"mode, a paginated document (PDF, slides) is organized by page: oneDocumentper non-empty page, each carryingmetadata["page_no"](1-based),metadata["page_count"]andmetadata["source_url"]. For PDFssource_urlis the source URI with a#page=Nfragment, so every chunk inherits a link to the exact page it came from. Documents without pages (.docx, HTML, …) are yielded whole, withoutpage_no.Conversion is synchronous and CPU-bound, so it always runs through
asyncio.to_threadrather than blocking the event loop it is awaited from.- Parameters:
output_format (OutputFormat)
describe_images (bool)
picture_description_options (Any | None)
allowed_formats (Sequence[InputFormat] | None)
format_options (Mapping[InputFormat, Any] | None)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- accepted_media_types: frozenset[str] | None = frozenset({'application/msword', 'application/pdf', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/xhtml+xml', 'image/*', 'text/*'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- config()[source]#
This parser’s cache-identity configuration.
output_formatchanges the shape of what a given file parses into — Markdown text versus a serializedDoclingDocument— so it is part of the fingerprint just as much asallowed_formats(which formats Docling will even attempt) is: switching either invalidates the cache instead of serving a caller who asked for one shape the other shape cached earlier.format_optionsbelongs for the same reason: it changes what Docling extracts from a given file (picture descriptions, say), so it must not serve a caller the pre-enrichment text cached earlier.
- async transform(item, context)[source]#
Yield one document per non-empty page, or nothing if there is no text.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- content_format: ContentFormat = 'text'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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.parsing.DoclingServeParser(*, api_key, base_url='https://docling.agrospai.udl.cat', timeout=600, pages=None, cache=None, policy=None)[source]#
Bases:
PDFParserParse PDFs to Markdown (one document per page) with docling-serve.
The server is asked to put a page-break marker between pages, and the Markdown is split on it. Non-contiguous
pagescost one request per contiguous run.parser = DoclingServeParser(api_key=DOCLING_API_KEY, base_url=DOCLING_URL)
- Parameters:
api_key (str)
base_url (str)
timeout (float)
pages (Pages | None)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- async parse_pdf(content, filename, pages)[source]#
Convert the PDF and split the Markdown on page breaks.
- Parameters:
- Return type:
- accepted_media_types: frozenset[str] | None = frozenset({'application/pdf'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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]
- async transform(item, context)#
Yield one document per non-empty PDF page, in page order.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- 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.parsing.DocusaurusParser(*, strip_selectors=('script', 'style', 'noscript', 'nav', 'footer', 'aside', 'a.hash-link'), encoding=None, vision=None, cache=None, policy=None)[source]#
Bases:
ParserExtract a Docusaurus page’s article, discarding the surrounding chrome.
Finds the first
divwhose class list includesmarkdown(Docusaurus themes typically render it asclass="theme-doc-markdown markdown") and converts only that subtree to Markdown, using the sameHtmlParsermachinery (strip selectors, link absolutization, HTML-to-Markdown conversion) — just scoped to the article rather than the whole document. A page with no suchdivis parsed whole, exactly asHtmlParserwould, and the produced document’s metadata records that the fallback happened.from fastrag.ingestion.steps.parsing import DocusaurusParser, ParserRouter parser = ParserRouter(cache=cache).route(docs_filter, DocusaurusParser())
- Parameters:
strip_selectors (Sequence[str])
encoding (str | None)
vision (OpenAIVisionParser | None)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- accepted_media_types: frozenset[str] | None = frozenset({'application/xhtml+xml', 'text/html'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- config()[source]#
This parser’s cache-identity configuration.
strip_selectors/encodingchange what a given page’s bytes parse into, so both are part of the fingerprint. Whichdivis matched is not configurable, so it is not part of it.
- async transform(item, context)[source]#
Yield one Markdown document per page, extracted or whole.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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.parsing.HtmlParser(*, strip_selectors=('script', 'style', 'noscript', 'nav', 'header', 'footer', 'aside'), encoding=None, vision=None, cache=None, policy=None)[source]#
Bases:
ParserConvert HTML to Markdown, dropping the page furniture first.
Markdown rather than stripped text, because the heading levels, lists, and tables it preserves are structure worth keeping. Relative links are resolved against the source’s URI, so a chunk quoted back to a user carries links that still work.
from fastrag.ingestion.steps.parsing import HtmlParser parser = HtmlParser(strip_selectors=("script", "style", ".cookie-banner"))
- Parameters:
strip_selectors (Sequence[str])
encoding (str | None)
vision (OpenAIVisionParser | None)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- accepted_media_types: frozenset[str] | None = frozenset({'application/xhtml+xml', 'text/html'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- config()[source]#
This parser’s cache-identity configuration.
strip_selectors/encodingchange what a given page’s bytes parse into, so both are part of the fingerprint.
- async transform(item, context)[source]#
Yield one Markdown document per HTML page, or nothing if it is blank.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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.parsing.MineruParser(*, api_key, base_url='https://mineru.agrospai.udl.cat', tier='standard', keep_images=False, concurrency=4, timeout=1000, pages=None, cache=None, policy=None)[source]#
Bases:
PDFParserParse PDFs to Markdown (one document per page) with a MinerU API.
MinerU returns one Markdown blob per request, so the PDF’s pages are requested individually (
concurrencyat a time) to keep page provenance. Needs thepdfextra (pypdf) to count pages.parser = MineruParser(api_key=MINERU_API_KEY, base_url=MINERU_URL)
- Parameters:
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- async parse_pdf(content, filename, pages)[source]#
Request each page and return its Markdown.
- Parameters:
- Return type:
- accepted_media_types: frozenset[str] | None = frozenset({'application/pdf'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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]
- async transform(item, context)#
Yield one document per non-empty PDF page, in page order.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- 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.parsing.PDFParser(*, pages=None, cache=None, policy=None)[source]#
Bases:
ParserBase class of every PDF parser: one document per page.
Subclasses implement
parse_pdf()andconfig(); they inherit media-type validation (application/pdfonly), per-page document construction, page metadata and per-page identities.- Parameters:
pages (Pages | None)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- accepted_media_types: frozenset[str] | None = frozenset({'application/pdf'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- abstractmethod async parse_pdf(content, filename, pages)[source]#
Parse
content(PDF bytes), returning per-page results.pagesis the sorted 1-based selection orNonefor all pages. Pages with no text may be omitted or returned empty.- Parameters:
- Return type:
- async transform(item, context)[source]#
Yield one document per non-empty PDF page, in page order.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- 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.
- content_format: ContentFormat = 'text'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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.parsing.Parser(*, cache=None, policy=None)[source]#
Bases:
DocumentStep,ABCTurns raw
Sourcebytes into text.One source may yield several documents, which is why
transform()(inherited abstract fromDocumentStep) returns an async iterator rather than a single document. Binding an upstream (parser(sources), via the inherited__call__) and evaluating it (async for document in parser/run()) never runs a parse eagerly — only consuming the resulting stream does.Every event a parser emits is labelled
"Parsing", inherited by every concrete parser (HtmlParser,DocusaurusParser,ParserRouter, …) unless it declares anevent_nameof its own.- Parameters:
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- event_name: str = 'Parsing'#
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.
- content_format: ContentFormat = 'text'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- accepted_media_types: frozenset[str] | None = None#
None retains legacy permissiveness; MIME patterns may use
type/*.
- validate_input(item)[source]#
Validate declared source capabilities before work and cache replay.
- Parameters:
item (Source)
- Return type:
None
- async evaluate(context)[source]#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)[source]#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- 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.
- 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:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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]
- abstractmethod transform(item, context)#
Transform one upstream item into zero or more output documents.
- Parameters:
item (Any) – One item from this step’s upstream (a
Sourcefor a parser, or aDocumentfor a chunker/embedder).context (ExecutionContext) – Execution-scoped state and services.
- Yields:
The documents this one upstream item produces.
- Return type:
- 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.parsing.ParserRouter(*, cache=None, policy=None)[source]#
Bases:
RoutedStep[Document],ParserRoute each source to the first matching
.routeparser, or.default.Holds no parsing logic of its own: a source matching no route with no default registered is skipped with an
ItemFailed.from fastrag.ingestion.steps.parsing import ( DefaultParser, HtmlParser, ParserRouter, html_filter, ) parser = ( ParserRouter(cache=cache) .route(html_filter, HtmlParser()) .default(DefaultParser()) )
- Parameters:
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- routing_requires_content: bool = False#
Unknown routing overrides conservatively require complete inputs. Opt out only when built-in selection uses identity/metadata alone.
- accepted_media_types: frozenset[str] | None = None#
None retains legacy permissiveness; MIME patterns may use
type/*.
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- config()#
No identity-affecting configuration of its own.
A routed item’s cache identity is keyed by whichever child matched it (see
_dispatch_route), never by the router itself.
- content_format: ContentFormat = 'text'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- default(step)#
Register a fallback step for items that match no route filters.
- Parameters:
step (PipelineStep[T]) – Default child step.
- Returns:
Self, for fluent chaining.
- Return type:
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- route(filter_rule, step)#
Register a conditional branch step matching a filter predicate.
- Parameters:
filter_rule (Filter[T]) – Filter predicate to match against incoming items.
step (PipelineStep[T]) – Child step to run on match.
- Returns:
Self, for fluent chaining.
- 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]
- async transform(item, context)#
Dispatch
itemto the first matching route, or the default.An item matching no route with no default registered is skipped with an
ItemFailednaming it — never silently dropped. A matched child that declares no explicit cache/policy of its own (cache is None) inherits this routed step’s effective cache and policy rather than the outer pipeline’s, since a routed child is conceptually scoped to its router. A child that does declare a policy has it applied to its own items, retries and timeout included — see_policy_for_item, which is where that half happens, since the retry wrap sits above this method rather than inside it.- Parameters:
item (T)
context (ExecutionContext)
- Return type:
- 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.
- validate_input(item)#
Validate declared source capabilities before work and cache replay.
- Parameters:
item (Source)
- Return type:
None
- routes: list[tuple[Filter[T], PipelineStep[T]]]#
- class fastrag.ingestion.steps.parsing.OpenAIVisionParser(*, model, api_key, base_url, prompt='Describe this image for a searchable documentation index. Transcribe meaningful text and explain diagram nodes, arrow directions and relationships. For screenshots describe the interface and visible values. Use concise English and only information visible in the image.', timeout=120, extra_body=None, max_tokens=2048, cache=None, policy=None)[source]#
Bases:
ParserDescribe standalone images, or enrich images embedded in HTML parsers.
SVGs are rasterized with the optional
dynamicextra. Credentials are excluded from cache identity; model, endpoint, prompt and extra body are included.extra_bodyadds JSON request fields and overrides matching defaults.- Parameters:
- accepted_media_types: frozenset[str] | None = frozenset({'image/*'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- async describe(content, content_type)[source]#
Send image bytes as a data URL and return the generated description.
- async transform(item, context)[source]#
Yield one searchable description for an image source.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- content_format: ContentFormat = 'text'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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.parsing.SvgParser(*, strip_selectors=('script', 'style', 'noscript', 'nav', 'header', 'footer', 'aside'), encoding=None, vision=None, cache=None, policy=None)[source]#
Bases:
HtmlParserExtract titles, descriptions, text and foreignObject labels from SVG.
- Parameters:
strip_selectors (Sequence[str])
encoding (str | None)
vision (OpenAIVisionParser | None)
cache (CacheStore | Literal[False] | None)
policy (Policy | None)
- accepted_media_types: frozenset[str] | None = frozenset({'image/svg+xml'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- async transform(item, context)[source]#
Use the HTML content pipeline to preserve meaningful SVG labels.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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.parsing.TrafilaturaParser(*, favor_precision=False, favor_recall=False, include_tables=True, include_links=True, include_images=False, include_comments=False, prune_xpath=(), encoding=None, cache=None, policy=None)[source]#
Bases:
ParserExtract a web page’s main content as Markdown, with no per-site selectors.
Trafilatura locates the article heuristically and discards navigation, sidebars, footers, and related-link blocks around it. Relative links are resolved against the source’s URI, and the page’s title, author, date, description, and site name travel in
Document.metadata.from fastrag.ingestion.steps.parsing import ( ParserRouter, TrafilaturaParser, html_filter, ) parser = ParserRouter(cache=cache).route( html_filter, TrafilaturaParser(favor_precision=True) )
- Parameters:
- content_format: ContentFormat = 'markdown'#
The
ContentFormatthis parser’s documents carry by default, stamped bybuild_document()intometadata["content_format"]. Override on a subclass whose output is always one format (HtmlParser/DocusaurusParsersetMARKDOWN); passcontent_format=to a singlebuild_document()call instead for a parser whose output format depends on its own configuration.
- accepted_media_types: frozenset[str] | None = frozenset({'application/xhtml+xml', 'text/html'})#
None retains legacy permissiveness; MIME patterns may use
type/*.
- config()[source]#
This parser’s cache-identity configuration.
Every option changes what a given page’s bytes parse into, so all of them are part of the fingerprint.
- async transform(item, context)[source]#
Yield one Markdown document per page, or nothing if it has no content.
- Parameters:
item (Source)
context (ExecutionContext)
- Return type:
- build_document(source, content, metadata=None, *, content_format=None)#
Build one document from
source’s parsedcontent.Sets
id(a hash of the source identity and parsed content),source_id,step_config_hash(this parser’s ownconfig_hash), and the reserved metadata keys every parser gets right without writing them itself:source_uri,content_type(source’s own, as declared or guessed upstream), andcontent_format(what kind of stringcontentis —content_formatunless overridden for this one call). Thesite_name/favicon_urla fetcher found onsourceare carried over too, unlessmetadatasets its own.- Parameters:
source (Source) – The source
contentwas parsed from.content (str) – The parsed text.
metadata (dict[str, Any] | None) – Extra metadata to carry, e.g. an HTML page’s
title.content_format (ContentFormat | None) – Overrides
content_formatfor this one document, for a parser whose output format depends on its own configuration rather than being fixed per class.
- Return type:
- property cache: CacheStore | Literal[False] | None#
Return the cache explicitly configured for this step.
- 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:
- async evaluate(context)#
Emit
DocumentParsedper document.Wraps
DocumentStep’s concreteevaluate(which already resolved, per item, whether the document came from cache or a freshtransform()call —document.cachedis trustworthy either way) rather than emitting inside a concrete parser’s owntransform(), so the event fires the same way for a cache hit as for a fresh parse, and exactly once regardless of how many layers of routing (e.g.ParserRouter) produced the document.- Parameters:
context (ExecutionContext)
- Return type:
- async evaluate_items(items, context)#
Transform a bounded cache window independently of worker concurrency.
- Parameters:
items (AsyncIterator[Any])
context (ExecutionContext)
- Return type:
- event_name: str = 'Parsing'#
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.
- replay_needs_content: bool = False#
Set by a step whose cached replay reads the full documents anyway (e.g. to re-validate them): its cache reads then skip the header-only projection rather than fetching every entry twice.
- 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
Model-guided content selection from supplied HTML, without fetching. |
|
Speech transcription through an OpenAI-compatible |
|
The |
|
MIME capability helpers; source MIME and output representation stay distinct. |
|
PDF parsing through a remote Chandra OCR API. |
|
|
|
Binary-format parsing via Docling. |
|
PDF parsing through a remote docling-serve. |
|
Docusaurus documentation parsing: the article, not the site chrome. |
|
SVG rasterization for vision parsing. |
|
HTML to Markdown with hidden panels, SVG labels and optional vision descriptions. |
|
PDF parsing through a remote MinerU API. |
|
|
|
|
|
Searchable SVG labels without requiring a vision model. |
|
Main-content extraction for arbitrary web pages, via Trafilatura. |
|
Image descriptions through an OpenAI-compatible vision endpoint. |