feat: initial commit — markitdown converter
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user