docpull 6.5.0__tar.gz → 6.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- docpull-6.5.2/PKG-INFO +279 -0
- docpull-6.5.2/README.md +153 -0
- {docpull-6.5.0 → docpull-6.5.2}/pyproject.toml +15 -12
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/__init__.py +1 -1
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/convert.py +36 -0
- docpull-6.5.2/src/docpull.egg-info/PKG-INFO +279 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull.egg-info/requires.txt +11 -11
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_ci_policy.py +27 -2
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_convert_step_new.py +11 -1
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_surface_contract.py +1 -1
- docpull-6.5.0/PKG-INFO +0 -843
- docpull-6.5.0/README.md +0 -717
- docpull-6.5.0/src/docpull.egg-info/PKG-INFO +0 -843
- {docpull-6.5.0 → docpull-6.5.2}/LICENSE +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/setup.cfg +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/__main__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/accounting.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/acquisition_workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/agent_publish.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/auth_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/basis.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/benchmark.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/cache/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/cache/frontier.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/cache/manager.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/cache/streaming_dedup.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/change_events.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_aliases.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_ci.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/_legacy_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/brand.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/common.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/dataset.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/feed.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/openapi.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/package.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/paper.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/policy_pack.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/product.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/relationship.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/repo.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/schema_extract.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/search.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/standards.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/styleguide.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/transcript.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/typed.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/typed_models.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/visuals.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/website.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/wiki.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/context_packs/workflow_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/contracts.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/contracts_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/article_cleanup.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/chunking.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/ensemble.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/extractor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/filings.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/markdown.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/protocols.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/special_cases.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/conversion/trafilatura_extractor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/core/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/core/fetcher.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/_fetch.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/composite.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/contracts.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/crawler.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/filters.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/link_extractors/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/link_extractors/enhanced.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/link_extractors/protocols.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/link_extractors/static.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/protocols.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery/sitemap.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/discovery_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/doctor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/document_parse.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/document_worker.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/eval_grade.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/evidence.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/evidence_pack.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/export_formats.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/exports.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/fixtures/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/fixtures/parallel-search-extract.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/free_core.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/free_core_smoke.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/graph.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/hosted.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/http/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/http/client.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/http/protocols.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/http/rate_limiter.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/integrations/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/integrations/_records.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/integrations/langchain.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/integrations/llamaindex.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/judge.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/llm_client.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/local_workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/mcp/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/mcp/server.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/mcp/sources.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/mcp/tools.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/metadata_extractor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/models/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/models/config.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/models/document.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/models/events.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/models/profiles.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/models/run.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/models/schema.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/monitor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/native_integrations.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/output_contract.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pack_reader.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pack_tools.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/parallel_workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/parity.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/parity_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/passk.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/base.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/manifest.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/chunk.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/dedup.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/fetch.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/metadata.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/render.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/save.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/save_json.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/save_ndjson.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/save_okf.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/save_sqlite.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/screen.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/pipeline/steps/validate.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/policy.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/policy_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/project.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/provenance.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/provider_adapters.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/provider_capabilities.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/provider_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/provider_keys.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/provider_probes.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/py.typed +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/redaction.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/rendering.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/artifact-manifest.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/basis.v2.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/change-event.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/citation-map.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/document.v3.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/intelligence-bundle.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/pack.v3.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/provenance.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/relationship-pack.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/rights.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/run-identity.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/website-snapshot.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/workflow-request.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/schemas/workflow-result.v1.schema.json +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/scraper.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/security/__init__.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/security/download_policy.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/security/injection.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/security/optout.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/security/robots.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/security/url_validator.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/server.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/share.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/skill_export.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/source_scoring.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/surface.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/time_utils.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/warc.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull/workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull.egg-info/SOURCES.txt +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull.egg-info/dependency_links.txt +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull.egg-info/entry_points.txt +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/src/docpull.egg-info/top_level.txt +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_accounting.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_acquisition_workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_archive_discovery.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_auth_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_basis.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_benchmark.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_cache_conditional_get.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_chunking.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_claim_audit_script.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_context_ci.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_context_packs.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_conversion.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_discovery.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_discovery_contracts.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_doctor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_document_parse.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_document_record.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_evidence_pack.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_exports.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_extractor_ensemble.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_feed_pack.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_free_core.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_frontier_resume.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_graph.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_hosted.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_http_efficiency.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_import_efficiency.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_injection_screen.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_integration.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_integrations.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_judge.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_link_extractors.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_live_web_smoke.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_llm_extract.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_local_pack_workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_local_workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_mcp_server.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_mcp_tools.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_metadata_extractor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_monitor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_naming.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_native_integrations.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_openapi_pack.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_optional_extras_installed.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_optout.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_output_contract.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_outputs_e2e.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_pack_server.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_pack_tools.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_parallel_workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_parity_workflows.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_passk.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_pipeline.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_policy.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_policy_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_project.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_provenance.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_provider_adapters.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_provider_cli.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_provider_keys.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_provider_probes.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_public_feature_smoke.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_qa_judge.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_rate_limiter.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_real_feature_smoke_script.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_real_site_regressions.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_relationship_workflow.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_release_a_plus_check_script.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_rendering.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_reproducible_release_build.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_save_ndjson.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_save_sqlite.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_security_hardening.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_share.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_source_scoring.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_special_cases.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_time_utils.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_token_metrics.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_trafilatura_extractor.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_typed_knowledge_packs.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_warc.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_website_snapshot.py +0 -0
- {docpull-6.5.0 → docpull-6.5.2}/tests/test_workflow_contracts.py +0 -0
docpull-6.5.2/PKG-INFO
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: docpull
|
|
3
|
+
Version: 6.5.2
|
|
4
|
+
Summary: Declare, sync, diff, and lock context dependencies for AI agents
|
|
5
|
+
Author-email: Zachary Roth <support@raintree.technology>
|
|
6
|
+
Maintainer-email: Raintree Technology <support@raintree.technology>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/raintree-technology/docpull
|
|
9
|
+
Project-URL: Documentation, https://github.com/raintree-technology/docpull#readme
|
|
10
|
+
Project-URL: Repository, https://github.com/raintree-technology/docpull
|
|
11
|
+
Project-URL: Source Code, https://github.com/raintree-technology/docpull
|
|
12
|
+
Project-URL: Bug Tracker, https://github.com/raintree-technology/docpull/issues
|
|
13
|
+
Project-URL: Releases, https://github.com/raintree-technology/docpull/releases
|
|
14
|
+
Project-URL: MCP Plugin, https://github.com/raintree-technology/docpull/tree/main/plugin
|
|
15
|
+
Project-URL: Comparison Guide, https://github.com/raintree-technology/docpull/blob/main/docs/alternatives.md
|
|
16
|
+
Project-URL: Download Stats, https://pepy.tech/project/docpull
|
|
17
|
+
Project-URL: Changelog, https://github.com/raintree-technology/docpull/blob/main/docs/CHANGELOG.md
|
|
18
|
+
Keywords: python,markdown,documentation,web,website,web-extraction,web-to-markdown,source-ingestion,provenance,context-ci,content-extraction,developer-tools,cli,rag,llm,mcp,ai-agents,context-engineering,context-dependencies,context-packs,source-packs,research,claude,ai-training-data
|
|
19
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
20
|
+
Classifier: Intended Audience :: Developers
|
|
21
|
+
Classifier: Intended Audience :: Information Technology
|
|
22
|
+
Classifier: Intended Audience :: Science/Research
|
|
23
|
+
Classifier: Intended Audience :: Education
|
|
24
|
+
Classifier: Environment :: Console
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
|
|
26
|
+
Classifier: Topic :: Text Processing :: Markup :: HTML
|
|
27
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
28
|
+
Classifier: Topic :: Utilities
|
|
29
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
30
|
+
Classifier: Natural Language :: English
|
|
31
|
+
Classifier: Operating System :: OS Independent
|
|
32
|
+
Classifier: Programming Language :: Python :: 3
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
38
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
39
|
+
Classifier: Typing :: Typed
|
|
40
|
+
Requires-Python: >=3.10
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
License-File: LICENSE
|
|
43
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
44
|
+
Requires-Dist: html2text>=2020.1.16
|
|
45
|
+
Requires-Dist: defusedxml>=0.7.1
|
|
46
|
+
Requires-Dist: extruct>=0.15.0
|
|
47
|
+
Requires-Dist: aiohttp>=3.14.3
|
|
48
|
+
Requires-Dist: idna>=3.15
|
|
49
|
+
Requires-Dist: regex>=2024.11.6
|
|
50
|
+
Requires-Dist: rich>=13.0.0
|
|
51
|
+
Requires-Dist: pyyaml>=6.0
|
|
52
|
+
Requires-Dist: pydantic>=2.0
|
|
53
|
+
Requires-Dist: urllib3>=2.7.0
|
|
54
|
+
Provides-Extra: proxy
|
|
55
|
+
Requires-Dist: aiohttp-socks>=0.11.0; extra == "proxy"
|
|
56
|
+
Provides-Extra: normalize
|
|
57
|
+
Requires-Dist: url-normalize>=1.4.0; extra == "normalize"
|
|
58
|
+
Provides-Extra: trafilatura
|
|
59
|
+
Requires-Dist: trafilatura>=1.12.0; extra == "trafilatura"
|
|
60
|
+
Provides-Extra: tokens
|
|
61
|
+
Requires-Dist: tiktoken>=0.7.0; extra == "tokens"
|
|
62
|
+
Provides-Extra: mcp
|
|
63
|
+
Requires-Dist: cryptography>=50.0.0; extra == "mcp"
|
|
64
|
+
Requires-Dist: mcp<2,>=1.28.1; extra == "mcp"
|
|
65
|
+
Requires-Dist: pydantic-settings>=2.14.2; extra == "mcp"
|
|
66
|
+
Requires-Dist: pyjwt>=2.13.0; extra == "mcp"
|
|
67
|
+
Requires-Dist: python-multipart>=0.0.27; extra == "mcp"
|
|
68
|
+
Requires-Dist: starlette>=1.3.1; extra == "mcp"
|
|
69
|
+
Provides-Extra: serve
|
|
70
|
+
Requires-Dist: uvicorn>=0.30.0; extra == "serve"
|
|
71
|
+
Provides-Extra: parquet
|
|
72
|
+
Requires-Dist: pyarrow>=16.0.0; extra == "parquet"
|
|
73
|
+
Provides-Extra: markitdown
|
|
74
|
+
Requires-Dist: pypdf>=6.15.0; extra == "markitdown"
|
|
75
|
+
Requires-Dist: markitdown[docx,pdf]>=0.1.0; extra == "markitdown"
|
|
76
|
+
Provides-Extra: unstructured
|
|
77
|
+
Requires-Dist: pypdf>=6.15.0; extra == "unstructured"
|
|
78
|
+
Requires-Dist: unstructured[all-docs]>=0.16.0; extra == "unstructured"
|
|
79
|
+
Provides-Extra: pdf
|
|
80
|
+
Requires-Dist: pypdf>=6.15.0; extra == "pdf"
|
|
81
|
+
Provides-Extra: parse
|
|
82
|
+
Requires-Dist: pypdf>=6.15.0; extra == "parse"
|
|
83
|
+
Requires-Dist: markitdown[docx,pdf]>=0.1.0; extra == "parse"
|
|
84
|
+
Requires-Dist: unstructured[all-docs]>=0.16.0; extra == "parse"
|
|
85
|
+
Provides-Extra: presidio
|
|
86
|
+
Requires-Dist: presidio-analyzer>=2.2.0; extra == "presidio"
|
|
87
|
+
Provides-Extra: provenance
|
|
88
|
+
Requires-Dist: cryptography>=50.0.0; extra == "provenance"
|
|
89
|
+
Provides-Extra: e2b
|
|
90
|
+
Requires-Dist: e2b>=2.0.0; extra == "e2b"
|
|
91
|
+
Provides-Extra: llm
|
|
92
|
+
Requires-Dist: tiktoken>=0.7.0; extra == "llm"
|
|
93
|
+
Provides-Extra: all
|
|
94
|
+
Requires-Dist: aiohttp-socks>=0.11.0; extra == "all"
|
|
95
|
+
Requires-Dist: url-normalize>=1.4.0; extra == "all"
|
|
96
|
+
Requires-Dist: trafilatura>=1.12.0; extra == "all"
|
|
97
|
+
Requires-Dist: tiktoken>=0.7.0; extra == "all"
|
|
98
|
+
Requires-Dist: cryptography>=50.0.0; extra == "all"
|
|
99
|
+
Requires-Dist: mcp<2,>=1.28.1; extra == "all"
|
|
100
|
+
Requires-Dist: pydantic-settings>=2.14.2; extra == "all"
|
|
101
|
+
Requires-Dist: pyjwt>=2.13.0; extra == "all"
|
|
102
|
+
Requires-Dist: python-multipart>=0.0.27; extra == "all"
|
|
103
|
+
Requires-Dist: starlette>=1.3.1; extra == "all"
|
|
104
|
+
Requires-Dist: uvicorn>=0.30.0; extra == "all"
|
|
105
|
+
Requires-Dist: pyarrow>=16.0.0; extra == "all"
|
|
106
|
+
Requires-Dist: pypdf>=6.15.0; extra == "all"
|
|
107
|
+
Requires-Dist: markitdown[docx,pdf]>=0.1.0; extra == "all"
|
|
108
|
+
Requires-Dist: unstructured[all-docs]>=0.16.0; extra == "all"
|
|
109
|
+
Requires-Dist: presidio-analyzer>=2.2.0; extra == "all"
|
|
110
|
+
Requires-Dist: e2b>=2.0.0; extra == "all"
|
|
111
|
+
Provides-Extra: dev
|
|
112
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
113
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
114
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
115
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
116
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
117
|
+
Requires-Dist: bandit>=1.7.0; extra == "dev"
|
|
118
|
+
Requires-Dist: pip-audit>=2.0.0; extra == "dev"
|
|
119
|
+
Requires-Dist: msgpack>=1.2.1; extra == "dev"
|
|
120
|
+
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
|
|
121
|
+
Requires-Dist: types-requests>=2.31.0; extra == "dev"
|
|
122
|
+
Requires-Dist: types-beautifulsoup4>=4.12.0; extra == "dev"
|
|
123
|
+
Requires-Dist: types-defusedxml>=0.7.0; extra == "dev"
|
|
124
|
+
Requires-Dist: types-pyyaml>=6.0.0; extra == "dev"
|
|
125
|
+
Dynamic: license-file
|
|
126
|
+
|
|
127
|
+
<p align="center">
|
|
128
|
+
<img src="https://raw.githubusercontent.com/raintree-technology/docpull/main/docs/launch-assets/logo-square-light-400.png" alt="DocPull" width="128" />
|
|
129
|
+
</p>
|
|
130
|
+
|
|
131
|
+
# DocPull
|
|
132
|
+
|
|
133
|
+
<!-- project-record: docpull -->
|
|
134
|
+
|
|
135
|
+
**Active open-source project · MIT License**
|
|
136
|
+
|
|
137
|
+
DocPull turns changing public web sources into cited, reproducible context for AI
|
|
138
|
+
agents and retrieval pipelines. Use it when your application needs to know which
|
|
139
|
+
sources it used, whether they changed, and how to rebuild the same context later.
|
|
140
|
+
|
|
141
|
+
[](https://www.python.org/downloads/)
|
|
142
|
+
[](https://pypi.org/project/docpull/)
|
|
143
|
+
[](LICENSE)
|
|
144
|
+
|
|
145
|
+
<!-- mcp-name: io.github.raintree-technology/docpull -->
|
|
146
|
+
|
|
147
|
+
## Install and sync your first source
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
pip install docpull
|
|
151
|
+
docpull init stripe-docs
|
|
152
|
+
docpull add https://docs.stripe.com
|
|
153
|
+
docpull sync
|
|
154
|
+
docpull diff
|
|
155
|
+
docpull export context-pack --target cursor
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The project stores declared sources in `docpull.yaml` and resolved inputs in
|
|
159
|
+
`.docpull/context.lock.json`. Later syncs produce a hash-based diff while preserving
|
|
160
|
+
source URLs, content hashes, run IDs, citations, and export metadata.
|
|
161
|
+
|
|
162
|
+

|
|
163
|
+
|
|
164
|
+
No account or paid API is required for this path. Direct fetching, discovery,
|
|
165
|
+
extraction, indexing, pack analysis, and diffs run locally.
|
|
166
|
+
|
|
167
|
+
## Why use DocPull
|
|
168
|
+
|
|
169
|
+
- **Reproduce agent context.** Stable IDs, hashes, manifests, and lockfiles show which
|
|
170
|
+
source versions produced an answer or artifact.
|
|
171
|
+
- **Detect source drift.** Sync and diff documentation, product pages, policies,
|
|
172
|
+
feeds, repositories, packages, standards, and local documents.
|
|
173
|
+
- **Keep evidence inspectable.** Markdown, NDJSON, SQLite, citations, and provenance
|
|
174
|
+
sidecars remain readable without a hosted service.
|
|
175
|
+
- **Choose the downstream surface.** Export context for agent clients, vector import,
|
|
176
|
+
data workflows, or a versioned context-pack release.
|
|
177
|
+
- **Keep expensive routes explicit.** Browser and cloud rendering require an explicit
|
|
178
|
+
choice and can be blocked with a zero-dollar budget.
|
|
179
|
+
|
|
180
|
+
## How it works
|
|
181
|
+
|
|
182
|
+
```text
|
|
183
|
+
declared sources → local acquisition → versioned evidence → diff and validation → export
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
DocPull's v3 pack contract separates raw extraction, agent-ready context, and
|
|
187
|
+
eval-grade evidence. Validate the level a downstream system requires:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
docpull pack prepare packs/docs --eval-grade
|
|
191
|
+
docpull pack validate packs/docs --level eval
|
|
192
|
+
docpull ci --prepare
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
`docpull ci` checks freshness, citation coverage, pack quality, rights metadata, and
|
|
196
|
+
other configured gates. It writes `context-ci.report.json` and `CONTEXT_CI.md`, then
|
|
197
|
+
exits non-zero when a hard gate fails.
|
|
198
|
+
|
|
199
|
+
## Supported surfaces
|
|
200
|
+
|
|
201
|
+
| Surface | Use it for | Start here |
|
|
202
|
+
| --- | --- | --- |
|
|
203
|
+
| CLI | Fetch, sync, diff, validate, and export | [`docs/cli-recipes.md`](docs/cli-recipes.md) |
|
|
204
|
+
| Python SDK | Embed acquisition in Python applications | [`docs/surface-contract.md`](docs/surface-contract.md) |
|
|
205
|
+
| MCP server | Give local agent clients source tools | [MCP server](#mcp-server) |
|
|
206
|
+
| TypeScript SDK | Read local packs and invoke the CLI from Node or Bun | [`sdk/js/README.md`](sdk/js/README.md) |
|
|
207
|
+
| Agent plugin | Install the supported MCP workflow in an agent client | [`plugin/README.md`](plugin/README.md) |
|
|
208
|
+
|
|
209
|
+
Common source shapes include static and server-rendered websites, OpenAPI documents,
|
|
210
|
+
feeds, papers, public GitHub repositories, npm and PyPI packages, standards, datasets,
|
|
211
|
+
transcripts, Wikimedia pages, product and policy pages, and local PDF or office files.
|
|
212
|
+
See [context-pack workflows](docs/context-packs.md) for the complete surface.
|
|
213
|
+
|
|
214
|
+
## MCP server
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
pip install 'docpull[mcp]'
|
|
218
|
+
docpull mcp
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Claude Code can register the same local server:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
claude mcp add --transport stdio docpull -- docpull mcp
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The Python stdio server is the supported release path. The TypeScript code formerly
|
|
228
|
+
documented under `mcp/` is an [internal semantic-search lab](docs/internal-mcp-lab.md),
|
|
229
|
+
not part of the package contract.
|
|
230
|
+
|
|
231
|
+
## Limits and security boundary
|
|
232
|
+
|
|
233
|
+
DocPull is an evidence-acquisition engine, not a hosted competitive-intelligence
|
|
234
|
+
product. It owns fetching, explicit rendering adapters, versioning, citations,
|
|
235
|
+
hashing, validation, replay, and export. Downstream products own scheduling, human
|
|
236
|
+
review, approved claims, legal conclusions, accounts, and notifications.
|
|
237
|
+
|
|
238
|
+
The default path does not handle complex interactive browser workflows, CAPTCHAs,
|
|
239
|
+
stealth scraping, or private dashboards. JavaScript rendering is explicit. Authenticated
|
|
240
|
+
sources require environment-variable references; DocPull does not persist credential
|
|
241
|
+
values in project artifacts.
|
|
242
|
+
|
|
243
|
+
Security defaults include HTTPS-only fetching, robots.txt compliance, SSRF and DNS
|
|
244
|
+
rebinding protections, redirect guards, XXE protection, and path-traversal checks. Read
|
|
245
|
+
the [web-source boundary](docs/scraping-boundary.md), [security posture](docs/compliance.md),
|
|
246
|
+
and [evidence-engine decision](docs/adr/0001-evidence-acquisition-engine.md) before
|
|
247
|
+
extending acquisition behavior.
|
|
248
|
+
|
|
249
|
+
## Documentation and evidence
|
|
250
|
+
|
|
251
|
+
- [CLI recipes](docs/cli-recipes.md) — Common commands and advanced workflows.
|
|
252
|
+
- [Context dependencies](docs/context-dependencies.md) — Project and lockfile model.
|
|
253
|
+
- [Context Pack Contract v3](docs/context-pack-contract-v3.md) — Artifact levels and compatibility.
|
|
254
|
+
- [Public contracts](docs/contracts.md) — Schemas and versioning rules.
|
|
255
|
+
- [Alternatives](docs/alternatives.md) — Browser automation and hosted extraction tradeoffs.
|
|
256
|
+
- [Evaluation lab](bench/docs/index.md) — Reproducible methods, results, and claim boundaries.
|
|
257
|
+
- [Changelog](docs/CHANGELOG.md) — Release history.
|
|
258
|
+
|
|
259
|
+
## Raintree open-source system
|
|
260
|
+
|
|
261
|
+
DocPull owns evidence acquisition and reproducible agent context. It can be used
|
|
262
|
+
independently; the sibling projects do not imply a required integration or shared
|
|
263
|
+
release cycle.
|
|
264
|
+
|
|
265
|
+
| Project | Responsibility |
|
|
266
|
+
| --- | --- |
|
|
267
|
+
| [Raintree Standards](https://github.com/raintree-technology/raintree.standards) | Defines governed requirements and evidence. |
|
|
268
|
+
| [Trellis](https://github.com/raintree-technology/trellis) | Enforces shared JavaScript and TypeScript code policy. |
|
|
269
|
+
| [HIG Doctor](https://github.com/raintree-technology/hig-doctor) | Audits interface source and provides HIG guidance. |
|
|
270
|
+
| [PolicyStrata](https://github.com/raintree-technology/policystrata) | Tests cross-layer policy behavior. |
|
|
271
|
+
|
|
272
|
+
See the [Raintree open-source portfolio](https://raintree.technology/portfolio#open-source)
|
|
273
|
+
for current lifecycle and distribution links.
|
|
274
|
+
|
|
275
|
+
## Project policies
|
|
276
|
+
|
|
277
|
+
[Contributing](CONTRIBUTING.md) · [Code of Conduct](CODE_OF_CONDUCT.md) · [Security](SECURITY.md) ·
|
|
278
|
+
[Metrics and evidence limits](METRICS.md) · [Source repository](https://github.com/raintree-technology/docpull) ·
|
|
279
|
+
[MIT License](LICENSE)
|
docpull-6.5.2/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/raintree-technology/docpull/main/docs/launch-assets/logo-square-light-400.png" alt="DocPull" width="128" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# DocPull
|
|
6
|
+
|
|
7
|
+
<!-- project-record: docpull -->
|
|
8
|
+
|
|
9
|
+
**Active open-source project · MIT License**
|
|
10
|
+
|
|
11
|
+
DocPull turns changing public web sources into cited, reproducible context for AI
|
|
12
|
+
agents and retrieval pipelines. Use it when your application needs to know which
|
|
13
|
+
sources it used, whether they changed, and how to rebuild the same context later.
|
|
14
|
+
|
|
15
|
+
[](https://www.python.org/downloads/)
|
|
16
|
+
[](https://pypi.org/project/docpull/)
|
|
17
|
+
[](LICENSE)
|
|
18
|
+
|
|
19
|
+
<!-- mcp-name: io.github.raintree-technology/docpull -->
|
|
20
|
+
|
|
21
|
+
## Install and sync your first source
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install docpull
|
|
25
|
+
docpull init stripe-docs
|
|
26
|
+
docpull add https://docs.stripe.com
|
|
27
|
+
docpull sync
|
|
28
|
+
docpull diff
|
|
29
|
+
docpull export context-pack --target cursor
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The project stores declared sources in `docpull.yaml` and resolved inputs in
|
|
33
|
+
`.docpull/context.lock.json`. Later syncs produce a hash-based diff while preserving
|
|
34
|
+
source URLs, content hashes, run IDs, citations, and export metadata.
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
No account or paid API is required for this path. Direct fetching, discovery,
|
|
39
|
+
extraction, indexing, pack analysis, and diffs run locally.
|
|
40
|
+
|
|
41
|
+
## Why use DocPull
|
|
42
|
+
|
|
43
|
+
- **Reproduce agent context.** Stable IDs, hashes, manifests, and lockfiles show which
|
|
44
|
+
source versions produced an answer or artifact.
|
|
45
|
+
- **Detect source drift.** Sync and diff documentation, product pages, policies,
|
|
46
|
+
feeds, repositories, packages, standards, and local documents.
|
|
47
|
+
- **Keep evidence inspectable.** Markdown, NDJSON, SQLite, citations, and provenance
|
|
48
|
+
sidecars remain readable without a hosted service.
|
|
49
|
+
- **Choose the downstream surface.** Export context for agent clients, vector import,
|
|
50
|
+
data workflows, or a versioned context-pack release.
|
|
51
|
+
- **Keep expensive routes explicit.** Browser and cloud rendering require an explicit
|
|
52
|
+
choice and can be blocked with a zero-dollar budget.
|
|
53
|
+
|
|
54
|
+
## How it works
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
declared sources → local acquisition → versioned evidence → diff and validation → export
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
DocPull's v3 pack contract separates raw extraction, agent-ready context, and
|
|
61
|
+
eval-grade evidence. Validate the level a downstream system requires:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
docpull pack prepare packs/docs --eval-grade
|
|
65
|
+
docpull pack validate packs/docs --level eval
|
|
66
|
+
docpull ci --prepare
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`docpull ci` checks freshness, citation coverage, pack quality, rights metadata, and
|
|
70
|
+
other configured gates. It writes `context-ci.report.json` and `CONTEXT_CI.md`, then
|
|
71
|
+
exits non-zero when a hard gate fails.
|
|
72
|
+
|
|
73
|
+
## Supported surfaces
|
|
74
|
+
|
|
75
|
+
| Surface | Use it for | Start here |
|
|
76
|
+
| --- | --- | --- |
|
|
77
|
+
| CLI | Fetch, sync, diff, validate, and export | [`docs/cli-recipes.md`](docs/cli-recipes.md) |
|
|
78
|
+
| Python SDK | Embed acquisition in Python applications | [`docs/surface-contract.md`](docs/surface-contract.md) |
|
|
79
|
+
| MCP server | Give local agent clients source tools | [MCP server](#mcp-server) |
|
|
80
|
+
| TypeScript SDK | Read local packs and invoke the CLI from Node or Bun | [`sdk/js/README.md`](sdk/js/README.md) |
|
|
81
|
+
| Agent plugin | Install the supported MCP workflow in an agent client | [`plugin/README.md`](plugin/README.md) |
|
|
82
|
+
|
|
83
|
+
Common source shapes include static and server-rendered websites, OpenAPI documents,
|
|
84
|
+
feeds, papers, public GitHub repositories, npm and PyPI packages, standards, datasets,
|
|
85
|
+
transcripts, Wikimedia pages, product and policy pages, and local PDF or office files.
|
|
86
|
+
See [context-pack workflows](docs/context-packs.md) for the complete surface.
|
|
87
|
+
|
|
88
|
+
## MCP server
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install 'docpull[mcp]'
|
|
92
|
+
docpull mcp
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Claude Code can register the same local server:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
claude mcp add --transport stdio docpull -- docpull mcp
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The Python stdio server is the supported release path. The TypeScript code formerly
|
|
102
|
+
documented under `mcp/` is an [internal semantic-search lab](docs/internal-mcp-lab.md),
|
|
103
|
+
not part of the package contract.
|
|
104
|
+
|
|
105
|
+
## Limits and security boundary
|
|
106
|
+
|
|
107
|
+
DocPull is an evidence-acquisition engine, not a hosted competitive-intelligence
|
|
108
|
+
product. It owns fetching, explicit rendering adapters, versioning, citations,
|
|
109
|
+
hashing, validation, replay, and export. Downstream products own scheduling, human
|
|
110
|
+
review, approved claims, legal conclusions, accounts, and notifications.
|
|
111
|
+
|
|
112
|
+
The default path does not handle complex interactive browser workflows, CAPTCHAs,
|
|
113
|
+
stealth scraping, or private dashboards. JavaScript rendering is explicit. Authenticated
|
|
114
|
+
sources require environment-variable references; DocPull does not persist credential
|
|
115
|
+
values in project artifacts.
|
|
116
|
+
|
|
117
|
+
Security defaults include HTTPS-only fetching, robots.txt compliance, SSRF and DNS
|
|
118
|
+
rebinding protections, redirect guards, XXE protection, and path-traversal checks. Read
|
|
119
|
+
the [web-source boundary](docs/scraping-boundary.md), [security posture](docs/compliance.md),
|
|
120
|
+
and [evidence-engine decision](docs/adr/0001-evidence-acquisition-engine.md) before
|
|
121
|
+
extending acquisition behavior.
|
|
122
|
+
|
|
123
|
+
## Documentation and evidence
|
|
124
|
+
|
|
125
|
+
- [CLI recipes](docs/cli-recipes.md) — Common commands and advanced workflows.
|
|
126
|
+
- [Context dependencies](docs/context-dependencies.md) — Project and lockfile model.
|
|
127
|
+
- [Context Pack Contract v3](docs/context-pack-contract-v3.md) — Artifact levels and compatibility.
|
|
128
|
+
- [Public contracts](docs/contracts.md) — Schemas and versioning rules.
|
|
129
|
+
- [Alternatives](docs/alternatives.md) — Browser automation and hosted extraction tradeoffs.
|
|
130
|
+
- [Evaluation lab](bench/docs/index.md) — Reproducible methods, results, and claim boundaries.
|
|
131
|
+
- [Changelog](docs/CHANGELOG.md) — Release history.
|
|
132
|
+
|
|
133
|
+
## Raintree open-source system
|
|
134
|
+
|
|
135
|
+
DocPull owns evidence acquisition and reproducible agent context. It can be used
|
|
136
|
+
independently; the sibling projects do not imply a required integration or shared
|
|
137
|
+
release cycle.
|
|
138
|
+
|
|
139
|
+
| Project | Responsibility |
|
|
140
|
+
| --- | --- |
|
|
141
|
+
| [Raintree Standards](https://github.com/raintree-technology/raintree.standards) | Defines governed requirements and evidence. |
|
|
142
|
+
| [Trellis](https://github.com/raintree-technology/trellis) | Enforces shared JavaScript and TypeScript code policy. |
|
|
143
|
+
| [HIG Doctor](https://github.com/raintree-technology/hig-doctor) | Audits interface source and provides HIG guidance. |
|
|
144
|
+
| [PolicyStrata](https://github.com/raintree-technology/policystrata) | Tests cross-layer policy behavior. |
|
|
145
|
+
|
|
146
|
+
See the [Raintree open-source portfolio](https://raintree.technology/portfolio#open-source)
|
|
147
|
+
for current lifecycle and distribution links.
|
|
148
|
+
|
|
149
|
+
## Project policies
|
|
150
|
+
|
|
151
|
+
[Contributing](CONTRIBUTING.md) · [Code of Conduct](CODE_OF_CONDUCT.md) · [Security](SECURITY.md) ·
|
|
152
|
+
[Metrics and evidence limits](METRICS.md) · [Source repository](https://github.com/raintree-technology/docpull) ·
|
|
153
|
+
[MIT License](LICENSE)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "docpull"
|
|
7
|
-
version = "6.5.
|
|
7
|
+
version = "6.5.2"
|
|
8
8
|
dynamic = []
|
|
9
9
|
description = "Declare, sync, diff, and lock context dependencies for AI agents"
|
|
10
10
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
@@ -86,7 +86,7 @@ dependencies = [
|
|
|
86
86
|
"html2text>=2020.1.16",
|
|
87
87
|
"defusedxml>=0.7.1",
|
|
88
88
|
"extruct>=0.15.0",
|
|
89
|
-
"aiohttp>=3.14.
|
|
89
|
+
"aiohttp>=3.14.3", # Security floor for the 2026 request-parsing advisories
|
|
90
90
|
"idna>=3.15", # Security floor for transitive URL/IDNA handling; Renovate raises as needed
|
|
91
91
|
"regex>=2024.11.6",
|
|
92
92
|
"rich>=13.0.0",
|
|
@@ -109,8 +109,8 @@ tokens = [
|
|
|
109
109
|
"tiktoken>=0.7.0",
|
|
110
110
|
]
|
|
111
111
|
mcp = [
|
|
112
|
-
"cryptography>=
|
|
113
|
-
"mcp>=1.28.1",
|
|
112
|
+
"cryptography>=50.0.0",
|
|
113
|
+
"mcp>=1.28.1,<2",
|
|
114
114
|
"pydantic-settings>=2.14.2",
|
|
115
115
|
"pyjwt>=2.13.0",
|
|
116
116
|
"python-multipart>=0.0.27",
|
|
@@ -123,18 +123,18 @@ parquet = [
|
|
|
123
123
|
"pyarrow>=16.0.0",
|
|
124
124
|
]
|
|
125
125
|
markitdown = [
|
|
126
|
-
"pypdf>=6.
|
|
126
|
+
"pypdf>=6.15.0",
|
|
127
127
|
"markitdown[docx,pdf]>=0.1.0",
|
|
128
128
|
]
|
|
129
129
|
unstructured = [
|
|
130
|
-
"pypdf>=6.
|
|
130
|
+
"pypdf>=6.15.0",
|
|
131
131
|
"unstructured[all-docs]>=0.16.0",
|
|
132
132
|
]
|
|
133
133
|
pdf = [
|
|
134
|
-
"pypdf>=6.
|
|
134
|
+
"pypdf>=6.15.0",
|
|
135
135
|
]
|
|
136
136
|
parse = [
|
|
137
|
-
"pypdf>=6.
|
|
137
|
+
"pypdf>=6.15.0",
|
|
138
138
|
"markitdown[docx,pdf]>=0.1.0",
|
|
139
139
|
"unstructured[all-docs]>=0.16.0",
|
|
140
140
|
]
|
|
@@ -142,7 +142,7 @@ presidio = [
|
|
|
142
142
|
"presidio-analyzer>=2.2.0",
|
|
143
143
|
]
|
|
144
144
|
provenance = [
|
|
145
|
-
"cryptography>=
|
|
145
|
+
"cryptography>=50.0.0",
|
|
146
146
|
]
|
|
147
147
|
e2b = [
|
|
148
148
|
"e2b>=2.0.0",
|
|
@@ -155,15 +155,15 @@ all = [
|
|
|
155
155
|
"url-normalize>=1.4.0",
|
|
156
156
|
"trafilatura>=1.12.0",
|
|
157
157
|
"tiktoken>=0.7.0",
|
|
158
|
-
"cryptography>=
|
|
159
|
-
"mcp>=1.28.1",
|
|
158
|
+
"cryptography>=50.0.0",
|
|
159
|
+
"mcp>=1.28.1,<2",
|
|
160
160
|
"pydantic-settings>=2.14.2",
|
|
161
161
|
"pyjwt>=2.13.0",
|
|
162
162
|
"python-multipart>=0.0.27",
|
|
163
163
|
"starlette>=1.3.1",
|
|
164
164
|
"uvicorn>=0.30.0",
|
|
165
165
|
"pyarrow>=16.0.0",
|
|
166
|
-
"pypdf>=6.
|
|
166
|
+
"pypdf>=6.15.0",
|
|
167
167
|
"markitdown[docx,pdf]>=0.1.0",
|
|
168
168
|
"unstructured[all-docs]>=0.16.0",
|
|
169
169
|
"presidio-analyzer>=2.2.0",
|
|
@@ -207,6 +207,9 @@ include = ["docpull*"]
|
|
|
207
207
|
[tool.setuptools.package-data]
|
|
208
208
|
docpull = ["py.typed", "fixtures/*.json", "schemas/*.schema.json"]
|
|
209
209
|
|
|
210
|
+
[tool.uv]
|
|
211
|
+
constraint-dependencies = ["h2>=4.4.1"]
|
|
212
|
+
|
|
210
213
|
[tool.ruff]
|
|
211
214
|
line-length = 110
|
|
212
215
|
target-version = "py310"
|
|
@@ -58,6 +58,28 @@ _FRONTMATTER_METADATA_KEYS: tuple[str, ...] = (
|
|
|
58
58
|
# outline. Code fences are also excluded — see _extract_headings below.
|
|
59
59
|
_HEADING_LINE_RE = re.compile(r"^(#{1,6})\s+(.+?)\s*#*\s*$")
|
|
60
60
|
|
|
61
|
+
_ACCESS_WALL_MARKERS: tuple[tuple[str, tuple[str, ...]], ...] = (
|
|
62
|
+
("bot_challenge", ("client challenge", "verify you are human", "checking your browser", "captcha")),
|
|
63
|
+
("auth_wall", ("sign in to continue", "log in to continue", "authentication required")),
|
|
64
|
+
("paywall", ("subscribe to continue", "subscription required", "purchase a subscription")),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def detect_access_wall(value: bytes | str) -> str | None:
|
|
69
|
+
"""Return a stable category for a short challenge, login, or paywall response."""
|
|
70
|
+
text = value.decode("utf-8", errors="replace") if isinstance(value, bytes) else value
|
|
71
|
+
normalized = re.sub(r"\s+", " ", text).casefold()
|
|
72
|
+
if len(normalized) > 50_000:
|
|
73
|
+
return None
|
|
74
|
+
for category, markers in _ACCESS_WALL_MARKERS:
|
|
75
|
+
if any(marker in normalized for marker in markers):
|
|
76
|
+
return category
|
|
77
|
+
if "enable javascript" in normalized and any(
|
|
78
|
+
marker in normalized for marker in ("proceed", "continue", "challenge", "access")
|
|
79
|
+
):
|
|
80
|
+
return "bot_challenge"
|
|
81
|
+
return None
|
|
82
|
+
|
|
61
83
|
|
|
62
84
|
def _extract_headings(markdown: str, max_level: int = 2, limit: int = 12) -> list[str]:
|
|
63
85
|
"""Pull a flat list of top-level headings from converted Markdown.
|
|
@@ -236,6 +258,13 @@ class ConvertStep:
|
|
|
236
258
|
return ctx
|
|
237
259
|
|
|
238
260
|
try:
|
|
261
|
+
access_wall = detect_access_wall(ctx.html)
|
|
262
|
+
if access_wall is not None:
|
|
263
|
+
ctx.mark_failed(f"access_wall:{access_wall}")
|
|
264
|
+
if emit:
|
|
265
|
+
emit(FetchEvent(type=EventType.FETCH_FAILED, url=ctx.url, error=ctx.error))
|
|
266
|
+
return ctx
|
|
267
|
+
|
|
239
268
|
optout = self._check_meta_robots(ctx)
|
|
240
269
|
if optout is not None:
|
|
241
270
|
reason = f"AI/TDM opt-out (meta robots: {', '.join(optout.matched)})"
|
|
@@ -301,6 +330,13 @@ class ConvertStep:
|
|
|
301
330
|
if looks_like_spa_output(markdown):
|
|
302
331
|
return self._handle_empty_content(ctx, emit)
|
|
303
332
|
|
|
333
|
+
access_wall = detect_access_wall(markdown)
|
|
334
|
+
if access_wall is not None:
|
|
335
|
+
ctx.mark_failed(f"access_wall:{access_wall}")
|
|
336
|
+
if emit:
|
|
337
|
+
emit(FetchEvent(type=EventType.FETCH_FAILED, url=ctx.url, error=ctx.error))
|
|
338
|
+
return ctx
|
|
339
|
+
|
|
304
340
|
markdown = clean_article_markdown(markdown, url=ctx.url, metadata=ctx.metadata)
|
|
305
341
|
headings, heading_count = _heading_summary(markdown)
|
|
306
342
|
|