symfonic.agent.attachments¶
attachments ¶
symfonic.agent.attachments — text extraction helpers for Attachment objects.
Public surface (spec §1):
from symfonic.agent.attachments import extract_text, extract_texts, is_extractable
Error classes are re-exported so callers can except UnsupportedAttachmentError
without importing from the internal errors submodule.
AttachmentExtractionError ¶
Bases: Exception
Base for all attachment extractor errors.
ExtractionDependencyMissingError ¶
Bases: AttachmentExtractionError
An extractor is registered but its optional dependency is not installed.
The exception message always names the pip install extra the caller
should add, e.g. pip install symfonic-core[attachments-pdf].
ExtractionFailedError ¶
Bases: AttachmentExtractionError
The dependency is present but extraction itself failed.
Common causes: corrupt or password-protected file, zero-confidence OCR, unexpected format inside the container.
__cause__ is always set to the underlying library exception so callers
can inspect or log it.
UnsupportedAttachmentError ¶
Bases: AttachmentExtractionError
No extractor is registered for this (kind, media_type) combination.
Also raised when source_type="url" is passed — the helper never
fetches remote URLs (SSRF avoidance; spec §4).
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).