docpull 4.3.0__tar.gz → 4.3.1__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-4.3.0/src/docpull.egg-info → docpull-4.3.1}/PKG-INFO +66 -35
- {docpull-4.3.0 → docpull-4.3.1}/README.md +57 -30
- {docpull-4.3.0 → docpull-4.3.1}/pyproject.toml +22 -6
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/__init__.py +1 -1
- {docpull-4.3.0 → docpull-4.3.1/src/docpull.egg-info}/PKG-INFO +66 -35
- {docpull-4.3.0 → docpull-4.3.1}/LICENSE +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/setup.cfg +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/__main__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/benchmark.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/cache/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/cache/frontier.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/cache/manager.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/cache/streaming_dedup.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/cli.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/conversion/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/conversion/chunking.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/conversion/extractor.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/conversion/markdown.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/conversion/protocols.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/conversion/special_cases.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/conversion/trafilatura_extractor.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/core/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/core/fetcher.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/_fetch.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/composite.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/crawler.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/filters.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/link_extractors/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/link_extractors/enhanced.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/link_extractors/protocols.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/link_extractors/static.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/protocols.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/discovery/sitemap.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/doctor.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/fixtures/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/fixtures/parallel-search-extract.json +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/http/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/http/client.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/http/protocols.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/http/rate_limiter.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/judge.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/mcp/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/mcp/server.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/mcp/sources.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/mcp/tools.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/metadata_extractor.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/models/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/models/config.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/models/document.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/models/events.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/models/profiles.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/models/run.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pack_tools.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/parallel_workflows.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/passk.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/base.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/manifest.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/chunk.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/convert.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/dedup.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/fetch.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/metadata.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/save.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/save_json.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/save_ndjson.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/save_okf.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/save_sqlite.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/pipeline/steps/validate.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/provider_cli.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/provider_keys.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/py.typed +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/scraper.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/security/__init__.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/security/download_policy.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/security/robots.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/security/url_validator.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/source_scoring.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull/time_utils.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull.egg-info/SOURCES.txt +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull.egg-info/dependency_links.txt +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull.egg-info/entry_points.txt +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull.egg-info/requires.txt +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/src/docpull.egg-info/top_level.txt +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_benchmark.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_cache_conditional_get.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_chunking.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_ci_policy.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_cli.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_conversion.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_convert_step_new.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_discovery.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_document_record.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_frontier_resume.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_integration.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_judge.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_link_extractors.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_mcp_server.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_mcp_tools.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_naming.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_outputs_e2e.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_pack_tools.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_parallel_workflows.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_passk.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_pipeline.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_provider_cli.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_real_site_regressions.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_save_ndjson.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_save_sqlite.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_security_hardening.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_special_cases.py +0 -0
- {docpull-4.3.0 → docpull-4.3.1}/tests/test_time_utils.py +0 -0
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docpull
|
|
3
|
-
Version: 4.3.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 4.3.1
|
|
4
|
+
Summary: Convert public web pages into clean Markdown for AI agents and RAG
|
|
5
5
|
Author-email: Zachary Roth <support@raintree.technology>
|
|
6
6
|
Maintainer-email: Raintree Technology <support@raintree.technology>
|
|
7
7
|
License-Expression: MIT
|
|
8
|
-
Project-URL: Homepage, https://
|
|
9
|
-
Project-URL: Documentation, https://
|
|
8
|
+
Project-URL: Homepage, https://docpull.raintree.technology
|
|
9
|
+
Project-URL: Documentation, https://docpull.raintree.technology
|
|
10
10
|
Project-URL: Repository, https://github.com/raintree-technology/docpull
|
|
11
11
|
Project-URL: Source Code, https://github.com/raintree-technology/docpull
|
|
12
12
|
Project-URL: Bug Tracker, https://github.com/raintree-technology/docpull/issues
|
|
13
13
|
Project-URL: Releases, https://github.com/raintree-technology/docpull/releases
|
|
14
|
-
|
|
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-scraping,web-crawler,crawler,developer-tools,cli,rag,llm,mcp,ai-agents,claude,ai-training-data
|
|
15
19
|
Classifier: Development Status :: 5 - Production/Stable
|
|
16
20
|
Classifier: Intended Audience :: Developers
|
|
17
21
|
Classifier: Intended Audience :: Information Technology
|
|
@@ -96,7 +100,7 @@ Dynamic: license-file
|
|
|
96
100
|
|
|
97
101
|
# docpull
|
|
98
102
|
|
|
99
|
-
**
|
|
103
|
+
**Public web to agent-ready Markdown. Fast, local, browser-free.**
|
|
100
104
|
|
|
101
105
|
[](https://www.python.org/downloads/)
|
|
102
106
|
[](https://badge.fury.io/py/docpull)
|
|
@@ -110,37 +114,35 @@ Dynamic: license-file
|
|
|
110
114
|
</a>
|
|
111
115
|
</p>
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
docpull is a Python CLI, SDK, and MCP server for pulling public static and
|
|
118
|
+
server-rendered web pages into clean Markdown, NDJSON, OKF bundles, SQLite, or
|
|
119
|
+
local archives. Documentation crawling is its sharpest default workflow, but
|
|
120
|
+
the product is broader than docs: blogs, API references, vendor pages, OpenAPI
|
|
121
|
+
specs, and other server-rendered web content all fit. It uses async HTTP instead
|
|
122
|
+
of Playwright, preserves source metadata, and is built for agent-selected URLs
|
|
123
|
+
with SSRF, XXE, DNS-rebinding, and CRLF-injection protections enabled by
|
|
124
|
+
default.
|
|
114
125
|
|
|
115
|
-
|
|
116
|
-
<img alt="Cumulative PyPI download history chart for docpull" src="docs/cumulative-downloads-history.svg" />
|
|
117
|
-
</a>
|
|
126
|
+
Use docpull when you need to:
|
|
118
127
|
|
|
119
|
-
|
|
128
|
+
- Load public web pages, docs, API references, or blogs into an LLM context.
|
|
129
|
+
- Build inspectable source corpora for RAG/search pipelines.
|
|
130
|
+
- Give a coding agent a local MCP tool for fetching, caching, grepping, and
|
|
131
|
+
reading docs.
|
|
132
|
+
- Mirror public web content for offline work while keeping source attribution.
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
<img alt="Star history chart for raintree-technology/docpull" src="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
126
|
-
</picture>
|
|
127
|
-
</a>
|
|
134
|
+
docpull intentionally does not render JavaScript. For JS-only apps, browser
|
|
135
|
+
automation, paid extraction APIs, or general web crawling, see
|
|
136
|
+
[`docs/scraping-boundary.md`](docs/scraping-boundary.md) and
|
|
137
|
+
[`docs/alternatives.md`](docs/alternatives.md).
|
|
128
138
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
sandbox-friendly way to pipe web content into an LLM context, a RAG index, or an
|
|
137
|
-
offline archive. SSRF, XXE, DNS-rebinding, and CRLF-injection protections are on
|
|
138
|
-
by default — a necessity when an AI agent is choosing the URLs.
|
|
139
|
-
|
|
140
|
-
docpull is intentionally not a general browser-automation scraper. See
|
|
141
|
-
[`docs/scraping-boundary.md`](docs/scraping-boundary.md) for the exact product
|
|
142
|
-
boundary and when to use Scrapy, Crawlee, hosted extraction APIs, or trafilatura
|
|
143
|
-
directly.
|
|
139
|
+
## Try it in 60 seconds
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pip install docpull
|
|
143
|
+
docpull https://docs.python.org/3/library/asyncio.html --single
|
|
144
|
+
docpull https://docs.python.org/3/library/asyncio.html --profile llm --stream | jq .
|
|
145
|
+
```
|
|
144
146
|
|
|
145
147
|
## Install
|
|
146
148
|
|
|
@@ -169,12 +171,26 @@ docpull https://docs.example.com/guide --single
|
|
|
169
171
|
docpull https://docs.example.com --profile llm --stream | jq .
|
|
170
172
|
|
|
171
173
|
# Open Knowledge Format bundle for agent/wiki interoperability
|
|
172
|
-
docpull https://
|
|
174
|
+
docpull https://example.com --format okf -o ./site-okf
|
|
173
175
|
|
|
174
176
|
# Mirror scraped content for offline use
|
|
175
177
|
docpull https://docs.example.com --profile mirror --cache
|
|
176
178
|
```
|
|
177
179
|
|
|
180
|
+
## Project traction
|
|
181
|
+
|
|
182
|
+
<a href="https://pepy.tech/project/docpull">
|
|
183
|
+
<img alt="Cumulative PyPI download history chart for docpull" src="docs/cumulative-downloads-history.svg" />
|
|
184
|
+
</a>
|
|
185
|
+
|
|
186
|
+
<a href="https://star-history.com/#raintree-technology/docpull&Date">
|
|
187
|
+
<picture>
|
|
188
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date&theme=dark" />
|
|
189
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
190
|
+
<img alt="Star history chart for raintree-technology/docpull" src="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
191
|
+
</picture>
|
|
192
|
+
</a>
|
|
193
|
+
|
|
178
194
|
## Framework-aware extraction
|
|
179
195
|
|
|
180
196
|
docpull inspects each page before running the generic extractor and can pull
|
|
@@ -564,7 +580,22 @@ NDJSON (one record per page or chunk):
|
|
|
564
580
|
Open Knowledge Format:
|
|
565
581
|
|
|
566
582
|
```bash
|
|
567
|
-
docpull https://
|
|
583
|
+
docpull https://example.com --format okf -o ./site-okf
|
|
584
|
+
|
|
585
|
+
# Equivalent profile form
|
|
586
|
+
docpull https://example.com --profile okf -o ./site-okf
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
A generated OKF bundle has a normal Markdown tree:
|
|
590
|
+
|
|
591
|
+
```text
|
|
592
|
+
site-okf/
|
|
593
|
+
index.md
|
|
594
|
+
corpus.manifest.json
|
|
595
|
+
_root.md
|
|
596
|
+
docs/
|
|
597
|
+
index.md
|
|
598
|
+
getting-started.md
|
|
568
599
|
```
|
|
569
600
|
|
|
570
601
|
OKF output is an opt-in Markdown bundle. Scraped pages are written as concept
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# docpull
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Public web to agent-ready Markdown. Fast, local, browser-free.**
|
|
4
4
|
|
|
5
5
|
[](https://www.python.org/downloads/)
|
|
6
6
|
[](https://badge.fury.io/py/docpull)
|
|
@@ -14,37 +14,35 @@
|
|
|
14
14
|
</a>
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
docpull is a Python CLI, SDK, and MCP server for pulling public static and
|
|
18
|
+
server-rendered web pages into clean Markdown, NDJSON, OKF bundles, SQLite, or
|
|
19
|
+
local archives. Documentation crawling is its sharpest default workflow, but
|
|
20
|
+
the product is broader than docs: blogs, API references, vendor pages, OpenAPI
|
|
21
|
+
specs, and other server-rendered web content all fit. It uses async HTTP instead
|
|
22
|
+
of Playwright, preserves source metadata, and is built for agent-selected URLs
|
|
23
|
+
with SSRF, XXE, DNS-rebinding, and CRLF-injection protections enabled by
|
|
24
|
+
default.
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
<img alt="Cumulative PyPI download history chart for docpull" src="docs/cumulative-downloads-history.svg" />
|
|
21
|
-
</a>
|
|
26
|
+
Use docpull when you need to:
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
- Load public web pages, docs, API references, or blogs into an LLM context.
|
|
29
|
+
- Build inspectable source corpora for RAG/search pipelines.
|
|
30
|
+
- Give a coding agent a local MCP tool for fetching, caching, grepping, and
|
|
31
|
+
reading docs.
|
|
32
|
+
- Mirror public web content for offline work while keeping source attribution.
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<img alt="Star history chart for raintree-technology/docpull" src="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
30
|
-
</picture>
|
|
31
|
-
</a>
|
|
34
|
+
docpull intentionally does not render JavaScript. For JS-only apps, browser
|
|
35
|
+
automation, paid extraction APIs, or general web crawling, see
|
|
36
|
+
[`docs/scraping-boundary.md`](docs/scraping-boundary.md) and
|
|
37
|
+
[`docs/alternatives.md`](docs/alternatives.md).
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
sandbox-friendly way to pipe web content into an LLM context, a RAG index, or an
|
|
41
|
-
offline archive. SSRF, XXE, DNS-rebinding, and CRLF-injection protections are on
|
|
42
|
-
by default — a necessity when an AI agent is choosing the URLs.
|
|
43
|
-
|
|
44
|
-
docpull is intentionally not a general browser-automation scraper. See
|
|
45
|
-
[`docs/scraping-boundary.md`](docs/scraping-boundary.md) for the exact product
|
|
46
|
-
boundary and when to use Scrapy, Crawlee, hosted extraction APIs, or trafilatura
|
|
47
|
-
directly.
|
|
39
|
+
## Try it in 60 seconds
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install docpull
|
|
43
|
+
docpull https://docs.python.org/3/library/asyncio.html --single
|
|
44
|
+
docpull https://docs.python.org/3/library/asyncio.html --profile llm --stream | jq .
|
|
45
|
+
```
|
|
48
46
|
|
|
49
47
|
## Install
|
|
50
48
|
|
|
@@ -73,12 +71,26 @@ docpull https://docs.example.com/guide --single
|
|
|
73
71
|
docpull https://docs.example.com --profile llm --stream | jq .
|
|
74
72
|
|
|
75
73
|
# Open Knowledge Format bundle for agent/wiki interoperability
|
|
76
|
-
docpull https://
|
|
74
|
+
docpull https://example.com --format okf -o ./site-okf
|
|
77
75
|
|
|
78
76
|
# Mirror scraped content for offline use
|
|
79
77
|
docpull https://docs.example.com --profile mirror --cache
|
|
80
78
|
```
|
|
81
79
|
|
|
80
|
+
## Project traction
|
|
81
|
+
|
|
82
|
+
<a href="https://pepy.tech/project/docpull">
|
|
83
|
+
<img alt="Cumulative PyPI download history chart for docpull" src="docs/cumulative-downloads-history.svg" />
|
|
84
|
+
</a>
|
|
85
|
+
|
|
86
|
+
<a href="https://star-history.com/#raintree-technology/docpull&Date">
|
|
87
|
+
<picture>
|
|
88
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date&theme=dark" />
|
|
89
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
90
|
+
<img alt="Star history chart for raintree-technology/docpull" src="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
91
|
+
</picture>
|
|
92
|
+
</a>
|
|
93
|
+
|
|
82
94
|
## Framework-aware extraction
|
|
83
95
|
|
|
84
96
|
docpull inspects each page before running the generic extractor and can pull
|
|
@@ -468,7 +480,22 @@ NDJSON (one record per page or chunk):
|
|
|
468
480
|
Open Knowledge Format:
|
|
469
481
|
|
|
470
482
|
```bash
|
|
471
|
-
docpull https://
|
|
483
|
+
docpull https://example.com --format okf -o ./site-okf
|
|
484
|
+
|
|
485
|
+
# Equivalent profile form
|
|
486
|
+
docpull https://example.com --profile okf -o ./site-okf
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
A generated OKF bundle has a normal Markdown tree:
|
|
490
|
+
|
|
491
|
+
```text
|
|
492
|
+
site-okf/
|
|
493
|
+
index.md
|
|
494
|
+
corpus.manifest.json
|
|
495
|
+
_root.md
|
|
496
|
+
docs/
|
|
497
|
+
index.md
|
|
498
|
+
getting-started.md
|
|
472
499
|
```
|
|
473
500
|
|
|
474
501
|
OKF output is an opt-in Markdown bundle. Scraped pages are written as concept
|
|
@@ -4,9 +4,9 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "docpull"
|
|
7
|
-
version = "4.3.
|
|
7
|
+
version = "4.3.1"
|
|
8
8
|
dynamic = []
|
|
9
|
-
description = "
|
|
9
|
+
description = "Convert public web pages into clean Markdown for AI agents and RAG"
|
|
10
10
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
11
11
|
requires-python = ">=3.10"
|
|
12
12
|
license = "MIT"
|
|
@@ -18,8 +18,20 @@ maintainers = [
|
|
|
18
18
|
{name = "Raintree Technology", email = "support@raintree.technology"}
|
|
19
19
|
]
|
|
20
20
|
keywords = [
|
|
21
|
-
"python",
|
|
22
|
-
"
|
|
21
|
+
"python",
|
|
22
|
+
"markdown",
|
|
23
|
+
"documentation",
|
|
24
|
+
"web-scraping",
|
|
25
|
+
"web-crawler",
|
|
26
|
+
"crawler",
|
|
27
|
+
"developer-tools",
|
|
28
|
+
"cli",
|
|
29
|
+
"rag",
|
|
30
|
+
"llm",
|
|
31
|
+
"mcp",
|
|
32
|
+
"ai-agents",
|
|
33
|
+
"claude",
|
|
34
|
+
"ai-training-data",
|
|
23
35
|
]
|
|
24
36
|
classifiers = [
|
|
25
37
|
# Development Status
|
|
@@ -134,12 +146,16 @@ dev = [
|
|
|
134
146
|
docpull = "docpull.cli:main"
|
|
135
147
|
|
|
136
148
|
[project.urls]
|
|
137
|
-
Homepage = "https://
|
|
138
|
-
Documentation = "https://
|
|
149
|
+
Homepage = "https://docpull.raintree.technology"
|
|
150
|
+
Documentation = "https://docpull.raintree.technology"
|
|
139
151
|
Repository = "https://github.com/raintree-technology/docpull"
|
|
140
152
|
"Source Code" = "https://github.com/raintree-technology/docpull"
|
|
141
153
|
"Bug Tracker" = "https://github.com/raintree-technology/docpull/issues"
|
|
142
154
|
"Releases" = "https://github.com/raintree-technology/docpull/releases"
|
|
155
|
+
"MCP Plugin" = "https://github.com/raintree-technology/docpull/tree/main/plugin"
|
|
156
|
+
"Comparison Guide" = "https://github.com/raintree-technology/docpull/blob/main/docs/alternatives.md"
|
|
157
|
+
"Download Stats" = "https://pepy.tech/project/docpull"
|
|
158
|
+
"Changelog" = "https://github.com/raintree-technology/docpull/blob/main/docs/CHANGELOG.md"
|
|
143
159
|
|
|
144
160
|
[tool.setuptools.packages.find]
|
|
145
161
|
where = ["src"]
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docpull
|
|
3
|
-
Version: 4.3.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 4.3.1
|
|
4
|
+
Summary: Convert public web pages into clean Markdown for AI agents and RAG
|
|
5
5
|
Author-email: Zachary Roth <support@raintree.technology>
|
|
6
6
|
Maintainer-email: Raintree Technology <support@raintree.technology>
|
|
7
7
|
License-Expression: MIT
|
|
8
|
-
Project-URL: Homepage, https://
|
|
9
|
-
Project-URL: Documentation, https://
|
|
8
|
+
Project-URL: Homepage, https://docpull.raintree.technology
|
|
9
|
+
Project-URL: Documentation, https://docpull.raintree.technology
|
|
10
10
|
Project-URL: Repository, https://github.com/raintree-technology/docpull
|
|
11
11
|
Project-URL: Source Code, https://github.com/raintree-technology/docpull
|
|
12
12
|
Project-URL: Bug Tracker, https://github.com/raintree-technology/docpull/issues
|
|
13
13
|
Project-URL: Releases, https://github.com/raintree-technology/docpull/releases
|
|
14
|
-
|
|
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-scraping,web-crawler,crawler,developer-tools,cli,rag,llm,mcp,ai-agents,claude,ai-training-data
|
|
15
19
|
Classifier: Development Status :: 5 - Production/Stable
|
|
16
20
|
Classifier: Intended Audience :: Developers
|
|
17
21
|
Classifier: Intended Audience :: Information Technology
|
|
@@ -96,7 +100,7 @@ Dynamic: license-file
|
|
|
96
100
|
|
|
97
101
|
# docpull
|
|
98
102
|
|
|
99
|
-
**
|
|
103
|
+
**Public web to agent-ready Markdown. Fast, local, browser-free.**
|
|
100
104
|
|
|
101
105
|
[](https://www.python.org/downloads/)
|
|
102
106
|
[](https://badge.fury.io/py/docpull)
|
|
@@ -110,37 +114,35 @@ Dynamic: license-file
|
|
|
110
114
|
</a>
|
|
111
115
|
</p>
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
docpull is a Python CLI, SDK, and MCP server for pulling public static and
|
|
118
|
+
server-rendered web pages into clean Markdown, NDJSON, OKF bundles, SQLite, or
|
|
119
|
+
local archives. Documentation crawling is its sharpest default workflow, but
|
|
120
|
+
the product is broader than docs: blogs, API references, vendor pages, OpenAPI
|
|
121
|
+
specs, and other server-rendered web content all fit. It uses async HTTP instead
|
|
122
|
+
of Playwright, preserves source metadata, and is built for agent-selected URLs
|
|
123
|
+
with SSRF, XXE, DNS-rebinding, and CRLF-injection protections enabled by
|
|
124
|
+
default.
|
|
114
125
|
|
|
115
|
-
|
|
116
|
-
<img alt="Cumulative PyPI download history chart for docpull" src="docs/cumulative-downloads-history.svg" />
|
|
117
|
-
</a>
|
|
126
|
+
Use docpull when you need to:
|
|
118
127
|
|
|
119
|
-
|
|
128
|
+
- Load public web pages, docs, API references, or blogs into an LLM context.
|
|
129
|
+
- Build inspectable source corpora for RAG/search pipelines.
|
|
130
|
+
- Give a coding agent a local MCP tool for fetching, caching, grepping, and
|
|
131
|
+
reading docs.
|
|
132
|
+
- Mirror public web content for offline work while keeping source attribution.
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
<img alt="Star history chart for raintree-technology/docpull" src="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
126
|
-
</picture>
|
|
127
|
-
</a>
|
|
134
|
+
docpull intentionally does not render JavaScript. For JS-only apps, browser
|
|
135
|
+
automation, paid extraction APIs, or general web crawling, see
|
|
136
|
+
[`docs/scraping-boundary.md`](docs/scraping-boundary.md) and
|
|
137
|
+
[`docs/alternatives.md`](docs/alternatives.md).
|
|
128
138
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
sandbox-friendly way to pipe web content into an LLM context, a RAG index, or an
|
|
137
|
-
offline archive. SSRF, XXE, DNS-rebinding, and CRLF-injection protections are on
|
|
138
|
-
by default — a necessity when an AI agent is choosing the URLs.
|
|
139
|
-
|
|
140
|
-
docpull is intentionally not a general browser-automation scraper. See
|
|
141
|
-
[`docs/scraping-boundary.md`](docs/scraping-boundary.md) for the exact product
|
|
142
|
-
boundary and when to use Scrapy, Crawlee, hosted extraction APIs, or trafilatura
|
|
143
|
-
directly.
|
|
139
|
+
## Try it in 60 seconds
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pip install docpull
|
|
143
|
+
docpull https://docs.python.org/3/library/asyncio.html --single
|
|
144
|
+
docpull https://docs.python.org/3/library/asyncio.html --profile llm --stream | jq .
|
|
145
|
+
```
|
|
144
146
|
|
|
145
147
|
## Install
|
|
146
148
|
|
|
@@ -169,12 +171,26 @@ docpull https://docs.example.com/guide --single
|
|
|
169
171
|
docpull https://docs.example.com --profile llm --stream | jq .
|
|
170
172
|
|
|
171
173
|
# Open Knowledge Format bundle for agent/wiki interoperability
|
|
172
|
-
docpull https://
|
|
174
|
+
docpull https://example.com --format okf -o ./site-okf
|
|
173
175
|
|
|
174
176
|
# Mirror scraped content for offline use
|
|
175
177
|
docpull https://docs.example.com --profile mirror --cache
|
|
176
178
|
```
|
|
177
179
|
|
|
180
|
+
## Project traction
|
|
181
|
+
|
|
182
|
+
<a href="https://pepy.tech/project/docpull">
|
|
183
|
+
<img alt="Cumulative PyPI download history chart for docpull" src="docs/cumulative-downloads-history.svg" />
|
|
184
|
+
</a>
|
|
185
|
+
|
|
186
|
+
<a href="https://star-history.com/#raintree-technology/docpull&Date">
|
|
187
|
+
<picture>
|
|
188
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date&theme=dark" />
|
|
189
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
190
|
+
<img alt="Star history chart for raintree-technology/docpull" src="https://api.star-history.com/svg?repos=raintree-technology/docpull&type=Date" />
|
|
191
|
+
</picture>
|
|
192
|
+
</a>
|
|
193
|
+
|
|
178
194
|
## Framework-aware extraction
|
|
179
195
|
|
|
180
196
|
docpull inspects each page before running the generic extractor and can pull
|
|
@@ -564,7 +580,22 @@ NDJSON (one record per page or chunk):
|
|
|
564
580
|
Open Knowledge Format:
|
|
565
581
|
|
|
566
582
|
```bash
|
|
567
|
-
docpull https://
|
|
583
|
+
docpull https://example.com --format okf -o ./site-okf
|
|
584
|
+
|
|
585
|
+
# Equivalent profile form
|
|
586
|
+
docpull https://example.com --profile okf -o ./site-okf
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
A generated OKF bundle has a normal Markdown tree:
|
|
590
|
+
|
|
591
|
+
```text
|
|
592
|
+
site-okf/
|
|
593
|
+
index.md
|
|
594
|
+
corpus.manifest.json
|
|
595
|
+
_root.md
|
|
596
|
+
docs/
|
|
597
|
+
index.md
|
|
598
|
+
getting-started.md
|
|
568
599
|
```
|
|
569
600
|
|
|
570
601
|
OKF output is an opt-in Markdown bundle. Scraped pages are written as concept
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|