Skip to main content

Shared web infrastructure: search, scraping, HTTP security, browsers

Project description

web-core

Sister projects from n24q02m (click to expand)
Project Tagline Tag
better-code-review-graph Knowledge graph for token-efficient code reviews -- fixed search, configurabl... MCP
better-email-mcp IMAP/SMTP email server for AI agents -- 6 composite tools with multi-account ... MCP
better-godot-mcp Composite MCP server for Godot Engine -- 17 mega-tools for AI-assisted game d... MCP
better-notion-mcp Markdown-first Notion API server for AI agents -- 10 composite tools replacin... MCP
better-telegram-mcp MCP server for Telegram with dual-mode support: Bot API (httpx) for quick bot... MCP
claude-plugins Full documentation: mcp.n24q02m.com — unified docs for all 8 servers + the mc... Marketplace
imagine-mcp Production-grade MCP server for image and video understanding + generation ac... MCP
jules-task-archiver Chrome Extension for bulk operations on Jules tasks via batchexecute API -- a... Tooling
mcp-core Unified MCP Streamable HTTP 2025-11-25 transport, OAuth 2.1 Authorization Ser... MCP
mnemo-mcp Persistent AI memory with hybrid search and embedded sync. Open, free, unlimi... MCP
qwen3-embed Lightweight Qwen3 text embedding and reranking via ONNX Runtime and GGUF Library
skret Secrets without the server. CLI
web-core Shared web infrastructure package for search, scraping, HTTP security, and st... Library
wet-mcp Open-source MCP Server for web search, content extraction, library docs & mul... MCP

Table of contents

Shared web infrastructure package: SearXNG search, multi-strategy scraping (basic, TLS spoof, Patchright stealth, Cloudflare CAPTCHA), SSRF-safe HTTP client, and stealth browser primitives. Used by knowledge-core and downstream applications.

Site-specific selectors moved to consumer applications. This package provides generic infrastructure only. Consumers bring their own per-domain selectors via the WEB_CORE_DOMAIN_COOKIES env-var pattern documented below.

Installation

# From PyPI
uv add n24q02m-web-core

# Or pin to v2.x (current stable line)
uv add "n24q02m-web-core>=2.0.0"

Quick Usage

SearXNG Search

from web_core.search import ensure_searxng, shutdown_searxng
from web_core.search.client import search

# Start/reuse a SearXNG instance (cross-process singleton)
url = await ensure_searxng()

# Search with retry, deduplication, and domain filtering
results = await search(
    searxng_url=url,
    query="Python async patterns",
    max_results=10,
    include_domains=["docs.python.org"],
)

for r in results:
    print(f"{r.title}: {r.url}")

# Clean shutdown
await shutdown_searxng()

Multi-Strategy Scraping

from web_core.scraper import ScrapingAgent
from web_core.scraper.strategies import BasicHTTPStrategy, TLSSpoofStrategy

# Initialize agent with desired strategies
# Note: Some strategies (e.g., HeadlessStrategy, PatchrightStrategy)
# require optional dependencies like crawl4ai or patchright.
agent = ScrapingAgent(strategies={
    "basic": BasicHTTPStrategy(),
    "tls": TLSSpoofStrategy(),
})

# Scrape with automatic strategy escalation
content = await agent.scrape("https://example.com/article")

SSRF-Safe HTTP Client

from web_core.http import safe_httpx_client, is_safe_url

# Validate URL before use
assert is_safe_url("https://example.com")  # True
assert not is_safe_url("http://localhost")  # False (SSRF blocked)

# Create client with automatic SSRF protection + DNS pinning
async with safe_httpx_client() as client:
    resp = await client.get("https://example.com")

URL Utilities

from web_core.http import normalize_url, strip_tracking_params, is_valid_domain

# Normalize for deduplication (lowercase, strip www/tracking/fragment)
normalize_url("https://WWW.Example.COM/page?utm_source=x#section")
# => "https://example.com/page"

# Validate domain names (prevents search operator injection)
is_valid_domain("example.com")   # True
is_valid_domain("localhost")     # False

Architecture

src/web_core/
  __init__.py              -- Public API re-exports
  py.typed                 -- PEP 561 type stub marker
  http/                    -- Layer 1: SSRF-safe HTTP primitives
    client.py              -- safe_httpx_client, DNS pinning, IP validation
    url.py                 -- normalize_url, strip_tracking_params, is_valid_domain
  search/                  -- Layer 2: SearXNG search engine
    client.py              -- search() with retry, dedup, domain filtering
    models.py              -- SearchResult, SearchError dataclasses
    runner.py              -- Cross-process SearXNG singleton manager
  scraper/                 -- Layer 2: Multi-strategy scraping agent
    agent.py               -- ScrapingAgent (LangGraph state machine)
    base.py                -- BaseStrategy ABC, ScrapingResult
    cache.py               -- StrategyCache (per-domain performance tracking)
    state.py               -- ScrapingState TypedDict, ScrapingError
    strategies/            -- Concrete strategy implementations
      api_direct.py        -- API endpoint detection and direct fetch
      basic_http.py        -- Simple httpx GET with SSRF protection
      captcha.py           -- CapSolver-backed captcha bypass
      headless.py          -- Crawl4AI headless browser rendering
      tls_spoof.py         -- curl_cffi TLS fingerprint spoofing
  browsers/                -- Layer 2: Stealth browser abstraction
    protocol.py            -- BrowserProvider Protocol (structural typing)
    patchright.py          -- Patchright (undetected Playwright) provider

Key Design Decisions

  • SSRF protection: All outbound HTTP goes through safe_httpx_client with DNS pinning to prevent DNS rebinding attacks.
  • Strategy escalation: The scraping agent tries strategies in cache-recommended order, validates responses, and automatically escalates on failure.
  • Cross-process SearXNG: A file-lock singleton ensures exactly one SearXNG instance runs across all Python processes.
  • Structural typing: BrowserProvider uses Protocol so implementations don't need inheritance.

Development

Prerequisites

  • Python 3.13
  • uv
  • mise (optional, for task shortcuts)

Setup

git clone git@github.com:n24q02m/web-core.git
cd web-core
uv sync --all-extras
pre-commit install

Commands

# Via mise
mise run setup     # uv sync --all-extras
mise run lint      # ruff check + ruff format --check
mise run test      # pytest with coverage
mise run fix       # auto-fix lint + format

# Direct
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
uv run ty check src/
uv run pytest --cov -q

Tests

  • asyncio_mode = "auto" -- no @pytest.mark.asyncio needed
  • Coverage threshold: 95% (enforced in pyproject.toml)
  • Test files mirror source module structure under tests/

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

n24q02m_web_core-2.0.0b1.tar.gz (218.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

n24q02m_web_core-2.0.0b1-py3-none-any.whl (59.3 kB view details)

Uploaded Python 3

File details

Details for the file n24q02m_web_core-2.0.0b1.tar.gz.

File metadata

  • Download URL: n24q02m_web_core-2.0.0b1.tar.gz
  • Upload date:
  • Size: 218.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for n24q02m_web_core-2.0.0b1.tar.gz
Algorithm Hash digest
SHA256 dd34566eacc97bbb448e54ded9b408d1d80da08ba3fab70b33e871ec3d9d6f74
MD5 e6d73e17ab3ca69a93af0fe8ac489b43
BLAKE2b-256 beaf0457a28ad068ba35976a255c7ce0bf6a4be5f5a1598cbf9421d86fd40adf

See more details on using hashes here.

File details

Details for the file n24q02m_web_core-2.0.0b1-py3-none-any.whl.

File metadata

  • Download URL: n24q02m_web_core-2.0.0b1-py3-none-any.whl
  • Upload date:
  • Size: 59.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for n24q02m_web_core-2.0.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 b8e013f822094cdae5ecb02d65ddad48f694477cdf69669b056739b9b4b7508e
MD5 b4a076625951fc0e407bebb7a6d05c5f
BLAKE2b-256 4ea755a8f8bf10c1bc7baf1772e94eac9af5b6653375e75a86b8752e9eea46a7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page