Akshay66777's picture
AgentScope Gradio chat app β€” ZeroGPU-ready
9792ea7 verified
Raw
History Blame Contribute Delete
3.27 kB
# -*- coding: utf-8 -*-
"""Shared helpers for binary parsers.
Three small utilities used by :class:`PDFParser`, :class:`ImageParser`,
and :class:`PPTParser`:
- :func:`_guess_image_media_type` β€” sniff the IANA media type from raw
image bytes by looking at the magic number. Used to populate the
``media_type`` field of :class:`Base64Source` for embedded images.
- :func:`_table_to_markdown` β€” render a 2-D ``list[list[str]]`` as a
Markdown pipe-table; the default rendering for table content.
- :func:`_table_to_json` β€” render the same shape as a JSON array
prefixed with a one-line ``<system-info>`` marker; used when the
caller picks ``table_format="json"`` to avoid Markdown's
multi-line-cell ambiguity.
"""
import json
def _guess_image_media_type(data: bytes) -> str:
"""Sniff the IANA media type of an image from its magic number.
Args:
data (`bytes`):
The raw image bytes.
Returns:
`str`:
The IANA media type (e.g. ``"image/png"``). Falls back to
``"image/jpeg"`` when no signature matches β€” JPEG is the
most permissive default and matches what every consumer can
decode.
"""
signatures = {
b"\x89PNG\r\n\x1a\n": "image/png",
b"\xff\xd8": "image/jpeg",
b"GIF87a": "image/gif",
b"GIF89a": "image/gif",
b"BM": "image/bmp",
}
for signature, media_type in signatures.items():
if data.startswith(signature):
return media_type
# WebP: ``RIFF`` at offset 0 + ``WEBP`` at offset 8.
if len(data) > 12 and data[:4] == b"RIFF" and data[8:12] == b"WEBP":
return "image/webp"
return "image/jpeg"
def _table_to_markdown(table_data: list[list[str]]) -> str:
"""Render a 2-D table as a Markdown pipe-table.
Args:
table_data (`list[list[str]]`):
The table data; ``table_data[0]`` is the header row.
Returns:
`str`:
The Markdown rendering, or the empty string when
``table_data`` is empty / column-less.
"""
if not table_data:
return ""
num_cols = len(table_data[0])
if num_cols == 0:
return ""
lines = [
"| " + " | ".join(table_data[0]) + " |",
"| " + " | ".join(["---"] * num_cols) + " |",
]
for row in table_data[1:]:
# Pad short rows so column counts match the header.
padded = list(row) + [""] * max(0, num_cols - len(row))
lines.append("| " + " | ".join(padded[:num_cols]) + " |")
return "\n".join(lines) + "\n"
def _table_to_json(table_data: list[list[str]]) -> str:
"""Render a 2-D table as JSON prefixed by a one-line marker.
The ``<system-info>`` marker lets the LLM (and any
structure-aware downstream renderer) tell at a glance that this
block is tabular data, not free text β€” which is otherwise
indistinguishable from a raw JSON dump in the middle of a chunk.
Args:
table_data (`list[list[str]]`):
The table data.
Returns:
`str`:
``"<system-info>...</system-info>\\n<json>"``.
"""
return (
"<system-info>A table loaded as a JSON array:</system-info>\n"
+ json.dumps(table_data, ensure_ascii=False)
)