Skip to main content

mudfish

Python bindings for Mudfish Crawler, a Rust-native web crawling and intelligence engine.

This package wraps the Rust crawl engine directly (via PyO3) — there is no subprocess or network hop to a separate server. It exposes a typed, Pythonic API over the engine; the Rust project itself is at an early stage (see the main repo's ROADMAP_HONEST.md for full status).

Install

pip install mudfish

Usage

import mudfish

result = mudfish.crawl("https://example.com", depth=2, concurrency=30)

print(result.stats.urls_fetched, result.stats.duration_secs)
for page in result:                          # CrawlResult is iterable over its pages
    print(page.status_code, page.url, page.title)

crawl() blocks until the crawl finishes (or hits max_urls / max_duration_secs) and returns a typed CrawlResult:

Object Fields
CrawlResult crawl_id, pages: list[Page], errors: list[CrawlError], stats: CrawlStats — iterable over pages, len() is the page count, plus ok_pages
Page url, final_url, status_code, content_type, depth, metadata: PageMetadata, links: list[Link], body_bytes, fetched_via: FetchMethod — helpers title, is_ok
PageMetadata title, meta_description, canonical
Link url, anchor_text, rel
CrawlError url, message
CrawlStats urls_discovered, urls_fetched, urls_skipped, errors, bytes_downloaded, duration_ms — helpers duration_secs, throughput_per_sec
FetchMethod FetchMethod.HTTP ("Http") / FetchMethod.BROWSER ("Browser")

Every typed object also supports the raw engine dict shape (result["stats"], page["status_code"], page.to_dict()), so code written against earlier versions keeps working. If you only want the raw dict, use mudfish.crawl_dict(...).

Async

crawl_async() runs the blocking engine on a worker thread, so it composes with asyncio and several crawls can run concurrently:

import asyncio
import mudfish

async def main() -> None:
    results = await asyncio.gather(
        mudfish.crawl_async("https://a.example"),
        mudfish.crawl_async("https://b.example"),
    )
    for result in results:
        print(result.stats.urls_fetched)

asyncio.run(main())

Reusable configuration

crawler = mudfish.Crawler(depth=1, concurrency=10)
home = crawler.crawl("https://example.com")
blog = await crawler.crawl_async("https://example.com/blog")

Errors

try:
    mudfish.crawl("not-a-url")
except mudfish.InvalidURLError:      # also a ValueError
    ...
except mudfish.CrawlFailedError:     # also a RuntimeError
    ...

Everything derives from mudfish.MudfishError.

Options

All keyword-only, matching the CLI's flags (also available as the CrawlOptions dataclass):

Parameter Default Meaning
depth 3 Max link-following depth
concurrency 50 Max requests in flight, whole crawl
per_host_concurrency 4 Max requests in flight per host
same_domain True Restrict crawl to the seed's resolved domain
max_urls 10000 Hard cap on URLs fetched
max_duration_secs None Optional wall-clock budget
timeout_secs 30 Per-request timeout
request_delay_ms 0 Min delay between requests to the same host
max_response_bytes 20 MB Per-response size cap
respect_robots True Honor robots.txt
allow_private_networks False Permit loopback/private targets (internal use only)
render_js False Re-render JS-dependent pages in headless Chrome (needs Chrome on the host; much slower)
render_settle_ms 2000 When render_js is on, settle time before capturing a rendered page

Limitations

  • Chrome is not bundled. With render_js=True the engine drives a headless Chrome that must already be installed on the host; if it cannot be launched, the crawl logs a warning and falls back to static HTML.
  • Single-platform wheels initially. Built and published from the maintainer's machine, not a cross-platform CI matrix yet — check PyPI for which platforms have wheels; others will need a Rust toolchain to build from source.

License

Apache-2.0.

Metadata

Release files for mudfish 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mudfish 0.2.0
File Size Uploaded
mudfish-0.2.0.tar.gz 76.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mudfish 0.2.0
File Interpreter ABI Platform
mudfish-0.2.0-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details

Total release size: 5.0 MB

Release files / mudfish-0.2.0.tar.gz

Download URL mudfish-0.2.0.tar.gz
Size 76.7 kB
Tags Source
SHA-256 checksum
How to use checksums
79067980803c080a69f71fbdf2d5c85a295b6ec5224ecfa9e4a0ae66388106d8
BLAKE2b-256 checksum
How to use checksums
5ca0b9eed0b37c1c7a37b985108dd97f079369834d9004d3a60dd8e41569ba81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / mudfish-0.2.0-cp39-abi3-macosx_11_0_arm64.whl

Download URL mudfish-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
Size 4.9 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0c069c83b2cc25ed74ebe9a546c695546bb248a3325c259a803de7b56abf9b7d
BLAKE2b-256 checksum
How to use checksums
3fe83b8187b133d8435e6c46b2b48e8b634f82629bc14f875bf6add614faa267
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

0.2.1

9 release files

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page