ffbb-data-client 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ffbb_data_client-2.0.0/.coveragerc +70 -0
- ffbb_data_client-2.0.0/.github/scripts/check_wrapper_parity.py +112 -0
- ffbb_data_client-2.0.0/.github/workflows/check_wrapper_parity.yml +35 -0
- ffbb_data_client-2.0.0/.github/workflows/ci.yml +152 -0
- ffbb_data_client-2.0.0/.github/workflows/deploy-pages.yml +73 -0
- ffbb_data_client-2.0.0/.github/workflows/publish.yml +114 -0
- ffbb_data_client-2.0.0/.github/workflows/release-after-discovery-merge.yml +87 -0
- ffbb_data_client-2.0.0/.github/workflows/update-ffbb-api-discovery.yml +79 -0
- ffbb_data_client-2.0.0/.gitignore +63 -0
- ffbb_data_client-2.0.0/.isort.cfg +3 -0
- ffbb_data_client-2.0.0/.jules/bolt.md +20 -0
- ffbb_data_client-2.0.0/.pre-commit-config.yaml +68 -0
- ffbb_data_client-2.0.0/.readthedocs.yml +27 -0
- ffbb_data_client-2.0.0/AUTHORS.rst +5 -0
- ffbb_data_client-2.0.0/CHANGELOG.md +217 -0
- ffbb_data_client-2.0.0/CONTRIBUTING.rst +353 -0
- ffbb_data_client-2.0.0/LICENSE.txt +201 -0
- ffbb_data_client-2.0.0/LOCAL_CI_GUIDE.md +214 -0
- ffbb_data_client-2.0.0/PKG-INFO +339 -0
- ffbb_data_client-2.0.0/README.md +287 -0
- ffbb_data_client-2.0.0/RELEASE_NOTES.md +330 -0
- ffbb_data_client-2.0.0/benchmark_search_organisme.py +46 -0
- ffbb_data_client-2.0.0/data/api.ffbb.app.json +340 -0
- ffbb_data_client-2.0.0/data/api_update_summary.md +24 -0
- ffbb_data_client-2.0.0/data/collections.json +1364 -0
- ffbb_data_client-2.0.0/data/endpoint_discovery.json +1875 -0
- ffbb_data_client-2.0.0/data/indexes.json +501 -0
- ffbb_data_client-2.0.0/data/meilisearch-prod.ffbb.app.json +94 -0
- ffbb_data_client-2.0.0/data/openapi.json +35713 -0
- ffbb_data_client-2.0.0/data/openapi_full.json +37622 -0
- ffbb_data_client-2.0.0/data/type_discovery_corrections.json +892 -0
- ffbb_data_client-2.0.0/diagnose-ci-issues.sh +243 -0
- ffbb_data_client-2.0.0/docs/Makefile +29 -0
- ffbb_data_client-2.0.0/docs/_static/.gitignore +1 -0
- ffbb_data_client-2.0.0/docs/architecture.rst +145 -0
- ffbb_data_client-2.0.0/docs/authors.rst +2 -0
- ffbb_data_client-2.0.0/docs/changelog.rst +2 -0
- ffbb_data_client-2.0.0/docs/conf.py +288 -0
- ffbb_data_client-2.0.0/docs/contributing.rst +1 -0
- ffbb_data_client-2.0.0/docs/examples.rst +441 -0
- ffbb_data_client-2.0.0/docs/index.rst +63 -0
- ffbb_data_client-2.0.0/docs/license.rst +7 -0
- ffbb_data_client-2.0.0/docs/migration.rst +168 -0
- ffbb_data_client-2.0.0/docs/readme.rst +2 -0
- ffbb_data_client-2.0.0/docs/requirements.txt +12 -0
- ffbb_data_client-2.0.0/docs/test_strategy.md +278 -0
- ffbb_data_client-2.0.0/docs/testing_conventions.md +132 -0
- ffbb_data_client-2.0.0/examples/README.md +134 -0
- ffbb_data_client-2.0.0/examples/complete_usage_example.py +228 -0
- ffbb_data_client-2.0.0/examples/quick_start.py +137 -0
- ffbb_data_client-2.0.0/examples/team_ranking_analysis.py +563 -0
- ffbb_data_client-2.0.0/pyproject.toml +46 -0
- ffbb_data_client-2.0.0/pytest.ini +12 -0
- ffbb_data_client-2.0.0/run-ci-locally.sh +149 -0
- ffbb_data_client-2.0.0/scratch.py +21 -0
- ffbb_data_client-2.0.0/scripts/discover_endpoints.py +447 -0
- ffbb_data_client-2.0.0/scripts/discover_types.py +831 -0
- ffbb_data_client-2.0.0/setup.cfg +101 -0
- ffbb_data_client-2.0.0/setup.py +22 -0
- ffbb_data_client-2.0.0/src/ffbb_api_client_v3/__init__.py +25 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/__init__.py +175 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/clients/__init__.py +13 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/clients/api_ffbb_app_client.py +2475 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/clients/ffbb_data_client.py +2789 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/clients/meilisearch_client.py +218 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/clients/meilisearch_ffbb_client.py +647 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/config.py +153 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/data/__init__.py +25 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/data/collections.json +1364 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/data/endpoint_discovery.json +1875 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/data/indexes.json +501 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/data/openapi.json +35713 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/data/openapi_full.json +37622 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/helpers/__init__.py +27 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/helpers/http_requests_helper.py +73 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/helpers/http_requests_utils.py +502 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/helpers/meilisearch_client_extension.py +153 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/helpers/multi_search_query_helper.py +35 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/__init__.py +241 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/affiche.py +45 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/cartographie.py +82 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/categorie.py +55 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/categorie_type.py +42 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/clock.py +38 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/club_contacts.py +77 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/code.py +7 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/commune.py +66 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_fields.py +309 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_id.py +116 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_id_categorie.py +31 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_id_sexe.py +31 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_id_type_competition.py +27 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_id_type_competition_generique.py +24 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_origine.py +69 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_origine_categorie.py +23 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_origine_type_competition.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_origine_type_competition_generique.py +24 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competition_type.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competitions_facet_distribution.py +65 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competitions_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competitions_hit.py +232 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competitions_multi_search_query.py +40 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/competitions_query.py +11 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/configuration_models.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/contact_info.py +18 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/content_multi_search_query.py +93 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/coordonnees.py +27 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/coordonnees_type.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/document_flyer.py +205 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/document_flyer_type.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/engagement_contacts.py +97 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/engagements_facet_distribution.py +59 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/engagements_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/engagements_hit.py +192 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/engagements_multi_search_query.py +41 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/etat.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/external_competition_id.py +42 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/external_id.py +72 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/facet_distribution.py +13 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/facet_stats.py +13 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/field_set.py +10 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/folder.py +35 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/formation_session.py +60 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/formations_facet_distribution.py +61 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/formations_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/formations_hit.py +277 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/formations_multi_search_query.py +41 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/game_stats_model.py +57 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/game_stats_models.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/generic_search.py +92 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/geo.py +27 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/geo_sort_order.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_commune_response.py +18 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_competition_response.py +523 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_configuration_response.py +45 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_engagement_response.py +23 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_entraineur_response.py +18 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_formation_response.py +28 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_officiel_response.py +18 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_organisme_response.py +476 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_poule_response.py +68 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_pratique_response.py +18 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_rencontre_response.py +93 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_saisons_response.py +56 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_salle_response.py +20 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_terrain_response.py +16 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/get_tournoi_response.py +16 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/gradient_color.py +27 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/hit.py +16 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/id_engagement_equipe.py +32 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/id_organisme_equipe.py +51 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/id_organisme_equipe1_logo.py +28 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/id_poule.py +27 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/jour.py +11 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/label.py +15 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/labellisation.py +30 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/live.py +192 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/lives.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/logo.py +28 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_queries.py +24 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_query.py +96 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_competitions.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_engagements.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_formations.py +12 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_organismes.py +12 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_pratiques.py +12 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_rencontres.py +12 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_salles.py +12 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_terrains.py +12 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_result_tournois.py +12 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_results.py +103 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/multi_search_results_class.py +96 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/nature_sol.py +57 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/niveau.py +10 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/niveau_class.py +27 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/niveau_extractor.py +214 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/niveau_info.py +64 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/niveau_models.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/niveau_type.py +10 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/objectif.py +7 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organisateur.py +197 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organisateur_type.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organisme_fields.py +327 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organisme_id_pere.py +177 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organismes_facet_distribution.py +46 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organismes_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organismes_hit.py +196 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organismes_multi_search_query.py +41 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/organismes_query.py +8 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/phase_code.py +23 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/poule.py +35 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/poule_fields.py +261 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/poule_rencontre_item_model.py +69 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/poules_models.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/poules_query.py +9 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/pratique.py +7 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/pratiques_facet_distribution.py +29 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/pratiques_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/pratiques_hit.py +310 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/pratiques_hit_type.py +9 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/pratiques_multi_search_query.py +41 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/pratiques_type_class.py +45 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/publication_internet.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/purple_logo.py +24 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/query_fields_manager.py +75 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/ranking_engagement.py +41 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/rankings_models.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/rencontres_engagement.py +23 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/rencontres_facet_distribution.py +65 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/rencontres_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/rencontres_hit.py +271 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/rencontres_multi_search_query.py +41 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/saison.py +23 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/saison_fields.py +36 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/saisons_models.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/saisons_query.py +9 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/salle.py +56 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/salles_facet_distribution.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/salles_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/salles_hit.py +153 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/salles_multi_search_query.py +40 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/sexe.py +9 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/sexe_class.py +31 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/source.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/status.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/team_engagement.py +56 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/team_ranking.py +108 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/terrains_categorie_championnat_3x3_libelle.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/terrains_facet_distribution.py +41 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/terrains_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/terrains_hit.py +223 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/terrains_multi_search_query.py +42 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/terrains_name.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/terrains_sexe_enum.py +7 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/terrains_storage.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournoi_type_class.py +35 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournoi_type_enum.py +7 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournoi_types_3x3.py +43 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournoi_types_3x3_libelle.py +60 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournoi_types_3x3_libelle_enum.py +10 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournois_facet_distribution.py +41 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournois_facet_stats.py +14 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournois_hit.py +132 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournois_hit_type.py +5 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournois_libelle.py +7 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/tournois_multi_search_query.py +40 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/type_association.py +23 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/type_association_libelle.py +30 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/type_class.py +23 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/type_competition.py +8 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/type_competition_generique.py +31 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/type_enum.py +7 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/models/type_league.py +6 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/py.typed +0 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/utils/__init__.py +27 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/utils/cache_manager.py +393 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/utils/converter_utils.py +329 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/utils/input_validation.py +360 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/utils/retry_utils.py +478 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/utils/secure_logging.py +153 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client/utils/token_manager.py +115 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client.egg-info/PKG-INFO +339 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client.egg-info/SOURCES.txt +342 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client.egg-info/dependency_links.txt +1 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client.egg-info/not-zip-safe +1 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client.egg-info/requires.txt +18 -0
- ffbb_data_client-2.0.0/src/ffbb_data_client.egg-info/top_level.txt +2 -0
- ffbb_data_client-2.0.0/tests/conftest.py +120 -0
- ffbb_data_client-2.0.0/tests/e2e/__init__.py +0 -0
- ffbb_data_client-2.0.0/tests/e2e/conftest.py +5 -0
- ffbb_data_client-2.0.0/tests/integration/__init__.py +0 -0
- ffbb_data_client-2.0.0/tests/integration/conftest.py +5 -0
- ffbb_data_client-2.0.0/tests/integration/test_500_user_journey.py +403 -0
- ffbb_data_client-2.0.0/tests/integration/test_501_user_journey_v3.py +368 -0
- ffbb_data_client-2.0.0/tests/integration/test_502_enhanced_integration.py +259 -0
- ffbb_data_client-2.0.0/tests/integration/test_503_secure_logging.py +135 -0
- ffbb_data_client-2.0.0/tests/integration/test_504_input_validation.py +215 -0
- ffbb_data_client-2.0.0/tests/integration/test_505_retry_timeout.py +188 -0
- ffbb_data_client-2.0.0/tests/integration/test_506_raw_json_model_conversion.py +1163 -0
- ffbb_data_client-2.0.0/tests/unit/__init__.py +0 -0
- ffbb_data_client-2.0.0/tests/unit/clients/__init__.py +0 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_200_api_ffbb_app_client.py +84 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_201_unit_tests_core.py +864 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_202_meilisearch_client.py +87 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_203_meilisearch_client_extension.py +97 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_204_ffbb_data_client.py +292 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_205_meilisearch_ffbb_client.py +334 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_206_coverage_gaps_clients.py +89 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_207_coverage_clients_extended.py +388 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_208_new_methods_coverage.py +328 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_209_automatic_token_resolution.py +49 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_210_targeted_clients_helpers_coverage.py +746 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_async_methods.py +81 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_meilisearch_async.py +46 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_v2_backport_search.py +124 -0
- ffbb_data_client-2.0.0/tests/unit/clients/test_v3_new_features.py +251 -0
- ffbb_data_client-2.0.0/tests/unit/conftest.py +85 -0
- ffbb_data_client-2.0.0/tests/unit/helpers/__init__.py +0 -0
- ffbb_data_client-2.0.0/tests/unit/helpers/test_400_http_helpers.py +210 -0
- ffbb_data_client-2.0.0/tests/unit/helpers/test_meilisearch_client_extension_recursive_pagination.py +74 -0
- ffbb_data_client-2.0.0/tests/unit/models/__init__.py +0 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_100_competition_id_categorie.py +36 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_101_competition_id_sexe.py +36 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_102_competition_id_type_competition.py +38 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_103_competition_id_type_competition_generique.py +40 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_104_competition_origine_categorie.py +29 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_105_competition_origine_type_competition_generique.py +35 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_106_competition_origine.py +52 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_107_id_engagement_equipe.py +43 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_108_id_organisme_equipe.py +56 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_109_id_organisme_equipe1_logo.py +42 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_110_labellisation.py +36 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_111_niveau_class.py +36 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_112_purple_logo.py +30 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_113_salle.py +59 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_114_tournoi_type_class.py +36 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_115_type_association_libelle.py +36 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_116_type_competition_generique.py +44 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_117_organisateur.py +76 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_118_competition_id.py +61 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_119_terrains_inner_models.py +172 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_120_pratiques_inner_models.py +195 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_121_to_dict_round_trip.py +984 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_122_coverage_gaps.py +924 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_123_missing_coverage.py +578 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_123_v2_backport.py +372 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_124_targeted_coverage_gains.py +446 -0
- ffbb_data_client-2.0.0/tests/unit/models/test_dx_aliases.py +83 -0
- ffbb_data_client-2.0.0/tests/unit/utils/__init__.py +0 -0
- ffbb_data_client-2.0.0/tests/unit/utils/test_300_secure_logging.py +130 -0
- ffbb_data_client-2.0.0/tests/unit/utils/test_301_input_validation.py +313 -0
- ffbb_data_client-2.0.0/tests/unit/utils/test_302_retry_utils.py +213 -0
- ffbb_data_client-2.0.0/tests/unit/utils/test_303_cache_manager.py +224 -0
- ffbb_data_client-2.0.0/tests/unit/utils/test_304_config.py +48 -0
- ffbb_data_client-2.0.0/tests/unit/utils/test_305_token_manager.py +148 -0
- ffbb_data_client-2.0.0/tests/unit/utils/test_306_converter_utils.py +362 -0
- ffbb_data_client-2.0.0/tests/unit/utils/test_307_coverage_gaps_utils.py +449 -0
- ffbb_data_client-2.0.0/tox.ini +125 -0
- ffbb_data_client-2.0.0/website/assets/logo.webp +0 -0
- ffbb_data_client-2.0.0/website/css/style.css +490 -0
- ffbb_data_client-2.0.0/website/index.html +256 -0
- ffbb_data_client-2.0.0/website/robots.txt +4 -0
- ffbb_data_client-2.0.0/website/sitemap.xml +9 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# .coveragerc — coverage.py configuration
|
|
2
|
+
# https://coverage.readthedocs.io/en/latest/config.html
|
|
3
|
+
|
|
4
|
+
[run]
|
|
5
|
+
branch = True
|
|
6
|
+
source = ffbb_api_client_v3
|
|
7
|
+
parallel = True
|
|
8
|
+
# CRITICAL for Coveralls: ensures paths are relative to the git root
|
|
9
|
+
# Without this, Coveralls reports 0% or fails to map files
|
|
10
|
+
relative_files = True
|
|
11
|
+
omit =
|
|
12
|
+
# Test files don't need to appear in coverage reports
|
|
13
|
+
tests/*
|
|
14
|
+
tests/**/*
|
|
15
|
+
# Build artifacts
|
|
16
|
+
setup.py
|
|
17
|
+
# Type stubs
|
|
18
|
+
*.pyi
|
|
19
|
+
|
|
20
|
+
[paths]
|
|
21
|
+
# Maps coverage paths from different environments (tox, Docker, etc.)
|
|
22
|
+
# to the canonical source root. Order matters: first match wins.
|
|
23
|
+
source =
|
|
24
|
+
src/ffbb_api_client_v3
|
|
25
|
+
*/ffbb_api_client_v3
|
|
26
|
+
*/src/ffbb_api_client_v3
|
|
27
|
+
|
|
28
|
+
[report]
|
|
29
|
+
# Minimum coverage threshold — CI will fail below this
|
|
30
|
+
# Uncomment and adjust once coverage stabilizes above 90%
|
|
31
|
+
# fail_under = 90
|
|
32
|
+
|
|
33
|
+
show_missing = True
|
|
34
|
+
skip_covered = False
|
|
35
|
+
skip_empty = True
|
|
36
|
+
precision = 2
|
|
37
|
+
|
|
38
|
+
# Lines to exclude from coverage measurement
|
|
39
|
+
exclude_lines =
|
|
40
|
+
# Standard pragma
|
|
41
|
+
pragma: no cover
|
|
42
|
+
|
|
43
|
+
# Debug-only code
|
|
44
|
+
def __repr__
|
|
45
|
+
if self\.debug
|
|
46
|
+
if settings\.DEBUG
|
|
47
|
+
|
|
48
|
+
# Defensive assertions — tested via other means
|
|
49
|
+
raise AssertionError
|
|
50
|
+
raise NotImplementedError
|
|
51
|
+
|
|
52
|
+
# Non-runnable code paths
|
|
53
|
+
if 0:
|
|
54
|
+
if __name__ == .__main__.:
|
|
55
|
+
|
|
56
|
+
# Type-checking imports (not executed at runtime)
|
|
57
|
+
if TYPE_CHECKING:
|
|
58
|
+
@(abc\.)?abstractmethod
|
|
59
|
+
|
|
60
|
+
# Protocol / overload stubs
|
|
61
|
+
\.\.\.
|
|
62
|
+
|
|
63
|
+
[html]
|
|
64
|
+
directory = htmlcov
|
|
65
|
+
title = FFBBApiClientV3 Coverage
|
|
66
|
+
|
|
67
|
+
[xml]
|
|
68
|
+
# Required by coverallsapp/github-action@v2 Universal Coverage Reporter
|
|
69
|
+
# when not using lcov format
|
|
70
|
+
output = coverage.xml
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Check that FFBBDataClient wrapper exposes all methods from inner clients."""
|
|
3
|
+
|
|
4
|
+
import ast
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
ROOT = Path(__file__).resolve().parents[2]
|
|
10
|
+
CLIENTS = ROOT / "src" / "ffbb_data_client" / "clients"
|
|
11
|
+
|
|
12
|
+
# Methods / names intentionally excluded from the parity check
|
|
13
|
+
EXCLUDED = {
|
|
14
|
+
"__init__",
|
|
15
|
+
"__repr__",
|
|
16
|
+
"__str__",
|
|
17
|
+
# Singleton-factory classmethod on the wrapper itself
|
|
18
|
+
"create",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_public_methods(path: Path) -> set[str]:
|
|
23
|
+
"""Return all public method names defined in the first class of a file.
|
|
24
|
+
|
|
25
|
+
Skips:
|
|
26
|
+
- dunder methods
|
|
27
|
+
- names listed in EXCLUDED
|
|
28
|
+
- @property decorated functions (they are attributes, not callable methods)
|
|
29
|
+
- @staticmethod / @classmethod that are internal helpers
|
|
30
|
+
"""
|
|
31
|
+
tree = ast.parse(path.read_text(encoding="utf-8"))
|
|
32
|
+
methods: set[str] = set()
|
|
33
|
+
for node in ast.walk(tree):
|
|
34
|
+
if isinstance(node, ast.ClassDef):
|
|
35
|
+
for item in node.body:
|
|
36
|
+
if not isinstance(item, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
37
|
+
continue
|
|
38
|
+
name = item.name
|
|
39
|
+
if name.startswith("_") or name in EXCLUDED:
|
|
40
|
+
continue
|
|
41
|
+
# Skip @property decorated functions
|
|
42
|
+
is_property = any(
|
|
43
|
+
(isinstance(d, ast.Name) and d.id == "property")
|
|
44
|
+
or (isinstance(d, ast.Attribute) and d.attr == "property")
|
|
45
|
+
for d in item.decorator_list
|
|
46
|
+
)
|
|
47
|
+
if is_property:
|
|
48
|
+
continue
|
|
49
|
+
methods.add(name)
|
|
50
|
+
break # only first class
|
|
51
|
+
return methods
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def write_summary(text: str) -> None:
|
|
55
|
+
"""Append text to the GitHub Actions step summary if available."""
|
|
56
|
+
summary_file = os.environ.get("GITHUB_STEP_SUMMARY")
|
|
57
|
+
if summary_file:
|
|
58
|
+
with open(summary_file, "a", encoding="utf-8") as f:
|
|
59
|
+
f.write(text + "\n")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def main() -> int:
|
|
63
|
+
api_methods = get_public_methods(CLIENTS / "api_ffbb_app_client.py")
|
|
64
|
+
ms_methods = get_public_methods(CLIENTS / "meilisearch_ffbb_client.py")
|
|
65
|
+
wrapper_methods = get_public_methods(CLIENTS / "ffbb_data_client.py")
|
|
66
|
+
|
|
67
|
+
all_inner = api_methods | ms_methods
|
|
68
|
+
missing = sorted(all_inner - wrapper_methods)
|
|
69
|
+
|
|
70
|
+
if not missing:
|
|
71
|
+
msg = "## ✅ Wrapper parity OK\n\nAll public methods from inner clients are exposed in `FFBBDataClient`."
|
|
72
|
+
print(msg)
|
|
73
|
+
write_summary(msg)
|
|
74
|
+
return 0
|
|
75
|
+
|
|
76
|
+
# Build markdown report
|
|
77
|
+
lines = [
|
|
78
|
+
"## ⚠️ Wrapper parity check failed",
|
|
79
|
+
"",
|
|
80
|
+
"The following methods exist in inner clients but are **not exposed** "
|
|
81
|
+
"in `FFBBDataClient`:",
|
|
82
|
+
"",
|
|
83
|
+
"| Method | Source client |",
|
|
84
|
+
"|---|---|",
|
|
85
|
+
]
|
|
86
|
+
for m in missing:
|
|
87
|
+
source = []
|
|
88
|
+
if m in api_methods:
|
|
89
|
+
source.append("`ApiFFBBAppClient`")
|
|
90
|
+
if m in ms_methods:
|
|
91
|
+
source.append("`MeilisearchFFBBClient`")
|
|
92
|
+
lines.append(f"| `{m}` | {', '.join(source)} |")
|
|
93
|
+
|
|
94
|
+
lines += [
|
|
95
|
+
"",
|
|
96
|
+
"### How to fix",
|
|
97
|
+
"Add the missing method(s) to "
|
|
98
|
+
"`src/ffbb_data_client/clients/ffbb_data_client.py` "
|
|
99
|
+
"so they delegate to the appropriate inner client.",
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
report = "\n".join(lines)
|
|
103
|
+
Path("parity_report.md").write_text(report, encoding="utf-8")
|
|
104
|
+
print(report)
|
|
105
|
+
write_summary(report)
|
|
106
|
+
|
|
107
|
+
print(f"\n❌ {len(missing)} missing method(s) found — failing build.")
|
|
108
|
+
return 1
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
sys.exit(main())
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Check Wrapper Parity
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
paths:
|
|
7
|
+
- 'src/ffbb_data_client/clients/**'
|
|
8
|
+
pull_request:
|
|
9
|
+
paths:
|
|
10
|
+
- 'src/ffbb_data_client/clients/**'
|
|
11
|
+
schedule:
|
|
12
|
+
- cron: '0 6 * * 1' # Every Monday at 06:00 UTC
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
env:
|
|
16
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
check-parity:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout
|
|
26
|
+
uses: actions/checkout@v6
|
|
27
|
+
|
|
28
|
+
- name: Set up Python
|
|
29
|
+
uses: actions/setup-python@v6
|
|
30
|
+
with:
|
|
31
|
+
python-version: '3.11'
|
|
32
|
+
|
|
33
|
+
- name: Run parity check
|
|
34
|
+
id: parity
|
|
35
|
+
run: python .github/scripts/check_wrapper_parity.py
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# GitHub Actions — CI Pipeline
|
|
2
|
+
# Tests + Coverage → Coveralls (parallel mode, LCOV + XML)
|
|
3
|
+
# Reference: https://docs.github.com/en/actions
|
|
4
|
+
# https://github.com/coverallsapp/github-action
|
|
5
|
+
|
|
6
|
+
name: tests
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches: [master]
|
|
11
|
+
tags: ['v[0-9]*', '[0-9]+.[0-9]+*']
|
|
12
|
+
pull_request:
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
schedule:
|
|
15
|
+
# Run roughly every 15 days at 00:00 UTC
|
|
16
|
+
- cron: '0 0 1,16 * *'
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
concurrency:
|
|
22
|
+
group: >-
|
|
23
|
+
${{ github.workflow }}-${{ github.ref_type }}-
|
|
24
|
+
${{ github.event.pull_request.number || github.sha }}
|
|
25
|
+
cancel-in-progress: true
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
prepare:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
outputs:
|
|
31
|
+
wheel-distribution: ${{ steps.wheel-distribution.outputs.path }}
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
34
|
+
with: {fetch-depth: 0} # deep clone for setuptools-scm
|
|
35
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
36
|
+
id: setup-python
|
|
37
|
+
with: {python-version: "3.14"}
|
|
38
|
+
- name: Run static analysis and format checkers
|
|
39
|
+
run: pipx run pre-commit run --all-files --show-diff-on-failure
|
|
40
|
+
- name: Build package distribution files
|
|
41
|
+
run: >-
|
|
42
|
+
pipx run --python '${{ steps.setup-python.outputs.python-path }}'
|
|
43
|
+
tox -e clean,build -- --wheel
|
|
44
|
+
- name: Verify packaged discovery artefacts
|
|
45
|
+
run: |
|
|
46
|
+
python - <<'PY'
|
|
47
|
+
import json
|
|
48
|
+
import zipfile
|
|
49
|
+
from pathlib import Path
|
|
50
|
+
|
|
51
|
+
wheels = list(Path('dist').glob('*.whl'))
|
|
52
|
+
if len(wheels) != 1:
|
|
53
|
+
raise SystemExit(f'Expected one wheel, found {len(wheels)}')
|
|
54
|
+
|
|
55
|
+
required = {
|
|
56
|
+
'ffbb_data_client/data/collections.json',
|
|
57
|
+
'ffbb_data_client/data/endpoint_discovery.json',
|
|
58
|
+
'ffbb_data_client/data/indexes.json',
|
|
59
|
+
'ffbb_data_client/data/openapi.json',
|
|
60
|
+
'ffbb_data_client/data/openapi_full.json',
|
|
61
|
+
}
|
|
62
|
+
with zipfile.ZipFile(wheels[0]) as wheel:
|
|
63
|
+
names = set(wheel.namelist())
|
|
64
|
+
missing = sorted(required - names)
|
|
65
|
+
if missing:
|
|
66
|
+
raise SystemExit(f'Missing discovery artefacts in wheel: {missing}')
|
|
67
|
+
with wheel.open('ffbb_data_client/data/endpoint_discovery.json') as handle:
|
|
68
|
+
json.load(handle)
|
|
69
|
+
print('Discovery artefacts are present in the wheel.')
|
|
70
|
+
PY
|
|
71
|
+
- name: Validate distribution files
|
|
72
|
+
run: >-
|
|
73
|
+
pipx run --python '${{ steps.setup-python.outputs.python-path }}'
|
|
74
|
+
tox -e validate
|
|
75
|
+
- name: Record the path of wheel distribution
|
|
76
|
+
id: wheel-distribution
|
|
77
|
+
run: echo "path=$(ls dist/*.whl)" >> $GITHUB_OUTPUT
|
|
78
|
+
- name: Store the distribution files for use in other stages
|
|
79
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
80
|
+
with:
|
|
81
|
+
name: python-distribution-files
|
|
82
|
+
path: dist/
|
|
83
|
+
retention-days: 1
|
|
84
|
+
|
|
85
|
+
test:
|
|
86
|
+
needs: prepare
|
|
87
|
+
strategy:
|
|
88
|
+
matrix:
|
|
89
|
+
python:
|
|
90
|
+
- "3.10"
|
|
91
|
+
- "3.11"
|
|
92
|
+
- "3.12"
|
|
93
|
+
- "3.13"
|
|
94
|
+
- "3.14"
|
|
95
|
+
platform:
|
|
96
|
+
- ubuntu-latest
|
|
97
|
+
runs-on: ${{ matrix.platform }}
|
|
98
|
+
steps:
|
|
99
|
+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
100
|
+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
101
|
+
id: setup-python
|
|
102
|
+
with:
|
|
103
|
+
python-version: ${{ matrix.python }}
|
|
104
|
+
- name: Retrieve pre-built distribution files
|
|
105
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
106
|
+
with: {name: python-distribution-files, path: dist/}
|
|
107
|
+
- name: Run tests
|
|
108
|
+
env:
|
|
109
|
+
API_FFBB_APP_BEARER_TOKEN: ${{ secrets.API_FFBB_APP_BEARER_TOKEN }}
|
|
110
|
+
MEILISEARCH_BEARER_TOKEN: ${{ secrets.MEILISEARCH_BEARER_TOKEN }}
|
|
111
|
+
run: >-
|
|
112
|
+
pipx run --python '${{ steps.setup-python.outputs.python-path }}'
|
|
113
|
+
tox --installpkg '${{ needs.prepare.outputs.wheel-distribution }}'
|
|
114
|
+
|
|
115
|
+
# ── Coveralls: upload partial report (parallel mode) ─────────────────
|
|
116
|
+
# coverallsapp/github-action@v2 uses the Universal Coverage Reporter
|
|
117
|
+
# which auto-detects LCOV (preferred) or XML if lcov is absent.
|
|
118
|
+
# `parallel: true` signals that more reports are coming from other jobs.
|
|
119
|
+
# `flag-name` labels this specific combination for per-flag drill-down on Coveralls.
|
|
120
|
+
- name: Upload coverage to Coveralls (parallel)
|
|
121
|
+
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
|
|
122
|
+
with:
|
|
123
|
+
file: coverage.lcov
|
|
124
|
+
format: lcov
|
|
125
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
126
|
+
flag-name: ${{ matrix.platform }}-py${{ matrix.python }}
|
|
127
|
+
parallel: true
|
|
128
|
+
|
|
129
|
+
# ── Coveralls: finalize parallel build ─────────────────────────────────────
|
|
130
|
+
# Must run after ALL test jobs complete, even if some are skipped/cancelled.
|
|
131
|
+
# Sends the "done" signal so Coveralls calculates the merged coverage %.
|
|
132
|
+
finalize:
|
|
133
|
+
needs: test
|
|
134
|
+
runs-on: ubuntu-latest
|
|
135
|
+
# Always finalize, even if some test matrix cells failed
|
|
136
|
+
if: ${{ always() }}
|
|
137
|
+
steps:
|
|
138
|
+
- name: Finalize coverage report on Coveralls
|
|
139
|
+
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
|
|
140
|
+
with:
|
|
141
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
142
|
+
parallel-finished: true
|
|
143
|
+
|
|
144
|
+
publish:
|
|
145
|
+
needs: finalize
|
|
146
|
+
if: ${{ github.event_name == 'push' && contains(github.ref, 'refs/tags/') }}
|
|
147
|
+
runs-on: ubuntu-latest
|
|
148
|
+
steps:
|
|
149
|
+
- name: Publishing handled by Publish to PyPI workflow
|
|
150
|
+
run: |
|
|
151
|
+
echo "Tag validation completed by CI."
|
|
152
|
+
echo "PyPI publishing is centralized in .github/workflows/publish.yml."
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: Deploy landing page to Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["master", "main"]
|
|
6
|
+
tags: ["v*"]
|
|
7
|
+
# Permet de lancer manuellement depuis l'onglet Actions
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
# Permissions nécessaires pour GitHub Pages
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
|
|
14
|
+
# Permet d'annuler les déploiements obsolètes
|
|
15
|
+
concurrency:
|
|
16
|
+
group: "pages"
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
deploy:
|
|
21
|
+
environment:
|
|
22
|
+
name: github-pages
|
|
23
|
+
url: ${{ steps.pages-url.outputs.url }}
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
env:
|
|
26
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
27
|
+
steps:
|
|
28
|
+
- name: Fetch repository
|
|
29
|
+
run: |
|
|
30
|
+
set -euo pipefail
|
|
31
|
+
git init source
|
|
32
|
+
cd source
|
|
33
|
+
git remote add origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
|
|
34
|
+
git fetch --tags --force origin "${GITHUB_REF}"
|
|
35
|
+
git checkout --detach FETCH_HEAD
|
|
36
|
+
|
|
37
|
+
- name: Inject Dynamic Version for SEO
|
|
38
|
+
run: |
|
|
39
|
+
cd source
|
|
40
|
+
LATEST_TAG=$(git describe --tags --abbrev=0)
|
|
41
|
+
VERSION=${LATEST_TAG#v}
|
|
42
|
+
echo "Dernière version trouvée : $VERSION. Injection dans le JSON-LD Schema..."
|
|
43
|
+
sed -i "s/\"softwareVersion\": \"[^\"]*\"/\"softwareVersion\": \"$VERSION\"/g" website/index.html
|
|
44
|
+
|
|
45
|
+
- name: Publish website to gh-pages
|
|
46
|
+
run: |
|
|
47
|
+
set -euo pipefail
|
|
48
|
+
git init gh-pages
|
|
49
|
+
cd gh-pages
|
|
50
|
+
git remote add origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
|
|
51
|
+
if git fetch origin gh-pages --depth=1; then
|
|
52
|
+
git checkout gh-pages
|
|
53
|
+
else
|
|
54
|
+
git checkout --orphan gh-pages
|
|
55
|
+
fi
|
|
56
|
+
rsync -a --delete --exclude .git ../source/website/ ./
|
|
57
|
+
touch .nojekyll
|
|
58
|
+
git add -A
|
|
59
|
+
if git diff --cached --quiet; then
|
|
60
|
+
echo "No changes to publish."
|
|
61
|
+
exit 0
|
|
62
|
+
fi
|
|
63
|
+
git config user.name "github-actions[bot]"
|
|
64
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
65
|
+
git commit -m "Deploy website from ${GITHUB_SHA}"
|
|
66
|
+
git push --force origin HEAD:gh-pages
|
|
67
|
+
|
|
68
|
+
- name: Set Pages URL
|
|
69
|
+
id: pages-url
|
|
70
|
+
run: |
|
|
71
|
+
OWNER=${GITHUB_REPOSITORY%/*}
|
|
72
|
+
REPO=${GITHUB_REPOSITORY#*/}
|
|
73
|
+
echo "url=https://${OWNER}.github.io/${REPO}/" >> "$GITHUB_OUTPUT"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build distribution
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout
|
|
15
|
+
uses: actions/checkout@v6
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0 # Required for setuptools_scm to resolve version from tags
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v6
|
|
21
|
+
with:
|
|
22
|
+
python-version: '3.11'
|
|
23
|
+
|
|
24
|
+
- name: Install build dependencies
|
|
25
|
+
run: pip install build
|
|
26
|
+
|
|
27
|
+
- name: Build package
|
|
28
|
+
run: python -m build
|
|
29
|
+
|
|
30
|
+
- name: Verify packaged discovery artefacts
|
|
31
|
+
run: |
|
|
32
|
+
python - <<'PY'
|
|
33
|
+
import json
|
|
34
|
+
import zipfile
|
|
35
|
+
from pathlib import Path
|
|
36
|
+
|
|
37
|
+
wheels = list(Path('dist').glob('*.whl'))
|
|
38
|
+
if len(wheels) != 1:
|
|
39
|
+
raise SystemExit(f'Expected one wheel, found {len(wheels)}')
|
|
40
|
+
|
|
41
|
+
required = {
|
|
42
|
+
'ffbb_data_client/data/collections.json',
|
|
43
|
+
'ffbb_data_client/data/endpoint_discovery.json',
|
|
44
|
+
'ffbb_data_client/data/indexes.json',
|
|
45
|
+
'ffbb_data_client/data/openapi.json',
|
|
46
|
+
'ffbb_data_client/data/openapi_full.json',
|
|
47
|
+
}
|
|
48
|
+
with zipfile.ZipFile(wheels[0]) as wheel:
|
|
49
|
+
names = set(wheel.namelist())
|
|
50
|
+
missing = sorted(required - names)
|
|
51
|
+
if missing:
|
|
52
|
+
raise SystemExit(f'Missing discovery artefacts in wheel: {missing}')
|
|
53
|
+
with wheel.open('ffbb_data_client/data/endpoint_discovery.json') as handle:
|
|
54
|
+
json.load(handle)
|
|
55
|
+
print('Discovery artefacts are present in the wheel.')
|
|
56
|
+
PY
|
|
57
|
+
|
|
58
|
+
- name: Upload distribution artifacts
|
|
59
|
+
uses: actions/upload-artifact@v7
|
|
60
|
+
with:
|
|
61
|
+
name: dist
|
|
62
|
+
path: dist/
|
|
63
|
+
|
|
64
|
+
publish-pypi:
|
|
65
|
+
name: Publish to PyPI
|
|
66
|
+
needs: build
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
environment: pypi
|
|
69
|
+
permissions:
|
|
70
|
+
id-token: write # Required for OIDC Trusted Publisher
|
|
71
|
+
|
|
72
|
+
steps:
|
|
73
|
+
- name: Download distribution artifacts
|
|
74
|
+
uses: actions/download-artifact@v8
|
|
75
|
+
with:
|
|
76
|
+
name: dist
|
|
77
|
+
path: dist/
|
|
78
|
+
|
|
79
|
+
- name: Publish to PyPI
|
|
80
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
81
|
+
|
|
82
|
+
publish-github-release:
|
|
83
|
+
name: Create GitHub Release
|
|
84
|
+
needs: build
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
permissions:
|
|
87
|
+
contents: write
|
|
88
|
+
|
|
89
|
+
steps:
|
|
90
|
+
- name: Download distribution artifacts
|
|
91
|
+
uses: actions/download-artifact@v8
|
|
92
|
+
with:
|
|
93
|
+
name: dist
|
|
94
|
+
path: dist/
|
|
95
|
+
|
|
96
|
+
- name: Create GitHub Release
|
|
97
|
+
uses: softprops/action-gh-release@v3
|
|
98
|
+
with:
|
|
99
|
+
files: dist/*
|
|
100
|
+
generate_release_notes: true
|
|
101
|
+
|
|
102
|
+
notify-mcp-server:
|
|
103
|
+
name: Notify FFBB-MCP-Server
|
|
104
|
+
needs: publish-pypi
|
|
105
|
+
runs-on: ubuntu-latest
|
|
106
|
+
|
|
107
|
+
steps:
|
|
108
|
+
- name: Dispatch bump event to FFBB-MCP-Server
|
|
109
|
+
uses: peter-evans/repository-dispatch@v4
|
|
110
|
+
with:
|
|
111
|
+
token: ${{ secrets.MCP_SERVER_PAT }}
|
|
112
|
+
repository: nickdesi/FFBB-MCP-Server
|
|
113
|
+
event-type: ffbb-client-released
|
|
114
|
+
client-payload: '{"version": "${{ github.ref_name }}"}'
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: Release after FFBB API discovery merge
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: [tests]
|
|
6
|
+
types: [completed]
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
pull-requests: read
|
|
12
|
+
|
|
13
|
+
env:
|
|
14
|
+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
tag-patch-release:
|
|
18
|
+
name: Tag patch release
|
|
19
|
+
if: github.event.workflow_run.conclusion == 'success'
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Resolve merged discovery PR
|
|
24
|
+
id: pr
|
|
25
|
+
env:
|
|
26
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
27
|
+
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
28
|
+
REPOSITORY: ${{ github.repository }}
|
|
29
|
+
run: |
|
|
30
|
+
pr_json="$(gh api "repos/$REPOSITORY/commits/$HEAD_SHA/pulls" -H "Accept: application/vnd.github+json")"
|
|
31
|
+
pr_count="$(jq 'length' <<< "$pr_json")"
|
|
32
|
+
if [[ "$pr_count" == "0" ]]; then
|
|
33
|
+
echo "release=false" >> "$GITHUB_OUTPUT"
|
|
34
|
+
echo "No PR associated with $HEAD_SHA."
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
pr_number="$(jq -r '.[0].number' <<< "$pr_json")"
|
|
39
|
+
pr_merged="$(jq -r '.[0].merged_at != null' <<< "$pr_json")"
|
|
40
|
+
pr_base="$(jq -r '.[0].base.ref' <<< "$pr_json")"
|
|
41
|
+
has_label="$(jq -r '.[0].labels | map(.name) | index("ffbb-api") != null' <<< "$pr_json")"
|
|
42
|
+
|
|
43
|
+
echo "number=$pr_number" >> "$GITHUB_OUTPUT"
|
|
44
|
+
echo "release=$([[ "$pr_merged" == "true" && "$pr_base" == "master" && "$has_label" == "true" ]] && echo true || echo false)" >> "$GITHUB_OUTPUT"
|
|
45
|
+
|
|
46
|
+
echo "PR #$pr_number merged=$pr_merged base=$pr_base ffbb-api-label=$has_label"
|
|
47
|
+
|
|
48
|
+
- name: Stop when this was not a discovery PR merge
|
|
49
|
+
if: steps.pr.outputs.release != 'true'
|
|
50
|
+
run: echo "No FFBB API discovery release needed."
|
|
51
|
+
|
|
52
|
+
- name: Checkout tested commit
|
|
53
|
+
if: steps.pr.outputs.release == 'true'
|
|
54
|
+
uses: actions/checkout@v6
|
|
55
|
+
with:
|
|
56
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
57
|
+
fetch-depth: 0
|
|
58
|
+
|
|
59
|
+
- name: Compute next patch tag
|
|
60
|
+
if: steps.pr.outputs.release == 'true'
|
|
61
|
+
id: version
|
|
62
|
+
run: |
|
|
63
|
+
latest_tag="$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -n 1)"
|
|
64
|
+
if [[ -z "$latest_tag" ]]; then
|
|
65
|
+
next_tag="v0.1.0"
|
|
66
|
+
else
|
|
67
|
+
version="${latest_tag#v}"
|
|
68
|
+
IFS='.' read -r major minor patch <<< "$version"
|
|
69
|
+
next_tag="v${major}.${minor}.$((patch + 1))"
|
|
70
|
+
fi
|
|
71
|
+
echo "tag=$next_tag" >> "$GITHUB_OUTPUT"
|
|
72
|
+
echo "Next tag: $next_tag"
|
|
73
|
+
|
|
74
|
+
- name: Create and push tag
|
|
75
|
+
if: steps.pr.outputs.release == 'true'
|
|
76
|
+
env:
|
|
77
|
+
NEXT_TAG: ${{ steps.version.outputs.tag }}
|
|
78
|
+
PR_NUMBER: ${{ steps.pr.outputs.number }}
|
|
79
|
+
run: |
|
|
80
|
+
if git rev-parse "$NEXT_TAG" >/dev/null 2>&1; then
|
|
81
|
+
echo "Tag $NEXT_TAG already exists."
|
|
82
|
+
exit 0
|
|
83
|
+
fi
|
|
84
|
+
git config user.name "github-actions[bot]"
|
|
85
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
86
|
+
git tag -a "$NEXT_TAG" -m "Release $NEXT_TAG after FFBB API discovery PR #$PR_NUMBER"
|
|
87
|
+
git push origin "$NEXT_TAG"
|