MarkItDown
Deploy MarkItDown as a bounded document conversion worker
Design a conversion worker around local inputs, selected extras, resource limits and durable outputs; distinguish this deployment design from the upstream library.
What you will learn
- Upload handling, queues and delivery are application responsibilities.
- Pin the runtime, extras and conversion options as one environment.
- Publish complete outputs only after content checks pass.
Before you start
- Basic Python and command-line usage
- A non-sensitive document whose contents you can verify
Use the chapter checklist to explain and verify this part of a document ingestion workflow.
Key takeaways
- Upload handling, queues and delivery are application responsibilities.
- Pin the runtime, extras and conversion options as one environment.
- Publish complete outputs only after content checks pass.
The library is not a job service
MarkItDown supplies conversion functions and a CLI. A queued upload service needs additional application decisions: who can submit a file, where it is stored, how long a conversion may run and how a caller obtains the result. The worker design in this article is an integration proposal, not a built-in hosted service.
Separate receiving an upload from converting it. Validate the accepted size and type, assign a job identifier, and place the input where the worker can read it. Run conversion with selected extras and publish the completed Markdown only after output checks pass. This separation makes a failed parser distinguishable from a failed upload.
Package runtime and format dependencies together
A useful worker image fixes Python, the resolved MarkItDown version and the extras required by the allowed file formats. If image description or a cloud converter is enabled, its settings and dependencies belong in that environment definition too. Installing an extra does not provision an external service or supply credentials.
The README also shows building a Docker image from the repository and passing input on stdin. Inspect the Dockerfile from the revision you select before adopting that route. For a production queue, set container resource limits and writable output paths in the surrounding deployment system; those limits are not supplied merely by using the CLI.
Design retry and result handling deliberately
Identify a conversion by source bytes, converter version and options. A retry of the same immutable job should produce a new attempt record rather than silently replacing a successful artifact with a partial file. Stage an output, check it, and then make it visible to the job consumer.
Dependency upgrades can change extracted text even when the source document stays identical. Keep representative conversion fixtures in the release check and retain the previous environment for rollback. Restore the matching output schema and consumer assumptions with the worker; changing only a container tag may not undo an ingestion already performed.
Implementation steps
- 1
Define permitted formats and select their extras.
- 2
Build an isolated worker with a read-only input directory.
- 3
Run a small fixture and inspect its Markdown before releasing output.
- 4
Replay the fixture before each environment upgrade.
Copy-ready example
from pathlib import Path
from markitdown import MarkItDown
# Fixed paths supplied by the worker, not arbitrary user paths.
result = MarkItDown(enable_plugins=False).convert_local("/input/example.docx")
if not result.markdown.strip():
raise ValueError("Conversion returned no usable text")
Path("/output/example.md").write_text(result.markdown, encoding="utf-8")Frequently asked questions
Does the package provide my upload API and queue?
No. Those are surrounding application components. The article describes one way to integrate the converter into a worker.
Can retries be unconditional?
No. Distinguish transient infrastructure failures from unsupported input or consistently invalid content, and keep attempt records.
Sources
- Pinned sourceSource checked 2026-09-07
- Core dispatcherSource checked 2026-09-07
- Plain-text converterSource checked 2026-09-07
- Public exportsSource checked 2026-09-07