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 ".[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.

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

Author

Alexander Provatorov — GitHub @AlexProvatorov

License

Licensed under the Apache License, Version 2.0.

Release files for whytrend 0.3.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.3.0
File Size Uploaded
whytrend-0.3.0.tar.gz 48.8 kB Details

Built distribution (wheel)

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

Total release size: 107.6 kB

Release files / whytrend-0.3.0.tar.gz

Download URL whytrend-0.3.0.tar.gz
Size 48.8 kB
Tags Source
SHA-256 checksum
How to use checksums
0e02c787e2aac3c1a189b3690d03f872177b53a8bac01958d48c259437411570
BLAKE2b-256 checksum
How to use checksums
eeda6f667bd9e9371b73bbf51aa290eb7388e7fd9f5755d1eaa8801bc4e19d91
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 4, 2026.

Transparency log

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

Download URL whytrend-0.3.0-py3-none-any.whl
Size 58.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d79148843614733dd8c7199fac575b892de1ebec9ac3061e395fff824500a416
BLAKE2b-256 checksum
How to use checksums
68c4a7f0ca49123d099e8a685e058045968e01c68f509be3023017234e1d213d
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 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.0

2 release files

This release

0.3.0 This release

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