From f020795408e569fb945e2d16e263cbcd2079a262 Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 24 Jul 2026 13:08:18 +0300 Subject: [PATCH 1/2] Add Live Tennis API integration Co-Authored-By: Claude Fable 5 --- integrations/livetennisapi.md | 138 ++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 integrations/livetennisapi.md diff --git a/integrations/livetennisapi.md b/integrations/livetennisapi.md new file mode 100644 index 00000000..b385ee54 --- /dev/null +++ b/integrations/livetennisapi.md @@ -0,0 +1,138 @@ +--- +layout: integration +name: Live Tennis API +description: Live tennis scores, matches and players as Haystack Documents for RAG and agent pipelines +authors: + - name: Ben + socials: + github: bensynapse +pypi: https://pypi.org/project/livetennisapi-haystack/ +repo: https://github.com/livetennisapi/livetennisapi-haystack +type: Data Ingestion +report_issue: https://github.com/livetennisapi/livetennisapi-haystack/issues +version: Haystack 2.0 +toc: true +--- + +### Table of Contents + +- [Overview](#overview) +- [Installation](#installation) +- [Usage](#usage) + - [LiveTennisMatchFetcher](#livetennismatchfetcher) + - [LiveTennisPlayerSearch](#livetennisplayersearch) +- [License](#license) + +## Overview + +The [Live Tennis API](https://livetennisapi.com) serves live scores, matches and player data +across the ATP, WTA, Challenger, ITF and junior tours. + +This integration provides: + +- **`LiveTennisMatchFetcher`**: fetches live, upcoming or completed matches (optionally one + match by id, optionally filtered by tour) and returns them as Haystack `Document` objects. + Each Document's `content` is a clean human-readable match summary and its `meta` carries + the structured fields (ids, players, sets/games/points, server, winner). +- **`LiveTennisPlayerSearch`**: searches players by name (ranked players first) and returns + them as `Document` objects with the same content/meta split. + +You need a Live Tennis API key to use this integration (a free tier is available). The +components read it from the `LIVETENNISAPI_KEY` environment variable via Haystack's `Secret`, +so serialized pipelines never contain the key. Built on the official +[`livetennisapi`](https://pypi.org/project/livetennisapi/) Python client. + +## Installation + +```bash +pip install livetennisapi-haystack +``` + +## Usage + +Set your API key as the `LIVETENNISAPI_KEY` environment variable. + +### LiveTennisMatchFetcher + +#### Basic Example + +```python +from livetennisapi_haystack import LiveTennisMatchFetcher + +fetcher = LiveTennisMatchFetcher(limit=5) +result = fetcher.run(status="live") +for doc in result["documents"]: + print(doc.content) +``` + +#### In a Pipeline + +A RAG pipeline that answers questions about the matches on court right now: + +```python +from haystack import Pipeline +from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder +from haystack.components.generators.chat import OpenAIChatGenerator +from haystack.dataclasses import ChatMessage + +from livetennisapi_haystack import LiveTennisMatchFetcher + +prompt_template = [ + ChatMessage.from_system("You are a tennis commentator."), + ChatMessage.from_user( + "Current matches:\n" + "{% for document in documents %}{{ document.content }}\n{% endfor %}\n" + "Answer the following question: {{ query }}\nAnswer:" + ), +] + +pipe = Pipeline() +pipe.add_component("matches", LiveTennisMatchFetcher(limit=10)) +pipe.add_component( + "prompt_builder", + ChatPromptBuilder(template=prompt_template, required_variables={"query", "documents"}), +) +pipe.add_component("llm", OpenAIChatGenerator(model="gpt-4o-mini")) +pipe.connect("matches.documents", "prompt_builder.documents") +pipe.connect("prompt_builder.prompt", "llm.messages") + +query = "Who is closest to winning right now?" +result = pipe.run({"matches": {"status": "live"}, "prompt_builder": {"query": query}}) +print(result["llm"]["replies"][0].text) +``` + +#### Parameters + +- **`api_key`**: API key for the Live Tennis API. Defaults to the `LIVETENNISAPI_KEY` + environment variable. +- **`status`**: Default lifecycle status: `"live"`, `"upcoming"` or `"completed"`. + Overridable per `run()`. +- **`tour`**: Optional tour filter: `"atp"`, `"wta"`, `"challenger"`, `"itf"` or + `"juniors"`. Each value covers its singles and doubles draws. +- **`limit`**: Maximum number of matches to return (1-200). Defaults to 10. +- **`run(match_id=...)`**: fetches one specific match instead of a listing. + +If your key's tier does not unlock an endpoint (HTTP 403), the component returns a single +readable Document tagged `meta["error"] = "upgrade_required"` instead of raising, so agents +can surface the message and RAG pipelines can filter it. + +### LiveTennisPlayerSearch + +```python +from livetennisapi_haystack import LiveTennisPlayerSearch + +search = LiveTennisPlayerSearch(limit=3) +result = search.run(query="alcaraz") +for doc in result["documents"]: + print(doc.content) +``` + +#### Parameters + +- **`api_key`**: API key. Defaults to the `LIVETENNISAPI_KEY` environment variable. +- **`limit`**: Maximum number of players to return (1-200). Defaults to 10. + +## License + +`livetennisapi-haystack` is distributed under the terms of the +[MIT](https://spdx.org/licenses/MIT.html) license. From 3bf161b5b803ed59336d8bbf7226cad7d8b96175 Mon Sep 17 00:00:00 2001 From: Ben Date: Fri, 7 Aug 2026 04:27:22 +0300 Subject: [PATCH 2/2] Update Live Tennis API integration for v0.2.0: h2h, results archive, rankings, statistics components; org authorship; logo --- integrations/livetennisapi.md | 87 ++++++++++++++++++++++++++++++++--- logos/livetennisapi.svg | 11 +++++ 2 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 logos/livetennisapi.svg diff --git a/integrations/livetennisapi.md b/integrations/livetennisapi.md index b385ee54..074e9b8e 100644 --- a/integrations/livetennisapi.md +++ b/integrations/livetennisapi.md @@ -1,15 +1,16 @@ --- layout: integration name: Live Tennis API -description: Live tennis scores, matches and players as Haystack Documents for RAG and agent pipelines +description: Live tennis scores, matches, players, head-to-heads, the 1968-2022 results archive, rankings and statistics as Haystack Documents for RAG and agent pipelines authors: - - name: Ben + - name: Live Tennis API socials: - github: bensynapse + github: livetennisapi pypi: https://pypi.org/project/livetennisapi-haystack/ repo: https://github.com/livetennisapi/livetennisapi-haystack type: Data Ingestion report_issue: https://github.com/livetennisapi/livetennisapi-haystack/issues +logo: /logos/livetennisapi.svg version: Haystack 2.0 toc: true --- @@ -21,21 +22,34 @@ toc: true - [Usage](#usage) - [LiveTennisMatchFetcher](#livetennismatchfetcher) - [LiveTennisPlayerSearch](#livetennisplayersearch) + - [LiveTennisH2HFetcher](#livetennish2hfetcher) + - [LiveTennisArchiveFetcher](#livetennisarchivefetcher) + - [LiveTennisRankingsFetcher](#livetennisrankingsfetcher) + - [LiveTennisMatchStatisticsFetcher](#livetennismatchstatisticsfetcher) - [License](#license) ## Overview The [Live Tennis API](https://livetennisapi.com) serves live scores, matches and player data -across the ATP, WTA, Challenger, ITF and junior tours. +across ATP, WTA, Challenger, ITF and juniors. This integration provides: - **`LiveTennisMatchFetcher`**: fetches live, upcoming or completed matches (optionally one - match by id, optionally filtered by tour) and returns them as Haystack `Document` objects. - Each Document's `content` is a clean human-readable match summary and its `meta` carries - the structured fields (ids, players, sets/games/points, server, winner). + match by id; filterable by tour, player, country and date range) and returns them as + Haystack `Document` objects. Each Document's `content` is a clean human-readable match + summary and its `meta` carries the structured fields (ids, players, sets/games/points, + server, winner). - **`LiveTennisPlayerSearch`**: searches players by name (ranked players first) and returns them as `Document` objects with the same content/meta split. +- **`LiveTennisH2HFetcher`**: the head-to-head record between two players — the results + archive (1968-2022) plus current matches (2023-now) in one Document. BASIC tier. +- **`LiveTennisArchiveFetcher`**: the results archive — 1,485,752 matches 1968-2022, player + bios and career aggregates. BASIC tier. +- **`LiveTennisRankingsFetcher`**: a published ranking table (ATP, WTA or the ITF circuits), + one Document per row, optionally as of a past week. PRO tier. +- **`LiveTennisMatchStatisticsFetcher`**: in-play statistics for one match (aces, double + faults, serve split, hold/break percentages, break points). ULTRA tier. You need a Live Tennis API key to use this integration (a free tier is available). The components read it from the `LIVETENNISAPI_KEY` environment variable via Haystack's `Secret`, @@ -132,6 +146,65 @@ for doc in result["documents"]: - **`api_key`**: API key. Defaults to the `LIVETENNISAPI_KEY` environment variable. - **`limit`**: Maximum number of players to return (1-200). Defaults to 10. +### LiveTennisH2HFetcher + +The record between two players across the results archive (1968-2022) and current matches +(2023-now), as one Document — who leads, the surface split, and the most recent meetings. +Players are keyed by name; a fragment matching more than one player yields a Document tagged +`meta["error"] = "ambiguous_name"` with the candidate list. Requires the BASIC tier. + +```python +from livetennisapi_haystack import LiveTennisH2HFetcher + +h2h = LiveTennisH2HFetcher() +result = h2h.run(p1="federer", p2="nadal") +print(result["documents"][0].content) +``` + +### LiveTennisArchiveFetcher + +The results archive (1968-2022) in three modes: `mode="matches"` (one Document per result, +filterable by player name, date range, round and level), `mode="players"` (bios) and +`mode="career"` (career aggregates for one player). Requires the BASIC tier. + +```python +from livetennisapi_haystack import LiveTennisArchiveFetcher + +archive = LiveTennisArchiveFetcher() +result = archive.run(name="borg", from_="1980-01-01", to="1980-12-31", round="F") +for doc in result["documents"]: + print(doc.content) +``` + +### LiveTennisRankingsFetcher + +A published ranking table — `system` is `"atp"`, `"wta"`, `"itf_jt"`, `"itf_mt"` or +`"itf_wt"` — one Document per row, optionally as of a past week (`as_of="YYYY-MM-DD"`). +Requires the PRO tier. + +```python +from livetennisapi_haystack import LiveTennisRankingsFetcher + +rankings = LiveTennisRankingsFetcher() +result = rankings.run(system="wta", limit=10) +for doc in result["documents"]: + print(doc.content) +``` + +### LiveTennisMatchStatisticsFetcher + +In-play statistics for one match as a single Document — aces, double faults, the serve +split, hold/break percentages and break points, rendering only the fields the API holds. +Requires the ULTRA tier. + +```python +from livetennisapi_haystack import LiveTennisMatchStatisticsFetcher + +stats = LiveTennisMatchStatisticsFetcher() +result = stats.run(match_id=12345, p1_name="Alcaraz", p2_name="Sinner") +print(result["documents"][0].content) +``` + ## License `livetennisapi-haystack` is distributed under the terms of the diff --git a/logos/livetennisapi.svg b/logos/livetennisapi.svg new file mode 100644 index 00000000..4d2bc708 --- /dev/null +++ b/logos/livetennisapi.svg @@ -0,0 +1,11 @@ + + + + + + + + + + +