FFBB Data Client — SDK Python asynchrone pour les Statistiques de Basket France. Type-safe Pydantic models, async/sync, Meilisearch.
Project description
🏀 FFBB Data Client
SDK Python moderne, typé et asynchrone pour exploiter les données publiques FFBB : clubs, compétitions, rencontres, classements, salles, officiels et recherche Meilisearch.
Installation • Démarrage rapide • Fonctionnalités • Recherche • Async • Développement
📌 À propos
ffbb_data_client simplifie l'accès aux API FFBB et à leurs index Meilisearch avec :
- une façade unique :
FFBBDataClient; - des modèles Pydantic v2 typés ;
- une API utilisable en synchrone ou en
async/await; - une gestion automatique des tokens via
TokenManager; - du cache HTTP configurable via
hishel; - des helpers prêts pour l'intégration MCP / agents IA.
🚀 Version v2.2.0 — Mai 2026
Principales évolutions récentes :
- refactor architecture :
FFBBDataClient(2865 → 272 lignes) découpé en_RestFacade+_SearchFacade— API publique 100% compatible ; - unification sync/async : les méthodes synchrones délèguent à leurs homologues asynchrones via
_run_async(), éliminant ~604 lignes de duplication ; - nouvelles entités : EDF (matches, joueurs, rosters, équipes), Genius Sport (matches, live logs), Rematch Videos ;
- cache SQLite concurrency-safe : fichiers séparés pour sync (
http_cache.db) et async (http_cache_async.db) ; - CI renforcée : mypy + pyright + CodeQL + Dependabot + hook pre-push + wrapper parity check ;
- nettoyage : suppression du shim
ffbb_api_client_v3, scripts morts et code mort (invalidate_pattern).
Voir aussi : CHANGELOG.md et RELEASE_NOTES.md.
📦 Installation
pip install ffbb-data-client
Pour contribuer ou exécuter les tests :
git clone https://github.com/nickdesi/ffbb-data-client.git
cd ffbb-data-client
pip install -e ".[testing]"
Prérequis : Python >=3.10.
⚡ Démarrage rapide
from ffbb_data_client import FFBBDataClient
client = FFBBDataClient.create()
# Recherche globale sur les index FFBB
results = client.multi_search("Pau Orthez")
for result in results or []:
print(result.index_uid, len(result.hits or []))
# Lives en cours
lives = client.get_lives()
FFBBDataClient.create() résout automatiquement les tokens si aucun token n'est passé explicitement.
✨ Fonctionnalités
| Domaine | Capacités |
|---|---|
| API FFBB | clubs, compétitions, organismes, saisons, poules, classements, rencontres, lives |
| Entités additionnelles | EDF (matches, joueurs, rosters, équipes), Genius Sport, Rematch Videos |
| Recherche | organismes, compétitions, rencontres, salles, terrains, pratiques, tournois, engagements et formations |
| REST typé | récupération de ressources individuelles avec modèles Pydantic v2 |
| Async | méthodes *_async() — source de vérité ; sync délègue via _run_async() |
| Cache | cache HTTP hishel, sessions httpx réutilisées, retries configurables, SQLite séparés sync/async |
| Sécurité | masquage des tokens dans les logs, CodeQL scanning, Dependabot |
| IA / MCP | structure compatible avec des wrappers MCP et agents IA |
🔍 Recherche Meilisearch
Recherche globale
results = client.multi_search("Clermont")
Recherche ciblée
organismes = client.search_organismes(
"Clermont",
filter=['codePostal = "63000"'],
sort=["nom:asc"],
limit=10,
)
rencontres = client.search_rencontres("N1M", limit=20)
salles = client.search_salles("Maison des Sports", limit=5)
engagements = client.search_engagements("U15M", limit=20)
Recherche géographique
clubs = client.search_organismes_by_geo(
lat=45.7772,
lng=3.0870,
radius_km=20,
limit=20,
)
Principales méthodes exposées
| Ressource | Méthode sync | Méthode async |
|---|---|---|
| Recherche globale | multi_search() |
multi_search_async() |
| Clubs / organismes | search_organismes() |
search_organismes_async() |
| Compétitions | search_competitions() |
search_competitions_async() |
| Rencontres | search_rencontres() |
search_rencontres_async() |
| Salles | search_salles() |
search_salles_async() |
| Terrains | search_terrains() |
search_terrains_async() |
| Pratiques | search_pratiques() |
search_pratiques_async() |
| Tournois | search_tournois() |
search_tournois_async() |
| Engagements | search_engagements() |
search_engagements_async() |
| Formations | search_formations() |
search_formations_async() |
🧱 Accès REST typé
# Ressources principales
organisme = client.get_organisme(12345)
competition = client.get_competition(67890)
poule = client.get_poule(11111)
# Ressources ajoutées récemment
rencontre = client.get_rencontre(22222)
officiel = client.get_officiel(33333)
entraineur = client.get_entraineur(44444)
Les assets Directus et autres collections peuvent être exploités via les méthodes REST/listing dédiées exposées par le client lorsque disponibles.
Les réponses sont converties en modèles Pydantic lorsque le schéma est connu, ce qui apporte validation, autocomplétion et sérialisation propre.
🧵 Utilisation asynchrone
import asyncio
from ffbb_data_client import FFBBDataClient
async def main() -> None:
client = FFBBDataClient.create()
results = await client.search_organismes_async("ASVEL")
lives = await client.get_lives_async()
print(results.estimated_total_hits if results else 0)
print(len(lives or []))
asyncio.run(main())
🔐 Tokens et configuration
Par défaut, le client utilise TokenManager.get_tokens() au moment de la création :
from ffbb_data_client import FFBBDataClient, TokenManager
tokens = TokenManager.get_tokens()
client = FFBBDataClient.create(
api_bearer_token=tokens.api_token,
meilisearch_bearer_token=tokens.meilisearch_token,
)
Il est donc possible de laisser le client résoudre les tokens automatiquement ou de les fournir explicitement selon le contexte d'exécution.
🏗 Architecture
src/ffbb_data_client/
├── clients/
│ ├── ffbb_data_client.py # Façade publique (272 lignes, delegation)
│ ├── _rest_facade.py # Façade REST API (Directus)
│ ├── _search_facade.py # Façade recherche Meilisearch
│ ├── api_ffbb_app_client.py # Client REST FFBB (async source of truth)
│ └── meilisearch_ffbb_client.py # Client recherche Meilisearch
├── helpers/ # Requêtes HTTP, multi-search, conversions
├── models/ # Modèles Pydantic v2
├── utils/ # cache (sync/async séparés), tokens, logging sécurisé
└── data/ # schémas et métadonnées embarqués
Architecture sync/async : Depuis v2.1.0, les méthodes asynchrones sont la source de vérité. Les méthodes synchrones délèguent via
_run_async(), un helper qui gère les event loops imbriqués avecThreadPoolExecutor.Architecture facades : Depuis v2.2.0,
FFBBDataClientest une fine coquille qui compose_RestFacadeet_SearchFacade. L'API publique reste identique —client.get_organisme(123)fonctionne comme avant.
🧪 Développement local
pip install -e ".[testing]"
pytest tests/
Commandes utiles :
pytest tests/unit/
pytest tests/integration/
pytest tests/ --cov=src
tox -e type # mypy + pyright
Hooks automatiques :
- pre-push : exécute mypy + pyright avant chaque push
- pre-commit : black, isort, flake8, trailing-whitespace
Documentation complémentaire :
🛠️ Découverte d'API et Détection de Drift (Schema Drift)
Le projet intègre un système robuste de surveillance quotidienne de l'API de production de la FFBB (Directus & Meilisearch) afin de détecter immédiatement l'apparition de nouvelles ressources, de nouveaux champs ou de changements de types.
1. Fonctionnement
- Script de découverte :
scripts/discover_endpoints.pyinterroge dynamiquement l'OpenAPI spec Directus de la FFBB, extrait toutes les collections, sonde les index Meilisearch (via un échantillonnage agrégé sur 20 hits) et calcule les différences structurelles avec les fichiers locaux. - Détection de dérive : Le script compare les structures internes de chaque modèle (propriétés ajoutées, supprimées ou types modifiés) ainsi que les attributs Meilisearch, et génère un rapport consolidé dans
data/api_update_summary.md.
2. Automatisation CI/CD
Un workflow quotidien (update-ffbb-api-discovery.yml) s'exécute chaque matin à 5h17 UTC pour :
- Télécharger l'OpenAPI spec et sonder Meilisearch en production.
- Analyser les dérives structurelles.
- Si un changement structurel est détecté (ajout de collection, de propriétés ou d'index), le workflow ouvre automatiquement une Pull Request sur GitHub contenant un résumé des modifications pour permettre aux développeurs de mettre à jour les modèles Pydantic.
3. Exécution locale
Pour lancer manuellement la découverte d'API et mettre à jour les fichiers de schémas locaux :
python scripts/discover_endpoints.py
🤖 Intégration IA / MCP
Le client sert de base au serveur MCP FFBB et expose une API stable pour construire des outils agent-friendly : recherche de clubs, récupération de poules, classements, lives, calendriers et détails de rencontres.
Projet associé : FFBB-MCP-Server
🤝 Contribuer
Les contributions sont bienvenues :
- ouvrez une issue pour un bug ;
- proposez une évolution via les discussions ;
- lancez les tests localement avant une pull request.
📄 Licence
Distribué sous licence Apache-2.0. Voir LICENSE.txt.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ffbb_data_client-2.3.0.tar.gz.
File metadata
- Download URL: ffbb_data_client-2.3.0.tar.gz
- Upload date:
- Size: 484.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b1c57047b95384fe1bf3b84c9f3634cfc4b90bab33f324a6eba209085652ebd
|
|
| MD5 |
80952e4a844bebbcd7c6cb23856a3c29
|
|
| BLAKE2b-256 |
33e862eae0b1f848cd6e0b82226730131b435c613254a5d82b1dcc67e1dbd127
|
Provenance
The following attestation bundles were made for ffbb_data_client-2.3.0.tar.gz:
Publisher:
publish.yml on nickdesi/ffbb-data-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ffbb_data_client-2.3.0.tar.gz -
Subject digest:
5b1c57047b95384fe1bf3b84c9f3634cfc4b90bab33f324a6eba209085652ebd - Sigstore transparency entry: 1622063874
- Sigstore integration time:
-
Permalink:
nickdesi/ffbb-data-client@81d839325f378edd2b9895310606a9ce9f9e699b -
Branch / Tag:
refs/tags/v2.3.0 - Owner: https://github.com/nickdesi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@81d839325f378edd2b9895310606a9ce9f9e699b -
Trigger Event:
push
-
Statement type:
File details
Details for the file ffbb_data_client-2.3.0-py3-none-any.whl.
File metadata
- Download URL: ffbb_data_client-2.3.0-py3-none-any.whl
- Upload date:
- Size: 261.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3299444cabef4b9bac9ebc7c3419e1abb688ed58268851fe9122885fd38812d3
|
|
| MD5 |
2777502cc7497fa148a18726bf982b5e
|
|
| BLAKE2b-256 |
b0c0134396028fa55b097443a14626e692ef850265410bfae8c420d3b56d121c
|
Provenance
The following attestation bundles were made for ffbb_data_client-2.3.0-py3-none-any.whl:
Publisher:
publish.yml on nickdesi/ffbb-data-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ffbb_data_client-2.3.0-py3-none-any.whl -
Subject digest:
3299444cabef4b9bac9ebc7c3419e1abb688ed58268851fe9122885fd38812d3 - Sigstore transparency entry: 1622064051
- Sigstore integration time:
-
Permalink:
nickdesi/ffbb-data-client@81d839325f378edd2b9895310606a9ce9f9e699b -
Branch / Tag:
refs/tags/v2.3.0 - Owner: https://github.com/nickdesi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@81d839325f378edd2b9895310606a9ce9f9e699b -
Trigger Event:
push
-
Statement type: