mdengine 0.4.0__tar.gz → 0.6.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.
- {mdengine-0.4.0 → mdengine-0.6.0}/PKG-INFO +66 -8
- {mdengine-0.4.0 → mdengine-0.6.0}/README.md +44 -5
- {mdengine-0.4.0 → mdengine-0.6.0}/pyproject.toml +43 -3
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/__init__.py +1 -1
- mdengine-0.6.0/src/md_generator/db/__init__.py +5 -0
- mdengine-0.6.0/src/md_generator/db/adapters/__init__.py +3 -0
- mdengine-0.6.0/src/md_generator/db/adapters/factory.py +46 -0
- mdengine-0.6.0/src/md_generator/db/adapters/mongo_adapter.py +142 -0
- mdengine-0.6.0/src/md_generator/db/adapters/mysql_adapter.py +310 -0
- mdengine-0.6.0/src/md_generator/db/adapters/oracle_adapter.py +330 -0
- mdengine-0.6.0/src/md_generator/db/adapters/postgres_adapter.py +290 -0
- mdengine-0.6.0/src/md_generator/db/adapters/sql_common.py +102 -0
- mdengine-0.6.0/src/md_generator/db/adapters/sqlite_adapter.py +107 -0
- mdengine-0.6.0/src/md_generator/db/api/__init__.py +3 -0
- mdengine-0.6.0/src/md_generator/db/api/main.py +266 -0
- mdengine-0.6.0/src/md_generator/db/api/mcp_server.py +29 -0
- mdengine-0.6.0/src/md_generator/db/api/run.py +15 -0
- mdengine-0.6.0/src/md_generator/db/api/schemas.py +82 -0
- mdengine-0.6.0/src/md_generator/db/api/settings.py +32 -0
- mdengine-0.6.0/src/md_generator/db/api/sqlite_upload.py +87 -0
- mdengine-0.6.0/src/md_generator/db/cli/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/db/cli/main.py +162 -0
- mdengine-0.6.0/src/md_generator/db/config/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/db/config/default.yaml +37 -0
- mdengine-0.6.0/src/md_generator/db/core/__init__.py +3 -0
- mdengine-0.6.0/src/md_generator/db/core/base_adapter.py +73 -0
- mdengine-0.6.0/src/md_generator/db/core/erd/__init__.py +3 -0
- mdengine-0.6.0/src/md_generator/db/core/erd/dot_emitter.py +50 -0
- mdengine-0.6.0/src/md_generator/db/core/erd/filter.py +65 -0
- mdengine-0.6.0/src/md_generator/db/core/erd/mermaid_emitter.py +39 -0
- mdengine-0.6.0/src/md_generator/db/core/erd/mermaid_render.py +27 -0
- mdengine-0.6.0/src/md_generator/db/core/erd/model.py +65 -0
- mdengine-0.6.0/src/md_generator/db/core/erd/pipeline.py +199 -0
- mdengine-0.6.0/src/md_generator/db/core/erd/render.py +35 -0
- mdengine-0.6.0/src/md_generator/db/core/extractor.py +537 -0
- mdengine-0.6.0/src/md_generator/db/core/job_manager.py +331 -0
- mdengine-0.6.0/src/md_generator/db/core/markdown_writer.py +429 -0
- mdengine-0.6.0/src/md_generator/db/core/models.py +163 -0
- mdengine-0.6.0/src/md_generator/db/core/run_config.py +145 -0
- mdengine-0.6.0/src/md_generator/db/core/util.py +34 -0
- mdengine-0.6.0/src/md_generator/db/core/zip_export.py +25 -0
- mdengine-0.6.0/src/md_generator/db/mcp/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/db/mcp/server.py +62 -0
- mdengine-0.6.0/src/md_generator/db/mcp/sse.py +9 -0
- mdengine-0.6.0/src/md_generator/db/mcp/stream.py +18 -0
- mdengine-0.6.0/src/md_generator/engine_cli.py +34 -0
- mdengine-0.6.0/src/md_generator/graph/__init__.py +3 -0
- mdengine-0.6.0/src/md_generator/graph/adapters/__init__.py +3 -0
- mdengine-0.6.0/src/md_generator/graph/adapters/factory.py +16 -0
- mdengine-0.6.0/src/md_generator/graph/adapters/neo4j_adapter.py +310 -0
- mdengine-0.6.0/src/md_generator/graph/adapters/networkx_adapter.py +105 -0
- mdengine-0.6.0/src/md_generator/graph/api/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/graph/api/main.py +181 -0
- mdengine-0.6.0/src/md_generator/graph/api/mcp_server.py +29 -0
- mdengine-0.6.0/src/md_generator/graph/api/run.py +15 -0
- mdengine-0.6.0/src/md_generator/graph/api/schemas.py +70 -0
- mdengine-0.6.0/src/md_generator/graph/api/settings.py +31 -0
- mdengine-0.6.0/src/md_generator/graph/cli/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/graph/cli/main.py +138 -0
- mdengine-0.6.0/src/md_generator/graph/config/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/graph/config/default.yaml +30 -0
- mdengine-0.6.0/src/md_generator/graph/core/__init__.py +3 -0
- mdengine-0.6.0/src/md_generator/graph/core/base_adapter.py +35 -0
- mdengine-0.6.0/src/md_generator/graph/core/extractor.py +93 -0
- mdengine-0.6.0/src/md_generator/graph/core/graph_builder.py +72 -0
- mdengine-0.6.0/src/md_generator/graph/core/job_manager.py +280 -0
- mdengine-0.6.0/src/md_generator/graph/core/markdown_writer.py +280 -0
- mdengine-0.6.0/src/md_generator/graph/core/models.py +37 -0
- mdengine-0.6.0/src/md_generator/graph/core/run_config.py +174 -0
- mdengine-0.6.0/src/md_generator/graph/core/viz.py +119 -0
- mdengine-0.6.0/src/md_generator/graph/core/zip_export.py +24 -0
- mdengine-0.6.0/src/md_generator/graph/mcp/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/graph/mcp/server.py +118 -0
- mdengine-0.6.0/src/md_generator/graph/mcp/sse.py +8 -0
- mdengine-0.6.0/src/md_generator/graph/mcp/stream.py +5 -0
- mdengine-0.6.0/src/md_generator/openapi/__init__.py +5 -0
- mdengine-0.6.0/src/md_generator/openapi/api/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/openapi/api/main.py +84 -0
- mdengine-0.6.0/src/md_generator/openapi/api/mcp_server.py +29 -0
- mdengine-0.6.0/src/md_generator/openapi/api/run.py +15 -0
- mdengine-0.6.0/src/md_generator/openapi/api/schemas.py +33 -0
- mdengine-0.6.0/src/md_generator/openapi/api/settings.py +21 -0
- mdengine-0.6.0/src/md_generator/openapi/cli/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/openapi/cli/main.py +75 -0
- mdengine-0.6.0/src/md_generator/openapi/config/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/openapi/config/default.yaml +14 -0
- mdengine-0.6.0/src/md_generator/openapi/converters/__init__.py +5 -0
- mdengine-0.6.0/src/md_generator/openapi/converters/swagger2_to_openapi3.py +453 -0
- mdengine-0.6.0/src/md_generator/openapi/core/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/openapi/core/extractor.py +207 -0
- mdengine-0.6.0/src/md_generator/openapi/core/run_config.py +100 -0
- mdengine-0.6.0/src/md_generator/openapi/core/zip_export.py +24 -0
- mdengine-0.6.0/src/md_generator/openapi/enrichers/__init__.py +5 -0
- mdengine-0.6.0/src/md_generator/openapi/enrichers/rules.py +133 -0
- mdengine-0.6.0/src/md_generator/openapi/enrichers/sample_body.py +73 -0
- mdengine-0.6.0/src/md_generator/openapi/generators/__init__.py +9 -0
- mdengine-0.6.0/src/md_generator/openapi/generators/dependency_graph.py +54 -0
- mdengine-0.6.0/src/md_generator/openapi/loaders/__init__.py +5 -0
- mdengine-0.6.0/src/md_generator/openapi/loaders/spec_loader.py +115 -0
- mdengine-0.6.0/src/md_generator/openapi/mcp/__init__.py +1 -0
- mdengine-0.6.0/src/md_generator/openapi/mcp/server.py +71 -0
- mdengine-0.6.0/src/md_generator/openapi/models/__init__.py +25 -0
- mdengine-0.6.0/src/md_generator/openapi/models/domain.py +106 -0
- mdengine-0.6.0/src/md_generator/openapi/normalizers/__init__.py +6 -0
- mdengine-0.6.0/src/md_generator/openapi/normalizers/operations.py +287 -0
- mdengine-0.6.0/src/md_generator/openapi/normalizers/schema_flatten.py +104 -0
- mdengine-0.6.0/src/md_generator/openapi/parsers/__init__.py +5 -0
- mdengine-0.6.0/src/md_generator/openapi/parsers/openapi_parser.py +18 -0
- mdengine-0.6.0/src/md_generator/openapi/resolvers/__init__.py +5 -0
- mdengine-0.6.0/src/md_generator/openapi/resolvers/ref_resolver.py +16 -0
- mdengine-0.6.0/src/md_generator/openapi/writers/__init__.py +5 -0
- mdengine-0.6.0/src/md_generator/openapi/writers/markdown_writer.py +253 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/mdengine.egg-info/PKG-INFO +66 -8
- {mdengine-0.4.0 → mdengine-0.6.0}/src/mdengine.egg-info/SOURCES.txt +108 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/mdengine.egg-info/entry_points.txt +10 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/mdengine.egg-info/requires.txt +22 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/LICENSE +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/setup.cfg +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/api/convert_runner.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/api/jobs.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/api/mcp_setup.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/api/query_options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/convert_impl.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/archive/options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/api/query_options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/api/staging.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/api/zip_bundle.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/backends/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/backends/base.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/backends/easy.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/backends/paddle.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/backends/tesseract.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/convert_impl.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/emit.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/io_util.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/image/utils.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/api/mcp_setup.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/api/run.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/formatter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/audio/service.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/document_converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/job_store.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/api/mcp_setup.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/api/run.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/formatter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/video/service.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/whisper_language.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/api/mcp_setup.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/api/run.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/formatter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/metadata.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/service.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/media/youtube/transcript.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/api/zip_bundle.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/md_emit.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/pdf_extract.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/pdf/utils.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/api/convert_runner.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/api/jobs.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/api/mcp_setup.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/api/run.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/assets.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/chunker.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/cli.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/extractor.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/html_to_md.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/pipeline.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/playwright/playwright_fetcher.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/api/convert_runner.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/api/jobs.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/api/mcp_setup.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/api/query_options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/convert_impl.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/embedded_extract.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/ooxml_media.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/post_assets.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/text_formatting.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/vendor_pdf_md/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/vendor_pdf_md/convert.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/vendor_word_md/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/vendor_word_md/convert.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/ppt/zip_deep.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/api/convert_runner.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/api/jobs.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/api/mcp_setup.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/api/query_options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/convert_impl.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/format_detect.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/md_emit_json.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/md_emit_txt.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/md_emit_xml.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/text/options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/api/convert_runner.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/api/jobs.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/api/mcp_setup.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/api/query_options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/api/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/assets.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/convert_impl.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/crawl.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/extract.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/fetch.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/html_to_md.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/options.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/page_convert.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/post_convert_assets.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/url/robots_util.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/api/convert_util.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/api/jobs.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/api/main.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/api/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/artifact.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/word/settings.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/api/__init__.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/api/app.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/convert_config.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/converter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/converter_core.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/excel_reader.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/markdown_emitter.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/md_generator/xlsx/mcp_server.py +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/mdengine.egg-info/dependency_links.txt +0 -0
- {mdengine-0.4.0 → mdengine-0.6.0}/src/mdengine.egg-info/top_level.txt +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mdengine
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Convert PDF, Office, images, audio, video, text/JSON/XML, ZIP archives,
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Convert PDF, Office, images, audio, video, text/JSON/XML, ZIP archives, web URLs, databases, graphs, and OpenAPI specs to Markdown.
|
|
5
5
|
Author: mdengine contributors
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/vishal7090/md-generator
|
|
8
8
|
Project-URL: Repository, https://github.com/vishal7090/md-generator
|
|
9
9
|
Project-URL: Issues, https://github.com/vishal7090/md-generator/issues
|
|
10
|
-
Keywords: markdown,pdf,docx,pptx,xlsx,ocr,zip,url,html,youtube,playwright
|
|
10
|
+
Keywords: markdown,pdf,docx,pptx,xlsx,ocr,zip,url,html,youtube,playwright,database,openapi
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
13
|
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
@@ -87,6 +87,22 @@ Requires-Dist: lxml>=5.0.0; extra == "playwright"
|
|
|
87
87
|
Requires-Dist: markdownify>=0.14.0; extra == "playwright"
|
|
88
88
|
Requires-Dist: readability-lxml>=0.8.1; extra == "playwright"
|
|
89
89
|
Requires-Dist: Pillow>=10.0.0; extra == "playwright"
|
|
90
|
+
Provides-Extra: db
|
|
91
|
+
Requires-Dist: sqlalchemy>=2.0.0; extra == "db"
|
|
92
|
+
Requires-Dist: pyyaml>=6.0.0; extra == "db"
|
|
93
|
+
Requires-Dist: psycopg2-binary>=2.9.9; extra == "db"
|
|
94
|
+
Requires-Dist: pymysql>=1.1.0; extra == "db"
|
|
95
|
+
Requires-Dist: oracledb>=2.0.0; extra == "db"
|
|
96
|
+
Requires-Dist: pymongo>=4.6.0; extra == "db"
|
|
97
|
+
Requires-Dist: mermaid-py>=0.8.0; extra == "db"
|
|
98
|
+
Provides-Extra: graph
|
|
99
|
+
Requires-Dist: networkx>=3.2.0; extra == "graph"
|
|
100
|
+
Requires-Dist: neo4j>=5.14.0; extra == "graph"
|
|
101
|
+
Requires-Dist: pyyaml>=6.0.0; extra == "graph"
|
|
102
|
+
Provides-Extra: openapi
|
|
103
|
+
Requires-Dist: pyyaml>=6.0.0; extra == "openapi"
|
|
104
|
+
Requires-Dist: prance>=23.6.0; extra == "openapi"
|
|
105
|
+
Requires-Dist: openapi-spec-validator>=0.7.0; extra == "openapi"
|
|
90
106
|
Provides-Extra: api
|
|
91
107
|
Requires-Dist: fastapi>=0.115.0; extra == "api"
|
|
92
108
|
Requires-Dist: uvicorn[standard]>=0.32.0; extra == "api"
|
|
@@ -106,6 +122,9 @@ Requires-Dist: mdengine[api]; extra == "dev"
|
|
|
106
122
|
Requires-Dist: mdengine[mcp]; extra == "dev"
|
|
107
123
|
Requires-Dist: mdengine[url]; extra == "dev"
|
|
108
124
|
Requires-Dist: mdengine[playwright]; extra == "dev"
|
|
125
|
+
Requires-Dist: mdengine[db]; extra == "dev"
|
|
126
|
+
Requires-Dist: mdengine[graph]; extra == "dev"
|
|
127
|
+
Requires-Dist: mdengine[openapi]; extra == "dev"
|
|
109
128
|
Provides-Extra: all
|
|
110
129
|
Requires-Dist: pymupdf>=1.24.0; extra == "all"
|
|
111
130
|
Requires-Dist: pdfplumber>=0.11.0; extra == "all"
|
|
@@ -136,7 +155,7 @@ Dynamic: license-file
|
|
|
136
155
|
|
|
137
156
|
# mdengine
|
|
138
157
|
|
|
139
|
-
Single Python distribution for converting **PDF**, **Word (.docx)**, **PowerPoint (.pptx)**, **Excel (.xlsx/.xlsm)**, **images** (OCR), **plain text / JSON / XML**, **ZIP archives**,
|
|
158
|
+
Single Python distribution for converting **PDF**, **Word (.docx)**, **PowerPoint (.pptx)**, **Excel (.xlsx/.xlsm)**, **images** (OCR), **plain text / JSON / XML**, **ZIP archives**, **audio / video** (Whisper transcription → Markdown), **database metadata** (SQL + Mongo), and **graphs** (Neo4j / NetworkX → Markdown) into **Markdown** (and related assets). Install only the extras you need; everything imports under the **`md_generator`** package.
|
|
140
159
|
|
|
141
160
|
- **PyPI name:** `mdengine` (import package: `md_generator`)
|
|
142
161
|
- **Source:** [github.com/vishal7090/md-generator](https://github.com/vishal7090/md-generator)
|
|
@@ -214,6 +233,7 @@ pip install "mdengine[all]"
|
|
|
214
233
|
| `video` | **Video → Markdown** (ffmpeg extracts mono 16 kHz WAV, then same Whisper stack as `audio`) |
|
|
215
234
|
| `api` | FastAPI, uvicorn, httpx, pydantic-settings |
|
|
216
235
|
| `mcp` | MCP servers (`mcp`, `fastmcp` where used) |
|
|
236
|
+
| `graph` | **Graph → Markdown** (Neo4j Bolt + NetworkX GraphML/GML): `networkx`, `neo4j`, `pyyaml` |
|
|
217
237
|
| `dev` | pytest + API/MCP test helpers |
|
|
218
238
|
| `all` | Large superset of dependencies (use only if you need everything) |
|
|
219
239
|
|
|
@@ -228,7 +248,7 @@ All converters can be run from a terminal after you install the package (with th
|
|
|
228
248
|
### 1. Install (once)
|
|
229
249
|
|
|
230
250
|
```bash
|
|
231
|
-
pip install "mdengine[pdf,word]" # adjust extras: ppt, xlsx, image, archive, text, …
|
|
251
|
+
pip install "mdengine[pdf,word]" # adjust extras: ppt, xlsx, image, archive, text, db, graph, …
|
|
232
252
|
# or from a clone:
|
|
233
253
|
pip install -e ".[pdf,word,archive]"
|
|
234
254
|
```
|
|
@@ -263,6 +283,28 @@ If the shell reports “command not found”, ensure the Python **Scripts** dire
|
|
|
263
283
|
| `md-audio-mcp` | `md_generator.media.audio.api.mcp_server:main` | Standalone MCP (`--transport stdio` \| `sse` \| `streamable-http`) |
|
|
264
284
|
| `md-video-mcp` | `md_generator.media.video.api.mcp_server:main` | Same for video |
|
|
265
285
|
| `md-youtube-mcp` | `md_generator.media.youtube.api.mcp_server:main` | Same for YouTube (`youtube_url_to_markdown`) |
|
|
286
|
+
| `md-db` | `md_generator.db.cli.main:main` | `pip install "mdengine[db]"` then `md-db --config db.yaml` (or `mdengine db-to-md …`) |
|
|
287
|
+
| `md-db-api` | `md_generator.db.api.run:main` | FastAPI on port **8010** (`DB_TO_MD_PORT`): `POST /db-to-md/run`, `POST /db-to-md/run/sqlite` (upload + ZIP), `POST /db-to-md/job`, `POST /db-to-md/job/sqlite` (upload + async job), SSE `/db-to-md/job/{id}/events` |
|
|
288
|
+
| `md-db-mcp` | `md_generator.db.api.mcp_server:main` | Standalone MCP for metadata export tools |
|
|
289
|
+
| `md-graph` | `md_generator.graph.cli.main:main` | `pip install "mdengine[graph]"` then `md-graph --source neo4j --uri bolt://…` (or `mdengine graph-to-md …`) |
|
|
290
|
+
| `md-graph-api` | `md_generator.graph.api.run:main` | FastAPI on port **8012** (`GRAPH_TO_MD_PORT`): `POST /graph-to-md/run`, `/graph-to-md/job`, SSE `/graph-to-md/job/{id}/events` |
|
|
291
|
+
| `md-graph-mcp` | `md_generator.graph.api.mcp_server:main` | Standalone MCP for graph export tools |
|
|
292
|
+
| `md-openapi` | `md_generator.openapi.cli.main:main` | `pip install "mdengine[openapi]"` then `md-openapi generate --file openapi.yaml --output ./docs` (or `mdengine openapi-to-md generate …`) |
|
|
293
|
+
| `md-openapi-api` | `md_generator.openapi.api.run:main` | FastAPI on port **8015** (`OPENAPI_TO_MD_PORT`): `POST /openapi-to-md/generate` (OpenAPI upload → ZIP), `/health`, MCP at **`/mcp`** |
|
|
294
|
+
| `md-openapi-mcp` | `md_generator.openapi.api.mcp_server:main` | Standalone MCP: `api_validate_openapi_yaml`, `api_generate_readme_markdown`, `api_run_sync_zip_base64` |
|
|
295
|
+
| `mdengine` | `md_generator.engine_cli:main` | `mdengine db-to-md …` / `mdengine graph-to-md …` / `mdengine openapi-to-md generate …` |
|
|
296
|
+
|
|
297
|
+
**openapi-to-md (`md-openapi`):** OpenAPI **3.x** is parsed directly; **Swagger 2.0** (`swagger: "2.0"`) documents are **converted in-process** to OpenAPI 3.0.3 (deterministic, in-repo converter) before `$ref` resolution. Edge-heavy specs (unusual OAuth2 flows, vendor extensions) may still need fixes after conversion.
|
|
298
|
+
|
|
299
|
+
**db-to-md ER diagrams:** add **`erd`** to the export feature list (YAML `features.include`, API body, or CLI `--include …,erd`). **Preferred:** **Graphviz** (`dot` on `PATH`, or **`GRAPHVIZ_DOT`**) produces `erd/*.dot`, `erd/*.png`, and `erd/*.svg`. **If Graphviz is missing,** the exporter falls back to **Mermaid** (`erDiagram`): it writes `erd/*.mermaid` plus a fenced **`erd/*.md`** for GitHub-style preview. With **`mermaid-py`** (included in `mdengine[db]`), it also requests **PNG/SVG** via mermaid.ink (requires network unless you self-host mermaid.ink and set **`MERMAID_INK_SERVER`** per [mermaid-py](https://pypi.org/project/mermaid-py/)). Tune **`erd.max_tables`** (default 100) and **`erd.scope`** (`full` \| `per_schema` \| `per_table`) under `erd:` in YAML; CLI: `--erd-max-tables`, `--erd-scope`. Async job SSE uses `progress_update` with `current` starting with `erd:`.
|
|
300
|
+
|
|
301
|
+
**db-to-md split exports and README merge:** with **`output.split_files: true`**, set **`output.write_combined_feature_markdown: true`** to also write root-level combined Markdown (for example `tables.md`, `functions.md`, `indexes.md`, and feature-specific paths such as `oracle/packages.md` or `mongodb/collections.md` when those features run). Set **`output.readme_feature_merge`** to **`inline`** (append full bundle bodies into `README.md`) or **`toc`** (append a linked list to those files). If merge is not **`none`** and split files are on, combined bundle writes are turned on automatically when loading config. CLI: `--write-combined-feature-markdown`, `--readme-feature-merge none|inline|toc`.
|
|
302
|
+
|
|
303
|
+
**db-to-md SQLite:** set **`database.type: sqlite`** and **`database.uri`** to a SQLAlchemy URL such as **`sqlite:///my.db`** or **`sqlite:////C:/data/my.db`**. The default SQLite catalog is **`main`**; packaged YAML that still has **`schema: public`** is normalized to **`main`** when the type is SQLite. CLI: **`--type sqlite`**. Stored routines, sequences, and partitions are not used by SQLite and stay empty; tables, indexes, views, triggers, and ERD (via FK introspection) follow the same export path as other SQL engines.
|
|
304
|
+
|
|
305
|
+
**db-to-md API SQLite upload:** **`POST /db-to-md/run/sqlite`** — `multipart/form-data` with field **`file`** (the `.sqlite` / `.db` bytes; must start with the standard `SQLite format 3` header) and optional **`config`** (JSON string with the same shape as a normal run body minus `database`: `schema`, `output`, `features`, `execution`, `limits`, `erd`). Returns the metadata ZIP immediately. **`POST /db-to-md/job/sqlite`** — same form fields; saves the file under the job workspace and runs the existing job pipeline (`GET /db-to-md/job/{id}/download` when complete). Upload size cap: env **`DB_TO_MD_MAX_SQLITE_UPLOAD_MB`** (default **256**). Large ZIPs may still require the async job path if they exceed **`DB_TO_MD_MAX_SYNC_ZIP_MB`** on the sync upload route.
|
|
306
|
+
|
|
307
|
+
**graph-to-md (Neo4j + NetworkX):** library lives under [`md_generator/graph/`](src/md_generator/graph/). **Sources:** **`networkx`** (GraphML/GML via `graph.graph_file` or `--graph-file`) or **`neo4j`** (`graph.uri`, `graph.user`, `graph.password`, optional `graph.database` for `session(database=…)`). **Output layout:** by default **`output.combine_markdown: true`** writes **`nodes.md`**, **`relationship.md`**, and **`graph_summary.md`** (summary plus embedded nodes and relationships). Set **`combine_markdown: false`** or CLI **`--individual` / `--markdown-layout individual`** for per-entity files under **`nodes/`** and **`relationships/`**. **Diagrams:** **`viz.mermaid: true`** (default) writes **`graph/graph.mmd`** and embeds a fenced Mermaid block in the export **`README.md`** (no Graphviz required). **`viz.enabled: true`** or CLI **`--viz`** also writes **`graph/graph.dot`** and runs **`dot`** for PNG/SVG/PDF when Graphviz is on `PATH` (or **`GRAPHVIZ_DOT`**). CLI **`--no-mermaid`** disables Mermaid; **`--depth`**, **`--start-node`**, **`--max-nodes`**, **`--max-edges`** bound traversal. Packaged defaults: [`src/md_generator/graph/config/default.yaml`](src/md_generator/graph/config/default.yaml). Tests: **`graph-to-md/tests/`**; API image: [`graph-to-md/Dockerfile.api`](graph-to-md/Dockerfile.api).
|
|
266
308
|
|
|
267
309
|
Every command accepts **`-h` / `--help`** for full flags (artifact layout, OCR, ZIP options, etc.).
|
|
268
310
|
|
|
@@ -282,6 +324,7 @@ md-zip archive.zip ./unzipped-md
|
|
|
282
324
|
md-url https://example.com/page ./page-bundle --artifact-layout
|
|
283
325
|
md-audio ./voice.mp3 ./voice.md --model tiny
|
|
284
326
|
md-video ./screen.mp4 ./screen.md --model base
|
|
327
|
+
pip install "mdengine[graph]" && md-graph --source neo4j --uri neo4j://localhost:7687 --user neo4j --password secret --database neo4j --output ./graph-out --viz
|
|
285
328
|
```
|
|
286
329
|
|
|
287
330
|
**Windows PowerShell** (same commands; use backslashes for paths if you prefer)
|
|
@@ -292,6 +335,8 @@ md-zip .\archive.zip .\zip-out
|
|
|
292
335
|
md-url https://example.com/page .\page-bundle --artifact-layout
|
|
293
336
|
md-audio .\voice.mp3 .\voice.md --model tiny
|
|
294
337
|
md-video .\screen.mp4 .\screen.md --model base
|
|
338
|
+
pip install "mdengine[graph]"
|
|
339
|
+
md-graph --source neo4j --uri neo4j://localhost:7687 --user neo4j --password secret --database neo4j --output .\graph-out --viz
|
|
295
340
|
```
|
|
296
341
|
|
|
297
342
|
**Windows CMD**
|
|
@@ -575,7 +620,7 @@ Equivalent modules: `python -m md_generator.media.audio.api.mcp_server`, `python
|
|
|
575
620
|
|
|
576
621
|
### Thin shims (repo clone)
|
|
577
622
|
|
|
578
|
-
[`audio-to-md/converter.py`](audio-to-md/converter.py), [`video-to-md/converter.py`](video-to-md/converter.py), and [`youtube-to-md/converter.py`](youtube-to-md/converter.py) delegate to the same `main` as `md-audio` / `md-video` / `md-youtube`. Tests and `pytest.ini` live under `audio-to-md/tests/`, `video-to-md/tests/`, and `youtube-to-md/tests/`.
|
|
623
|
+
[`audio-to-md/converter.py`](audio-to-md/converter.py), [`video-to-md/converter.py`](video-to-md/converter.py), and [`youtube-to-md/converter.py`](youtube-to-md/converter.py) delegate to the same `main` as `md-audio` / `md-video` / `md-youtube`. Tests and `pytest.ini` live under `audio-to-md/tests/`, `video-to-md/tests/`, and `youtube-to-md/tests/`. [`db-to-md/converter.py`](db-to-md/converter.py) delegates to `md-db`; tests live under `db-to-md/tests/`. **graph-to-md** uses `md-graph` / `mdengine graph-to-md` directly (no thin `converter.py` shim); tests live under [`graph-to-md/tests/`](graph-to-md/tests/). [`openapi-to-md/converter.py`](openapi-to-md/converter.py) delegates to `md-openapi`; tests live under [`openapi-to-md/tests/`](openapi-to-md/tests/); example OpenAPI and output notes: [`openapi-to-md/examples/`](openapi-to-md/examples/).
|
|
579
624
|
|
|
580
625
|
---
|
|
581
626
|
|
|
@@ -605,6 +650,9 @@ Install `mdengine[api]` plus the format extra(s), then run the **`app`** object
|
|
|
605
650
|
| ZIP | `md_generator.archive.api.main:app` | `archive`, `api`, `mcp` (+ extras for nested office/PDF) |
|
|
606
651
|
| URL / HTML | `md_generator.url.api.main:app` | `url`, `api`, `mcp` |
|
|
607
652
|
| Playwright / SPA | `md_generator.playwright.api.main:app` | `playwright`, `api`, `mcp` |
|
|
653
|
+
| Database metadata | `md_generator.db.api.main:app` | `db`, `api`, `mcp` |
|
|
654
|
+
| Graph metadata (Neo4j / NetworkX) | `md_generator.graph.api.main:app` | `graph`, `api`, `mcp` |
|
|
655
|
+
| OpenAPI → Markdown | `md_generator.openapi.api.main:app` | `openapi`, `api`, `mcp` |
|
|
608
656
|
| Audio (Whisper) | `md_generator.media.audio.api.main:create_app` (use **`--factory`**) or `…main:app` | `audio`, `api`, `mcp` |
|
|
609
657
|
| Video (Whisper) | `md_generator.media.video.api.main:create_app` (use **`--factory`**) or `…main:app` | `video`, `api`, `mcp` |
|
|
610
658
|
| YouTube | `md_generator.media.youtube.api.main:create_app` (use **`--factory`**) or `…main:app` | `youtube`, `api`, `mcp` |
|
|
@@ -617,11 +665,15 @@ uvicorn md_generator.word.api.main:app --host 127.0.0.1 --port 8002
|
|
|
617
665
|
uvicorn md_generator.archive.api.main:app --host 127.0.0.1 --port 8010
|
|
618
666
|
uvicorn md_generator.url.api.main:app --host 127.0.0.1 --port 8011
|
|
619
667
|
uvicorn md_generator.playwright.api.main:app --host 127.0.0.1 --port 8014
|
|
668
|
+
uvicorn md_generator.graph.api.main:app --host 127.0.0.1 --port 8012
|
|
669
|
+
uvicorn md_generator.openapi.api.main:app --host 127.0.0.1 --port 8015
|
|
620
670
|
uvicorn md_generator.media.audio.api.main:create_app --factory --host 127.0.0.1 --port 8011
|
|
621
671
|
uvicorn md_generator.media.video.api.main:create_app --factory --host 127.0.0.1 --port 8012
|
|
622
672
|
uvicorn md_generator.media.youtube.api.main:create_app --factory --host 127.0.0.1 --port 8013
|
|
623
673
|
```
|
|
624
674
|
|
|
675
|
+
**Port note:** **`md-graph-api`** and **`md-video-api`** both default to **8012**; set **`GRAPH_TO_MD_PORT`** or **`MD_VIDEO_API_PORT`** when you need both on one machine. **`md-openapi-api`** defaults to **8015** (`OPENAPI_TO_MD_PORT`) so it does not collide with **`md-youtube-api`** (**8013**) or **`md-playwright-api`** (**8014**).
|
|
676
|
+
|
|
625
677
|
### MCP over HTTP on the same server
|
|
626
678
|
|
|
627
679
|
These apps mount an MCP HTTP app at **`/mcp`** (Streamable HTTP / framework-specific). Start the API as above, then point an MCP client at `http://<host>:<port>/mcp` where supported.
|
|
@@ -640,6 +692,9 @@ Prefixes differ per service (often read from a `.env` file next to the process):
|
|
|
640
692
|
| XLSX | `XLSX_TO_MD_` | `XLSX_TO_MD_TEMP_DIR`, `XLSX_TO_MD_CORS_ORIGINS`, etc. (see `md_generator.xlsx.api.app`) |
|
|
641
693
|
| URL | `URL_TO_MD_` | `URL_TO_MD_MAX_SYNC_URLS`, `URL_TO_MD_MAX_SYNC_CRAWL_PAGES`, `URL_TO_MD_MAX_JOB_URLS`, `URL_TO_MD_JOB_TTL_SECONDS`, `URL_TO_MD_TEMP_DIR`, `URL_TO_MD_CORS_ORIGINS` |
|
|
642
694
|
| Playwright / SPA | `PLAYWRIGHT_TO_MD_` | `PLAYWRIGHT_TO_MD_MAX_SYNC_URLS`, `PLAYWRIGHT_TO_MD_MAX_JOB_URLS`, `PLAYWRIGHT_TO_MD_JOB_TTL_SECONDS`, `PLAYWRIGHT_TO_MD_TEMP_DIR`, `PLAYWRIGHT_TO_MD_CORS_ORIGINS`, `PLAYWRIGHT_TO_MD_API_HOST`, `PLAYWRIGHT_TO_MD_API_PORT` (default **8014**) |
|
|
695
|
+
| Database metadata | `DB_TO_MD_` | `DB_TO_MD_JOB_SQLITE_PATH`, `DB_TO_MD_JOB_WORKSPACE_ROOT`, `DB_TO_MD_CORS_ORIGINS`, `DB_TO_MD_MAX_SYNC_ZIP_MB`, `DB_TO_MD_HOST`, `DB_TO_MD_PORT` (default **8010**) |
|
|
696
|
+
| Graph metadata | `GRAPH_TO_MD_` | `GRAPH_TO_MD_JOB_SQLITE_PATH`, `GRAPH_TO_MD_JOB_WORKSPACE_ROOT`, `GRAPH_TO_MD_CORS_ORIGINS`, `GRAPH_TO_MD_MAX_SYNC_ZIP_MB`, `GRAPH_TO_MD_HOST`, `GRAPH_TO_MD_PORT` (default **8012**) |
|
|
697
|
+
| OpenAPI → Markdown | `OPENAPI_TO_MD_` | `OPENAPI_TO_MD_CORS_ORIGINS`, `OPENAPI_TO_MD_MAX_SYNC_ZIP_MB`, `OPENAPI_TO_MD_HOST`, `OPENAPI_TO_MD_PORT` (default **8015**) |
|
|
643
698
|
| Audio API | `MD_AUDIO_` | `MD_AUDIO_MAX_UPLOAD_MB`, `MD_AUDIO_MAX_SYNC_UPLOAD_MB`, `MD_AUDIO_JOB_TTL_SECONDS`, `MD_AUDIO_TEMP_DIR`, `MD_AUDIO_CORS_ORIGINS`, `MD_AUDIO_API_HOST`, `MD_AUDIO_API_PORT` |
|
|
644
699
|
| Video API | `MD_VIDEO_` | Same pattern as audio with `MD_VIDEO_*` (defaults: larger upload/sync caps, port **8012**) |
|
|
645
700
|
| YouTube API | `MD_YOUTUBE_` | `MD_YOUTUBE_JOB_TTL_SECONDS`, `MD_YOUTUBE_TEMP_DIR`, `MD_YOUTUBE_CORS_ORIGINS`, `MD_YOUTUBE_API_HOST`, `MD_YOUTUBE_API_PORT` (default **8013**); optional `MD_YOUTUBE_YTDLP` path for audio fallback |
|
|
@@ -670,6 +725,9 @@ Two usage patterns:
|
|
|
670
725
|
| Audio | `md-audio-mcp` or `python -m md_generator.media.audio.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
671
726
|
| Video | `md-video-mcp` or `python -m md_generator.media.video.api.mcp_server` — same transports |
|
|
672
727
|
| YouTube | `md-youtube-mcp` or `python -m md_generator.media.youtube.api.mcp_server` — same transports |
|
|
728
|
+
| Database metadata | `md-db-mcp` or `python -m md_generator.db.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
729
|
+
| Graph (Neo4j / NetworkX) | `md-graph-mcp` or `python -m md_generator.graph.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
730
|
+
| OpenAPI → Markdown | `md-openapi-mcp` or `python -m md_generator.openapi.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
673
731
|
|
|
674
732
|
**Word** and **XLSX** also ship a small runner script in the repo:
|
|
675
733
|
|
|
@@ -694,7 +752,7 @@ pip install -e ".[dev,all]" # or a smaller subset of extras
|
|
|
694
752
|
python -m pytest
|
|
695
753
|
```
|
|
696
754
|
|
|
697
|
-
Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`)
|
|
755
|
+
Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`), **`graph-to-md/tests/`**, and **`openapi-to-md/tests/`**; `pyproject.toml` configures `pythonpath = ["src"]` so `md_generator` resolves without a separate `PYTHONPATH`.
|
|
698
756
|
|
|
699
757
|
---
|
|
700
758
|
|
|
@@ -704,7 +762,7 @@ Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/test
|
|
|
704
762
|
|------|------|
|
|
705
763
|
| `LICENSE` | MIT license text |
|
|
706
764
|
| `CODE_OF_CONDUCT.md` | [Contributor Covenant](https://www.contributor-covenant.org/) 2.1 |
|
|
707
|
-
| `src/md_generator/` | **Library source** (all formats + `api` subpackages); **audio/video** under [`media/audio/`](src/md_generator/media/audio/) and [`media/video/`](src/md_generator/media/video/) |
|
|
765
|
+
| `src/md_generator/` | **Library source** (all formats + `api` subpackages); **audio/video** under [`media/audio/`](src/md_generator/media/audio/) and [`media/video/`](src/md_generator/media/video/); **graph-to-md** under [`graph/`](src/md_generator/graph/) |
|
|
708
766
|
| `pyproject.toml` | Packaging, extras, CLI entry points, pytest |
|
|
709
767
|
| `*-to-md/` | **Docs, tests, fixtures**, thin `converter.py` shims, some `run.py` helpers |
|
|
710
768
|
| `README.md` | This document |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# mdengine
|
|
2
2
|
|
|
3
|
-
Single Python distribution for converting **PDF**, **Word (.docx)**, **PowerPoint (.pptx)**, **Excel (.xlsx/.xlsm)**, **images** (OCR), **plain text / JSON / XML**, **ZIP archives**,
|
|
3
|
+
Single Python distribution for converting **PDF**, **Word (.docx)**, **PowerPoint (.pptx)**, **Excel (.xlsx/.xlsm)**, **images** (OCR), **plain text / JSON / XML**, **ZIP archives**, **audio / video** (Whisper transcription → Markdown), **database metadata** (SQL + Mongo), and **graphs** (Neo4j / NetworkX → Markdown) into **Markdown** (and related assets). Install only the extras you need; everything imports under the **`md_generator`** package.
|
|
4
4
|
|
|
5
5
|
- **PyPI name:** `mdengine` (import package: `md_generator`)
|
|
6
6
|
- **Source:** [github.com/vishal7090/md-generator](https://github.com/vishal7090/md-generator)
|
|
@@ -78,6 +78,7 @@ pip install "mdengine[all]"
|
|
|
78
78
|
| `video` | **Video → Markdown** (ffmpeg extracts mono 16 kHz WAV, then same Whisper stack as `audio`) |
|
|
79
79
|
| `api` | FastAPI, uvicorn, httpx, pydantic-settings |
|
|
80
80
|
| `mcp` | MCP servers (`mcp`, `fastmcp` where used) |
|
|
81
|
+
| `graph` | **Graph → Markdown** (Neo4j Bolt + NetworkX GraphML/GML): `networkx`, `neo4j`, `pyyaml` |
|
|
81
82
|
| `dev` | pytest + API/MCP test helpers |
|
|
82
83
|
| `all` | Large superset of dependencies (use only if you need everything) |
|
|
83
84
|
|
|
@@ -92,7 +93,7 @@ All converters can be run from a terminal after you install the package (with th
|
|
|
92
93
|
### 1. Install (once)
|
|
93
94
|
|
|
94
95
|
```bash
|
|
95
|
-
pip install "mdengine[pdf,word]" # adjust extras: ppt, xlsx, image, archive, text, …
|
|
96
|
+
pip install "mdengine[pdf,word]" # adjust extras: ppt, xlsx, image, archive, text, db, graph, …
|
|
96
97
|
# or from a clone:
|
|
97
98
|
pip install -e ".[pdf,word,archive]"
|
|
98
99
|
```
|
|
@@ -127,6 +128,28 @@ If the shell reports “command not found”, ensure the Python **Scripts** dire
|
|
|
127
128
|
| `md-audio-mcp` | `md_generator.media.audio.api.mcp_server:main` | Standalone MCP (`--transport stdio` \| `sse` \| `streamable-http`) |
|
|
128
129
|
| `md-video-mcp` | `md_generator.media.video.api.mcp_server:main` | Same for video |
|
|
129
130
|
| `md-youtube-mcp` | `md_generator.media.youtube.api.mcp_server:main` | Same for YouTube (`youtube_url_to_markdown`) |
|
|
131
|
+
| `md-db` | `md_generator.db.cli.main:main` | `pip install "mdengine[db]"` then `md-db --config db.yaml` (or `mdengine db-to-md …`) |
|
|
132
|
+
| `md-db-api` | `md_generator.db.api.run:main` | FastAPI on port **8010** (`DB_TO_MD_PORT`): `POST /db-to-md/run`, `POST /db-to-md/run/sqlite` (upload + ZIP), `POST /db-to-md/job`, `POST /db-to-md/job/sqlite` (upload + async job), SSE `/db-to-md/job/{id}/events` |
|
|
133
|
+
| `md-db-mcp` | `md_generator.db.api.mcp_server:main` | Standalone MCP for metadata export tools |
|
|
134
|
+
| `md-graph` | `md_generator.graph.cli.main:main` | `pip install "mdengine[graph]"` then `md-graph --source neo4j --uri bolt://…` (or `mdengine graph-to-md …`) |
|
|
135
|
+
| `md-graph-api` | `md_generator.graph.api.run:main` | FastAPI on port **8012** (`GRAPH_TO_MD_PORT`): `POST /graph-to-md/run`, `/graph-to-md/job`, SSE `/graph-to-md/job/{id}/events` |
|
|
136
|
+
| `md-graph-mcp` | `md_generator.graph.api.mcp_server:main` | Standalone MCP for graph export tools |
|
|
137
|
+
| `md-openapi` | `md_generator.openapi.cli.main:main` | `pip install "mdengine[openapi]"` then `md-openapi generate --file openapi.yaml --output ./docs` (or `mdengine openapi-to-md generate …`) |
|
|
138
|
+
| `md-openapi-api` | `md_generator.openapi.api.run:main` | FastAPI on port **8015** (`OPENAPI_TO_MD_PORT`): `POST /openapi-to-md/generate` (OpenAPI upload → ZIP), `/health`, MCP at **`/mcp`** |
|
|
139
|
+
| `md-openapi-mcp` | `md_generator.openapi.api.mcp_server:main` | Standalone MCP: `api_validate_openapi_yaml`, `api_generate_readme_markdown`, `api_run_sync_zip_base64` |
|
|
140
|
+
| `mdengine` | `md_generator.engine_cli:main` | `mdengine db-to-md …` / `mdengine graph-to-md …` / `mdengine openapi-to-md generate …` |
|
|
141
|
+
|
|
142
|
+
**openapi-to-md (`md-openapi`):** OpenAPI **3.x** is parsed directly; **Swagger 2.0** (`swagger: "2.0"`) documents are **converted in-process** to OpenAPI 3.0.3 (deterministic, in-repo converter) before `$ref` resolution. Edge-heavy specs (unusual OAuth2 flows, vendor extensions) may still need fixes after conversion.
|
|
143
|
+
|
|
144
|
+
**db-to-md ER diagrams:** add **`erd`** to the export feature list (YAML `features.include`, API body, or CLI `--include …,erd`). **Preferred:** **Graphviz** (`dot` on `PATH`, or **`GRAPHVIZ_DOT`**) produces `erd/*.dot`, `erd/*.png`, and `erd/*.svg`. **If Graphviz is missing,** the exporter falls back to **Mermaid** (`erDiagram`): it writes `erd/*.mermaid` plus a fenced **`erd/*.md`** for GitHub-style preview. With **`mermaid-py`** (included in `mdengine[db]`), it also requests **PNG/SVG** via mermaid.ink (requires network unless you self-host mermaid.ink and set **`MERMAID_INK_SERVER`** per [mermaid-py](https://pypi.org/project/mermaid-py/)). Tune **`erd.max_tables`** (default 100) and **`erd.scope`** (`full` \| `per_schema` \| `per_table`) under `erd:` in YAML; CLI: `--erd-max-tables`, `--erd-scope`. Async job SSE uses `progress_update` with `current` starting with `erd:`.
|
|
145
|
+
|
|
146
|
+
**db-to-md split exports and README merge:** with **`output.split_files: true`**, set **`output.write_combined_feature_markdown: true`** to also write root-level combined Markdown (for example `tables.md`, `functions.md`, `indexes.md`, and feature-specific paths such as `oracle/packages.md` or `mongodb/collections.md` when those features run). Set **`output.readme_feature_merge`** to **`inline`** (append full bundle bodies into `README.md`) or **`toc`** (append a linked list to those files). If merge is not **`none`** and split files are on, combined bundle writes are turned on automatically when loading config. CLI: `--write-combined-feature-markdown`, `--readme-feature-merge none|inline|toc`.
|
|
147
|
+
|
|
148
|
+
**db-to-md SQLite:** set **`database.type: sqlite`** and **`database.uri`** to a SQLAlchemy URL such as **`sqlite:///my.db`** or **`sqlite:////C:/data/my.db`**. The default SQLite catalog is **`main`**; packaged YAML that still has **`schema: public`** is normalized to **`main`** when the type is SQLite. CLI: **`--type sqlite`**. Stored routines, sequences, and partitions are not used by SQLite and stay empty; tables, indexes, views, triggers, and ERD (via FK introspection) follow the same export path as other SQL engines.
|
|
149
|
+
|
|
150
|
+
**db-to-md API SQLite upload:** **`POST /db-to-md/run/sqlite`** — `multipart/form-data` with field **`file`** (the `.sqlite` / `.db` bytes; must start with the standard `SQLite format 3` header) and optional **`config`** (JSON string with the same shape as a normal run body minus `database`: `schema`, `output`, `features`, `execution`, `limits`, `erd`). Returns the metadata ZIP immediately. **`POST /db-to-md/job/sqlite`** — same form fields; saves the file under the job workspace and runs the existing job pipeline (`GET /db-to-md/job/{id}/download` when complete). Upload size cap: env **`DB_TO_MD_MAX_SQLITE_UPLOAD_MB`** (default **256**). Large ZIPs may still require the async job path if they exceed **`DB_TO_MD_MAX_SYNC_ZIP_MB`** on the sync upload route.
|
|
151
|
+
|
|
152
|
+
**graph-to-md (Neo4j + NetworkX):** library lives under [`md_generator/graph/`](src/md_generator/graph/). **Sources:** **`networkx`** (GraphML/GML via `graph.graph_file` or `--graph-file`) or **`neo4j`** (`graph.uri`, `graph.user`, `graph.password`, optional `graph.database` for `session(database=…)`). **Output layout:** by default **`output.combine_markdown: true`** writes **`nodes.md`**, **`relationship.md`**, and **`graph_summary.md`** (summary plus embedded nodes and relationships). Set **`combine_markdown: false`** or CLI **`--individual` / `--markdown-layout individual`** for per-entity files under **`nodes/`** and **`relationships/`**. **Diagrams:** **`viz.mermaid: true`** (default) writes **`graph/graph.mmd`** and embeds a fenced Mermaid block in the export **`README.md`** (no Graphviz required). **`viz.enabled: true`** or CLI **`--viz`** also writes **`graph/graph.dot`** and runs **`dot`** for PNG/SVG/PDF when Graphviz is on `PATH` (or **`GRAPHVIZ_DOT`**). CLI **`--no-mermaid`** disables Mermaid; **`--depth`**, **`--start-node`**, **`--max-nodes`**, **`--max-edges`** bound traversal. Packaged defaults: [`src/md_generator/graph/config/default.yaml`](src/md_generator/graph/config/default.yaml). Tests: **`graph-to-md/tests/`**; API image: [`graph-to-md/Dockerfile.api`](graph-to-md/Dockerfile.api).
|
|
130
153
|
|
|
131
154
|
Every command accepts **`-h` / `--help`** for full flags (artifact layout, OCR, ZIP options, etc.).
|
|
132
155
|
|
|
@@ -146,6 +169,7 @@ md-zip archive.zip ./unzipped-md
|
|
|
146
169
|
md-url https://example.com/page ./page-bundle --artifact-layout
|
|
147
170
|
md-audio ./voice.mp3 ./voice.md --model tiny
|
|
148
171
|
md-video ./screen.mp4 ./screen.md --model base
|
|
172
|
+
pip install "mdengine[graph]" && md-graph --source neo4j --uri neo4j://localhost:7687 --user neo4j --password secret --database neo4j --output ./graph-out --viz
|
|
149
173
|
```
|
|
150
174
|
|
|
151
175
|
**Windows PowerShell** (same commands; use backslashes for paths if you prefer)
|
|
@@ -156,6 +180,8 @@ md-zip .\archive.zip .\zip-out
|
|
|
156
180
|
md-url https://example.com/page .\page-bundle --artifact-layout
|
|
157
181
|
md-audio .\voice.mp3 .\voice.md --model tiny
|
|
158
182
|
md-video .\screen.mp4 .\screen.md --model base
|
|
183
|
+
pip install "mdengine[graph]"
|
|
184
|
+
md-graph --source neo4j --uri neo4j://localhost:7687 --user neo4j --password secret --database neo4j --output .\graph-out --viz
|
|
159
185
|
```
|
|
160
186
|
|
|
161
187
|
**Windows CMD**
|
|
@@ -439,7 +465,7 @@ Equivalent modules: `python -m md_generator.media.audio.api.mcp_server`, `python
|
|
|
439
465
|
|
|
440
466
|
### Thin shims (repo clone)
|
|
441
467
|
|
|
442
|
-
[`audio-to-md/converter.py`](audio-to-md/converter.py), [`video-to-md/converter.py`](video-to-md/converter.py), and [`youtube-to-md/converter.py`](youtube-to-md/converter.py) delegate to the same `main` as `md-audio` / `md-video` / `md-youtube`. Tests and `pytest.ini` live under `audio-to-md/tests/`, `video-to-md/tests/`, and `youtube-to-md/tests/`.
|
|
468
|
+
[`audio-to-md/converter.py`](audio-to-md/converter.py), [`video-to-md/converter.py`](video-to-md/converter.py), and [`youtube-to-md/converter.py`](youtube-to-md/converter.py) delegate to the same `main` as `md-audio` / `md-video` / `md-youtube`. Tests and `pytest.ini` live under `audio-to-md/tests/`, `video-to-md/tests/`, and `youtube-to-md/tests/`. [`db-to-md/converter.py`](db-to-md/converter.py) delegates to `md-db`; tests live under `db-to-md/tests/`. **graph-to-md** uses `md-graph` / `mdengine graph-to-md` directly (no thin `converter.py` shim); tests live under [`graph-to-md/tests/`](graph-to-md/tests/). [`openapi-to-md/converter.py`](openapi-to-md/converter.py) delegates to `md-openapi`; tests live under [`openapi-to-md/tests/`](openapi-to-md/tests/); example OpenAPI and output notes: [`openapi-to-md/examples/`](openapi-to-md/examples/).
|
|
443
469
|
|
|
444
470
|
---
|
|
445
471
|
|
|
@@ -469,6 +495,9 @@ Install `mdengine[api]` plus the format extra(s), then run the **`app`** object
|
|
|
469
495
|
| ZIP | `md_generator.archive.api.main:app` | `archive`, `api`, `mcp` (+ extras for nested office/PDF) |
|
|
470
496
|
| URL / HTML | `md_generator.url.api.main:app` | `url`, `api`, `mcp` |
|
|
471
497
|
| Playwright / SPA | `md_generator.playwright.api.main:app` | `playwright`, `api`, `mcp` |
|
|
498
|
+
| Database metadata | `md_generator.db.api.main:app` | `db`, `api`, `mcp` |
|
|
499
|
+
| Graph metadata (Neo4j / NetworkX) | `md_generator.graph.api.main:app` | `graph`, `api`, `mcp` |
|
|
500
|
+
| OpenAPI → Markdown | `md_generator.openapi.api.main:app` | `openapi`, `api`, `mcp` |
|
|
472
501
|
| Audio (Whisper) | `md_generator.media.audio.api.main:create_app` (use **`--factory`**) or `…main:app` | `audio`, `api`, `mcp` |
|
|
473
502
|
| Video (Whisper) | `md_generator.media.video.api.main:create_app` (use **`--factory`**) or `…main:app` | `video`, `api`, `mcp` |
|
|
474
503
|
| YouTube | `md_generator.media.youtube.api.main:create_app` (use **`--factory`**) or `…main:app` | `youtube`, `api`, `mcp` |
|
|
@@ -481,11 +510,15 @@ uvicorn md_generator.word.api.main:app --host 127.0.0.1 --port 8002
|
|
|
481
510
|
uvicorn md_generator.archive.api.main:app --host 127.0.0.1 --port 8010
|
|
482
511
|
uvicorn md_generator.url.api.main:app --host 127.0.0.1 --port 8011
|
|
483
512
|
uvicorn md_generator.playwright.api.main:app --host 127.0.0.1 --port 8014
|
|
513
|
+
uvicorn md_generator.graph.api.main:app --host 127.0.0.1 --port 8012
|
|
514
|
+
uvicorn md_generator.openapi.api.main:app --host 127.0.0.1 --port 8015
|
|
484
515
|
uvicorn md_generator.media.audio.api.main:create_app --factory --host 127.0.0.1 --port 8011
|
|
485
516
|
uvicorn md_generator.media.video.api.main:create_app --factory --host 127.0.0.1 --port 8012
|
|
486
517
|
uvicorn md_generator.media.youtube.api.main:create_app --factory --host 127.0.0.1 --port 8013
|
|
487
518
|
```
|
|
488
519
|
|
|
520
|
+
**Port note:** **`md-graph-api`** and **`md-video-api`** both default to **8012**; set **`GRAPH_TO_MD_PORT`** or **`MD_VIDEO_API_PORT`** when you need both on one machine. **`md-openapi-api`** defaults to **8015** (`OPENAPI_TO_MD_PORT`) so it does not collide with **`md-youtube-api`** (**8013**) or **`md-playwright-api`** (**8014**).
|
|
521
|
+
|
|
489
522
|
### MCP over HTTP on the same server
|
|
490
523
|
|
|
491
524
|
These apps mount an MCP HTTP app at **`/mcp`** (Streamable HTTP / framework-specific). Start the API as above, then point an MCP client at `http://<host>:<port>/mcp` where supported.
|
|
@@ -504,6 +537,9 @@ Prefixes differ per service (often read from a `.env` file next to the process):
|
|
|
504
537
|
| XLSX | `XLSX_TO_MD_` | `XLSX_TO_MD_TEMP_DIR`, `XLSX_TO_MD_CORS_ORIGINS`, etc. (see `md_generator.xlsx.api.app`) |
|
|
505
538
|
| URL | `URL_TO_MD_` | `URL_TO_MD_MAX_SYNC_URLS`, `URL_TO_MD_MAX_SYNC_CRAWL_PAGES`, `URL_TO_MD_MAX_JOB_URLS`, `URL_TO_MD_JOB_TTL_SECONDS`, `URL_TO_MD_TEMP_DIR`, `URL_TO_MD_CORS_ORIGINS` |
|
|
506
539
|
| Playwright / SPA | `PLAYWRIGHT_TO_MD_` | `PLAYWRIGHT_TO_MD_MAX_SYNC_URLS`, `PLAYWRIGHT_TO_MD_MAX_JOB_URLS`, `PLAYWRIGHT_TO_MD_JOB_TTL_SECONDS`, `PLAYWRIGHT_TO_MD_TEMP_DIR`, `PLAYWRIGHT_TO_MD_CORS_ORIGINS`, `PLAYWRIGHT_TO_MD_API_HOST`, `PLAYWRIGHT_TO_MD_API_PORT` (default **8014**) |
|
|
540
|
+
| Database metadata | `DB_TO_MD_` | `DB_TO_MD_JOB_SQLITE_PATH`, `DB_TO_MD_JOB_WORKSPACE_ROOT`, `DB_TO_MD_CORS_ORIGINS`, `DB_TO_MD_MAX_SYNC_ZIP_MB`, `DB_TO_MD_HOST`, `DB_TO_MD_PORT` (default **8010**) |
|
|
541
|
+
| Graph metadata | `GRAPH_TO_MD_` | `GRAPH_TO_MD_JOB_SQLITE_PATH`, `GRAPH_TO_MD_JOB_WORKSPACE_ROOT`, `GRAPH_TO_MD_CORS_ORIGINS`, `GRAPH_TO_MD_MAX_SYNC_ZIP_MB`, `GRAPH_TO_MD_HOST`, `GRAPH_TO_MD_PORT` (default **8012**) |
|
|
542
|
+
| OpenAPI → Markdown | `OPENAPI_TO_MD_` | `OPENAPI_TO_MD_CORS_ORIGINS`, `OPENAPI_TO_MD_MAX_SYNC_ZIP_MB`, `OPENAPI_TO_MD_HOST`, `OPENAPI_TO_MD_PORT` (default **8015**) |
|
|
507
543
|
| Audio API | `MD_AUDIO_` | `MD_AUDIO_MAX_UPLOAD_MB`, `MD_AUDIO_MAX_SYNC_UPLOAD_MB`, `MD_AUDIO_JOB_TTL_SECONDS`, `MD_AUDIO_TEMP_DIR`, `MD_AUDIO_CORS_ORIGINS`, `MD_AUDIO_API_HOST`, `MD_AUDIO_API_PORT` |
|
|
508
544
|
| Video API | `MD_VIDEO_` | Same pattern as audio with `MD_VIDEO_*` (defaults: larger upload/sync caps, port **8012**) |
|
|
509
545
|
| YouTube API | `MD_YOUTUBE_` | `MD_YOUTUBE_JOB_TTL_SECONDS`, `MD_YOUTUBE_TEMP_DIR`, `MD_YOUTUBE_CORS_ORIGINS`, `MD_YOUTUBE_API_HOST`, `MD_YOUTUBE_API_PORT` (default **8013**); optional `MD_YOUTUBE_YTDLP` path for audio fallback |
|
|
@@ -534,6 +570,9 @@ Two usage patterns:
|
|
|
534
570
|
| Audio | `md-audio-mcp` or `python -m md_generator.media.audio.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
535
571
|
| Video | `md-video-mcp` or `python -m md_generator.media.video.api.mcp_server` — same transports |
|
|
536
572
|
| YouTube | `md-youtube-mcp` or `python -m md_generator.media.youtube.api.mcp_server` — same transports |
|
|
573
|
+
| Database metadata | `md-db-mcp` or `python -m md_generator.db.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
574
|
+
| Graph (Neo4j / NetworkX) | `md-graph-mcp` or `python -m md_generator.graph.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
575
|
+
| OpenAPI → Markdown | `md-openapi-mcp` or `python -m md_generator.openapi.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
537
576
|
|
|
538
577
|
**Word** and **XLSX** also ship a small runner script in the repo:
|
|
539
578
|
|
|
@@ -558,7 +597,7 @@ pip install -e ".[dev,all]" # or a smaller subset of extras
|
|
|
558
597
|
python -m pytest
|
|
559
598
|
```
|
|
560
599
|
|
|
561
|
-
Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`)
|
|
600
|
+
Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`), **`graph-to-md/tests/`**, and **`openapi-to-md/tests/`**; `pyproject.toml` configures `pythonpath = ["src"]` so `md_generator` resolves without a separate `PYTHONPATH`.
|
|
562
601
|
|
|
563
602
|
---
|
|
564
603
|
|
|
@@ -568,7 +607,7 @@ Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/test
|
|
|
568
607
|
|------|------|
|
|
569
608
|
| `LICENSE` | MIT license text |
|
|
570
609
|
| `CODE_OF_CONDUCT.md` | [Contributor Covenant](https://www.contributor-covenant.org/) 2.1 |
|
|
571
|
-
| `src/md_generator/` | **Library source** (all formats + `api` subpackages); **audio/video** under [`media/audio/`](src/md_generator/media/audio/) and [`media/video/`](src/md_generator/media/video/) |
|
|
610
|
+
| `src/md_generator/` | **Library source** (all formats + `api` subpackages); **audio/video** under [`media/audio/`](src/md_generator/media/audio/) and [`media/video/`](src/md_generator/media/video/); **graph-to-md** under [`graph/`](src/md_generator/graph/) |
|
|
572
611
|
| `pyproject.toml` | Packaging, extras, CLI entry points, pytest |
|
|
573
612
|
| `*-to-md/` | **Docs, tests, fixtures**, thin `converter.py` shims, some `run.py` helpers |
|
|
574
613
|
| `README.md` | This document |
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mdengine"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Convert PDF, Office, images, audio, video, text/JSON/XML, ZIP archives,
|
|
7
|
+
version = "0.6.0"
|
|
8
|
+
description = "Convert PDF, Office, images, audio, video, text/JSON/XML, ZIP archives, web URLs, databases, graphs, and OpenAPI specs to Markdown."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = "MIT"
|
|
12
12
|
license-files = ["LICENSE"]
|
|
13
13
|
authors = [{ name = "mdengine contributors" }]
|
|
14
|
-
keywords = ["markdown", "pdf", "docx", "pptx", "xlsx", "ocr", "zip", "url", "html", "youtube", "playwright"]
|
|
14
|
+
keywords = ["markdown", "pdf", "docx", "pptx", "xlsx", "ocr", "zip", "url", "html", "youtube", "playwright", "database", "openapi"]
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Programming Language :: Python :: 3",
|
|
17
17
|
"Programming Language :: Python :: 3 :: Only",
|
|
@@ -92,6 +92,25 @@ playwright = [
|
|
|
92
92
|
"readability-lxml>=0.8.1",
|
|
93
93
|
"Pillow>=10.0.0",
|
|
94
94
|
]
|
|
95
|
+
db = [
|
|
96
|
+
"sqlalchemy>=2.0.0",
|
|
97
|
+
"pyyaml>=6.0.0",
|
|
98
|
+
"psycopg2-binary>=2.9.9",
|
|
99
|
+
"pymysql>=1.1.0",
|
|
100
|
+
"oracledb>=2.0.0",
|
|
101
|
+
"pymongo>=4.6.0",
|
|
102
|
+
"mermaid-py>=0.8.0",
|
|
103
|
+
]
|
|
104
|
+
graph = [
|
|
105
|
+
"networkx>=3.2.0",
|
|
106
|
+
"neo4j>=5.14.0",
|
|
107
|
+
"pyyaml>=6.0.0",
|
|
108
|
+
]
|
|
109
|
+
openapi = [
|
|
110
|
+
"pyyaml>=6.0.0",
|
|
111
|
+
"prance>=23.6.0",
|
|
112
|
+
"openapi-spec-validator>=0.7.0",
|
|
113
|
+
]
|
|
95
114
|
api = [
|
|
96
115
|
"fastapi>=0.115.0",
|
|
97
116
|
"uvicorn[standard]>=0.32.0",
|
|
@@ -110,6 +129,9 @@ dev = [
|
|
|
110
129
|
"mdengine[mcp]",
|
|
111
130
|
"mdengine[url]",
|
|
112
131
|
"mdengine[playwright]",
|
|
132
|
+
"mdengine[db]",
|
|
133
|
+
"mdengine[graph]",
|
|
134
|
+
"mdengine[openapi]",
|
|
113
135
|
]
|
|
114
136
|
all = [
|
|
115
137
|
"pymupdf>=1.24.0",
|
|
@@ -165,10 +187,25 @@ md-youtube-mcp = "md_generator.media.youtube.api.mcp_server:main"
|
|
|
165
187
|
md-playwright = "md_generator.playwright.cli:main"
|
|
166
188
|
md-playwright-api = "md_generator.playwright.api.run:main"
|
|
167
189
|
md-playwright-mcp = "md_generator.playwright.api.mcp_server:main"
|
|
190
|
+
md-db = "md_generator.db.cli.main:main"
|
|
191
|
+
md-db-api = "md_generator.db.api.run:main"
|
|
192
|
+
md-db-mcp = "md_generator.db.api.mcp_server:main"
|
|
193
|
+
md-graph = "md_generator.graph.cli.main:main"
|
|
194
|
+
md-graph-api = "md_generator.graph.api.run:main"
|
|
195
|
+
md-graph-mcp = "md_generator.graph.api.mcp_server:main"
|
|
196
|
+
md-openapi = "md_generator.openapi.cli.main:main"
|
|
197
|
+
md-openapi-api = "md_generator.openapi.api.run:main"
|
|
198
|
+
md-openapi-mcp = "md_generator.openapi.api.mcp_server:main"
|
|
199
|
+
mdengine = "md_generator.engine_cli:main"
|
|
168
200
|
|
|
169
201
|
[tool.setuptools.packages.find]
|
|
170
202
|
where = ["src"]
|
|
171
203
|
|
|
204
|
+
[tool.setuptools.package-data]
|
|
205
|
+
"md_generator.db.config" = ["*.yaml"]
|
|
206
|
+
"md_generator.graph.config" = ["*.yaml"]
|
|
207
|
+
"md_generator.openapi.config" = ["*.yaml"]
|
|
208
|
+
|
|
172
209
|
[tool.pytest.ini_options]
|
|
173
210
|
pythonpath = ["src"]
|
|
174
211
|
testpaths = [
|
|
@@ -184,5 +221,8 @@ testpaths = [
|
|
|
184
221
|
"video-to-md/tests",
|
|
185
222
|
"youtube-to-md/tests",
|
|
186
223
|
"playwright-to-md/tests",
|
|
224
|
+
"db-to-md/tests",
|
|
225
|
+
"graph-to-md/tests",
|
|
226
|
+
"openapi-to-md/tests",
|
|
187
227
|
]
|
|
188
228
|
markers = ["integration: optional dependency or slower checks"]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from sqlalchemy.engine.url import make_url
|
|
6
|
+
|
|
7
|
+
from md_generator.db.adapters.mongo_adapter import MongoAdapter
|
|
8
|
+
from md_generator.db.adapters.mysql_adapter import MysqlAdapter
|
|
9
|
+
from md_generator.db.adapters.oracle_adapter import OracleAdapter
|
|
10
|
+
from md_generator.db.adapters.postgres_adapter import PostgresAdapter
|
|
11
|
+
from md_generator.db.adapters.sqlite_adapter import SqliteAdapter
|
|
12
|
+
from md_generator.db.core.base_adapter import BaseAdapter
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_adapter(
|
|
16
|
+
db_type: str,
|
|
17
|
+
uri: str,
|
|
18
|
+
*,
|
|
19
|
+
schema: str | None = None,
|
|
20
|
+
database: str | None = None,
|
|
21
|
+
limits: dict[str, Any] | None = None,
|
|
22
|
+
) -> BaseAdapter:
|
|
23
|
+
lim = dict(limits or {})
|
|
24
|
+
t = db_type.lower().strip()
|
|
25
|
+
if t in ("postgres", "postgresql"):
|
|
26
|
+
sch = schema or "public"
|
|
27
|
+
return PostgresAdapter(uri, sch, lim)
|
|
28
|
+
if t in ("mysql", "mariadb"):
|
|
29
|
+
sch = schema or make_url(uri).database
|
|
30
|
+
if not sch:
|
|
31
|
+
raise ValueError("MySQL requires database in URI path or --schema")
|
|
32
|
+
return MysqlAdapter(uri, sch, lim)
|
|
33
|
+
if t in ("oracle",):
|
|
34
|
+
if not schema:
|
|
35
|
+
raise ValueError("Oracle requires schema (owner) in config or --schema")
|
|
36
|
+
return OracleAdapter(uri, schema, lim)
|
|
37
|
+
if t in ("mongo", "mongodb"):
|
|
38
|
+
if not database:
|
|
39
|
+
raise ValueError("MongoDB requires database name in config or --database")
|
|
40
|
+
return MongoAdapter(uri, database, lim)
|
|
41
|
+
if t in ("sqlite",):
|
|
42
|
+
sch = (schema or "main").strip()
|
|
43
|
+
if sch.lower() == "public":
|
|
44
|
+
sch = "main"
|
|
45
|
+
return SqliteAdapter(uri, sch, lim)
|
|
46
|
+
raise ValueError(f"Unsupported database type: {db_type!r}")
|