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.
- markitdown_pro-2.0.0/.github/workflows/lint.yaml +44 -0
- markitdown_pro-2.0.0/.github/workflows/publish.yaml +51 -0
- markitdown_pro-2.0.0/.github/workflows/test.yml +123 -0
- markitdown_pro-2.0.0/.gitignore +26 -0
- markitdown_pro-2.0.0/.vscode/settings.json +17 -0
- markitdown_pro-2.0.0/PKG-INFO +301 -0
- markitdown_pro-2.0.0/README.md +269 -0
- markitdown_pro-2.0.0/markitdown_pro/common/config.py +56 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/common/isolated_worker.py +6 -3
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/conversion_pipeline.py +56 -46
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/converters/base.py +15 -5
- markitdown_pro-2.0.0/markitdown_pro/converters/doc_intel_converter.py +21 -0
- markitdown_pro-2.0.0/markitdown_pro/converters/gotenberg_converter.py +118 -0
- 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
- markitdown_pro-2.0.0/markitdown_pro/converters/markitdown_converter.py +54 -0
- markitdown_pro-2.0.0/markitdown_pro/converters/pymupdf_converter.py +35 -0
- 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
- markitdown_pro-1.3.7/markitdown_pro/converters/tabular_wrapper.py → markitdown_pro-2.0.0/markitdown_pro/converters/tabular_converter.py +5 -7
- markitdown_pro-1.3.7/markitdown_pro/converters/unstructured_wrapper.py → markitdown_pro-2.0.0/markitdown_pro/converters/unstructured_converter.py +14 -11
- markitdown_pro-1.3.7/markitdown_pro/converters/youtube_wrapper.py → markitdown_pro-2.0.0/markitdown_pro/converters/youtube_converter.py +3 -4
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/audio_handler.py +16 -9
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/base_handler.py +2 -3
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/email_handler.py +15 -16
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/epub_handler.py +4 -5
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/image_handler.py +18 -16
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/ipynb_handler.py +1 -3
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/markup_handler.py +2 -3
- markitdown_pro-2.0.0/markitdown_pro/handlers/office_handler.py +90 -0
- markitdown_pro-2.0.0/markitdown_pro/handlers/page_pdf_converter.py +249 -0
- markitdown_pro-2.0.0/markitdown_pro/handlers/pdf_handler.py +178 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/pst_handler.py +5 -5
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/tabular_handler.py +4 -5
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/handlers/text_handler.py +1 -2
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/services/azure_doc_intelligence.py +13 -14
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/services/azure_speech.py +32 -34
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/services/openai_services.py +38 -24
- markitdown_pro-2.0.0/pyproject.toml +120 -0
- markitdown_pro-2.0.0/tests/common/test_config.py +39 -0
- markitdown_pro-2.0.0/tests/conftest.py +210 -0
- markitdown_pro-2.0.0/tests/conversion_pipeline/__init__.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/conversion_pipeline/test_conversion_pipeline.py +3 -3
- markitdown_pro-2.0.0/tests/converters/test_azure_doc_intel_wrapper.py +44 -0
- markitdown_pro-2.0.0/tests/converters/test_azure_speech_wrapper.py +29 -0
- markitdown_pro-2.0.0/tests/converters/test_doc_intel_lifecycle.py +35 -0
- markitdown_pro-2.0.0/tests/converters/test_gpt_vision_config.py +23 -0
- markitdown_pro-2.0.0/tests/converters/test_gpt_vision_wrapper.py +28 -0
- markitdown_pro-2.0.0/tests/converters/test_pymupdf_wrapper.py +28 -0
- markitdown_pro-2.0.0/tests/converters/test_pymupdf_wrapper_async.py +26 -0
- markitdown_pro-2.0.0/tests/converters/test_unstructured_io_wrapper.py +28 -0
- markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_cn.wav +0 -0
- markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_en.mp3 +0 -0
- markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_en.wav +0 -0
- markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_es.mp3 +0 -0
- markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_es.wav +0 -0
- markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_it.wav +0 -0
- markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_jp.mp3 +0 -0
- markitdown_pro-2.0.0/tests/data/audio/the-power-of-small-steps_jp.wav +0 -0
- markitdown_pro-2.0.0/tests/data/eml/email-with-image.eml +3828 -0
- markitdown_pro-2.0.0/tests/data/eml/mime-different-plain-html.eml +34 -0
- markitdown_pro-2.0.0/tests/data/epub/sample1.epub +0 -0
- markitdown_pro-2.0.0/tests/data/images/flower.jpg +0 -0
- markitdown_pro-2.0.0/tests/data/images/geometry_colors.bmp +0 -0
- markitdown_pro-2.0.0/tests/data/images/handwriting.jpg +0 -0
- markitdown_pro-2.0.0/tests/data/images/scanned_text.heic +0 -0
- markitdown_pro-2.0.0/tests/data/images/scanned_text.png +0 -0
- markitdown_pro-2.0.0/tests/data/images/text_with_image.jpg +0 -0
- markitdown_pro-2.0.0/tests/data/markup/blog.html +69 -0
- markitdown_pro-2.0.0/tests/data/markup/factbook.xml +27 -0
- markitdown_pro-2.0.0/tests/data/markup/simple.json +127 -0
- markitdown_pro-2.0.0/tests/data/markup/simple.yaml +19 -0
- markitdown_pro-2.0.0/tests/data/msg/fake-email-multiple-attachments.msg +0 -0
- markitdown_pro-2.0.0/tests/data/msg/fake-email.msg +0 -0
- markitdown_pro-2.0.0/tests/data/pdf/geometry-colors.pdf +0 -0
- markitdown_pro-2.0.0/tests/data/pdf/lorem-ipsum-only-images.pdf +0 -0
- markitdown_pro-2.0.0/tests/data/pdf/lorem-ipsum-only-text.pdf +0 -0
- markitdown_pro-2.0.0/tests/data/pdf/lorem-ipsum-scanned-text.pdf +0 -0
- markitdown_pro-2.0.0/tests/data/pdf/lorem-ipsum-text-with-image.pdf +0 -0
- markitdown_pro-2.0.0/tests/data/powerpoint/geometry-colors.pptx +0 -0
- markitdown_pro-2.0.0/tests/data/powerpoint/lorem-ipsum-only-text.pptx +0 -0
- markitdown_pro-2.0.0/tests/data/powerpoint/lorem-ipsum-scanned-text.pptx +0 -0
- markitdown_pro-2.0.0/tests/data/powerpoint/lorem-ipsum-text-with-image.pptx +0 -0
- markitdown_pro-2.0.0/tests/data/powerpoint/lorem-ipsum-text-with-scanned-text.pptx +0 -0
- markitdown_pro-2.0.0/tests/data/tabular/2023-half-year-analyses-by-segment.xlsx +0 -0
- markitdown_pro-2.0.0/tests/data/tabular/stanley-cups.csv +5 -0
- markitdown_pro-2.0.0/tests/data/tabular/stanley-cups.tsv +5 -0
- markitdown_pro-2.0.0/tests/data/tabular/stanley-cups.xlsx +0 -0
- markitdown_pro-2.0.0/tests/data/test_expectations.yaml +224 -0
- markitdown_pro-2.0.0/tests/data/text/book-war-and-peace-1p.txt +62 -0
- markitdown_pro-2.0.0/tests/data/text/fake-email.txt +25 -0
- markitdown_pro-2.0.0/tests/data/text/logger.py +19 -0
- markitdown_pro-2.0.0/tests/data/word/geometry-colors.docx +0 -0
- markitdown_pro-2.0.0/tests/data/word/lorem-ipsum-only-text.docx +0 -0
- markitdown_pro-2.0.0/tests/data/word/lorem-ipsum-scanned-text.docx +0 -0
- markitdown_pro-2.0.0/tests/data/word/lorem-ipsum-text-with-image.docx +0 -0
- markitdown_pro-2.0.0/tests/data/word/lorem-ipsum-text-with-scanned-text.docx +0 -0
- markitdown_pro-2.0.0/tests/fixtures.py +16 -0
- markitdown_pro-2.0.0/tests/handlers/__init__.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_markitdown_handler.py +6 -6
- markitdown_pro-2.0.0/tests/handlers/test_markitdown_validation.py +25 -0
- markitdown_pro-2.0.0/tests/handlers/test_page_pdf_converter.py +159 -0
- markitdown_pro-2.0.0/tests/handlers/test_pdf_handler.py +114 -0
- markitdown_pro-2.0.0/tests/integration/__init__.py +0 -0
- markitdown_pro-2.0.0/tests/integration/cheat_sheet.py +55 -0
- markitdown_pro-2.0.0/tests/integration/runner.py +69 -0
- markitdown_pro-2.0.0/tests/integration/test_audio_handler.py +27 -0
- markitdown_pro-2.0.0/tests/integration/test_doc_intelligence_converter.py +30 -0
- markitdown_pro-2.0.0/tests/integration/test_email_handler.py +27 -0
- markitdown_pro-2.0.0/tests/integration/test_gotenberg_converter.py +34 -0
- markitdown_pro-2.0.0/tests/integration/test_gpt_vision_converter.py +30 -0
- markitdown_pro-2.0.0/tests/integration/test_markitdown_converter.py +27 -0
- markitdown_pro-2.0.0/tests/integration/test_markup_handler.py +27 -0
- markitdown_pro-2.0.0/tests/integration/test_pdf_handler.py +30 -0
- markitdown_pro-2.0.0/tests/integration/test_pymupdf_converter.py +27 -0
- markitdown_pro-2.0.0/tests/integration/test_tabular_handler.py +27 -0
- markitdown_pro-2.0.0/tests/integration/test_text_handler.py +27 -0
- markitdown_pro-2.0.0/tests/page_count/__init__.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/page_count/test_pdf_page_count.py +4 -4
- markitdown_pro-2.0.0/tests/unit/__init__.py +0 -0
- markitdown_pro-2.0.0/tests/unit/test_audio_handler.py +58 -0
- markitdown_pro-2.0.0/tests/unit/test_base_converter.py +69 -0
- markitdown_pro-2.0.0/tests/unit/test_conversion_pipeline.py +141 -0
- markitdown_pro-2.0.0/tests/unit/test_doc_intel_converter.py +70 -0
- markitdown_pro-2.0.0/tests/unit/test_gpt_vision_converter.py +128 -0
- markitdown_pro-2.0.0/tests/unit/test_image_handler.py +115 -0
- markitdown_pro-2.0.0/tests/unit/test_markitdown_converter.py +92 -0
- markitdown_pro-2.0.0/tests/unit/test_office_handler.py +111 -0
- markitdown_pro-2.0.0/tests/unit/test_page_pdf_converter.py +208 -0
- markitdown_pro-2.0.0/tests/unit/test_pdf_handler.py +245 -0
- markitdown_pro-2.0.0/tests/unit/test_pymupdf_converter.py +71 -0
- markitdown_pro-2.0.0/tests/unit/test_speech_converter.py +38 -0
- markitdown_pro-2.0.0/tests/utils.py +96 -0
- markitdown_pro-2.0.0/uv.lock +2886 -0
- markitdown_pro-1.3.7/PKG-INFO +0 -345
- markitdown_pro-1.3.7/README.md +0 -304
- markitdown_pro-1.3.7/markitdown_pro/converters/azure_doc_intel_wrapper.py +0 -22
- markitdown_pro-1.3.7/markitdown_pro/converters/markitdown_wrapper.py +0 -24
- markitdown_pro-1.3.7/markitdown_pro/converters/pymupdf_wrapper.py +0 -37
- markitdown_pro-1.3.7/markitdown_pro/handlers/markitdown_handler.py +0 -66
- markitdown_pro-1.3.7/markitdown_pro/handlers/office_handler.py +0 -75
- markitdown_pro-1.3.7/markitdown_pro/handlers/pdf_handler.py +0 -377
- markitdown_pro-1.3.7/markitdown_pro.egg-info/PKG-INFO +0 -345
- markitdown_pro-1.3.7/markitdown_pro.egg-info/SOURCES.txt +0 -58
- markitdown_pro-1.3.7/markitdown_pro.egg-info/dependency_links.txt +0 -1
- markitdown_pro-1.3.7/markitdown_pro.egg-info/requires.txt +0 -23
- markitdown_pro-1.3.7/markitdown_pro.egg-info/top_level.txt +0 -2
- markitdown_pro-1.3.7/pyproject.toml +0 -41
- markitdown_pro-1.3.7/setup.cfg +0 -8
- markitdown_pro-1.3.7/setup.py +0 -44
- {markitdown_pro-1.3.7/markitdown_pro/common → markitdown_pro-2.0.0}/__init__.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/__init__.py +0 -0
- {markitdown_pro-1.3.7/markitdown_pro/converters → markitdown_pro-2.0.0/markitdown_pro/common}/__init__.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/common/logger.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/common/schemas.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/markitdown_pro/common/utils.py +0 -0
- {markitdown_pro-1.3.7/markitdown_pro/handlers → markitdown_pro-2.0.0/markitdown_pro/converters}/__init__.py +0 -0
- {markitdown_pro-1.3.7/markitdown_pro/services → markitdown_pro-2.0.0/markitdown_pro/handlers}/__init__.py +0 -0
- {markitdown_pro-1.3.7/tests/conversion_pipeline → markitdown_pro-2.0.0/markitdown_pro/services}/__init__.py +0 -0
- {markitdown_pro-1.3.7/tests/handlers → markitdown_pro-2.0.0/tests}/__init__.py +0 -0
- {markitdown_pro-1.3.7/tests/page_count → markitdown_pro-2.0.0/tests/common}/__init__.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_email_handler.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_epub_handler.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_image_handler.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_ipynb_handler.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_markup_handler.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_pst_handler.py +0 -0
- {markitdown_pro-1.3.7 → markitdown_pro-2.0.0}/tests/handlers/test_tabular_handler.py +0 -0
- {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
|