Skip to main content

WhyTrend

CI License Python

Open Source Framework for Explainable Time Series Analysis

WhyTrend detects anomalies, change points, and trend shifts in time series — then automatically explains why they happened using external context and LLMs.

If this project is useful to you, consider giving it a star on GitHub — it helps others discover the project. Forks and pull requests are welcome.

Features

  • Fluent Pipeline API for source → detection → collection → ranking → explanation
  • Pluggable sources, detectors, collectors, rankers, and LLM providers
  • Structured Report output (JSON and Markdown)
  • Async collectors and LLM calls
  • Works offline with MockLLMProvider and local models via OllamaExplainer

Installation

git clone https://github.com/AlexProvatorov/WhyTrend.git
cd WhyTrend
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Optional extras

pip install -e ".[openai]"      # OpenAI API
pip install -e ".[anthropic]"   # Anthropic Claude
pip install -e ".[deepseek]"    # DeepSeek (OpenAI-compatible client)
pip install -e ".[azure]"       # Azure OpenAI
pip install -e ".[openrouter]"  # OpenRouter
pip install -e ".[gemini]"      # Gemini marker (uses core httpx; no extra package)
pip install -e ".[trends]"      # Google Trends
pip install -e ".[prophet]"       # Prophet detector
pip install -e ".[ruptures]"      # change-point detector
pip install -e ".[river]"         # online / streaming detector
pip install -e ".[ranking]"       # Embedding ranker
pip install -e ".[all]"           # everything

Quickstart (CSV, no API keys)

from whytrend import (
    BM25Ranker,
    CSVSource,
    LLMExplainer,
    MockLLMProvider,
    Pipeline,
    ZScoreDetector,
)

pipeline = (
    Pipeline(window_days=3)
    .add_source(CSVSource("tests/fixtures/python_interest.csv", keyword="Python"))
    .add_detector(ZScoreDetector(threshold=1.0))
    .add_ranker(BM25Ranker(top_k=5))
    .add_explainer(LLMExplainer(MockLLMProvider()))
)

report = pipeline.run()
print(report.executive_summary)
print(report.to_markdown())

Run the full demo:

pip install -e ".[dev]"
python examples/mvp_demo.py

Production-style example

from whytrend import (
    GoogleTrends,
    OpenAIExplainer,
    Pipeline,
    ProphetDetector,
)
from whytrend.collectors import (
    GitHubReleasesCollector,
    GoogleNewsCollector,
    HackerNewsCollector,
    RSSFeedCollector,
    RedditCollector,
    StackOverflowCollector,
    WikipediaCollector,
)
from whytrend.rankers import BM25Ranker

pipeline = (
    Pipeline()
    .add_source(GoogleTrends("Python"))
    .add_detector(ProphetDetector())
    .add_collector(GoogleNewsCollector())
    .add_collector(HackerNewsCollector())
    .add_collector(RedditCollector())  # REDDIT_CLIENT_ID + REDDIT_CLIENT_SECRET
    .add_collector(GitHubReleasesCollector())  # optional GITHUB_TOKEN
    .add_collector(StackOverflowCollector())  # optional STACKEXCHANGE_KEY
    .add_collector(
        RSSFeedCollector(
            [
                "https://blog.python.org/feeds/posts/default",
                "https://pyfound.blogspot.com/feeds/posts/default",
            ]
        )
    )
    .add_collector(WikipediaCollector())
    .add_ranker(BM25Ranker())
    .add_explainer(OpenAIExplainer())  # OPENAI_API_KEY env var or api_key="..."
)

report = pipeline.run()
print(report.executive_summary)

Use OllamaExplainer(model="llama3.2") for a local LLM instead of OpenAI.

Other cloud providers (same explainability pipeline, different backends):

from whytrend import (
    AnthropicExplainer,
    AzureOpenAIExplainer,
    DeepSeekExplainer,
    GeminiExplainer,
    OpenRouterExplainer,
)

# ANTHROPIC_API_KEY — default model: claude-sonnet-4-20250514
AnthropicExplainer()

# GEMINI_API_KEY or GOOGLE_API_KEY — default model: gemini-2.0-flash
GeminiExplainer()

# DEEPSEEK_API_KEY — default model: deepseek-chat
DeepSeekExplainer()

# AZURE_OPENAI_API_KEY + AZURE_OPENAI_ENDPOINT (or pass api_key= / azure_endpoint=)
AzureOpenAIExplainer(deployment="gpt-4o-mini")

# OPENROUTER_API_KEY — default model: openai/gpt-4o-mini
# Optional site_url= / app_title= set OpenRouter ranking headers
OpenRouterExplainer(model="anthropic/claude-sonnet-4")

Pass api_key="..." to any of these constructors if you prefer not to use env vars. Swap them into .add_explainer(...) the same way as OpenAIExplainer.

OpenAIExplainer(base_url="https://openrouter.ai/api/v1", api_key=...) also works for OpenRouter; the dedicated classes improve DX (env vars, Azure deployment/endpoint, OpenRouter headers).

Reddit credentials (create at https://www.reddit.com/prefs/apps):

export REDDIT_CLIENT_ID="..."
export REDDIT_CLIENT_SECRET="..."

Or pass them explicitly:

RedditCollector(client_id="...", client_secret="...", subreddits=["Python", "MachineLearning"])

GitHub Releases works without a token for light use. For higher rate limits:

export GITHUB_TOKEN="ghp_..."
GitHubReleasesCollector(token="ghp_...", repos=["python/cpython"])

Stack Overflow works without a key for light use. For a higher daily quota (register at https://stackapps.com/):

export STACKEXCHANGE_KEY="..."
StackOverflowCollector(api_key="...", site="stackoverflow")

Custom RSS/Atom feeds (keyword + time-window filtered):

RSSFeedCollector(
    [
        "https://blog.python.org/feeds/posts/default",
        "https://hnrss.org/frontpage",
    ]
)

Architecture

Source → Detector → Event Builder → Collectors → Ranker → Explainer → Report

Choosing a detector

Detector Best for Notes
ZScoreDetector Sudden spikes/drops vs the series mean Fast, no extra deps
ProphetDetector Points outside a forecast band (trend + seasonality) Needs whytrend[prophet]
RupturesDetector Structural breaks / regime changes Needs whytrend[ruptures]; emits changepoint
RiverDetector Online / streaming point-by-point scores Needs whytrend[river]; batch + update()
from whytrend import RiverDetector, RupturesDetector

RupturesDetector(algorithm="pelt", model="rbf", penalty=10.0)
RiverDetector(model="gaussian", threshold=0.95, min_points=10)

Roadmap

Core MVP is in place. Next focus: integrations and ecosystem.

v0.2 — More collectors

  • Google News
  • Reddit
  • GitHub Releases
  • RSS / Stack Overflow

v0.3 — More detectors

  • Ruptures (change-point)
  • River / streaming detectors

v0.4 — More LLM providers

  • Anthropic, Gemini, DeepSeek
  • Azure OpenAI, OpenRouter

v0.5 — Reports and DX

  • HTML / PDF reports
  • CLI (whytrend analyze ...)
  • Plugin registry (entry points)

v0.6 — Ranking quality

  • Hybrid ranker (BM25 + embeddings merged with RRF)
  • Post-ranker evidence filter (relevance thresholds, stronger rerank, explicit verdicts like evidence_insufficient / correlation_only / likely_cause)

Track progress in GitHub Issues.

Development

make install   # install with detected tool (uv / poetry / pip)
make check     # ruff + format check + mypy + pytest

Supports the three common workflows:

Tool Install Run checks
uv (default if installed) make install make check
poetry make install TOOL=poetry make check TOOL=poetry
pip / venv make install TOOL=pip make check TOOL=pip

Auto-detect order: uv → poetry → pip. Override anytime with TOOL=....

Useful targets:

make lint          # ruff check
make format        # ruff format + autofix
make format-check  # ruff format --check
make typecheck     # mypy
make test          # pytest
make help          # list all targets

Contributing

See CONTRIBUTING.md. Please follow the Code of Conduct. Security reports: SECURITY.md.

Author

Alexander Provatorov — GitHub @AlexProvatorov

License

Licensed under the Apache License, Version 2.0.

Release files for whytrend 0.4.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 whytrend 0.4.0
File Size Uploaded
whytrend-0.4.0.tar.gz 57.5 kB Details

Built distribution (wheel)

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

Total release size: 126.3 kB

Release files / whytrend-0.4.0.tar.gz

Download URL whytrend-0.4.0.tar.gz
Size 57.5 kB
Tags Source
SHA-256 checksum
How to use checksums
17b8a44ed789f4f77e2aae2a9bcef544ddfcc827f113b2edcc6d811c896f0eae
BLAKE2b-256 checksum
How to use checksums
5538680073ce21f3747e792d9753587690a04f20f8dfa680fa633062ebc38479
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.

Transparency log

Release files / whytrend-0.4.0-py3-none-any.whl

Download URL whytrend-0.4.0-py3-none-any.whl
Size 68.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
72ddca578e867263762bd6ef490917a40cc230fbd56789cc05b439011181970b
BLAKE2b-256 checksum
How to use checksums
101168b9727ecc56239b4e15e51713caa46cdf917e4fe5db62959459fdd2a66d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

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