mdengine 0.5.0__tar.gz → 0.7.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.5.0 → mdengine-0.7.0}/PKG-INFO +38 -8
- {mdengine-0.5.0 → mdengine-0.7.0}/README.md +18 -5
- {mdengine-0.5.0 → mdengine-0.7.0}/pyproject.toml +34 -3
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/__init__.py +1 -1
- mdengine-0.7.0/src/md_generator/codeflow/__init__.py +7 -0
- mdengine-0.7.0/src/md_generator/codeflow/analyzers/__init__.py +9 -0
- mdengine-0.7.0/src/md_generator/codeflow/analyzers/flow_analyzer.py +68 -0
- mdengine-0.7.0/src/md_generator/codeflow/api/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/codeflow/api/job_manager.py +249 -0
- mdengine-0.7.0/src/md_generator/codeflow/api/main.py +185 -0
- mdengine-0.7.0/src/md_generator/codeflow/api/mcp_server.py +16 -0
- mdengine-0.7.0/src/md_generator/codeflow/api/run.py +15 -0
- mdengine-0.7.0/src/md_generator/codeflow/api/schemas.py +96 -0
- mdengine-0.7.0/src/md_generator/codeflow/api/settings.py +28 -0
- mdengine-0.7.0/src/md_generator/codeflow/cli/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/codeflow/cli/main.py +132 -0
- mdengine-0.7.0/src/md_generator/codeflow/core/__init__.py +6 -0
- mdengine-0.7.0/src/md_generator/codeflow/core/extractor.py +193 -0
- mdengine-0.7.0/src/md_generator/codeflow/core/run_config.py +31 -0
- mdengine-0.7.0/src/md_generator/codeflow/detectors/__init__.py +7 -0
- mdengine-0.7.0/src/md_generator/codeflow/detectors/api_detector.py +222 -0
- mdengine-0.7.0/src/md_generator/codeflow/detectors/entry_detector.py +46 -0
- mdengine-0.7.0/src/md_generator/codeflow/detectors/entry_rank.py +51 -0
- mdengine-0.7.0/src/md_generator/codeflow/detectors/kafka_detector.py +47 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/business_rules_markdown.py +68 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/cytoscape_enrich.py +97 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/entry_markdown.py +198 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/flow_summary.py +262 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/html.py +361 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/markdown.py +35 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/mermaid.py +45 -0
- mdengine-0.7.0/src/md_generator/codeflow/generators/sequence.py +33 -0
- mdengine-0.7.0/src/md_generator/codeflow/graph/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/codeflow/graph/builder.py +181 -0
- mdengine-0.7.0/src/md_generator/codeflow/ingestion/__init__.py +10 -0
- mdengine-0.7.0/src/md_generator/codeflow/ingestion/loader.py +66 -0
- mdengine-0.7.0/src/md_generator/codeflow/lang_dispatch.py +64 -0
- mdengine-0.7.0/src/md_generator/codeflow/mcp/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/codeflow/mcp/server.py +42 -0
- mdengine-0.7.0/src/md_generator/codeflow/models/__init__.py +21 -0
- mdengine-0.7.0/src/md_generator/codeflow/models/ir.py +97 -0
- mdengine-0.7.0/src/md_generator/codeflow/parsers/__init__.py +18 -0
- mdengine-0.7.0/src/md_generator/codeflow/parsers/base.py +57 -0
- mdengine-0.7.0/src/md_generator/codeflow/parsers/cpp_parser.py +155 -0
- mdengine-0.7.0/src/md_generator/codeflow/parsers/go_parser.py +82 -0
- mdengine-0.7.0/src/md_generator/codeflow/parsers/java_parser.py +116 -0
- mdengine-0.7.0/src/md_generator/codeflow/parsers/php_parser.py +79 -0
- mdengine-0.7.0/src/md_generator/codeflow/parsers/python_parser.py +295 -0
- mdengine-0.7.0/src/md_generator/codeflow/parsers/treesitter_js_ts_parser.py +119 -0
- mdengine-0.7.0/src/md_generator/codeflow/rules/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/codeflow/rules/collector.py +284 -0
- mdengine-0.7.0/src/md_generator/codeflow/runtime/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/codeflow/runtime/tracer.py +14 -0
- mdengine-0.7.0/src/md_generator/codeflow/utils/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/codeflow/utils/tools_root.py +13 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/factory.py +6 -0
- mdengine-0.7.0/src/md_generator/db/adapters/sqlite_adapter.py +107 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/main.py +89 -1
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/schemas.py +1 -1
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/settings.py +1 -0
- mdengine-0.7.0/src/md_generator/db/api/sqlite_upload.py +87 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/cli/main.py +1 -1
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/job_manager.py +44 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/run_config.py +5 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/util.py +12 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/engine_cli.py +10 -2
- mdengine-0.7.0/src/md_generator/graph/mcp/sse.py +8 -0
- mdengine-0.7.0/src/md_generator/openapi/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/openapi/api/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/openapi/api/main.py +84 -0
- mdengine-0.7.0/src/md_generator/openapi/api/mcp_server.py +29 -0
- mdengine-0.7.0/src/md_generator/openapi/api/run.py +15 -0
- mdengine-0.7.0/src/md_generator/openapi/api/schemas.py +33 -0
- mdengine-0.7.0/src/md_generator/openapi/api/settings.py +21 -0
- mdengine-0.7.0/src/md_generator/openapi/cli/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/openapi/cli/main.py +75 -0
- mdengine-0.7.0/src/md_generator/openapi/config/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/openapi/config/default.yaml +14 -0
- mdengine-0.7.0/src/md_generator/openapi/converters/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/openapi/converters/swagger2_to_openapi3.py +453 -0
- mdengine-0.7.0/src/md_generator/openapi/core/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/openapi/core/extractor.py +207 -0
- mdengine-0.7.0/src/md_generator/openapi/core/run_config.py +100 -0
- mdengine-0.7.0/src/md_generator/openapi/core/zip_export.py +24 -0
- mdengine-0.7.0/src/md_generator/openapi/enrichers/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/openapi/enrichers/rules.py +133 -0
- mdengine-0.7.0/src/md_generator/openapi/enrichers/sample_body.py +73 -0
- mdengine-0.7.0/src/md_generator/openapi/generators/__init__.py +9 -0
- mdengine-0.7.0/src/md_generator/openapi/generators/dependency_graph.py +54 -0
- mdengine-0.7.0/src/md_generator/openapi/loaders/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/openapi/loaders/spec_loader.py +115 -0
- mdengine-0.7.0/src/md_generator/openapi/mcp/__init__.py +1 -0
- mdengine-0.7.0/src/md_generator/openapi/mcp/server.py +71 -0
- mdengine-0.7.0/src/md_generator/openapi/models/__init__.py +25 -0
- mdengine-0.7.0/src/md_generator/openapi/models/domain.py +106 -0
- mdengine-0.7.0/src/md_generator/openapi/normalizers/__init__.py +6 -0
- mdengine-0.7.0/src/md_generator/openapi/normalizers/operations.py +287 -0
- mdengine-0.7.0/src/md_generator/openapi/normalizers/schema_flatten.py +104 -0
- mdengine-0.7.0/src/md_generator/openapi/parsers/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/openapi/parsers/openapi_parser.py +18 -0
- mdengine-0.7.0/src/md_generator/openapi/resolvers/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/openapi/resolvers/ref_resolver.py +16 -0
- mdengine-0.7.0/src/md_generator/openapi/writers/__init__.py +5 -0
- mdengine-0.7.0/src/md_generator/openapi/writers/markdown_writer.py +253 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/PKG-INFO +38 -8
- {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/SOURCES.txt +92 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/entry_points.txt +7 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/requires.txt +21 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/LICENSE +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/setup.cfg +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/convert_runner.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/jobs.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/mcp_setup.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/query_options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/convert_impl.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/options.py +0 -0
- {mdengine-0.5.0/src/md_generator/graph/mcp → mdengine-0.7.0/src/md_generator/codeflow/api}/sse.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/mongo_adapter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/mysql_adapter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/oracle_adapter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/postgres_adapter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/sql_common.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/run.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/cli/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/config/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/config/default.yaml +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/base_adapter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/dot_emitter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/filter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/mermaid_emitter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/mermaid_render.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/model.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/pipeline.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/render.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/extractor.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/markdown_writer.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/models.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/zip_export.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/mcp/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/mcp/server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/mcp/sse.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/mcp/stream.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/adapters/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/adapters/factory.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/adapters/neo4j_adapter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/adapters/networkx_adapter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/run.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/schemas.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/cli/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/cli/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/config/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/config/default.yaml +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/base_adapter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/extractor.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/graph_builder.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/job_manager.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/markdown_writer.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/models.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/run_config.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/viz.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/zip_export.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/mcp/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/mcp/server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/mcp/stream.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/query_options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/staging.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/zip_bundle.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/base.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/easy.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/paddle.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/tesseract.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/convert_impl.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/emit.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/io_util.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/utils.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/mcp_setup.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/run.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/formatter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/service.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/document_converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/job_store.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/mcp_setup.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/run.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/formatter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/service.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/whisper_language.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/mcp_setup.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/run.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/formatter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/metadata.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/service.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/transcript.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/zip_bundle.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/md_emit.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/pdf_extract.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/utils.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/convert_runner.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/jobs.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/mcp_setup.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/run.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/assets.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/chunker.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/cli.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/extractor.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/html_to_md.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/pipeline.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/playwright_fetcher.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/convert_runner.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/jobs.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/mcp_setup.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/query_options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/convert_impl.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/embedded_extract.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/ooxml_media.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/post_assets.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/text_formatting.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/vendor_pdf_md/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/vendor_pdf_md/convert.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/vendor_word_md/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/vendor_word_md/convert.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/zip_deep.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/convert_runner.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/jobs.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/mcp_setup.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/query_options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/convert_impl.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/format_detect.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/md_emit_json.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/md_emit_txt.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/md_emit_xml.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/convert_runner.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/jobs.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/mcp_setup.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/query_options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/assets.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/convert_impl.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/crawl.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/extract.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/fetch.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/html_to_md.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/options.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/page_convert.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/post_convert_assets.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/robots_util.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/convert_util.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/jobs.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/main.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/artifact.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/settings.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/api/__init__.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/api/app.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/convert_config.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/converter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/converter_core.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/excel_reader.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/markdown_emitter.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/mcp_server.py +0 -0
- {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/dependency_links.txt +0 -0
- {mdengine-0.5.0 → mdengine-0.7.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.7.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,database
|
|
10
|
+
Keywords: markdown,pdf,docx,pptx,xlsx,ocr,zip,url,html,youtube,playwright,database,openapi,codeflow
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
13
|
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
@@ -99,6 +99,20 @@ Provides-Extra: graph
|
|
|
99
99
|
Requires-Dist: networkx>=3.2.0; extra == "graph"
|
|
100
100
|
Requires-Dist: neo4j>=5.14.0; extra == "graph"
|
|
101
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"
|
|
106
|
+
Provides-Extra: codeflow
|
|
107
|
+
Requires-Dist: networkx>=3.2.0; extra == "codeflow"
|
|
108
|
+
Requires-Dist: javalang>=0.13.0; extra == "codeflow"
|
|
109
|
+
Provides-Extra: codeflow-treesitter
|
|
110
|
+
Requires-Dist: tree-sitter>=0.21.0; extra == "codeflow-treesitter"
|
|
111
|
+
Requires-Dist: tree-sitter-javascript>=0.21.0; extra == "codeflow-treesitter"
|
|
112
|
+
Requires-Dist: tree-sitter-typescript>=0.23.0; extra == "codeflow-treesitter"
|
|
113
|
+
Requires-Dist: tree-sitter-cpp>=0.23.0; extra == "codeflow-treesitter"
|
|
114
|
+
Provides-Extra: codeflow-clang
|
|
115
|
+
Requires-Dist: clang>=16.0.0; extra == "codeflow-clang"
|
|
102
116
|
Provides-Extra: api
|
|
103
117
|
Requires-Dist: fastapi>=0.115.0; extra == "api"
|
|
104
118
|
Requires-Dist: uvicorn[standard]>=0.32.0; extra == "api"
|
|
@@ -120,6 +134,9 @@ Requires-Dist: mdengine[url]; extra == "dev"
|
|
|
120
134
|
Requires-Dist: mdengine[playwright]; extra == "dev"
|
|
121
135
|
Requires-Dist: mdengine[db]; extra == "dev"
|
|
122
136
|
Requires-Dist: mdengine[graph]; extra == "dev"
|
|
137
|
+
Requires-Dist: mdengine[openapi]; extra == "dev"
|
|
138
|
+
Requires-Dist: mdengine[codeflow]; extra == "dev"
|
|
139
|
+
Requires-Dist: mdengine[codeflow-treesitter]; extra == "dev"
|
|
123
140
|
Provides-Extra: all
|
|
124
141
|
Requires-Dist: pymupdf>=1.24.0; extra == "all"
|
|
125
142
|
Requires-Dist: pdfplumber>=0.11.0; extra == "all"
|
|
@@ -279,17 +296,26 @@ If the shell reports “command not found”, ensure the Python **Scripts** dire
|
|
|
279
296
|
| `md-video-mcp` | `md_generator.media.video.api.mcp_server:main` | Same for video |
|
|
280
297
|
| `md-youtube-mcp` | `md_generator.media.youtube.api.mcp_server:main` | Same for YouTube (`youtube_url_to_markdown`) |
|
|
281
298
|
| `md-db` | `md_generator.db.cli.main:main` | `pip install "mdengine[db]"` then `md-db --config db.yaml` (or `mdengine db-to-md …`) |
|
|
282
|
-
| `md-db-api` | `md_generator.db.api.run:main` | FastAPI on port **8010** (`DB_TO_MD_PORT`): `POST /db-to-md/run`,
|
|
299
|
+
| `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` |
|
|
283
300
|
| `md-db-mcp` | `md_generator.db.api.mcp_server:main` | Standalone MCP for metadata export tools |
|
|
284
301
|
| `md-graph` | `md_generator.graph.cli.main:main` | `pip install "mdengine[graph]"` then `md-graph --source neo4j --uri bolt://…` (or `mdengine graph-to-md …`) |
|
|
285
302
|
| `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` |
|
|
286
303
|
| `md-graph-mcp` | `md_generator.graph.api.mcp_server:main` | Standalone MCP for graph export tools |
|
|
287
|
-
| `
|
|
304
|
+
| `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 …`) |
|
|
305
|
+
| `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`** |
|
|
306
|
+
| `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` |
|
|
307
|
+
| `mdengine` | `md_generator.engine_cli:main` | `mdengine db-to-md …` / `mdengine graph-to-md …` / `mdengine openapi-to-md generate …` |
|
|
308
|
+
|
|
309
|
+
**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.
|
|
288
310
|
|
|
289
311
|
**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:`.
|
|
290
312
|
|
|
291
313
|
**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`.
|
|
292
314
|
|
|
315
|
+
**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.
|
|
316
|
+
|
|
317
|
+
**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.
|
|
318
|
+
|
|
293
319
|
**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).
|
|
294
320
|
|
|
295
321
|
Every command accepts **`-h` / `--help`** for full flags (artifact layout, OCR, ZIP options, etc.).
|
|
@@ -606,7 +632,7 @@ Equivalent modules: `python -m md_generator.media.audio.api.mcp_server`, `python
|
|
|
606
632
|
|
|
607
633
|
### Thin shims (repo clone)
|
|
608
634
|
|
|
609
|
-
[`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/).
|
|
635
|
+
[`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/).
|
|
610
636
|
|
|
611
637
|
---
|
|
612
638
|
|
|
@@ -638,6 +664,7 @@ Install `mdengine[api]` plus the format extra(s), then run the **`app`** object
|
|
|
638
664
|
| Playwright / SPA | `md_generator.playwright.api.main:app` | `playwright`, `api`, `mcp` |
|
|
639
665
|
| Database metadata | `md_generator.db.api.main:app` | `db`, `api`, `mcp` |
|
|
640
666
|
| Graph metadata (Neo4j / NetworkX) | `md_generator.graph.api.main:app` | `graph`, `api`, `mcp` |
|
|
667
|
+
| OpenAPI → Markdown | `md_generator.openapi.api.main:app` | `openapi`, `api`, `mcp` |
|
|
641
668
|
| Audio (Whisper) | `md_generator.media.audio.api.main:create_app` (use **`--factory`**) or `…main:app` | `audio`, `api`, `mcp` |
|
|
642
669
|
| Video (Whisper) | `md_generator.media.video.api.main:create_app` (use **`--factory`**) or `…main:app` | `video`, `api`, `mcp` |
|
|
643
670
|
| YouTube | `md_generator.media.youtube.api.main:create_app` (use **`--factory`**) or `…main:app` | `youtube`, `api`, `mcp` |
|
|
@@ -651,12 +678,13 @@ uvicorn md_generator.archive.api.main:app --host 127.0.0.1 --port 8010
|
|
|
651
678
|
uvicorn md_generator.url.api.main:app --host 127.0.0.1 --port 8011
|
|
652
679
|
uvicorn md_generator.playwright.api.main:app --host 127.0.0.1 --port 8014
|
|
653
680
|
uvicorn md_generator.graph.api.main:app --host 127.0.0.1 --port 8012
|
|
681
|
+
uvicorn md_generator.openapi.api.main:app --host 127.0.0.1 --port 8015
|
|
654
682
|
uvicorn md_generator.media.audio.api.main:create_app --factory --host 127.0.0.1 --port 8011
|
|
655
683
|
uvicorn md_generator.media.video.api.main:create_app --factory --host 127.0.0.1 --port 8012
|
|
656
684
|
uvicorn md_generator.media.youtube.api.main:create_app --factory --host 127.0.0.1 --port 8013
|
|
657
685
|
```
|
|
658
686
|
|
|
659
|
-
**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.
|
|
687
|
+
**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**).
|
|
660
688
|
|
|
661
689
|
### MCP over HTTP on the same server
|
|
662
690
|
|
|
@@ -678,6 +706,7 @@ Prefixes differ per service (often read from a `.env` file next to the process):
|
|
|
678
706
|
| 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**) |
|
|
679
707
|
| 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**) |
|
|
680
708
|
| 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**) |
|
|
709
|
+
| 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**) |
|
|
681
710
|
| 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` |
|
|
682
711
|
| Video API | `MD_VIDEO_` | Same pattern as audio with `MD_VIDEO_*` (defaults: larger upload/sync caps, port **8012**) |
|
|
683
712
|
| 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 |
|
|
@@ -710,6 +739,7 @@ Two usage patterns:
|
|
|
710
739
|
| YouTube | `md-youtube-mcp` or `python -m md_generator.media.youtube.api.mcp_server` — same transports |
|
|
711
740
|
| Database metadata | `md-db-mcp` or `python -m md_generator.db.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
712
741
|
| Graph (Neo4j / NetworkX) | `md-graph-mcp` or `python -m md_generator.graph.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
742
|
+
| OpenAPI → Markdown | `md-openapi-mcp` or `python -m md_generator.openapi.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
713
743
|
|
|
714
744
|
**Word** and **XLSX** also ship a small runner script in the repo:
|
|
715
745
|
|
|
@@ -734,7 +764,7 @@ pip install -e ".[dev,all]" # or a smaller subset of extras
|
|
|
734
764
|
python -m pytest
|
|
735
765
|
```
|
|
736
766
|
|
|
737
|
-
Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`) and **`
|
|
767
|
+
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`.
|
|
738
768
|
|
|
739
769
|
---
|
|
740
770
|
|
|
@@ -129,17 +129,26 @@ If the shell reports “command not found”, ensure the Python **Scripts** dire
|
|
|
129
129
|
| `md-video-mcp` | `md_generator.media.video.api.mcp_server:main` | Same for video |
|
|
130
130
|
| `md-youtube-mcp` | `md_generator.media.youtube.api.mcp_server:main` | Same for YouTube (`youtube_url_to_markdown`) |
|
|
131
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`,
|
|
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
133
|
| `md-db-mcp` | `md_generator.db.api.mcp_server:main` | Standalone MCP for metadata export tools |
|
|
134
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
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
136
|
| `md-graph-mcp` | `md_generator.graph.api.mcp_server:main` | Standalone MCP for graph export tools |
|
|
137
|
-
| `
|
|
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.
|
|
138
143
|
|
|
139
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:`.
|
|
140
145
|
|
|
141
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`.
|
|
142
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
|
+
|
|
143
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).
|
|
144
153
|
|
|
145
154
|
Every command accepts **`-h` / `--help`** for full flags (artifact layout, OCR, ZIP options, etc.).
|
|
@@ -456,7 +465,7 @@ Equivalent modules: `python -m md_generator.media.audio.api.mcp_server`, `python
|
|
|
456
465
|
|
|
457
466
|
### Thin shims (repo clone)
|
|
458
467
|
|
|
459
|
-
[`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/).
|
|
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/).
|
|
460
469
|
|
|
461
470
|
---
|
|
462
471
|
|
|
@@ -488,6 +497,7 @@ Install `mdengine[api]` plus the format extra(s), then run the **`app`** object
|
|
|
488
497
|
| Playwright / SPA | `md_generator.playwright.api.main:app` | `playwright`, `api`, `mcp` |
|
|
489
498
|
| Database metadata | `md_generator.db.api.main:app` | `db`, `api`, `mcp` |
|
|
490
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` |
|
|
491
501
|
| Audio (Whisper) | `md_generator.media.audio.api.main:create_app` (use **`--factory`**) or `…main:app` | `audio`, `api`, `mcp` |
|
|
492
502
|
| Video (Whisper) | `md_generator.media.video.api.main:create_app` (use **`--factory`**) or `…main:app` | `video`, `api`, `mcp` |
|
|
493
503
|
| YouTube | `md_generator.media.youtube.api.main:create_app` (use **`--factory`**) or `…main:app` | `youtube`, `api`, `mcp` |
|
|
@@ -501,12 +511,13 @@ uvicorn md_generator.archive.api.main:app --host 127.0.0.1 --port 8010
|
|
|
501
511
|
uvicorn md_generator.url.api.main:app --host 127.0.0.1 --port 8011
|
|
502
512
|
uvicorn md_generator.playwright.api.main:app --host 127.0.0.1 --port 8014
|
|
503
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
|
|
504
515
|
uvicorn md_generator.media.audio.api.main:create_app --factory --host 127.0.0.1 --port 8011
|
|
505
516
|
uvicorn md_generator.media.video.api.main:create_app --factory --host 127.0.0.1 --port 8012
|
|
506
517
|
uvicorn md_generator.media.youtube.api.main:create_app --factory --host 127.0.0.1 --port 8013
|
|
507
518
|
```
|
|
508
519
|
|
|
509
|
-
**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.
|
|
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**).
|
|
510
521
|
|
|
511
522
|
### MCP over HTTP on the same server
|
|
512
523
|
|
|
@@ -528,6 +539,7 @@ Prefixes differ per service (often read from a `.env` file next to the process):
|
|
|
528
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**) |
|
|
529
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**) |
|
|
530
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**) |
|
|
531
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` |
|
|
532
544
|
| Video API | `MD_VIDEO_` | Same pattern as audio with `MD_VIDEO_*` (defaults: larger upload/sync caps, port **8012**) |
|
|
533
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 |
|
|
@@ -560,6 +572,7 @@ Two usage patterns:
|
|
|
560
572
|
| YouTube | `md-youtube-mcp` or `python -m md_generator.media.youtube.api.mcp_server` — same transports |
|
|
561
573
|
| Database metadata | `md-db-mcp` or `python -m md_generator.db.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
|
|
562
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` |
|
|
563
576
|
|
|
564
577
|
**Word** and **XLSX** also ship a small runner script in the repo:
|
|
565
578
|
|
|
@@ -584,7 +597,7 @@ pip install -e ".[dev,all]" # or a smaller subset of extras
|
|
|
584
597
|
python -m pytest
|
|
585
598
|
```
|
|
586
599
|
|
|
587
|
-
Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`) and **`
|
|
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`.
|
|
588
601
|
|
|
589
602
|
---
|
|
590
603
|
|
|
@@ -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.7.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", "database"]
|
|
14
|
+
keywords = ["markdown", "pdf", "docx", "pptx", "xlsx", "ocr", "zip", "url", "html", "youtube", "playwright", "database", "openapi", "codeflow"]
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Programming Language :: Python :: 3",
|
|
17
17
|
"Programming Language :: Python :: 3 :: Only",
|
|
@@ -106,6 +106,24 @@ graph = [
|
|
|
106
106
|
"neo4j>=5.14.0",
|
|
107
107
|
"pyyaml>=6.0.0",
|
|
108
108
|
]
|
|
109
|
+
openapi = [
|
|
110
|
+
"pyyaml>=6.0.0",
|
|
111
|
+
"prance>=23.6.0",
|
|
112
|
+
"openapi-spec-validator>=0.7.0",
|
|
113
|
+
]
|
|
114
|
+
codeflow = [
|
|
115
|
+
"networkx>=3.2.0",
|
|
116
|
+
"javalang>=0.13.0",
|
|
117
|
+
]
|
|
118
|
+
codeflow-treesitter = [
|
|
119
|
+
"tree-sitter>=0.21.0",
|
|
120
|
+
"tree-sitter-javascript>=0.21.0",
|
|
121
|
+
"tree-sitter-typescript>=0.23.0",
|
|
122
|
+
"tree-sitter-cpp>=0.23.0",
|
|
123
|
+
]
|
|
124
|
+
codeflow-clang = [
|
|
125
|
+
"clang>=16.0.0",
|
|
126
|
+
]
|
|
109
127
|
api = [
|
|
110
128
|
"fastapi>=0.115.0",
|
|
111
129
|
"uvicorn[standard]>=0.32.0",
|
|
@@ -126,6 +144,9 @@ dev = [
|
|
|
126
144
|
"mdengine[playwright]",
|
|
127
145
|
"mdengine[db]",
|
|
128
146
|
"mdengine[graph]",
|
|
147
|
+
"mdengine[openapi]",
|
|
148
|
+
"mdengine[codeflow]",
|
|
149
|
+
"mdengine[codeflow-treesitter]",
|
|
129
150
|
]
|
|
130
151
|
all = [
|
|
131
152
|
"pymupdf>=1.24.0",
|
|
@@ -187,6 +208,13 @@ md-db-mcp = "md_generator.db.api.mcp_server:main"
|
|
|
187
208
|
md-graph = "md_generator.graph.cli.main:main"
|
|
188
209
|
md-graph-api = "md_generator.graph.api.run:main"
|
|
189
210
|
md-graph-mcp = "md_generator.graph.api.mcp_server:main"
|
|
211
|
+
md-openapi = "md_generator.openapi.cli.main:main"
|
|
212
|
+
md-openapi-api = "md_generator.openapi.api.run:main"
|
|
213
|
+
md-openapi-mcp = "md_generator.openapi.api.mcp_server:main"
|
|
214
|
+
md-codeflow = "md_generator.codeflow.cli.main:main"
|
|
215
|
+
codeflow = "md_generator.codeflow.cli.main:main"
|
|
216
|
+
md-codeflow-api = "md_generator.codeflow.api.run:main"
|
|
217
|
+
md-codeflow-mcp = "md_generator.codeflow.api.mcp_server:main"
|
|
190
218
|
mdengine = "md_generator.engine_cli:main"
|
|
191
219
|
|
|
192
220
|
[tool.setuptools.packages.find]
|
|
@@ -195,6 +223,7 @@ where = ["src"]
|
|
|
195
223
|
[tool.setuptools.package-data]
|
|
196
224
|
"md_generator.db.config" = ["*.yaml"]
|
|
197
225
|
"md_generator.graph.config" = ["*.yaml"]
|
|
226
|
+
"md_generator.openapi.config" = ["*.yaml"]
|
|
198
227
|
|
|
199
228
|
[tool.pytest.ini_options]
|
|
200
229
|
pythonpath = ["src"]
|
|
@@ -213,5 +242,7 @@ testpaths = [
|
|
|
213
242
|
"playwright-to-md/tests",
|
|
214
243
|
"db-to-md/tests",
|
|
215
244
|
"graph-to-md/tests",
|
|
245
|
+
"openapi-to-md/tests",
|
|
246
|
+
"codeflow-to-md/tests",
|
|
216
247
|
]
|
|
217
248
|
markers = ["integration: optional dependency or slower checks"]
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
|
|
5
|
+
import networkx as nx
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(slots=True)
|
|
9
|
+
class FlowSlice:
|
|
10
|
+
entry_id: str
|
|
11
|
+
nodes: set[str]
|
|
12
|
+
edges: list[tuple[str, str, dict]]
|
|
13
|
+
depth: int
|
|
14
|
+
cycle_nodes: set[str] = field(default_factory=set)
|
|
15
|
+
truncated: bool = False
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def walk_with_depth(
|
|
19
|
+
g: nx.DiGraph,
|
|
20
|
+
start: str,
|
|
21
|
+
max_depth: int,
|
|
22
|
+
) -> tuple[set[str], list[tuple[str, str, dict]], set[str], bool]:
|
|
23
|
+
"""Reachability from start within ``max_depth`` hops (shortest-path layering)."""
|
|
24
|
+
if start not in g:
|
|
25
|
+
return {start}, [], set(), False
|
|
26
|
+
try:
|
|
27
|
+
plen = nx.single_source_shortest_path_length(g, start, cutoff=max_depth)
|
|
28
|
+
except nx.NetworkXError:
|
|
29
|
+
plen = {start: 0}
|
|
30
|
+
|
|
31
|
+
nodes = set(plen.keys())
|
|
32
|
+
edges_out: list[tuple[str, str, dict]] = []
|
|
33
|
+
cycle_guess: set[str] = set()
|
|
34
|
+
truncated = False
|
|
35
|
+
|
|
36
|
+
for u in nodes:
|
|
37
|
+
du = plen[u]
|
|
38
|
+
if du >= max_depth:
|
|
39
|
+
succ = list(g.successors(u))
|
|
40
|
+
if succ:
|
|
41
|
+
truncated = True
|
|
42
|
+
continue
|
|
43
|
+
for v in g.successors(u):
|
|
44
|
+
ed = dict(g.edges[u, v])
|
|
45
|
+
edges_out.append((u, v, ed))
|
|
46
|
+
dv = plen.get(v)
|
|
47
|
+
if dv is not None and dv <= du:
|
|
48
|
+
cycle_guess.add(v)
|
|
49
|
+
if v not in plen and du + 1 > max_depth:
|
|
50
|
+
truncated = True
|
|
51
|
+
|
|
52
|
+
return nodes, edges_out, cycle_guess, truncated
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def slice_from_entry(
|
|
56
|
+
g: nx.DiGraph,
|
|
57
|
+
entry_id: str,
|
|
58
|
+
max_depth: int,
|
|
59
|
+
) -> FlowSlice:
|
|
60
|
+
nodes, edges, cycles, truncated = walk_with_depth(g, entry_id, max_depth)
|
|
61
|
+
return FlowSlice(
|
|
62
|
+
entry_id=entry_id,
|
|
63
|
+
nodes=nodes,
|
|
64
|
+
edges=edges,
|
|
65
|
+
depth=max_depth,
|
|
66
|
+
cycle_nodes=cycles,
|
|
67
|
+
truncated=truncated,
|
|
68
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from __future__ import annotations
|