symfonic.agent.attachments.extractors¶
extractors ¶
Attachment text-extraction dispatch and public API.
Spec §1-§8. Heavy dependencies (pdfplumber, pypdf, pytesseract, python-docx,
openpyxl, Pillow) are imported lazily inside each extractor function so
from symfonic.agent.attachments import extract_text never pulls any
optional library into memory for callers who never call it.
extract_text ¶
Extract plain text from an attachment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
att
|
Any
|
|
required |
max_pages
|
int | None
|
Optional page limit for PDFs and multi-page documents.
|
None
|
page_markers
|
bool
|
When |
True
|
Returns:
| Type | Description |
|---|---|
str
|
UTF-8 text. Empty string only if the source is genuinely empty. |
Raises:
| Type | Description |
|---|---|
UnsupportedAttachmentError
|
No extractor matches the kind/media_type,
or the attachment is a URL (which this helper never fetches), or
a |
ExtractionDependencyMissingError
|
An extractor exists but its optional pip extra isn't installed. Message names the extra to install. |
ExtractionFailedError
|
Dependency present but extraction failed
(corrupt file, malformed base64, password-protected PDF,
scan-only PDF, OCR confidence below threshold). |
ValueError
|
|
Source code in src/symfonic/agent/attachments/extractors.py
extract_texts ¶
extract_texts(
atts: Sequence[Any],
*,
max_pages: int | None = None,
page_markers: bool = True,
on_error: Literal["raise", "skip", "warn"] = "warn",
) -> list[str]
Batch extraction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atts
|
Sequence[Any]
|
Sequence of |
required |
max_pages
|
int | None
|
Forwarded to :func: |
None
|
page_markers
|
bool
|
Forwarded to :func: |
True
|
on_error
|
Literal['raise', 'skip', 'warn']
|
Controls per-item failure handling.
|
'warn'
|
Returns:
| Type | Description |
|---|---|
list[str]
|
A list of extracted text strings, one per successfully extracted |
list[str]
|
item. The returned length may be less than |
list[str]
|
|
list[str]
|
correspondence with |
list[str]
|
|
Source code in src/symfonic/agent/attachments/extractors.py
is_extractable ¶
Return True when the (kind, media_type) combination is supported
AND the optional dependency is installed.
This is a capability check, not a payload validator. It answers three questions:
- Is the input shape recognised (Attachment or known content-block dict)?
- Is there an extractor registered for
(kind, media_type)? - Is the extractor's optional Python dependency importable?
For image OCR, also: is the
tesseractbinary on PATH?
Does NOT validate payload contents. A True result does not
guarantee :func:extract_text will succeed on a specific payload — the
call may still fail with UnsupportedAttachmentError (e.g., a
non-base64 data: URL that carries a supported media_type), or
ExtractionFailedError (e.g., corrupt PDF, malformed base64). The
capability check is deliberately cheap and payload-agnostic (M5 + N2).
Callers that need to know whether extraction would actually succeed
should call :func:extract_text and catch AttachmentExtractionError.
Never raises. Safe to use for runtime routing decisions (spec §1).