markitdown-pro 1.3.7__tar.gz → 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. markitdown_pro-2.0.0/.github/workflows/lint.yaml +44 -0
  2. markitdown_pro-2.0.0/.github/workflows/publish.yaml +51 -0
  3. markitdown_pro-2.0.0/.github/workflows/test.yml +123 -0
  4. markitdown_pro-2.0.0/.gitignore +26 -0
  5. markitdown_pro-2.0.0/.vscode/settings.json +17 -0
  6. markitdown_pro-2.0.0/PKG-INFO +301 -0
  7. markitdown_pro-2.0.0/README.md +269 -0
  8. markitdown_pro-2.0.0/markitdown_pro/common/config.py +56 -0
  9. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/common/isolated_worker.py +6 -3
  10. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/conversion_pipeline.py +56 -46
  11. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/converters/base.py +15 -5
  12. markitdown_pro-2.0.0/markitdown_pro/converters/doc_intel_converter.py +21 -0
  13. markitdown_pro-2.0.0/markitdown_pro/converters/gotenberg_converter.py +118 -0
  14. markitdown_pro-1.3.7/markitdown_pro/converters/gpt_vision_wrapper.py → markitdown_pro-2.0.0/markitdown_pro/converters/gpt_vision_converter.py +23 -20
  15. markitdown_pro-2.0.0/markitdown_pro/converters/markitdown_converter.py +54 -0
  16. markitdown_pro-2.0.0/markitdown_pro/converters/pymupdf_converter.py +35 -0
  17. markitdown_pro-1.3.7/markitdown_pro/converters/azure_speech_wrapper.py → markitdown_pro-2.0.0/markitdown_pro/converters/speech_converter.py +3 -5
  18. markitdown_pro-1.3.7/markitdown_pro/converters/tabular_wrapper.py → markitdown_pro-2.0.0/markitdown_pro/converters/tabular_converter.py +5 -7
  19. markitdown_pro-1.3.7/markitdown_pro/converters/unstructured_wrapper.py → markitdown_pro-2.0.0/markitdown_pro/converters/unstructured_converter.py +14 -11
  20. markitdown_pro-1.3.7/markitdown_pro/converters/youtube_wrapper.py → markitdown_pro-2.0.0/markitdown_pro/converters/youtube_converter.py +3 -4
  21. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/audio_handler.py +16 -9
  22. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/base_handler.py +2 -3
  23. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/email_handler.py +15 -16
  24. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/epub_handler.py +4 -5
  25. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/image_handler.py +18 -16
  26. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/ipynb_handler.py +1 -3
  27. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/markup_handler.py +2 -3
  28. markitdown_pro-2.0.0/markitdown_pro/handlers/office_handler.py +90 -0
  29. markitdown_pro-2.0.0/markitdown_pro/handlers/page_pdf_converter.py +249 -0
  30. markitdown_pro-2.0.0/markitdown_pro/handlers/pdf_handler.py +178 -0
  31. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/pst_handler.py +5 -5
  32. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/tabular_handler.py +4 -5
  33. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/text_handler.py +1 -2
  34. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/services/azure_doc_intelligence.py +13 -14
  35. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/services/azure_speech.py +32 -34
  36. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/services/openai_services.py +38 -24
  37. markitdown_pro-2.0.0/pyproject.toml +120 -0
  38. markitdown_pro-2.0.0/tests/common/test_config.py +39 -0
  39. markitdown_pro-2.0.0/tests/conftest.py +210 -0
  40. markitdown_pro-2.0.0/tests/conversion_pipeline/__init__.py +0 -0
  41. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/conversion_pipeline/test_conversion_pipeline.py +3 -3
  42. markitdown_pro-2.0.0/tests/converters/test_azure_doc_intel_wrapper.py +44 -0
  43. markitdown_pro-2.0.0/tests/converters/test_azure_speech_wrapper.py +29 -0
  44. markitdown_pro-2.0.0/tests/converters/test_doc_intel_lifecycle.py +35 -0
  45. markitdown_pro-2.0.0/tests/converters/test_gpt_vision_config.py +23 -0
  46. markitdown_pro-2.0.0/tests/converters/test_gpt_vision_wrapper.py +28 -0
  47. markitdown_pro-2.0.0/tests/converters/test_pymupdf_wrapper.py +28 -0
  48. markitdown_pro-2.0.0/tests/converters/test_pymupdf_wrapper_async.py +26 -0
  49. markitdown_pro-2.0.0/tests/converters/test_unstructured_io_wrapper.py +28 -0
  50. markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_cn.wav +0 -0
  51. markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_en.mp3 +0 -0
  52. markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_en.wav +0 -0
  53. markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_es.mp3 +0 -0
  54. markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_es.wav +0 -0
  55. markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_it.wav +0 -0
  56. markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_jp.mp3 +0 -0
  57. markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_jp.wav +0 -0
  58. markitdown_pro-2.0.0/tests/data/eml/email-with-image.eml +3828 -0
  59. markitdown_pro-2.0.0/tests/data/eml/mime-different-plain-html.eml +34 -0
  60. markitdown_pro-2.0.0/tests/data/epub/sample1.epub +0 -0
  61. markitdown_pro-2.0.0/tests/data/images/flower.jpg +0 -0
  62. markitdown_pro-2.0.0/tests/data/images/geometry_colors.bmp +0 -0
  63. markitdown_pro-2.0.0/tests/data/images/handwriting.jpg +0 -0
  64. markitdown_pro-2.0.0/tests/data/images/scanned_text.heic +0 -0
  65. markitdown_pro-2.0.0/tests/data/images/scanned_text.png +0 -0
  66. markitdown_pro-2.0.0/tests/data/images/text_with_image.jpg +0 -0
  67. markitdown_pro-2.0.0/tests/data/markup/blog.html +69 -0
  68. markitdown_pro-2.0.0/tests/data/markup/factbook.xml +27 -0
  69. markitdown_pro-2.0.0/tests/data/markup/simple.json +127 -0
  70. markitdown_pro-2.0.0/tests/data/markup/simple.yaml +19 -0
  71. markitdown_pro-2.0.0/tests/data/msg/fake-email-multiple-attachments.msg +0 -0
  72. markitdown_pro-2.0.0/tests/data/msg/fake-email.msg +0 -0
  73. markitdown_pro-2.0.0/tests/data/pdf/geometry-colors.pdf +0 -0
  74. markitdown_pro-2.0.0/tests/data/pdf/lorem-ipsum-only-images.pdf +0 -0
  75. markitdown_pro-2.0.0/tests/data/pdf/lorem-ipsum-only-text.pdf +0 -0
  76. markitdown_pro-2.0.0/tests/data/pdf/lorem-ipsum-scanned-text.pdf +0 -0
  77. markitdown_pro-2.0.0/tests/data/pdf/lorem-ipsum-text-with-image.pdf +0 -0
  78. markitdown_pro-2.0.0/tests/data/powerpoint/geometry-colors.pptx +0 -0
  79. markitdown_pro-2.0.0/tests/data/powerpoint/lorem-ipsum-only-text.pptx +0 -0
  80. markitdown_pro-2.0.0/tests/data/powerpoint/lorem-ipsum-scanned-text.pptx +0 -0
  81. markitdown_pro-2.0.0/tests/data/powerpoint/lorem-ipsum-text-with-image.pptx +0 -0
  82. markitdown_pro-2.0.0/tests/data/powerpoint/lorem-ipsum-text-with-scanned-text.pptx +0 -0
  83. markitdown_pro-2.0.0/tests/data/tabular/2023-half-year-analyses-by-segment.xlsx +0 -0
  84. markitdown_pro-2.0.0/tests/data/tabular/stanley-cups.csv +5 -0
  85. markitdown_pro-2.0.0/tests/data/tabular/stanley-cups.tsv +5 -0
  86. markitdown_pro-2.0.0/tests/data/tabular/stanley-cups.xlsx +0 -0
  87. markitdown_pro-2.0.0/tests/data/test_expectations.yaml +224 -0
  88. markitdown_pro-2.0.0/tests/data/text/book-war-and-peace-1p.txt +62 -0
  89. markitdown_pro-2.0.0/tests/data/text/fake-email.txt +25 -0
  90. markitdown_pro-2.0.0/tests/data/text/logger.py +19 -0
  91. markitdown_pro-2.0.0/tests/data/word/geometry-colors.docx +0 -0
  92. markitdown_pro-2.0.0/tests/data/word/lorem-ipsum-only-text.docx +0 -0
  93. markitdown_pro-2.0.0/tests/data/word/lorem-ipsum-scanned-text.docx +0 -0
  94. markitdown_pro-2.0.0/tests/data/word/lorem-ipsum-text-with-image.docx +0 -0
  95. markitdown_pro-2.0.0/tests/data/word/lorem-ipsum-text-with-scanned-text.docx +0 -0
  96. markitdown_pro-2.0.0/tests/fixtures.py +16 -0
  97. markitdown_pro-2.0.0/tests/handlers/__init__.py +0 -0
  98. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_markitdown_handler.py +6 -6
  99. markitdown_pro-2.0.0/tests/handlers/test_markitdown_validation.py +25 -0
  100. markitdown_pro-2.0.0/tests/handlers/test_page_pdf_converter.py +159 -0
  101. markitdown_pro-2.0.0/tests/handlers/test_pdf_handler.py +114 -0
  102. markitdown_pro-2.0.0/tests/integration/__init__.py +0 -0
  103. markitdown_pro-2.0.0/tests/integration/cheat_sheet.py +55 -0
  104. markitdown_pro-2.0.0/tests/integration/runner.py +69 -0
  105. markitdown_pro-2.0.0/tests/integration/test_audio_handler.py +27 -0
  106. markitdown_pro-2.0.0/tests/integration/test_doc_intelligence_converter.py +30 -0
  107. markitdown_pro-2.0.0/tests/integration/test_email_handler.py +27 -0
  108. markitdown_pro-2.0.0/tests/integration/test_gotenberg_converter.py +34 -0
  109. markitdown_pro-2.0.0/tests/integration/test_gpt_vision_converter.py +30 -0
  110. markitdown_pro-2.0.0/tests/integration/test_markitdown_converter.py +27 -0
  111. markitdown_pro-2.0.0/tests/integration/test_markup_handler.py +27 -0
  112. markitdown_pro-2.0.0/tests/integration/test_pdf_handler.py +30 -0
  113. markitdown_pro-2.0.0/tests/integration/test_pymupdf_converter.py +27 -0
  114. markitdown_pro-2.0.0/tests/integration/test_tabular_handler.py +27 -0
  115. markitdown_pro-2.0.0/tests/integration/test_text_handler.py +27 -0
  116. markitdown_pro-2.0.0/tests/page_count/__init__.py +0 -0
  117. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/page_count/test_pdf_page_count.py +4 -4
  118. markitdown_pro-2.0.0/tests/unit/__init__.py +0 -0
  119. markitdown_pro-2.0.0/tests/unit/test_audio_handler.py +58 -0
  120. markitdown_pro-2.0.0/tests/unit/test_base_converter.py +69 -0
  121. markitdown_pro-2.0.0/tests/unit/test_conversion_pipeline.py +141 -0
  122. markitdown_pro-2.0.0/tests/unit/test_doc_intel_converter.py +70 -0
  123. markitdown_pro-2.0.0/tests/unit/test_gpt_vision_converter.py +128 -0
  124. markitdown_pro-2.0.0/tests/unit/test_image_handler.py +115 -0
  125. markitdown_pro-2.0.0/tests/unit/test_markitdown_converter.py +92 -0
  126. markitdown_pro-2.0.0/tests/unit/test_office_handler.py +111 -0
  127. markitdown_pro-2.0.0/tests/unit/test_page_pdf_converter.py +208 -0
  128. markitdown_pro-2.0.0/tests/unit/test_pdf_handler.py +245 -0
  129. markitdown_pro-2.0.0/tests/unit/test_pymupdf_converter.py +71 -0
  130. markitdown_pro-2.0.0/tests/unit/test_speech_converter.py +38 -0
  131. markitdown_pro-2.0.0/tests/utils.py +96 -0
  132. markitdown_pro-2.0.0/uv.lock +2886 -0
  133. markitdown_pro-1.3.7/PKG-INFO +0 -345
  134. markitdown_pro-1.3.7/README.md +0 -304
  135. markitdown_pro-1.3.7/markitdown_pro/converters/azure_doc_intel_wrapper.py +0 -22
  136. markitdown_pro-1.3.7/markitdown_pro/converters/markitdown_wrapper.py +0 -24
  137. markitdown_pro-1.3.7/markitdown_pro/converters/pymupdf_wrapper.py +0 -37
  138. markitdown_pro-1.3.7/markitdown_pro/handlers/markitdown_handler.py +0 -66
  139. markitdown_pro-1.3.7/markitdown_pro/handlers/office_handler.py +0 -75
  140. markitdown_pro-1.3.7/markitdown_pro/handlers/pdf_handler.py +0 -377
  141. markitdown_pro-1.3.7/markitdown_pro.egg-info/PKG-INFO +0 -345
  142. markitdown_pro-1.3.7/markitdown_pro.egg-info/SOURCES.txt +0 -58
  143. markitdown_pro-1.3.7/markitdown_pro.egg-info/dependency_links.txt +0 -1
  144. markitdown_pro-1.3.7/markitdown_pro.egg-info/requires.txt +0 -23
  145. markitdown_pro-1.3.7/markitdown_pro.egg-info/top_level.txt +0 -2
  146. markitdown_pro-1.3.7/pyproject.toml +0 -41
  147. markitdown_pro-1.3.7/setup.cfg +0 -8
  148. markitdown_pro-1.3.7/setup.py +0 -44
  149. {markitdown_pro-1.3.7/markitdown_pro/common → markitdown_pro-2.0.0}/__init__.py +0 -0
  150. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/__init__.py +0 -0
  151. {markitdown_pro-1.3.7/markitdown_pro/converters → markitdown_pro-2.0.0/markitdown_pro/common}/__init__.py +0 -0
  152. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/common/logger.py +0 -0
  153. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/common/schemas.py +0 -0
  154. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/common/utils.py +0 -0
  155. {markitdown_pro-1.3.7/markitdown_pro/handlers → markitdown_pro-2.0.0/markitdown_pro/converters}/__init__.py +0 -0
  156. {markitdown_pro-1.3.7/markitdown_pro/services → markitdown_pro-2.0.0/markitdown_pro/handlers}/__init__.py +0 -0
  157. {markitdown_pro-1.3.7/tests/conversion_pipeline → markitdown_pro-2.0.0/markitdown_pro/services}/__init__.py +0 -0
  158. {markitdown_pro-1.3.7/tests/handlers → markitdown_pro-2.0.0/tests}/__init__.py +0 -0
  159. {markitdown_pro-1.3.7/tests/page_count → markitdown_pro-2.0.0/tests/common}/__init__.py +0 -0
  160. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_email_handler.py +0 -0
  161. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_epub_handler.py +0 -0
  162. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_image_handler.py +0 -0
  163. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_ipynb_handler.py +0 -0
  164. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_markup_handler.py +0 -0
  165. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_pst_handler.py +0 -0
  166. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_tabular_handler.py +0 -0
  167. {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_text_handler.py +0 -0
@@ -0,0 +1,44 @@
1
+ name: '🧹 Lint checks'
2
+
3
+ on:
4
+ merge_group:
5
+ types:
6
+ - checks_requested
7
+ pull_request:
8
+ branches:
9
+ - main
10
+ types:
11
+ - assigned
12
+ - opened
13
+ - synchronize
14
+ - reopened
15
+ paths:
16
+ - 'markitdown_pro/**'
17
+ - 'tests/**'
18
+ - 'pyproject.toml'
19
+ workflow_dispatch:
20
+ inputs:
21
+ comment:
22
+ description: 'Run comments'
23
+ required: false
24
+
25
+ permissions:
26
+ contents: read
27
+
28
+ jobs:
29
+ lint-format:
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - name: Checkout repo
33
+ uses: actions/checkout@v4
34
+
35
+ - name: Install uv
36
+ uses: astral-sh/setup-uv@v5
37
+ with:
38
+ python-version: "3.13"
39
+
40
+ - name: Check linting
41
+ run: uvx ruff check markitdown_pro/
42
+
43
+ - name: Check formatting
44
+ run: uvx ruff format --check markitdown_pro/
@@ -0,0 +1,51 @@
1
+ name: '📦 Publish package'
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+ workflow_dispatch:
8
+ inputs:
9
+ version:
10
+ description: 'Version to publish (e.g., 1.4.0). Will create and push the git tag.'
11
+ required: true
12
+ type: string
13
+
14
+ permissions:
15
+ contents: write
16
+ packages: write
17
+ id-token: write
18
+
19
+ jobs:
20
+ publish:
21
+ name: Publish 🚀
22
+ runs-on: ubuntu-latest
23
+
24
+ steps:
25
+ - name: Checkout code
26
+ uses: actions/checkout@v4
27
+ with:
28
+ fetch-depth: 0
29
+
30
+ - name: Create tag from manual input
31
+ if: github.event_name == 'workflow_dispatch'
32
+ run: |
33
+ git tag "v${{ inputs.version }}"
34
+ git push origin "v${{ inputs.version }}"
35
+
36
+ - name: Install uv
37
+ uses: astral-sh/setup-uv@v5
38
+ with:
39
+ python-version: "3.13"
40
+
41
+ - name: Build distribution
42
+ run: uv build
43
+
44
+ - name: Show version
45
+ run: ls dist/
46
+
47
+ - name: Publish to PyPI
48
+ env:
49
+ TWINE_USERNAME: __token__
50
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
51
+ run: uvx twine upload dist/* --skip-existing
@@ -0,0 +1,123 @@
1
+ name: '🧪 Test package'
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - 'markitdown_pro/**'
9
+ - 'tests/**'
10
+ - 'pyproject.toml'
11
+ pull_request:
12
+ branches:
13
+ - main
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ unit-tests:
20
+ name: Unit Tests (fast, no credentials)
21
+ runs-on: ubuntu-latest
22
+ strategy:
23
+ matrix:
24
+ python-version: ["3.13"]
25
+ steps:
26
+ - name: Checkout code
27
+ uses: actions/checkout@v4
28
+
29
+ - name: Install uv
30
+ uses: astral-sh/setup-uv@v5
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+
34
+ - name: Install project dependencies
35
+ run: uv sync --dev
36
+
37
+ - name: Run unit tests
38
+ run: uv run pytest tests/unit/ -v
39
+
40
+ integration-tests:
41
+ name: Integration Tests (Azure + Gotenberg)
42
+ runs-on: ubuntu-latest
43
+ environment: ci
44
+ needs: unit-tests
45
+ services:
46
+ gotenberg:
47
+ image: gotenberg/gotenberg:8
48
+ ports:
49
+ - 3000:3000
50
+ steps:
51
+ - name: Checkout code
52
+ uses: actions/checkout@v4
53
+
54
+ - name: Install uv
55
+ uses: astral-sh/setup-uv@v5
56
+ with:
57
+ python-version: "3.13"
58
+
59
+ - name: Install system packages
60
+ run: |
61
+ sudo apt-get update
62
+ sudo apt-get install -y \
63
+ ffmpeg \
64
+ libgstreamer1.0-0 \
65
+ gstreamer1.0-plugins-base \
66
+ gstreamer1.0-plugins-good \
67
+ gstreamer1.0-plugins-bad \
68
+ gstreamer1.0-plugins-ugly \
69
+ gstreamer1.0-libav
70
+
71
+ - name: Install project dependencies
72
+ run: uv sync --dev
73
+
74
+ - name: Create .test.env from GitHub secrets
75
+ run: |
76
+ cat <<EOF > .test.env
77
+ DEBUG=True
78
+ LOG_LEVEL=10
79
+ AZURE_OPENAI_ENDPOINT=${{ secrets.AZURE_OPENAI_ENDPOINT }}
80
+ AZURE_OPENAI_API_KEY=${{ secrets.AZURE_OPENAI_API_KEY }}
81
+ AZURE_OPENAI_API_VERSION=${{ secrets.AZURE_OPENAI_API_VERSION }}
82
+ AZURE_DOCINTEL_ENDPOINT=${{ secrets.AZURE_DOCINTEL_ENDPOINT }}
83
+ AZURE_DOCINTEL_KEY=${{ secrets.AZURE_DOCINTEL_KEY }}
84
+ AZURE_SPEECH_KEY=${{ secrets.AZURE_SPEECH_KEY }}
85
+ AZURE_SPEECH_USE_V2=1
86
+ AZURE_SPEECH_REGION=${{ secrets.AZURE_SPEECH_REGION }}
87
+ MARKITDOWN_MIN_IMAGE_AREA=150_000
88
+ GOTENBERG_URL=http://localhost:3000
89
+ EOF
90
+
91
+ - name: Create .env from GitHub secrets
92
+ run: |
93
+ cat <<EOF > .env
94
+ DEBUG=True
95
+ LOG_LEVEL=10
96
+ AZURE_OPENAI_ENDPOINT=${{ secrets.AZURE_OPENAI_ENDPOINT }}
97
+ AZURE_OPENAI_API_KEY=${{ secrets.AZURE_OPENAI_API_KEY }}
98
+ AZURE_OPENAI_API_VERSION=${{ secrets.AZURE_OPENAI_API_VERSION }}
99
+ AZURE_DOCINTEL_ENDPOINT=${{ secrets.AZURE_DOCINTEL_ENDPOINT }}
100
+ AZURE_DOCINTEL_KEY=${{ secrets.AZURE_DOCINTEL_KEY }}
101
+ AZURE_SPEECH_KEY=${{ secrets.AZURE_SPEECH_KEY }}
102
+ AZURE_SPEECH_USE_V2=1
103
+ AZURE_SPEECH_REGION=${{ secrets.AZURE_SPEECH_REGION }}
104
+ MARKITDOWN_MIN_IMAGE_AREA=150_000
105
+ GOTENBERG_URL=http://localhost:3000
106
+ EOF
107
+
108
+ - name: Wait for Gotenberg to be ready
109
+ run: |
110
+ for i in $(seq 1 30); do
111
+ curl -s http://localhost:3000/health && break
112
+ sleep 1
113
+ done
114
+
115
+ - name: Run integration tests
116
+ run: uv run pytest -m integration -v
117
+
118
+ - name: Archive test results
119
+ if: always()
120
+ uses: actions/upload-artifact@v4
121
+ with:
122
+ name: test-results
123
+ path: tests/data/
@@ -0,0 +1,26 @@
1
+ .amlignore
2
+ .ipynb_checkpoints/
3
+ .ipynb_aml_checkpoints/
4
+ __pycache__/
5
+ *.amltmp
6
+ *.amltemp
7
+ .azure/
8
+ **/__pycache__/
9
+ /venv/
10
+ .venv/
11
+ /.idea/
12
+ .DS_Store
13
+ output/
14
+ **/build/**
15
+ **/dist/**
16
+ **/*egg-info/**
17
+ **/.env
18
+ **/.test.env
19
+ **/*.ipynb
20
+ tests/data/**/*.mddist/
21
+ .claude/
22
+ docs/
23
+ **/CLAUDE.md
24
+ !./CLAUDE.md
25
+ **/CONTINUITY.md
26
+ **/CHANGELOG.md
@@ -0,0 +1,17 @@
1
+ {
2
+ "editor.defaultFormatter": "ms-python.black-formatter",
3
+ "[python]": {
4
+ "editor.codeActionsOnSave": {
5
+ "source.organizeImports": "explicit",
6
+ },
7
+ "editor.formatOnSave": true,
8
+
9
+ },
10
+ "black-formatter.args": [
11
+ "--line-length",
12
+ "100"
13
+ ],
14
+ "[json]": {
15
+ "editor.defaultFormatter": "vscode.json-language-features"
16
+ }
17
+ }
@@ -0,0 +1,301 @@
1
+ Metadata-Version: 2.4
2
+ Name: markitdown-pro
3
+ Version: 2.0.0
4
+ Summary: A package that converts almost any file format to Markdown.
5
+ Author: Developer
6
+ License-Expression: MIT
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Programming Language :: Python :: 3
10
+ Requires-Python: >=3.13
11
+ Requires-Dist: aiohttp
12
+ Requires-Dist: azure-ai-documentintelligence==1.0.2
13
+ Requires-Dist: azure-cognitiveservices-speech==1.42.0
14
+ Requires-Dist: beautifulsoup4
15
+ Requires-Dist: cairosvg
16
+ Requires-Dist: chardet==5.2.0
17
+ Requires-Dist: ebooklib
18
+ Requires-Dist: httpx
19
+ Requires-Dist: huggingface-hub[hf-xet]
20
+ Requires-Dist: langchain-core==0.3.74
21
+ Requires-Dist: langchain-openai==0.3.29
22
+ Requires-Dist: markitdown[all]==0.1.5
23
+ Requires-Dist: nbformat
24
+ Requires-Dist: pillow-heif
25
+ Requires-Dist: pymupdf
26
+ Requires-Dist: pypdf
27
+ Requires-Dist: python-dotenv
28
+ Requires-Dist: requests
29
+ Requires-Dist: tabulate
30
+ Requires-Dist: youtube-transcript-api
31
+ Description-Content-Type: text/markdown
32
+
33
+ # MarkItDown-Pro
34
+
35
+ **MarkItDown-Pro** is a Python library that converts **50+ document formats into Markdown**, built to power RAG (Retrieval-Augmented Generation) pipelines for semantic search. It extends [Microsoft MarkItDown](https://github.com/microsoft/markitdown) with Azure AI services, per-page OCR, and customizable converter pipelines.
36
+
37
+ ---
38
+
39
+ ## Features
40
+
41
+ - **Async-first API** -- all public methods are `async`, designed for concurrent document processing
42
+ - **Per-page PDF routing** -- classifies each page as text or image, extracts text locally and OCRs only image pages
43
+ - **Customizable pipelines** -- inject your own converter order per handler to optimize for quality, speed, or cost
44
+ - **GPT Vision OCR** -- concurrent page-by-page OCR via Azure OpenAI (gpt-5.4-mini default)
45
+ - **Gotenberg integration** -- convert Office files to PDF for full OCR via [Gotenberg](https://gotenberg.dev) HTTP API
46
+ - **Azure Document Intelligence** -- layout-aware text extraction with the `prebuilt-layout` model
47
+ - **Azure Speech-to-Text** -- audio transcription with automatic language detection
48
+ - **Structured logging** -- `Component | filename.ext | page N | method | message` format for Log Analytics
49
+ - **Graceful degradation** -- missing API keys or services are handled automatically; converters fall back silently
50
+
51
+ ## Supported Formats
52
+
53
+ | Category | Formats |
54
+ | --------------- | ----------------------------------------------------------------------------------- |
55
+ | **PDF** | `.pdf` (text, scanned, mixed — per-page routing) |
56
+ | **Office** | `.docx`, `.pptx` (via Gotenberg + DocIntelligence + MarkItDown) |
57
+ | **Spreadsheet** | `.csv`, `.tsv`, `.xls`, `.xlsx` |
58
+ | **Images** | `.png`, `.jpg`, `.jpeg`, `.gif`, `.bmp`, `.svg`, `.tiff`, `.webp`, `.heic`, `.heif` |
59
+ | **Audio** | `.mp3`, `.wav` |
60
+ | **Email** | `.eml`, `.msg`, `.p7s` |
61
+ | **Archives** | `.pst` (Outlook) |
62
+ | **E-books** | `.epub` |
63
+ | **Notebooks** | `.ipynb` |
64
+ | **Markup** | `.html`, `.htm`, `.xml`, `.json`, `.ndjson`, `.yaml`, `.yml` |
65
+ | **Text** | `.txt`, `.md`, `.py`, `.go` |
66
+
67
+ ## Architecture
68
+
69
+ ```
70
+ ConversionPipeline (async)
71
+ |-- detect extension
72
+ |-- route to Handler
73
+ | |-- try Converter 1 (primary)
74
+ | |-- try Converter 2 (fallback)
75
+ | |-- try Converter N
76
+ |-- validate content
77
+ |-- clean markdown
78
+ ```
79
+
80
+ ### Default Converter Pipelines
81
+
82
+ | Handler | Pipeline (in order) | What each captures |
83
+ | ------------------ | ------------------------------------------------------------------------------------------------ | -------------------------------------------- |
84
+ | **PDFHandler** | MarkItDown (all-text only) → PagePDFConverter (per-page: PyMuPDF → GPT Vision → DocIntelligence) | Text + images + scanned content |
85
+ | **OfficeHandler** | Gotenberg → DocIntelligence → MarkItDown | Text + images (via Gotenberg PDF conversion) |
86
+ | **ImageHandler** | GPT Vision (primary model) → GPT Vision (fallback model) | OCR on images |
87
+ | **AudioHandler** | Azure Speech | Transcription |
88
+ | **TabularHandler** | openpyxl/pandas | Tables to markdown |
89
+ | **MarkupHandler** | BeautifulSoup/yaml/json | Structured markup |
90
+ | **TextHandler** | chardet encoding detection | Raw text |
91
+ | **EmailHandler** | Python email parser | Email text + attachments |
92
+
93
+ ## Installation
94
+
95
+ ### Prerequisites
96
+
97
+ - Python >= 3.13
98
+ - [uv](https://docs.astral.sh/uv/) (package manager)
99
+ - System dependencies: `ffmpeg` (audio)
100
+ - Optional: [Gotenberg](https://gotenberg.dev) Docker service (for Office → PDF OCR)
101
+
102
+ ### Install
103
+
104
+ ```bash
105
+ git clone https://github.com/your-org/markitdown-pro.git
106
+ cd markitdown-pro
107
+
108
+ # Install all dependencies (creates .venv automatically)
109
+ uv sync
110
+
111
+ # With dev tools (pytest, ruff)
112
+ uv sync --dev
113
+ ```
114
+
115
+ ### Configure Environment
116
+
117
+ Create a `.env` file in the project root:
118
+
119
+ ```bash
120
+ # Azure OpenAI (required for GPT Vision OCR)
121
+ AZURE_OPENAI_ENDPOINT="https://<resource>.openai.azure.com"
122
+ AZURE_OPENAI_API_KEY="your-key"
123
+ AZURE_OPENAI_API_VERSION="2024-12-01-preview"
124
+
125
+ # Azure Document Intelligence (required for doc intelligence fallback)
126
+ AZURE_DOCINTEL_ENDPOINT="https://<resource>.cognitiveservices.azure.com"
127
+ AZURE_DOCINTEL_KEY="your-key"
128
+
129
+ # Azure Speech (required for audio transcription)
130
+ AZURE_SPEECH_KEY="your-key"
131
+ AZURE_SPEECH_REGION="eastus"
132
+
133
+ # Gotenberg (optional — for Office → PDF → OCR)
134
+ GOTENBERG_URL="http://gotenberg:3000"
135
+
136
+ # OCR model configuration (optional — defaults shown)
137
+ MARKITDOWN_OCR_MODEL="gpt-5.4-mini"
138
+ MARKITDOWN_OCR_FALLBACK_MODEL="gpt-5.4"
139
+ MARKITDOWN_OCR_TIMEOUT="60.0"
140
+ MARKITDOWN_OCR_MAX_RETRIES="6"
141
+ MARKITDOWN_MIN_IMAGE_AREA="150000"
142
+
143
+ # General
144
+ LOG_LEVEL=20 # 10=DEBUG, 20=INFO, 30=WARNING
145
+ ```
146
+
147
+ All services are optional -- the library degrades gracefully when credentials are missing.
148
+
149
+ ## Usage
150
+
151
+ ### Basic
152
+
153
+ ```python
154
+ import asyncio
155
+ from markitdown_pro.conversion_pipeline import ConversionPipeline
156
+
157
+ async def main():
158
+ pipeline = ConversionPipeline()
159
+ try:
160
+ md = await pipeline.convert_document_to_md("/path/to/document.pdf")
161
+ print(md)
162
+ finally:
163
+ await pipeline.aclose()
164
+
165
+ asyncio.run(main())
166
+ ```
167
+
168
+ ### Custom Pipeline (speed-first)
169
+
170
+ Skip Gotenberg and GPT Vision, use only local converters:
171
+
172
+ ```python
173
+ from markitdown_pro.conversion_pipeline import ConversionPipeline
174
+ from markitdown_pro.converters.markitdown_converter import MarkItDownConverter
175
+ from markitdown_pro.converters.doc_intel_converter import DocIntelligenceConverter
176
+ from markitdown_pro.handlers.office_handler import OfficeHandler
177
+
178
+ # Office: MarkItDown first (fast, local), DocIntelligence fallback
179
+ office = OfficeHandler(pipeline=[
180
+ (MarkItDownConverter(), "MarkItDown"),
181
+ (DocIntelligenceConverter(), "DocIntelligence"),
182
+ ])
183
+
184
+ pipeline = ConversionPipeline(office_handler=office)
185
+ ```
186
+
187
+ ### Custom Pipeline (quality-first with Gotenberg)
188
+
189
+ Ensure Office files go through Gotenberg for full OCR:
190
+
191
+ ```python
192
+ from markitdown_pro.converters.gotenberg_converter import GotenbergConverter
193
+ from markitdown_pro.converters.doc_intel_converter import DocIntelligenceConverter
194
+ from markitdown_pro.converters.markitdown_converter import MarkItDownConverter
195
+ from markitdown_pro.handlers.office_handler import OfficeHandler
196
+
197
+ office = OfficeHandler(pipeline=[
198
+ (GotenbergConverter(gotenberg_url="http://localhost:3000"), "Gotenberg"),
199
+ (DocIntelligenceConverter(), "DocIntelligence"),
200
+ (MarkItDownConverter(), "MarkItDown"),
201
+ ])
202
+
203
+ pipeline = ConversionPipeline(office_handler=office)
204
+ ```
205
+
206
+ ### Custom Pipeline (cost-first, no API calls)
207
+
208
+ ```python
209
+ from markitdown_pro.converters.markitdown_converter import MarkItDownConverter
210
+ from markitdown_pro.handlers.office_handler import OfficeHandler
211
+
212
+ office = OfficeHandler(pipeline=[
213
+ (MarkItDownConverter(), "MarkItDown"),
214
+ ])
215
+
216
+ pipeline = ConversionPipeline(office_handler=office)
217
+ ```
218
+
219
+ ### Custom OCR Model
220
+
221
+ ```python
222
+ from markitdown_pro.converters.gpt_vision_converter import GPTVisionConverter
223
+ from markitdown_pro.handlers.image_handler import ImageHandler
224
+
225
+ image = ImageHandler(pipeline=[
226
+ GPTVisionConverter(model_name="gpt-5.4-nano"), # cheapest
227
+ ])
228
+
229
+ pipeline = ConversionPipeline(image_handler=image)
230
+ ```
231
+
232
+ ### All Handler Overrides
233
+
234
+ ```python
235
+ pipeline = ConversionPipeline(
236
+ pdf_handler=my_pdf_handler,
237
+ office_handler=my_office_handler,
238
+ image_handler=my_image_handler,
239
+ audio_handler=my_audio_handler,
240
+ # text, tabular, markup, email, epub, pst, ipynb also injectable
241
+ )
242
+ ```
243
+
244
+ ### Gotenberg Setup
245
+
246
+ [Gotenberg](https://gotenberg.dev) converts Office files to PDF for per-page OCR. Run it as a Docker container:
247
+
248
+ ```bash
249
+ docker run -d -p 3000:3000 gotenberg/gotenberg:8
250
+ ```
251
+
252
+ Or in Docker Compose:
253
+
254
+ ```yaml
255
+ services:
256
+ gotenberg:
257
+ image: gotenberg/gotenberg:8
258
+ ports:
259
+ - "3000:3000"
260
+ ```
261
+
262
+ Set the URL in your environment:
263
+
264
+ ```bash
265
+ GOTENBERG_URL=http://localhost:3000
266
+ ```
267
+
268
+ ## Testing
269
+
270
+ ```bash
271
+ # Unit tests (fast, no credentials, ~0.2s)
272
+ uv run pytest tests/unit/ -v
273
+
274
+ # Integration tests (requires Azure credentials in .env)
275
+ uv run pytest -m integration -v
276
+
277
+ # Local-only integration tests (no Azure needed)
278
+ uv run pytest tests/integration/test_text_handler.py tests/integration/test_markup_handler.py tests/integration/test_tabular_handler.py tests/integration/test_email_handler.py -v
279
+
280
+ # All tests
281
+ uv run pytest tests/unit/ tests/integration/ -v
282
+ ```
283
+
284
+ Test expectations are defined per-handler in `tests/data/test_expectations.yaml`.
285
+
286
+ ## Development
287
+
288
+ ```bash
289
+ # Lint
290
+ uv run ruff check markitdown_pro/
291
+
292
+ # Format
293
+ uv run ruff format markitdown_pro/
294
+
295
+ # Build package
296
+ uv build
297
+ ```
298
+
299
+ ## License
300
+
301
+ MIT