anydoc in Python - firecrawl-anydoc
API ReferencePython
The Python binding is firecrawl-anydoc. It releases the GIL during conversion, so it's safe to mix with asyncio and threads without stalling your whole process.
Install
pip install firecrawl-anydocPython stubs are included — type hints work out of the box.
The three core APIs
import anydoc
# 1. From a path
markdown = anydoc.to_markdown("report.docx")
print(markdown)
# 2. From bytes
data = open("slides.pptx", "rb").read()
md = anydoc.to_markdown_bytes(data)
# 3. Stop at the document model (keep embedded assets)
doc = anydoc.to_document(data)
# doc exposes raw bytes and media types of images/objectsError handling
try:
anydoc.to_markdown("scanned.pdf")
except anydoc.UnsupportedError as e:
print("Unsupported format or scanned PDF:", e)Errors surface as exception subclasses: UnsupportedError, MalformedError, EncryptedError, ResourceLimitError, MissingPartError, IoError. See Error Handling & Limits.
Common scenarios
Concurrent conversion in an asyncio service
import asyncio
import anydoc
async def convert(path: str) -> str:
return await asyncio.to_thread(anydoc.to_markdown, path)
async def main():
files = ["a.docx", "b.pdf", "c.xlsx"]
results = await asyncio.gather(*(convert(f) for f in files))Because the GIL is released during conversion, to_thread calls don't drag each other down.
Data-analysis pipelines
import anydoc
md = anydoc.to_markdown("sales.xlsx")
# The Markdown tables can go straight into an LLM for analysisBatch-cleaning contract text
from pathlib import Path
for p in Path("contracts").glob("*.docx"):
md = anydoc.to_markdown(str(p))
Path(f"markdown/{p.stem}.md").write_text(md, encoding="utf-8")Tips
to_markdown_bytesacceptsbytes— file streams and HTTP response bodies work directly- Want embedded assets? Stop at
to_documentinstead of converting to a string - A
ResourceLimiterror on huge files is the safety limit working as intended, not a performance problem