Markdrop
A Python package for converting PDFs to structured Markdown and interactive HTML, with AI-powered image and table descriptions across six major LLM providers. Available on PyPI.
Features
- PDF → Markdown conversion with formatting preservation (via Docling)
- Automatic image extraction using XRef IDs
- Table detection using Microsoft's Table Transformer
- PDF URL support
- AI-powered image and table descriptions — 6 providers: Gemini, OpenAI, Anthropic Claude, Groq, OpenRouter, LiteLLM
- Interactive HTML output with downloadable Excel tables
- Customisable image resolution and UI elements
- Structured logging (never pollutes your app's root logger)
Installation
Core install (PDF conversion + Gemini/OpenAI):
pip install markdrop
With Anthropic Claude:
pip install "markdrop[anthropic]"
With Groq:
pip install "markdrop[groq]"
With LiteLLM (routes to 100+ providers):
pip install "markdrop[litellm]"
Everything (including local HuggingFace models):
pip install "markdrop[all]"
Faster CPU / lightweight Markdown (--fast mode):
pip install "markdrop[lite]"
markdrop convert report.pdf --output_dir out --fast
See docs/cpu-guide.md for CPU-only and Colab guidance.
OpenRouter is accessed through the
openaipackage (already included in core), so no extra install is needed.
Supported AI Providers
| Provider | --ai_provider |
Default vision model | Default text model (tables) | Vision |
|---|---|---|---|---|
| Google Gemini | gemini |
gemini-3.1-flash-lite |
gemini-3.1-flash-lite |
✅ |
| OpenAI | openai |
gpt-5.6-terra |
gpt-5.6-luna |
✅ |
| Anthropic Claude | anthropic |
claude-opus-5 |
claude-sonnet-5 |
✅ |
| Groq | groq |
meta-llama/llama-4-maverick-17b-128e-instruct |
meta-llama/llama-4-scout-17b-16e-instruct |
✅ |
| OpenRouter | openrouter |
google/gemini-3.1-flash-lite |
anthropic/claude-sonnet-5 |
✅ |
| LiteLLM | litellm |
openai/gpt-5.6-terra |
openai/gpt-5.6-luna |
✅ |
All models are configurable — use
--modelto override for any provider, or setmodel_name_overrideinProcessorConfig.
Quick Start
See examples/quickstart.md for copy-paste commands.
CLI Usage
Check the installed version:
markdrop --version
1. Convert PDF → Markdown + HTML
markdrop convert <input_path> --output_dir <dir> [--add_tables] [--fast]
# Example
markdrop convert report.pdf --output_dir out --add_tables
# Outputs: out/report-markdroped.md and out/report-markdroped.html
# Also works with URLs (SSRF-protected download):
markdrop convert https://arxiv.org/pdf/1706.03762 --output_dir out
2. Generate AI Descriptions for Images & Tables
markdrop describe <markdown_file> --ai_provider <provider> [--output_dir <dir>] [--remove_images] [--remove_tables]
| Provider | --ai_provider |
|---|---|
| Google Gemini | gemini |
| OpenAI | openai |
| Anthropic Claude | anthropic |
| Groq | groq |
| OpenRouter | openrouter |
| LiteLLM | litellm |
# Gemini (default)
markdrop describe doc.md --ai_provider gemini
# Anthropic Claude
markdrop describe doc.md --ai_provider anthropic --remove_images
# Groq (fastest inference)
markdrop describe doc.md --ai_provider groq
# OpenRouter (any model)
markdrop describe doc.md --ai_provider openrouter
# LiteLLM (unified gateway)
markdrop describe doc.md --ai_provider litellm
3. Set Up API Keys
markdrop setup <provider>
Keys are stored in your user config directory (via platformdirs, with a fallback to ~/.config/markdrop/):
- Linux/macOS:
~/.config/markdrop/.env(or$XDG_CONFIG_HOME/markdrop/.env) - Windows:
%LOCALAPPDATA%\markdrop\.env
On POSIX systems, the .env file is written with 0o600 permissions.
markdrop setup gemini # → GEMINI_API_KEY (GOOGLE_API_KEY also accepted)
markdrop setup openai # → OPENAI_API_KEY
markdrop setup anthropic # → ANTHROPIC_API_KEY
markdrop setup groq # → GROQ_API_KEY
markdrop setup openrouter # → OPENROUTER_API_KEY
markdrop setup litellm # → LITELLM_API_KEY
4. Analyze Images in a PDF
markdrop analyze report.pdf --output_dir pdf_analysis --save_images
5. Batch Image Description Generation
markdrop generate images/ --output_dir descriptions/ --prompt "Describe in detail." \
--llm_client gemini openai
Available --llm_client values: qwen, gemini, openai, llama-vision, molmo, pixtral
Python API
PDF Conversion
from markdrop import markdrop, MarkDropConfig, add_downloadable_tables
from pathlib import Path
import logging
config = MarkDropConfig(
image_resolution_scale=2.0,
download_button_color="#444444",
log_level=logging.INFO,
log_dir="logs",
excel_dir="markdrop-excel-tables",
)
html_path = markdrop("path/to/input.pdf", "output", config)
downloadable_html = add_downloadable_tables(html_path, config)
AI Descriptions
import asyncio
from markdrop import process_markdown, ProcessorConfig, AIProvider, setup_keys
# One-time key setup (writes to user config ~/.config/markdrop/.env)
setup_keys("anthropic")
config = ProcessorConfig(
input_path="out/report-markdroped.md",
output_dir="output",
ai_provider=AIProvider.ANTHROPIC, # GEMINI | OPENAI | ANTHROPIC | GROQ | OPENROUTER | LITELLM
remove_images=False,
remove_tables=False,
table_descriptions=True,
image_descriptions=True,
max_retries=3,
retry_delay=2,
# Override default models (all providers have matching config fields):
anthropic_model_name="claude-opus-5",
anthropic_text_model_name="claude-sonnet-5",
)
output_path = asyncio.run(process_markdown(config))
Using OpenRouter to access any model
config = ProcessorConfig(
input_path="doc.md",
output_dir="output",
ai_provider=AIProvider.OPENROUTER,
openrouter_model_name="meta-llama/llama-4-scout", # any model on openrouter.ai/models
openrouter_text_model_name="anthropic/claude-sonnet-5",
openrouter_site_url="https://yoursite.com",
openrouter_site_name="My App",
)
Using LiteLLM for any 100+ provider
import os
os.environ["ANTHROPIC_API_KEY"] = "..." # set any provider's key
config = ProcessorConfig(
input_path="doc.md",
output_dir="output",
ai_provider=AIProvider.LITELLM,
litellm_model_name="anthropic/claude-opus-5",
litellm_text_model_name="openai/gpt-5.6-luna",
)
Batch Image Description Generation
from markdrop import generate_descriptions
generate_descriptions(
input_path="images/",
output_dir="output/",
prompt="Give a highly detailed description of this image.",
llm_client=["gemini", "llama-vision"],
)
API Reference
ProcessorConfig – AI Provider Fields
| Field | Default | Notes |
|---|---|---|
gemini_model_name |
gemini-3.1-flash-lite |
Vision model |
gemini_text_model_name |
gemini-3.1-flash-lite |
Text model |
openai_model_name |
gpt-5.6-terra |
Vision |
openai_text_model_name |
gpt-5.6-luna |
Tables / text |
anthropic_model_name |
claude-opus-5 |
Vision |
anthropic_text_model_name |
claude-sonnet-5 |
Text (cheaper) |
groq_model_name |
meta-llama/llama-4-maverick-17b-128e-instruct |
Vision |
groq_text_model_name |
meta-llama/llama-4-scout-17b-16e-instruct |
Text |
openrouter_model_name |
google/gemini-3.1-flash-lite |
Any model string from openrouter.ai/models |
openrouter_text_model_name |
anthropic/claude-sonnet-5 |
|
litellm_model_name |
openai/gpt-5.6-terra |
provider/model format |
litellm_text_model_name |
openai/gpt-5.6-luna |
MarkDropConfig
| Field | Default | Notes |
|---|---|---|
image_resolution_scale |
2.0 |
Scale factor for extracted images |
download_button_color |
'#444444' |
HTML button colour |
log_level |
logging.INFO |
|
log_dir |
'logs' |
|
excel_dir |
'markdrop_excel_tables' |
Contributing
We welcome contributions! See CONTRIBUTING.md. Please read our Code of Conduct.
git clone https://github.com/shoryasethia/markdrop.git
cd markdrop
python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e .
Project Structure
markdrop/
├── setup.py
├── requirements.txt
├── README.md
└── markdrop/
├── __init__.py
├── main.py ← CLI entry-point
├── process.py ← PDF conversion
├── parse.py ← AI description engine (all 6 providers)
├── helper.py ← PDF image analysis
├── utils.py ← PDF download helpers
├── setup_keys.py ← Interactive API key manager
├── ignore_warnings.py
├── src/
│ └── markdrop-logo.png
└── models/
├── img_descriptions.py
├── model_loader.py ← Local HF model loader
├── responder.py
└── logger.py
License
GPL-3.0 — see LICENSE.
Changelog
See CHANGELOG.md.
Support
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file markdrop-4.1.2.tar.gz.
File metadata
- Download URL: markdrop-4.1.2.tar.gz
- Upload date:
- Size: 49.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bb6ba3b72257c47d6767aedb5ec25278f920feb1a96f274857286b524fe5b40
|
|
| MD5 |
267d5f10a0f6c314dfbda5ef05548ea1
|
|
| BLAKE2b-256 |
60238a77d772c44932983a3e0afc9074bbc9ec7e5ff50911c25e9d45ef681264
|
File details
Details for the file markdrop-4.1.2-py3-none-any.whl.
File metadata
- Download URL: markdrop-4.1.2-py3-none-any.whl
- Upload date:
- Size: 52.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed90cedb8f4a3e2f1fd55b8fe47d5f14ae617d8760190dd34f7857742dce4230
|
|
| MD5 |
7ab4e480bb7f0e52d8943dec0bced53f
|
|
| BLAKE2b-256 |
0e4a617aeb6a1f1a5b2a18cb6b8d706e5b1f353d1e4b16ff2038554eb496db9b
|