Skip to main content

Open Source Framework for Explainable Time Series Analysis

Project description

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

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)

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: uvpoetrypip. 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 ProvatorovGitHub @AlexProvatorov

License

Licensed under the Apache License, Version 2.0.

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

whytrend-0.2.0.tar.gz (43.7 kB view details)

Uploaded Source

Built Distribution

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

whytrend-0.2.0-py3-none-any.whl (53.4 kB view details)

Uploaded Python 3

File details

Details for the file whytrend-0.2.0.tar.gz.

File metadata

  • Download URL: whytrend-0.2.0.tar.gz
  • Upload date:
  • Size: 43.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for whytrend-0.2.0.tar.gz
Algorithm Hash digest
SHA256 723bbcb502b4cf5412a851e4b0f63a92e4010a2eb3f3044cdea1f7771534dcf1
MD5 e3d82603a62b3e10d2de626ba3b7e785
BLAKE2b-256 30620d5dbe69e0c70cb67d68799c8cf4a32ddc4ffb1f66fbe31742bc9df013c7

See more details on using hashes here.

Provenance

The following attestation bundles were made for whytrend-0.2.0.tar.gz:

Publisher: publish.yml on AlexProvatorov/WhyTrend

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whytrend-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: whytrend-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 53.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for whytrend-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e961065cfbfa75bb866a947c21bd00f998599fdf38b64a3dc60f906313aafe0b
MD5 0c737e053d920b0bb466cde9e798ddd2
BLAKE2b-256 26c8fc94b253390540cfea7c838c6d09fe424529f1716d2837652d2984a3a361

See more details on using hashes here.

Provenance

The following attestation bundles were made for whytrend-0.2.0-py3-none-any.whl:

Publisher: publish.yml on AlexProvatorov/WhyTrend

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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