markitdown-pro 2.1.0__tar.gz → 2.1.2__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.1.0 → markitdown_pro-2.1.2}/.github/workflows/test.yml +1 -7
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/.gitignore +1 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/PKG-INFO +1 -1
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/gotenberg_converter.py +88 -26
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/gpt_vision_converter.py +3 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/page_pdf_converter.py +1 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/services/azure_doc_intelligence.py +1 -1
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/services/openai_services.py +10 -2
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/.github/workflows/lint.yaml +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/.github/workflows/publish.yaml +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/.vscode/settings.json +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/README.md +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/common/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/common/config.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/common/isolated_worker.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/common/logger.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/common/schemas.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/common/utils.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/conversion_pipeline.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/base.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/doc_intel_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/markitdown_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/pymupdf_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/speech_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/tabular_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/unstructured_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/youtube_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/audio_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/base_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/email_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/epub_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/image_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/ipynb_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/markup_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/office_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/pdf_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/pst_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/tabular_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/handlers/text_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/services/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/services/azure_speech.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/pyproject.toml +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/common/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/common/test_config.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/conftest.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/conversion_pipeline/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/conversion_pipeline/test_conversion_pipeline.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_azure_doc_intel_wrapper.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_azure_speech_wrapper.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_doc_intel_lifecycle.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_gpt_vision_config.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_gpt_vision_wrapper.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_pymupdf_wrapper.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_pymupdf_wrapper_async.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_unstructured_io_wrapper.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_cn.wav +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_en.mp3 +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_en.wav +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_es.mp3 +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_es.wav +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_it.wav +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_jp.mp3 +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_jp.wav +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/eml/email-with-image.eml +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/eml/mime-different-plain-html.eml +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/epub/sample1.epub +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/images/flower.jpg +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/images/geometry_colors.bmp +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/images/handwriting.jpg +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/images/scanned_text.heic +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/images/scanned_text.png +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/images/text_with_image.jpg +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/markup/blog.html +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/markup/factbook.xml +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/markup/simple.json +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/markup/simple.yaml +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/msg/fake-email-multiple-attachments.msg +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/msg/fake-email.msg +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/pdf/geometry-colors.pdf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/pdf/lorem-ipsum-only-images.pdf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/pdf/lorem-ipsum-only-text.pdf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/pdf/lorem-ipsum-scanned-text.pdf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/pdf/lorem-ipsum-text-with-image.pdf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint/geometry-colors.pptx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint/lorem-ipsum-only-text.pptx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint/lorem-ipsum-scanned-text.pptx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint/lorem-ipsum-text-with-image.pptx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint/lorem-ipsum-text-with-scanned-text.pptx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint-legacy/geometry-colors.ppt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint-legacy/lorem-ipsum-only-text.ppt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint-legacy/lorem-ipsum-scanned-text.ppt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint-legacy/lorem-ipsum-text-with-image.ppt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint-legacy/lorem-ipsum-text-with-scanned-text.ppt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/tabular/2023-half-year-analyses-by-segment.xlsx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/tabular/stanley-cups.csv +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/tabular/stanley-cups.tsv +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/tabular/stanley-cups.xlsx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/test_expectations.yaml +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/text/book-war-and-peace-1p.txt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/text/fake-email.txt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/text/logger.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word/geometry-colors.docx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word/lorem-ipsum-only-text.docx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word/lorem-ipsum-scanned-text.docx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word/lorem-ipsum-text-with-image.docx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word/lorem-ipsum-text-with-scanned-text.docx +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/geometry-colors.doc +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/geometry-colors.odt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/geometry-colors.rtf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-only-text.doc +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-only-text.odt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-only-text.rtf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-scanned-text.doc +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-scanned-text.odt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-scanned-text.rtf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-image.doc +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-image.odt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-image.rtf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-scanned-text.doc +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-scanned-text.odt +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-scanned-text.rtf +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/fixtures.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_email_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_epub_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_image_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_ipynb_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_markitdown_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_markitdown_validation.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_markup_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_page_pdf_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_pdf_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_pst_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_tabular_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/handlers/test_text_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/cheat_sheet.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/runner.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_audio_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_doc_intelligence_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_email_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_gotenberg_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_gpt_vision_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_legacy_office_formats.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_markitdown_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_markup_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_pdf_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_pymupdf_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_tabular_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_text_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/page_count/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/page_count/test_pdf_page_count.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/__init__.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_audio_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_base_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_conversion_pipeline.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_doc_intel_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_gotenberg_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_gpt_vision_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_image_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_markitdown_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_office_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_page_pdf_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_pdf_handler.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_pymupdf_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/unit/test_speech_converter.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/utils.py +0 -0
- {markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/uv.lock +0 -0
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
name: '🧪 Test package'
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
paths:
|
|
8
|
-
- 'markitdown_pro/**'
|
|
9
|
-
- 'tests/**'
|
|
10
|
-
- 'pyproject.toml'
|
|
11
4
|
pull_request:
|
|
12
5
|
branches:
|
|
13
6
|
- main
|
|
@@ -15,6 +8,7 @@ on:
|
|
|
15
8
|
- 'markitdown_pro/**'
|
|
16
9
|
- 'tests/**'
|
|
17
10
|
- 'pyproject.toml'
|
|
11
|
+
workflow_dispatch:
|
|
18
12
|
|
|
19
13
|
permissions:
|
|
20
14
|
contents: read
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/gotenberg_converter.py
RENAMED
|
@@ -15,10 +15,14 @@ If the Gotenberg service is configured but unreachable at call time,
|
|
|
15
15
|
converter.
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
+
import asyncio
|
|
18
19
|
import contextlib
|
|
20
|
+
import functools
|
|
19
21
|
import os
|
|
20
22
|
import tempfile
|
|
23
|
+
from collections.abc import Awaitable, Callable
|
|
21
24
|
from pathlib import Path
|
|
25
|
+
from typing import TypeVar
|
|
22
26
|
|
|
23
27
|
import httpx
|
|
24
28
|
|
|
@@ -28,6 +32,52 @@ from .base import Converter
|
|
|
28
32
|
_COMPONENT = "GotenbergConverter"
|
|
29
33
|
_CONVERT_ENDPOINT = "/forms/libreoffice/convert"
|
|
30
34
|
|
|
35
|
+
# Transient failures worth retrying. ConnectError is intentionally excluded —
|
|
36
|
+
# "service unreachable" is handled as a graceful skip, not a retry.
|
|
37
|
+
_RETRYABLE_EXC: tuple[type[BaseException], ...] = (
|
|
38
|
+
httpx.TimeoutException,
|
|
39
|
+
httpx.RemoteProtocolError,
|
|
40
|
+
httpx.ReadError,
|
|
41
|
+
httpx.WriteError,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
T = TypeVar("T")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _retry_transient(
|
|
48
|
+
attempts: int = 3, delays: tuple[float, ...] = (1.0, 3.0)
|
|
49
|
+
) -> Callable[[Callable[..., Awaitable[T | None]]], Callable[..., Awaitable[T | None]]]:
|
|
50
|
+
"""Retry an async method on transient httpx errors. Sleeps between attempts
|
|
51
|
+
are taken from ``delays`` (short, fixed backoff — enough to ride out a
|
|
52
|
+
worker restart or a brief connection hiccup)."""
|
|
53
|
+
|
|
54
|
+
def decorator(
|
|
55
|
+
fn: Callable[..., Awaitable[T | None]],
|
|
56
|
+
) -> Callable[..., Awaitable[T | None]]:
|
|
57
|
+
"""Wrap ``fn`` with the retry-on-transient-httpx-errors policy above."""
|
|
58
|
+
|
|
59
|
+
@functools.wraps(fn)
|
|
60
|
+
async def wrapper(self, *args, **kwargs) -> T | None:
|
|
61
|
+
"""Call ``fn`` up to ``attempts`` times, sleeping per ``delays``."""
|
|
62
|
+
tag = args[1] if len(args) >= 2 else kwargs.get("tag", _COMPONENT)
|
|
63
|
+
for i in range(attempts):
|
|
64
|
+
try:
|
|
65
|
+
return await fn(self, *args, **kwargs)
|
|
66
|
+
except _RETRYABLE_EXC as e:
|
|
67
|
+
if i == attempts - 1:
|
|
68
|
+
raise
|
|
69
|
+
sleep_for = delays[min(i, len(delays) - 1)]
|
|
70
|
+
logger.warning(
|
|
71
|
+
f"{tag} | transient {type(e).__name__}: {e}; "
|
|
72
|
+
f"retry {i + 1}/{attempts - 1} in {sleep_for:.1f}s"
|
|
73
|
+
)
|
|
74
|
+
await asyncio.sleep(sleep_for)
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
return wrapper
|
|
78
|
+
|
|
79
|
+
return decorator
|
|
80
|
+
|
|
31
81
|
|
|
32
82
|
class GotenbergConverter(Converter):
|
|
33
83
|
"""
|
|
@@ -81,7 +131,11 @@ class GotenbergConverter(Converter):
|
|
|
81
131
|
|
|
82
132
|
logger.info(f"{tag} | converting to PDF via Gotenberg ({self.gotenberg_url})")
|
|
83
133
|
|
|
84
|
-
|
|
134
|
+
try:
|
|
135
|
+
pdf_bytes = await self._convert_to_pdf(file_path, tag)
|
|
136
|
+
except _RETRYABLE_EXC as e:
|
|
137
|
+
logger.error(f"{tag} | Gotenberg error after retries: {type(e).__name__}: {e}")
|
|
138
|
+
return None
|
|
85
139
|
if not pdf_bytes:
|
|
86
140
|
return None
|
|
87
141
|
|
|
@@ -90,7 +144,7 @@ class GotenbergConverter(Converter):
|
|
|
90
144
|
try:
|
|
91
145
|
fd, tmp_pdf = tempfile.mkstemp(suffix=".pdf", prefix="mkdpro_")
|
|
92
146
|
os.close(fd)
|
|
93
|
-
Path(tmp_pdf).write_bytes
|
|
147
|
+
await asyncio.to_thread(Path(tmp_pdf).write_bytes, pdf_bytes)
|
|
94
148
|
|
|
95
149
|
logger.info(f"{tag} | PDF received ({len(pdf_bytes)} bytes), delegating to PDFHandler")
|
|
96
150
|
|
|
@@ -114,34 +168,42 @@ class GotenbergConverter(Converter):
|
|
|
114
168
|
with contextlib.suppress(Exception):
|
|
115
169
|
os.unlink(tmp_pdf)
|
|
116
170
|
|
|
171
|
+
@_retry_transient(attempts=3, delays=(1.0, 3.0))
|
|
117
172
|
async def _convert_to_pdf(self, file_path: str, tag: str) -> bytes | None:
|
|
118
|
-
"""Send file to Gotenberg and return PDF bytes.
|
|
119
|
-
try:
|
|
120
|
-
async with httpx.AsyncClient(timeout=120) as client:
|
|
121
|
-
with open(file_path, "rb") as f:
|
|
122
|
-
response = await client.post(
|
|
123
|
-
self._convert_url,
|
|
124
|
-
files={"files": (Path(file_path).name, f)},
|
|
125
|
-
data={
|
|
126
|
-
"losslessImageCompression": "true",
|
|
127
|
-
"quality": "100",
|
|
128
|
-
},
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
if response.status_code == 200:
|
|
132
|
-
return response.content
|
|
133
|
-
|
|
134
|
-
logger.warning(
|
|
135
|
-
f"{tag} | Gotenberg returned {response.status_code}: {response.text[:200]}"
|
|
136
|
-
)
|
|
137
|
-
return None
|
|
173
|
+
"""Send file to Gotenberg and return PDF bytes.
|
|
138
174
|
|
|
175
|
+
The HTTP call runs inside ``asyncio.to_thread`` with a sync
|
|
176
|
+
``httpx.Client`` + open file handle so httpx streams the multipart
|
|
177
|
+
body from disk instead of holding the entire upload in memory.
|
|
178
|
+
Keeps peak memory bounded under concurrent large-file conversions.
|
|
179
|
+
"""
|
|
180
|
+
try:
|
|
181
|
+
return await asyncio.to_thread(self._post_sync, file_path, tag)
|
|
139
182
|
except httpx.ConnectError:
|
|
140
183
|
logger.info(f"{tag} | Gotenberg not reachable at {self.gotenberg_url}, skipping")
|
|
141
184
|
return None
|
|
142
|
-
except
|
|
143
|
-
|
|
144
|
-
|
|
185
|
+
except _RETRYABLE_EXC:
|
|
186
|
+
# Let the retry decorator handle transient errors. If retries are
|
|
187
|
+
# exhausted it re-raises, and the caller in ``convert()`` logs.
|
|
188
|
+
raise
|
|
145
189
|
except Exception as e:
|
|
146
|
-
logger.
|
|
190
|
+
logger.error(f"{tag} | Gotenberg error: {e}")
|
|
147
191
|
return None
|
|
192
|
+
|
|
193
|
+
def _post_sync(self, file_path: str, tag: str) -> bytes | None:
|
|
194
|
+
"""Blocking multipart upload to Gotenberg. Called via ``to_thread``."""
|
|
195
|
+
with httpx.Client(timeout=120) as client, open(file_path, "rb") as f:
|
|
196
|
+
response = client.post(
|
|
197
|
+
self._convert_url,
|
|
198
|
+
files={"files": (Path(file_path).name, f)},
|
|
199
|
+
data={
|
|
200
|
+
"losslessImageCompression": "true",
|
|
201
|
+
"quality": "100",
|
|
202
|
+
},
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
if response.status_code == 200:
|
|
206
|
+
return response.content
|
|
207
|
+
|
|
208
|
+
logger.error(f"{tag} | Gotenberg returned {response.status_code}: {response.text[:200]}")
|
|
209
|
+
return None
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/gpt_vision_converter.py
RENAMED
|
@@ -11,6 +11,8 @@ Returns Markdown when successful, or `None` if conversion produced
|
|
|
11
11
|
insufficient content (as determined by `ensure_minimum_content` in the service).
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
14
16
|
from ..common import config
|
|
15
17
|
from ..common.utils import is_pdf
|
|
16
18
|
from ..services.openai_services import GPTVision
|
|
@@ -115,6 +117,7 @@ class GPTVisionConverter(Converter):
|
|
|
115
117
|
max_retries=_retries,
|
|
116
118
|
base_delay=base_delay,
|
|
117
119
|
max_delay=max_delay,
|
|
120
|
+
context_label=Path(file_path).name,
|
|
118
121
|
)
|
|
119
122
|
|
|
120
123
|
async def aclose(self) -> None:
|
|
@@ -158,6 +158,7 @@ class PagePDFConverter:
|
|
|
158
158
|
png_path = await asyncio.to_thread(self._render_page_to_png, file_path, page_idx)
|
|
159
159
|
content = await self.gpt_vision.gpt_vision.process_image(
|
|
160
160
|
file_or_url=png_path,
|
|
161
|
+
context_label=f"{Path(file_path).name} page {page_idx + 1}",
|
|
161
162
|
)
|
|
162
163
|
if content:
|
|
163
164
|
logger.info(f"{tag} | succeeded ({len(content)} chars)")
|
|
@@ -240,6 +240,7 @@ class GPTVision:
|
|
|
240
240
|
base_delay: float = 0.5,
|
|
241
241
|
max_delay: float = 20.0,
|
|
242
242
|
retry_http_statuses: tuple[int, ...] = _RETRY_HTTP_STATUSES,
|
|
243
|
+
context_label: str | None = None,
|
|
243
244
|
):
|
|
244
245
|
"""
|
|
245
246
|
Call self.lang_client.ainvoke with:
|
|
@@ -275,8 +276,9 @@ class GPTVision:
|
|
|
275
276
|
raise last_err
|
|
276
277
|
cap = min(max_delay, base_delay * (2 ** (attempt - 1)))
|
|
277
278
|
sleep_for = random.uniform(0, cap)
|
|
279
|
+
label = context_label or file_or_url
|
|
278
280
|
logger.warning(
|
|
279
|
-
f"GPTVision: ainvoke transient error {
|
|
281
|
+
f"GPTVision: ainvoke transient error {label}: attempt {attempt}/{max_retries}: "
|
|
280
282
|
f"{type(last_err).__name__}: {last_err}. Retrying in {sleep_for:.2f}s"
|
|
281
283
|
)
|
|
282
284
|
await asyncio.sleep(sleep_for)
|
|
@@ -331,6 +333,7 @@ class GPTVision:
|
|
|
331
333
|
max_retries: int = 6,
|
|
332
334
|
base_delay: float = 0.5,
|
|
333
335
|
max_delay: float = 20.0,
|
|
336
|
+
context_label: str | None = None,
|
|
334
337
|
) -> str | None:
|
|
335
338
|
"""
|
|
336
339
|
OCR a single image (local path or URL) with the vision model.
|
|
@@ -373,6 +376,7 @@ class GPTVision:
|
|
|
373
376
|
max_retries=max_retries,
|
|
374
377
|
base_delay=base_delay,
|
|
375
378
|
max_delay=max_delay,
|
|
379
|
+
context_label=context_label,
|
|
376
380
|
)
|
|
377
381
|
finally:
|
|
378
382
|
with suppress(Exception):
|
|
@@ -469,7 +473,11 @@ class GPTVision:
|
|
|
469
473
|
# Per-page hard timeout so one slow page cannot stall the run
|
|
470
474
|
try:
|
|
471
475
|
partial_md = await asyncio.wait_for(
|
|
472
|
-
self.process_image(
|
|
476
|
+
self.process_image(
|
|
477
|
+
png_path,
|
|
478
|
+
context_label=f"{file_stem} page {page_index + 1}/{num_pages}",
|
|
479
|
+
),
|
|
480
|
+
timeout=self.page_timeout_s,
|
|
473
481
|
)
|
|
474
482
|
except TimeoutError:
|
|
475
483
|
logger.error(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/doc_intel_converter.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/markitdown_converter.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/pymupdf_converter.py
RENAMED
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/tabular_converter.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/unstructured_converter.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/markitdown_pro/converters/youtube_converter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/conversion_pipeline/test_conversion_pipeline.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_azure_doc_intel_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_pymupdf_wrapper_async.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/converters/test_unstructured_io_wrapper.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_cn.wav
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_en.mp3
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_en.wav
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_es.mp3
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_es.wav
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_it.wav
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_jp.mp3
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/audio/the-power-of-small-steps_jp.wav
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/msg/fake-email-multiple-attachments.msg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/pdf/lorem-ipsum-text-with-image.pdf
RENAMED
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint/lorem-ipsum-only-text.pptx
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint/lorem-ipsum-scanned-text.pptx
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint/lorem-ipsum-text-with-image.pptx
RENAMED
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint-legacy/geometry-colors.ppt
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/powerpoint-legacy/lorem-ipsum-only-text.ppt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word/lorem-ipsum-text-with-image.docx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-only-text.doc
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-only-text.odt
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-only-text.rtf
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-scanned-text.doc
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-scanned-text.odt
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-scanned-text.rtf
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-image.doc
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-image.odt
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/data/word-legacy/lorem-ipsum-text-with-image.rtf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_doc_intelligence_converter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_gpt_vision_converter.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_legacy_office_formats.py
RENAMED
|
File without changes
|
{markitdown_pro-2.1.0 → markitdown_pro-2.1.2}/tests/integration/test_markitdown_converter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|