Files
markitdown/main.py
T

70 lines
2.3 KiB
Python

from fastapi import FastAPI, UploadFile, File, Request
from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from markitdown import MarkItDown
from markitdown._stream_info import StreamInfo
import io, os, mimetypes
app = FastAPI(title="MarkItDown Converter")
templates = Jinja2Templates(directory="templates")
# markitdown supports: PDF, DOCX, PPTX, XLSX, HTML, CSV, JSON, XML,
# images (with OCR via LLM), audio, ZIP, EPUB, YouTube URLs, Wikipedia, etc.
ALLOWED_EXTENSIONS = {
".pdf", ".docx", ".doc", ".pptx", ".ppt", ".xlsx", ".xls",
".html", ".htm", ".csv", ".json", ".xml", ".epub",
".txt", ".md", ".rst", ".zip", ".msg",
".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp",
".mp3", ".wav", ".m4a",
}
MAX_SIZE_MB = 50
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.post("/convert")
async def convert(file: UploadFile = File(...)):
# Validate extension
_, ext = os.path.splitext(file.filename or "")
ext = ext.lower()
if ext not in ALLOWED_EXTENSIONS:
return JSONResponse(
{"error": f"Unsupported file type: '{ext}'. Supported: {', '.join(sorted(ALLOWED_EXTENSIONS))}"},
status_code=400
)
# Read into memory
data = await file.read()
size_mb = len(data) / (1024 * 1024)
if size_mb > MAX_SIZE_MB:
return JSONResponse(
{"error": f"File too large ({size_mb:.1f} MB). Max: {MAX_SIZE_MB} MB"},
status_code=413
)
try:
md = MarkItDown()
stream = io.BytesIO(data)
mime = mimetypes.types_map.get(ext, "application/octet-stream")
result = md.convert_stream(
stream,
stream_info=StreamInfo(
mimetype=mime,
extension=ext,
filename=file.filename,
)
)
markdown_text = result.text_content or ""
return JSONResponse({
"markdown": markdown_text,
"filename": file.filename,
"size_kb": round(len(data) / 1024, 1),
"chars": len(markdown_text),
})
except Exception as e:
return JSONResponse({"error": f"Conversion failed: {str(e)}"}, status_code=500)