Skip to main content

Josty Logo

Zero-config, keyless metasearch and bounded content extraction.

CI Python 3.10+ License: MIT Changelog Code Style: Ruff


What It Is

Josty (from Persian جستن / Jostan — to seek) queries keyless public search backends in parallel, fuses rankings with Reciprocal Rank Fusion (RRF), canonicalizes URLs, strips tracking telemetry, and extracts bounded Markdown from target pages.

It provides a dependable, structured search subprocess and async Python API without requiring search API keys, background daemons, or heavy browser dependencies.


Installation

# Recommended: Instant cached execution (zero persistent virtualenv overhead)
uvx josty "Python 3.13 changes" --limit 5

# Global CLI installation via uv:
uv tool install josty

# Alternative installation via pipx or standard pip:
pipx install josty
pip install josty

Quickstart

1. CLI Usage

# Basic web search (top 5 results)
josty "Python 3.13 features" --limit 5

# Developer profile (boosts GitHub, PyPI, crates.io, MDN, StackOverflow)
josty "FastAPI dependency injection" --profile dev --limit 5

# Academic profile (boosts arXiv, PubMed, IEEE, Nature, OpenAlex)
josty "retrieval augmented generation" --profile academic --limit 5

# Domain filtering (up to 5 domains)
josty "httpx connection reset" --site github.com --site stackoverflow.com

# Open Source discovery mode
josty "document indexing" --mode oss --github

# Extract clean, bounded Markdown from top result pages
josty "RRF rank fusion algorithm" --limit 3 --fetch

2. Versioned JSON Output

stdout emits pure, parseable JSON conforming to a strict schema contract (schema_version: "1.0"):

{
  "schema_version": "1.0",
  "query": "Python 3.13 features",
  "status": "complete",
  "count": 3,
  "partial": false,
  "cached": false,
  "run_at": "2026-09-02T12:00:00+00:00",
  "provider_count": 3,
  "nonempty_provider_count": 3,
  "coverage": 1.0,
  "query_variant_count": 1,
  "request_count": 3,
  "fetch": {
    "requested": true,
    "attempted": 3,
    "ok": 3,
    "failed": 0,
    "status": "complete"
  },
  "providers": [
    { "provider": "brave", "query": "Python 3.13 features", "ok": true, "result_count": 5, "error": null, "error_kind": null },
    { "provider": "duckduckgo", "query": "Python 3.13 features", "ok": true, "result_count": 5, "error": null, "error_kind": null },
    { "provider": "google", "query": "Python 3.13 features", "ok": true, "result_count": 4, "error": null, "error_kind": null }
  ],
  "results": [
    {
      "title": "What's New In Python 3.13 — Python 3.13.0 documentation",
      "url": "https://docs.python.org/3/whatsnew/3.13.html",
      "snippet": "Python 3.13 includes an experimental free-threaded build mode...",
      "sources": ["brave", "duckduckgo", "google"],
      "score": 0.032787,
      "content": "## What's New In Python 3.13\n\nThis article explains the new features...",
      "extraction_method": "trafilatura"
    }
  ]
}

Python API & Integrations

Direct Async Python API

import asyncio
from josty import Josty

async def main():
    engine = Josty(profile="dev")
    run = await engine.research_run("Linux kernel initial release year", limit=3)
    
    if run.status != "failed":
        for result in run.results:
            print(f"[{result.title}]({result.url})\n{result.snippet}\n")

asyncio.run(main())

Function Calling Tool Schema

search_tool_definition = {
    "type": "function",
    "function": {
        "name": "web_search",
        "description": "Search the web for up-to-date documentation and technical resources. Returns ranked results.",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "The search query."
                },
                "fetch": {
                    "type": "boolean",
                    "description": "Set to true to fetch and extract clean Markdown page content.",
                    "default": False
                },
                "profile": {
                    "type": "string",
                    "enum": ["general", "dev", "academic"],
                    "description": "Ranking profile boosting authoritative technical or academic domains.",
                    "default": "general"
                },
                "mode": {
                    "type": "string",
                    "enum": ["plain", "exact", "oss"],
                    "description": "Search mode ('oss' filters for open-source repositories).",
                    "default": "plain"
                }
            },
            "required": ["query"]
        }
    }
}

Technical Specifications & Architecture

graph TD
    Query["Search Query"] --> Cache{"SQLite WAL Cache<br/>Tiered TTL (d:30m/news:1h/w:2h, else 6h)<br/>5k rows / 50 MB, SERP-only"}
    
    Cache -- Cache Hit --> Out["<b>Pure JSON Output</b><br/>(schema_version: 1.0)"]
    Cache -- "Cache Hit + --fetch" --> Traf
    
    Cache -- Cache Miss --> Fanout["<b>Async Parallel Fanout</b><br/>(one call per engine)"]
    
    Fanout --> B1["Engine Group 1<br/>(Brave, DuckDuckGo)"]
    Fanout --> B2["Engine Group 2<br/>(Google, Mojeek, Startpage)"]
    Fanout --> B3["Engine Group 3<br/>(Yahoo)"]
    Fanout --> GH["GitHub Search<br/>(Optional --github)"]
    
    B1 --> Circuit["<b>Per-Engine Circuit Breakers</b><br/>(Sliding Window)"]
    B2 --> Circuit
    B3 --> Circuit
    GH --> Circuit
    
    Circuit --> RRF["<b>Domain-Weighted RRF Fusion</b><br/>(k=60 + Dev/Academic Profiles)"]
    
    RRF --> Canon["<b>URL Canonicalization</b><br/>(RFC 3986 + Tracking Stripper)"]
    
    Canon --> Fetch{"<b>--fetch Active?</b>"}
    
    Fetch -- Yes --> Traf["Trafilatura Extractor<br/>Bounded Markdown"]
    Fetch -- No --> Out
    Traf --> Out

    style Query fill:#dbeafe,stroke:#1e40af,stroke-width:2px;
    style Out fill:#dcfce7,stroke:#15803d,stroke-width:2px;
    style RRF fill:#fef3c7,stroke:#b45309,stroke-width:2px;
Parameter / Feature Code Value / Contract Description
Schema Version 1.0 Output format contract on stdout
Max Domain Filters 5 (--site) Maximum concurrent site constraints per query
Max Query Variants unlimited (--max-query-variants) Caps mode/site query expansion — set this for --mode oss with multiple --site filters to bound upstream fanout
Search Concurrency 6 (--search-concurrency) Default bounded semaphore for search backends
Fetch Concurrency 4 (--fetch-concurrency) Default bounded semaphore for page content fetching
Max Content Size 8,000 chars (--max-content-chars) Extracted Markdown character ceiling per page (0 for unlimited)
Download Byte Limit 2,000,000 bytes (2MB) Hard ceiling on raw HTTP downloads before parsing
RRF Parameter $k=60$ Cormack et al. (2009) reciprocal rank smoothing factor
SSRF Safeguards Verified Blocks private subnets, loopback, RFC 1918, and 169.254.169.254 metadata

Roadmap

Shipped in v0.4.0: error_kind=empty, diagnose challenged, no hidden query rewrite, and a bounded cache. Shipped in v0.5.0: per-engine providers[] observability (one status per engine) and an engine-availability gate. Query relaxation, news engine filters, and hard host floors are out of scope. See ROADMAP.md.


Development

# Clone repository
git clone https://github.com/Alih-b/Josty.git
cd josty

# Create and activate a virtual environment first (PEP 668:
# Debian/Ubuntu system Python rejects direct pip installs)
python -m venv .venv
source .venv/bin/activate

# Install in editable mode with dev dependencies
python -m pip install -e ".[dev]"

# Run test suite
pytest -q

# Lint and check code style
ruff check .

License

MIT © Ali Bayest. See LICENSE for details.

Release files for josty 0.5.2

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

Source distribution (sdist)

Source distribution for josty 0.5.2
File Size Uploaded
josty-0.5.2.tar.gz 137.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for josty 0.5.2
File Interpreter ABI Platform
josty-0.5.2-py3-none-any.whl Python 3 none any Details

Total release size: 169.5 kB

Release files / josty-0.5.2.tar.gz

Download URL josty-0.5.2.tar.gz
Size 137.0 kB
Tags Source
SHA-256 checksum
How to use checksums
474887bf09931ffba80b9f5d0d2f7a2833ddd6e82756fd78538fc78a5e87bca6
BLAKE2b-256 checksum
How to use checksums
47b206084dd0c2e6beefe890e5551576a79aaa8269ecb8c281e0bd85b3f96c39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / josty-0.5.2-py3-none-any.whl

Download URL josty-0.5.2-py3-none-any.whl
Size 32.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d49b6cd211e03dcfacd0e7c478f8a2ae3a9769b3cb44b5d33c569b8d074c111c
BLAKE2b-256 checksum
How to use checksums
3ae485c2f0b11a8d5cc60c18f70d31bd8860f35e32b141a8ce5af59aa624816f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.7.1

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

This release

0.5.2 This release

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.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