ffbb-data-client 2.4.29__tar.gz → 2.4.31__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.4.29 → ffbb_data_client-2.4.31}/PKG-INFO +1 -1
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/api.py +279 -5
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/helpers/meilisearch_client_extension.py +11 -4
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/PKG-INFO +1 -1
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/SOURCES.txt +1 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/scm_file_list.json +1 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/scm_version.json +2 -2
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/helpers/test_meilisearch_client_extension_recursive_pagination.py +9 -0
- ffbb_data_client-2.4.31/tests/unit/test_314_api_endpoints.py +144 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.agents/rules/antigravity-rtk-rules.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.coveragerc +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.gitattributes +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/FUNDING.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/dependabot.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/scripts/ai-pr-reviewer.cjs +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/scripts/check_wrapper_parity.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/ai-pr-reviewer.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/check_wrapper_parity.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/ci.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/codeql.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/deploy-pages.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/keep-ffbb-api-discovery-alive.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/publish.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/release-after-discovery-merge.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/update-ffbb-api-discovery.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.gitignore +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.isort.cfg +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.jules/bolt.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.omc/skills/codeql-security-hardening-expertise.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.omc/skills/pypi-immutable-release-workflow.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.omc/skills/terminal-output-hygiene-expertise.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.pre-commit-config.yaml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.readthedocs.yml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/AGENTS.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/AUTHORS.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/CHANGELOG.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/CODE_OF_CONDUCT.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/CONTRIBUTING.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/DESIGN.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/Dockerfile +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/LICENSE.txt +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/LOCAL_CI_GUIDE.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/README.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/RELEASE_NOTES.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/SECURITY.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/api.ffbb.app.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/api_update_summary.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/collections.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/endpoint_discovery.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/field_dictionary.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/indexes.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/meilisearch-prod.ffbb.app.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/openapi.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/openapi_full.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/permission_drift_summary.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/permission_matrix.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/data/type_discovery_corrections.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/Makefile +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/_static/.gitignore +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/architecture.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/authors.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/changelog.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/conf.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/contributing.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/data_dictionary.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/examples.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/index.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/license.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/migration.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/readme.rst +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/requirements.txt +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/test_strategy.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/docs/testing_conventions.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/examples/README.md +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/examples/complete_usage_example.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/examples/quick_start.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/examples/team_ranking_analysis.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/pyproject.toml +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/run-ci-locally.sh +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/scripts/benchmark_concurrent_pagination.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/scripts/benchmark_search_organisme.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/scripts/discover_endpoints.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/scripts/discover_permissions.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/scripts/discover_types.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/setup.cfg +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/setup.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_helpers.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_mixins/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_mixins/competition.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_mixins/external.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_mixins/getters.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_mixins/list_methods.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_mixins/organisme.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_rest_facade.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/_search_facade.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/api_ffbb_app_client.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/ffbb_data_client.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/meilisearch_client.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/clients/meilisearch_ffbb_client.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/config.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/data/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/data/collections.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/data/endpoint_discovery.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/data/field_dictionary.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/data/indexes.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/data/openapi.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/data/permission_matrix.json +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/exceptions.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/helpers/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/helpers/http_requests_helper.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/helpers/http_requests_utils.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/helpers/multi_search_query_helper.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/helpers/normalization.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/affiche.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/cartographie.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/categorie.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/categorie_type.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/clock.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/club_contacts.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/code.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/commune.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_fields.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_id.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_id_categorie.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_id_sexe.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_id_type_competition.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_id_type_competition_generique.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_origine.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_origine_categorie.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_origine_type_competition.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_origine_type_competition_generique.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competition_type.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competitions_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competitions_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competitions_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competitions_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/competitions_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/configuration_models.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/contact_info.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/content_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/coordonnees.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/coordonnees_type.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/document_flyer.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/document_flyer_type.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/engagement_contacts.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/engagements_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/engagements_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/engagements_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/engagements_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/etat.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/external_competition_id.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/external_id.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/field_set.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/folder.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/formation_session.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/formations_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/formations_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/formations_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/formations_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/game_stats_model.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/game_stats_models.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/generic_search.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/geo.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/geo_sort_order.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_commune_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_competition_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_configuration_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_engagement_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_entraineur_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_formation_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_officiel_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_organisme_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_poule_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_pratique_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_rencontre_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_saisons_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_salle_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_terrain_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/get_tournoi_response.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/gradient_color.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/id_engagement_equipe.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/id_organisme_equipe.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/id_organisme_equipe1_logo.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/id_poule.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/jour.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/label.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/labellisation.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/live.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/lives.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/logo.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_queries.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_competitions.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_engagements.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_formations.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_organismes.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_pratiques.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_rencontres.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_salles.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_terrains.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_result_tournois.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_results.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/multi_search_results_class.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/nature_sol.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/niveau.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/niveau_class.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/niveau_extractor.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/niveau_info.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/niveau_models.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/niveau_type.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/objectif.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organisateur.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organisateur_type.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organisme_fields.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organisme_id_pere.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organismes_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organismes_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organismes_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organismes_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/organismes_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/phase_code.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/poule.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/poule_fields.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/poule_rencontre_item_model.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/poules_models.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/poules_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/pratique.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/pratiques_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/pratiques_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/pratiques_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/pratiques_hit_type.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/pratiques_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/pratiques_type_class.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/publication_internet.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/purple_logo.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/query_fields_manager.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/ranking_engagement.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/rankings_models.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/rencontres_engagement.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/rencontres_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/rencontres_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/rencontres_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/rencontres_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/saison.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/saison_fields.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/saisons_models.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/saisons_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/salle.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/salles_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/salles_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/salles_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/salles_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/sexe.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/sexe_class.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/source.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/status.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/team_engagement.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/team_ranking.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/terrains_categorie_championnat_3x3_libelle.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/terrains_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/terrains_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/terrains_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/terrains_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/terrains_name.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/terrains_sexe_enum.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/terrains_storage.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournoi_type_class.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournoi_type_enum.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournoi_types_3x3.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournoi_types_3x3_libelle.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournoi_types_3x3_libelle_enum.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournois_facet_distribution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournois_facet_stats.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournois_hit.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournois_hit_type.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournois_libelle.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/tournois_multi_search_query.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/type_association.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/type_association_libelle.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/type_class.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/type_competition.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/type_competition_generique.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/type_enum.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/models/type_league.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/py.typed +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/utils/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/utils/cache_manager.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/utils/concurrency_utils.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/utils/converter_utils.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/utils/input_validation.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/utils/retry_utils.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/utils/secure_logging.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client/utils/token_manager.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/dependency_links.txt +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/not-zip-safe +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/requires.txt +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/top_level.txt +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/conftest.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/e2e/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/e2e/conftest.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/conftest.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/test_500_user_journey.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/test_501_user_journey_v3.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/test_502_enhanced_integration.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/test_503_secure_logging.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/test_504_input_validation.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/test_505_retry_timeout.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/integration/test_506_raw_json_model_conversion.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_200_api_ffbb_app_client.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_201_unit_tests_core.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_202_meilisearch_client.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_203_meilisearch_client_extension.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_204_ffbb_data_client.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_205_meilisearch_ffbb_client.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_206_coverage_gaps_clients.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_207_coverage_clients_extended.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_208_new_methods_coverage.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_209_automatic_token_resolution.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_210_targeted_clients_helpers_coverage.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_api_optimizations.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_async_methods.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_meilisearch_async.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_search_many.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_v2_backport_search.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_v3_new_features.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_v4_aiter_and_contacts.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/clients/test_warm_cache.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/conftest.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/helpers/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/helpers/test_400_http_helpers.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/helpers/test_meilisearch_pagination_concurrent.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/helpers/test_normalization.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_100_competition_id_categorie.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_101_competition_id_sexe.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_102_competition_id_type_competition.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_103_competition_id_type_competition_generique.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_104_competition_origine_categorie.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_105_competition_origine_type_competition_generique.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_106_competition_origine.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_107_id_engagement_equipe.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_108_id_organisme_equipe.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_109_id_organisme_equipe1_logo.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_110_labellisation.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_111_niveau_class.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_112_purple_logo.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_113_salle.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_114_tournoi_type_class.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_115_type_association_libelle.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_116_type_competition_generique.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_117_organisateur.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_118_competition_id.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_119_terrains_inner_models.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_120_pratiques_inner_models.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_121_to_dict_round_trip.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_122_coverage_gaps.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_123_missing_coverage.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_123_v2_backport.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_124_targeted_coverage_gains.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/models/test_dx_aliases.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/test_310_discover_endpoints.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/test_311_normalize_team_name.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/test_312_api_cors.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/test_313_api_metrics.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/test_314_discover_permissions.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/__init__.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_300_secure_logging.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_301_input_validation.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_302_retry_utils.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_303_cache_manager.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_304_config.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_305_token_manager.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_306_converter_utils.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_307_coverage_gaps_utils.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_308_converter_utils_extended.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tests/unit/utils/test_309_concurrency_utils.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tools/update_agents_md.py +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/tox.ini +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/assets/apple-touch-icon.png +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/assets/favicon-192x192.png +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/assets/favicon-48x48.png +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/assets/favicon-96x96.png +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/assets/favicon.ico +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/assets/logo.webp +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/css/style.css +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/favicon.ico +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/index.html +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/llms-full.txt +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/llms.txt +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/robots.txt +0 -0
- {ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/website/sitemap.xml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ffbb-data-client
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.31
|
|
4
4
|
Summary: API FFBB — SDK Python moderne & asynchrone pour les donnees officielles de la Federation Francaise de BasketBall (clubs, classements, calendriers, lives, Meilisearch). Alternative moderne a ffbb-api-client.
|
|
5
5
|
Home-page: https://github.com/nickdesi/ffbb-data-client
|
|
6
6
|
Author: nickdesi
|
|
@@ -22,9 +22,10 @@ from typing import Any
|
|
|
22
22
|
from fastapi import FastAPI, HTTPException
|
|
23
23
|
from fastapi import Path as PathParam
|
|
24
24
|
from fastapi import Query, Request, Response
|
|
25
|
+
from fastapi.exceptions import RequestValidationError
|
|
25
26
|
from fastapi.middleware.cors import CORSMiddleware
|
|
26
27
|
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
|
|
27
|
-
from fastapi.responses import FileResponse, HTMLResponse
|
|
28
|
+
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
|
|
28
29
|
from fastapi.staticfiles import StaticFiles
|
|
29
30
|
|
|
30
31
|
from .clients.ffbb_data_client import FFBBDataClient
|
|
@@ -97,7 +98,7 @@ l'ensemble des données publiques de la **Fédération Française de BasketBall*
|
|
|
97
98
|
- ⭐ **Code Source GitHub** : [`https://github.com/nickdesi/ffbb-data-client`](https://github.com/nickdesi/ffbb-data-client)
|
|
98
99
|
- 📖 **Documentation Sphinx complète** : [`https://nickdesi.github.io/ffbb-data-client/`](https://nickdesi.github.io/ffbb-data-client/)
|
|
99
100
|
""",
|
|
100
|
-
version="2.4.
|
|
101
|
+
version="2.4.31",
|
|
101
102
|
openapi_tags=TAGS_METADATA,
|
|
102
103
|
docs_url=None,
|
|
103
104
|
redoc_url=None,
|
|
@@ -115,6 +116,66 @@ l'ensemble des données publiques de la **Fédération Française de BasketBall*
|
|
|
115
116
|
lifespan=lifespan,
|
|
116
117
|
)
|
|
117
118
|
|
|
119
|
+
|
|
120
|
+
# ---------------------------------------------------------------------------
|
|
121
|
+
# Standard Error Formatting Handlers (REST Best Practices RFC 7807)
|
|
122
|
+
# ---------------------------------------------------------------------------
|
|
123
|
+
@app.exception_handler(HTTPException)
|
|
124
|
+
async def http_exception_handler(request: Request, exc: HTTPException):
|
|
125
|
+
code_map = {
|
|
126
|
+
400: "BAD_REQUEST",
|
|
127
|
+
401: "UNAUTHORIZED",
|
|
128
|
+
403: "FORBIDDEN",
|
|
129
|
+
404: "NOT_FOUND",
|
|
130
|
+
409: "CONFLICT",
|
|
131
|
+
422: "UNPROCESSABLE_ENTITY",
|
|
132
|
+
429: "RATE_LIMIT_EXCEEDED",
|
|
133
|
+
500: "INTERNAL_SERVER_ERROR",
|
|
134
|
+
502: "BAD_GATEWAY",
|
|
135
|
+
503: "SERVICE_UNAVAILABLE",
|
|
136
|
+
}
|
|
137
|
+
error_code = code_map.get(exc.status_code, f"HTTP_{exc.status_code}")
|
|
138
|
+
message = str(exc.detail)
|
|
139
|
+
return JSONResponse(
|
|
140
|
+
status_code=exc.status_code,
|
|
141
|
+
content={
|
|
142
|
+
"detail": exc.detail,
|
|
143
|
+
"error": {
|
|
144
|
+
"code": error_code,
|
|
145
|
+
"message": message,
|
|
146
|
+
"status": exc.status_code,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
headers=getattr(exc, "headers", None),
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@app.exception_handler(RequestValidationError)
|
|
154
|
+
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
|
155
|
+
errors = []
|
|
156
|
+
for err in exc.errors():
|
|
157
|
+
field = ".".join(str(loc) for loc in err.get("loc", []))
|
|
158
|
+
errors.append(
|
|
159
|
+
{
|
|
160
|
+
"field": field,
|
|
161
|
+
"message": err.get("msg", ""),
|
|
162
|
+
"type": err.get("type", ""),
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
return JSONResponse(
|
|
166
|
+
status_code=422,
|
|
167
|
+
content={
|
|
168
|
+
"detail": exc.errors(),
|
|
169
|
+
"error": {
|
|
170
|
+
"code": "VALIDATION_ERROR",
|
|
171
|
+
"message": "Erreur de validation des paramètres de la requête.",
|
|
172
|
+
"status": 422,
|
|
173
|
+
"errors": errors,
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
|
|
118
179
|
_cors_env = os.getenv("FFBB_CORS_ORIGINS", "*")
|
|
119
180
|
_cors_origins = [origin.strip() for origin in _cors_env.split(",") if origin.strip()]
|
|
120
181
|
if "*" in _cors_origins:
|
|
@@ -589,6 +650,42 @@ async def health():
|
|
|
589
650
|
}
|
|
590
651
|
|
|
591
652
|
|
|
653
|
+
@app.get(
|
|
654
|
+
"/health/ready",
|
|
655
|
+
tags=["Monitoring & Diagnostic"],
|
|
656
|
+
summary="Readiness probe avec dépendances (/health/ready)",
|
|
657
|
+
)
|
|
658
|
+
async def health_ready(response: Response):
|
|
659
|
+
"""Vérifie la disponibilité réelle du serveur et de ses dépendances amont (Directus & Meilisearch)."""
|
|
660
|
+
client = get_client()
|
|
661
|
+
checks: dict[str, str] = {}
|
|
662
|
+
is_ready = True
|
|
663
|
+
|
|
664
|
+
try:
|
|
665
|
+
saisons = await client.get_saisons_async()
|
|
666
|
+
checks["directus"] = "ok" if saisons else "empty"
|
|
667
|
+
except Exception as e:
|
|
668
|
+
checks["directus"] = f"error: {e}"
|
|
669
|
+
is_ready = False
|
|
670
|
+
|
|
671
|
+
try:
|
|
672
|
+
res = client.multi_search(name="Clermont")
|
|
673
|
+
checks["meilisearch"] = "ok" if res else "empty"
|
|
674
|
+
except Exception as e:
|
|
675
|
+
checks["meilisearch"] = f"error: {e}"
|
|
676
|
+
is_ready = False
|
|
677
|
+
|
|
678
|
+
if not is_ready:
|
|
679
|
+
response.status_code = 503
|
|
680
|
+
|
|
681
|
+
return {
|
|
682
|
+
"status": "ready" if is_ready else "not_ready",
|
|
683
|
+
"service": "ffbb-data-client-api",
|
|
684
|
+
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
685
|
+
"checks": checks,
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
|
|
592
689
|
@app.head("/health", include_in_schema=False)
|
|
593
690
|
async def health_head():
|
|
594
691
|
return Response(status_code=200)
|
|
@@ -693,9 +790,23 @@ async def search_ffbb(
|
|
|
693
790
|
status_code=400,
|
|
694
791
|
detail="Le terme de recherche doit comporter au moins 2 caractères.",
|
|
695
792
|
)
|
|
793
|
+
# Résolution des acronymes fréquents (ex: SCBA -> Stade Clermontois Basket Auvergne)
|
|
794
|
+
_SEARCH_ACRONYMS = {
|
|
795
|
+
"SCBA": "Stade Clermontois Basket Auvergne",
|
|
796
|
+
"SCBF": "Stade Clermontois Basket Féminin",
|
|
797
|
+
"ASVEL": "LDLC ASVEL",
|
|
798
|
+
"SIG": "Strasbourg IG",
|
|
799
|
+
"JDA": "JDA Dijon",
|
|
800
|
+
"MSB": "Le Mans Sarthe Basket",
|
|
801
|
+
"EBPLO": "Elan Béarnais",
|
|
802
|
+
"CSP": "Limoges CSP",
|
|
803
|
+
"BCM": "Gravelines Dunkerque",
|
|
804
|
+
"ESSM": "Le Portel",
|
|
805
|
+
}
|
|
806
|
+
effective_query = _SEARCH_ACRONYMS.get(search_term.upper(), search_term)
|
|
696
807
|
client = get_client()
|
|
697
808
|
try:
|
|
698
|
-
results = client.multi_search(name=
|
|
809
|
+
results = client.multi_search(name=effective_query)
|
|
699
810
|
return results
|
|
700
811
|
except Exception as e:
|
|
701
812
|
raise HTTPException(status_code=500, detail=f"Erreur de recherche: {e}")
|
|
@@ -708,6 +819,7 @@ async def search_ffbb(
|
|
|
708
819
|
response_description="Liste ordonnée des rencontres avec adresses et logos",
|
|
709
820
|
)
|
|
710
821
|
async def get_club_matches(
|
|
822
|
+
response: Response,
|
|
711
823
|
organisme_id: int = PathParam(
|
|
712
824
|
...,
|
|
713
825
|
ge=1,
|
|
@@ -719,6 +831,19 @@ async def get_club_matches(
|
|
|
719
831
|
description="Filtrer par équipe (ex: 'SENIOR M1', 'U18 M1', 'ALL')",
|
|
720
832
|
examples=["SENIOR M1"],
|
|
721
833
|
),
|
|
834
|
+
limit: int | None = Query(
|
|
835
|
+
None,
|
|
836
|
+
ge=1,
|
|
837
|
+
le=500,
|
|
838
|
+
description="Nombre maximal de rencontres à renvoyer (pagination)",
|
|
839
|
+
examples=[50],
|
|
840
|
+
),
|
|
841
|
+
offset: int = Query(
|
|
842
|
+
0,
|
|
843
|
+
ge=0,
|
|
844
|
+
description="Décalage de pagination",
|
|
845
|
+
examples=[0],
|
|
846
|
+
),
|
|
722
847
|
):
|
|
723
848
|
"""
|
|
724
849
|
Récupère l'ensemble des rencontres officielles FFBB d'un club,
|
|
@@ -975,6 +1100,14 @@ async def get_club_matches(
|
|
|
975
1100
|
else (parsed_cat.numero_equipe if parsed_cat.numero_equipe else 1)
|
|
976
1101
|
)
|
|
977
1102
|
|
|
1103
|
+
res1 = getattr(m, "resultatEquipe1", None)
|
|
1104
|
+
res2 = getattr(m, "resultatEquipe2", None)
|
|
1105
|
+
is_played = bool(
|
|
1106
|
+
getattr(m, "joue", False) or res1 is not None or res2 is not None
|
|
1107
|
+
)
|
|
1108
|
+
score_local = res1 if is_home else res2
|
|
1109
|
+
score_opp = res2 if is_home else res1
|
|
1110
|
+
|
|
978
1111
|
match_data: dict[str, Any] = {
|
|
979
1112
|
"ffbbMatchId": m_id,
|
|
980
1113
|
"team": scba_team,
|
|
@@ -990,6 +1123,14 @@ async def get_club_matches(
|
|
|
990
1123
|
"competition": comp_nom,
|
|
991
1124
|
"poule": poule_nom,
|
|
992
1125
|
"pouleId": poule_id,
|
|
1126
|
+
"round": getattr(m, "numeroJournee", None)
|
|
1127
|
+
or getattr(m, "numero_journee", None),
|
|
1128
|
+
"isPlayed": is_played,
|
|
1129
|
+
"scoreLocal": score_local,
|
|
1130
|
+
"scoreOpponent": score_opp,
|
|
1131
|
+
"scoreEquipe1": res1,
|
|
1132
|
+
"scoreEquipe2": res2,
|
|
1133
|
+
"competitionUrl": getattr(m, "url_competition", "") or "",
|
|
993
1134
|
"teamLogo": club_logo_url,
|
|
994
1135
|
}
|
|
995
1136
|
if opponent_logo:
|
|
@@ -1003,12 +1144,27 @@ async def get_club_matches(
|
|
|
1003
1144
|
matches_list = [m for m in built_matches if m is not None]
|
|
1004
1145
|
|
|
1005
1146
|
matches_list.sort(key=lambda x: (x.get("dateISO", ""), x.get("time", "")))
|
|
1147
|
+
response.headers["Cache-Control"] = "public, max-age=180, stale-while-revalidate=60"
|
|
1148
|
+
|
|
1149
|
+
total_count = len(matches_list)
|
|
1150
|
+
paged_matches = (
|
|
1151
|
+
matches_list[offset : offset + limit]
|
|
1152
|
+
if limit is not None
|
|
1153
|
+
else matches_list[offset:]
|
|
1154
|
+
)
|
|
1006
1155
|
|
|
1007
1156
|
return {
|
|
1008
1157
|
"organisme_id": organisme_id,
|
|
1009
1158
|
"club": club_name,
|
|
1010
|
-
"matches":
|
|
1011
|
-
"count": len(
|
|
1159
|
+
"matches": paged_matches,
|
|
1160
|
+
"count": len(paged_matches),
|
|
1161
|
+
"total": total_count,
|
|
1162
|
+
"pagination": {
|
|
1163
|
+
"total": total_count,
|
|
1164
|
+
"limit": limit if limit is not None else total_count,
|
|
1165
|
+
"offset": offset,
|
|
1166
|
+
"has_more": (offset + len(paged_matches)) < total_count,
|
|
1167
|
+
},
|
|
1012
1168
|
}
|
|
1013
1169
|
|
|
1014
1170
|
|
|
@@ -1119,6 +1275,7 @@ async def get_poule(
|
|
|
1119
1275
|
response_description="Classement détaillé avec points, victoires et goal-average",
|
|
1120
1276
|
)
|
|
1121
1277
|
async def get_poule_classement(
|
|
1278
|
+
response: Response,
|
|
1122
1279
|
poule_id: int = PathParam(
|
|
1123
1280
|
..., ge=1, description="ID de la poule FFBB", examples=[129759]
|
|
1124
1281
|
),
|
|
@@ -1137,6 +1294,9 @@ async def get_poule_classement(
|
|
|
1137
1294
|
or getattr(poule, "classements", [])
|
|
1138
1295
|
or []
|
|
1139
1296
|
)
|
|
1297
|
+
response.headers["Cache-Control"] = (
|
|
1298
|
+
"public, max-age=300, stale-while-revalidate=60"
|
|
1299
|
+
)
|
|
1140
1300
|
return {
|
|
1141
1301
|
"poule_id": poule_id,
|
|
1142
1302
|
"nom": getattr(poule, "nom", "") or getattr(poule, "libelle", ""),
|
|
@@ -1164,6 +1324,120 @@ async def get_lives():
|
|
|
1164
1324
|
raise HTTPException(status_code=500, detail=str(e))
|
|
1165
1325
|
|
|
1166
1326
|
|
|
1327
|
+
@app.get(
|
|
1328
|
+
"/api/v1/rencontre/{rencontre_id}",
|
|
1329
|
+
tags=["Matchs & Calendriers"],
|
|
1330
|
+
summary="Détails complets d'une rencontre FFBB",
|
|
1331
|
+
response_description="Fiche officielle détaillée de la rencontre, scores, salle et officiels",
|
|
1332
|
+
)
|
|
1333
|
+
@app.get(
|
|
1334
|
+
"/api/v1/match/{rencontre_id}",
|
|
1335
|
+
tags=["Matchs & Calendriers"],
|
|
1336
|
+
summary="Détails complets d'une rencontre FFBB (alias /match)",
|
|
1337
|
+
include_in_schema=False,
|
|
1338
|
+
)
|
|
1339
|
+
async def get_rencontre_detail(
|
|
1340
|
+
rencontre_id: str = PathParam(
|
|
1341
|
+
...,
|
|
1342
|
+
description="ID FFBB de la rencontre (ex: '200000014753740')",
|
|
1343
|
+
examples=["200000014753740"],
|
|
1344
|
+
),
|
|
1345
|
+
):
|
|
1346
|
+
"""Retourne la fiche détaillée d'un match officiel FFBB avec scores, salle résolue et détails des équipes."""
|
|
1347
|
+
client = get_client()
|
|
1348
|
+
try:
|
|
1349
|
+
match_data = await client.get_rencontre_async(rencontre_id)
|
|
1350
|
+
if not match_data:
|
|
1351
|
+
raise HTTPException(
|
|
1352
|
+
status_code=404, detail=f"Rencontre {rencontre_id} introuvable."
|
|
1353
|
+
)
|
|
1354
|
+
return match_data
|
|
1355
|
+
except HTTPException:
|
|
1356
|
+
raise
|
|
1357
|
+
except Exception as e:
|
|
1358
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
@app.get(
|
|
1362
|
+
"/api/v1/salle/{salle_id}",
|
|
1363
|
+
tags=["Clubs"],
|
|
1364
|
+
summary="Détails d'une salle / gymnase",
|
|
1365
|
+
response_description="Fiche gymnase avec adresse complète et géolocalisation",
|
|
1366
|
+
)
|
|
1367
|
+
async def get_salle_detail(
|
|
1368
|
+
response: Response,
|
|
1369
|
+
salle_id: str = PathParam(
|
|
1370
|
+
...,
|
|
1371
|
+
description="ID FFBB de la salle (ex: '6543')",
|
|
1372
|
+
examples=["6543"],
|
|
1373
|
+
),
|
|
1374
|
+
):
|
|
1375
|
+
"""Retourne les informations complètes d'un gymnase (nom, rue, code postal, ville, cartographie)."""
|
|
1376
|
+
client = get_client()
|
|
1377
|
+
try:
|
|
1378
|
+
salle = await client.get_salle_async(salle_id)
|
|
1379
|
+
if not salle:
|
|
1380
|
+
raise HTTPException(
|
|
1381
|
+
status_code=404, detail=f"Salle {salle_id} introuvable."
|
|
1382
|
+
)
|
|
1383
|
+
response.headers["Cache-Control"] = (
|
|
1384
|
+
"public, max-age=86400, stale-while-revalidate=3600"
|
|
1385
|
+
)
|
|
1386
|
+
return salle
|
|
1387
|
+
except HTTPException:
|
|
1388
|
+
raise
|
|
1389
|
+
except Exception as e:
|
|
1390
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
@app.get(
|
|
1394
|
+
"/api/v1/competition/{competition_id}",
|
|
1395
|
+
tags=["Compétitions & Poules"],
|
|
1396
|
+
summary="Détails d'une compétition",
|
|
1397
|
+
response_description="Informations sur la compétition et composition des poules",
|
|
1398
|
+
)
|
|
1399
|
+
async def get_competition_detail(
|
|
1400
|
+
competition_id: int = PathParam(
|
|
1401
|
+
...,
|
|
1402
|
+
ge=1,
|
|
1403
|
+
description="ID FFBB de la compétition (ex: 200000002898785)",
|
|
1404
|
+
examples=[200000002898785],
|
|
1405
|
+
),
|
|
1406
|
+
):
|
|
1407
|
+
"""Retourne les métadonnées et la liste des poules associées à une compétition officielle FFBB."""
|
|
1408
|
+
client = get_client()
|
|
1409
|
+
try:
|
|
1410
|
+
comp = await client.get_competition_async(competition_id)
|
|
1411
|
+
if not comp:
|
|
1412
|
+
raise HTTPException(
|
|
1413
|
+
status_code=404,
|
|
1414
|
+
detail=f"Compétition {competition_id} introuvable.",
|
|
1415
|
+
)
|
|
1416
|
+
return comp
|
|
1417
|
+
except HTTPException:
|
|
1418
|
+
raise
|
|
1419
|
+
except Exception as e:
|
|
1420
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
@app.get(
|
|
1424
|
+
"/api/v1/saisons",
|
|
1425
|
+
tags=["Compétitions & Poules"],
|
|
1426
|
+
summary="Liste des saisons officielles FFBB",
|
|
1427
|
+
response_description="Historique et saison active",
|
|
1428
|
+
)
|
|
1429
|
+
async def get_saisons(response: Response):
|
|
1430
|
+
"""Retourne la liste des saisons officielles FFBB avec indication de la saison en cours."""
|
|
1431
|
+
client = get_client()
|
|
1432
|
+
try:
|
|
1433
|
+
response.headers["Cache-Control"] = (
|
|
1434
|
+
"public, max-age=86400, stale-while-revalidate=3600"
|
|
1435
|
+
)
|
|
1436
|
+
return await client.get_saisons_async()
|
|
1437
|
+
except Exception as e:
|
|
1438
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
1439
|
+
|
|
1440
|
+
|
|
1167
1441
|
# --------------------------------------------------------------------------
|
|
1168
1442
|
# Modern API Documentation Interfaces (Scalar, Swagger UI, ReDoc)
|
|
1169
1443
|
# --------------------------------------------------------------------------
|
|
@@ -79,10 +79,11 @@ def _build_pagination_jobs(
|
|
|
79
79
|
return jobs
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
def _single_result(multi: MultiSearchResults, index: int) -> MultiSearchResults:
|
|
82
|
+
def _single_result(multi: MultiSearchResults, index: int) -> MultiSearchResults | None:
|
|
83
83
|
"""Isole le i-ème sous-résultat d'un multi_search dans un MultiSearchResults
|
|
84
84
|
à un élément, pour une fusion cohérente avec ``_merge_page``."""
|
|
85
|
-
|
|
85
|
+
if not multi.results or index >= len(multi.results):
|
|
86
|
+
return None
|
|
86
87
|
return MultiSearchResults(results=[multi.results[index]])
|
|
87
88
|
|
|
88
89
|
|
|
@@ -148,7 +149,10 @@ class MeilisearchClientExtension(MeilisearchClient):
|
|
|
148
149
|
out: list[tuple[int, int, MultiSearchResults | None]] = []
|
|
149
150
|
if new_result and new_result.results:
|
|
150
151
|
for k, (orig_idx, offset, _q) in enumerate(batch):
|
|
151
|
-
|
|
152
|
+
if k < len(new_result.results):
|
|
153
|
+
res = _single_result(new_result, k)
|
|
154
|
+
if res is not None:
|
|
155
|
+
out.append((orig_idx, offset, res))
|
|
152
156
|
return out
|
|
153
157
|
|
|
154
158
|
async def _fetch_batch_async(
|
|
@@ -162,7 +166,10 @@ class MeilisearchClientExtension(MeilisearchClient):
|
|
|
162
166
|
out: list[tuple[int, int, MultiSearchResults | None]] = []
|
|
163
167
|
if new_result and new_result.results:
|
|
164
168
|
for k, (orig_idx, offset, _q) in enumerate(batch):
|
|
165
|
-
|
|
169
|
+
if k < len(new_result.results):
|
|
170
|
+
res = _single_result(new_result, k)
|
|
171
|
+
if res is not None:
|
|
172
|
+
out.append((orig_idx, offset, res))
|
|
166
173
|
return out
|
|
167
174
|
|
|
168
175
|
def recursive_smart_multi_search(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ffbb-data-client
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.31
|
|
4
4
|
Summary: API FFBB — SDK Python moderne & asynchrone pour les donnees officielles de la Federation Francaise de BasketBall (clubs, classements, calendriers, lives, Meilisearch). Alternative moderne a ffbb-api-client.
|
|
5
5
|
Home-page: https://github.com/nickdesi/ffbb-data-client
|
|
6
6
|
Author: nickdesi
|
{ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/SOURCES.txt
RENAMED
|
@@ -320,6 +320,7 @@ tests/unit/test_310_discover_endpoints.py
|
|
|
320
320
|
tests/unit/test_311_normalize_team_name.py
|
|
321
321
|
tests/unit/test_312_api_cors.py
|
|
322
322
|
tests/unit/test_313_api_metrics.py
|
|
323
|
+
tests/unit/test_314_api_endpoints.py
|
|
323
324
|
tests/unit/test_314_discover_permissions.py
|
|
324
325
|
tests/unit/clients/__init__.py
|
|
325
326
|
tests/unit/clients/test_200_api_ffbb_app_client.py
|
{ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/src/ffbb_data_client.egg-info/scm_file_list.json
RENAMED
|
@@ -366,6 +366,7 @@
|
|
|
366
366
|
"tests/unit/test_311_normalize_team_name.py",
|
|
367
367
|
"tests/unit/test_312_api_cors.py",
|
|
368
368
|
"tests/unit/test_313_api_metrics.py",
|
|
369
|
+
"tests/unit/test_314_api_endpoints.py",
|
|
369
370
|
"tests/unit/test_314_discover_permissions.py",
|
|
370
371
|
"tests/unit/utils/__init__.py",
|
|
371
372
|
"tests/unit/utils/test_300_secure_logging.py",
|
|
@@ -91,3 +91,12 @@ def test_merge_page_with_empty_or_missing_results():
|
|
|
91
91
|
|
|
92
92
|
# 3. orig_idx out of bounds
|
|
93
93
|
_merge_page(res, 999, empty_page)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_single_result_out_of_bounds_safety():
|
|
97
|
+
from ffbb_data_client.helpers.meilisearch_client_extension import _single_result
|
|
98
|
+
|
|
99
|
+
res = MultiSearchResults(results=[CompetitionsMultiSearchResult()])
|
|
100
|
+
assert _single_result(res, 0) is not None
|
|
101
|
+
assert _single_result(res, 1) is None
|
|
102
|
+
assert _single_result(MultiSearchResults(results=[]), 0) is None
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""Tests for the REST endpoints, Best Practices, error envelopes, and caching in api.py."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import AsyncMock, MagicMock, patch
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from httpx import ASGITransport, AsyncClient
|
|
7
|
+
|
|
8
|
+
from ffbb_data_client.api import app
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.mark.asyncio
|
|
12
|
+
async def test_search_acronym_expansion():
|
|
13
|
+
transport = ASGITransport(app=app)
|
|
14
|
+
mock_client = MagicMock()
|
|
15
|
+
mock_client.multi_search = MagicMock(
|
|
16
|
+
return_value=[
|
|
17
|
+
{"index_uid": "organismes", "hits": [{"nom": "STADE CLERMONTOIS"}]}
|
|
18
|
+
]
|
|
19
|
+
)
|
|
20
|
+
with patch("ffbb_data_client.api.get_client", return_value=mock_client):
|
|
21
|
+
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
22
|
+
r = await ac.get("/api/v1/search?query=SCBA")
|
|
23
|
+
assert r.status_code == 200
|
|
24
|
+
mock_client.multi_search.assert_called_with(
|
|
25
|
+
name="Stade Clermontois Basket Auvergne"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.mark.asyncio
|
|
30
|
+
async def test_health_ready_endpoint():
|
|
31
|
+
transport = ASGITransport(app=app)
|
|
32
|
+
mock_client = MagicMock()
|
|
33
|
+
mock_client.get_saisons_async = AsyncMock(return_value=[{"id": "1037"}])
|
|
34
|
+
mock_client.multi_search = MagicMock(return_value=[{"hits": []}])
|
|
35
|
+
|
|
36
|
+
with patch("ffbb_data_client.api.get_client", return_value=mock_client):
|
|
37
|
+
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
38
|
+
r = await ac.get("/health/ready")
|
|
39
|
+
assert r.status_code == 200
|
|
40
|
+
data = r.json()
|
|
41
|
+
assert data.get("status") == "ready"
|
|
42
|
+
assert data.get("checks", {}).get("directus") == "ok"
|
|
43
|
+
assert data.get("checks", {}).get("meilisearch") == "ok"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@pytest.mark.asyncio
|
|
47
|
+
async def test_standard_error_envelope_404():
|
|
48
|
+
transport = ASGITransport(app=app)
|
|
49
|
+
mock_client = MagicMock()
|
|
50
|
+
mock_client.get_organisme_async = AsyncMock(return_value=None)
|
|
51
|
+
|
|
52
|
+
with patch("ffbb_data_client.api.get_client", return_value=mock_client):
|
|
53
|
+
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
54
|
+
r = await ac.get("/api/v1/club/999999")
|
|
55
|
+
assert r.status_code == 404
|
|
56
|
+
data = r.json()
|
|
57
|
+
assert "detail" in data
|
|
58
|
+
assert "error" in data
|
|
59
|
+
assert data["error"]["code"] == "NOT_FOUND"
|
|
60
|
+
assert data["error"]["status"] == 404
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@pytest.mark.asyncio
|
|
64
|
+
async def test_standard_validation_error_422():
|
|
65
|
+
transport = ASGITransport(app=app)
|
|
66
|
+
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
67
|
+
# Invalid query param length
|
|
68
|
+
r = await ac.get("/api/v1/club/not_a_number")
|
|
69
|
+
assert r.status_code == 422
|
|
70
|
+
data = r.json()
|
|
71
|
+
assert "error" in data
|
|
72
|
+
assert data["error"]["code"] == "VALIDATION_ERROR"
|
|
73
|
+
assert len(data["error"]["errors"]) > 0
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@pytest.mark.asyncio
|
|
77
|
+
async def test_match_card_enrichment_and_pagination():
|
|
78
|
+
transport = ASGITransport(app=app)
|
|
79
|
+
mock_client = MagicMock()
|
|
80
|
+
mock_org = MagicMock()
|
|
81
|
+
mock_org.nom = "STADE CLERMONTOIS BASKET AUVERGNE"
|
|
82
|
+
mock_org.logo = None
|
|
83
|
+
mock_org.engagements = []
|
|
84
|
+
mock_client.get_organisme_async = AsyncMock(return_value=mock_org)
|
|
85
|
+
|
|
86
|
+
with patch("ffbb_data_client.api.get_client", return_value=mock_client):
|
|
87
|
+
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
88
|
+
r = await ac.get("/api/v1/club/9326/matches?limit=10&offset=0")
|
|
89
|
+
assert r.status_code == 200
|
|
90
|
+
assert "Cache-Control" in r.headers
|
|
91
|
+
data = r.json()
|
|
92
|
+
assert "matches" in data
|
|
93
|
+
assert "pagination" in data
|
|
94
|
+
assert data["pagination"]["limit"] == 10
|
|
95
|
+
assert data["pagination"]["offset"] == 0
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@pytest.mark.asyncio
|
|
99
|
+
async def test_rencontre_endpoint():
|
|
100
|
+
transport = ASGITransport(app=app)
|
|
101
|
+
mock_client = MagicMock()
|
|
102
|
+
mock_match = {"id": "12345", "nomEquipe1": "Eq A", "nomEquipe2": "Eq B"}
|
|
103
|
+
mock_client.get_rencontre_async = AsyncMock(return_value=mock_match)
|
|
104
|
+
|
|
105
|
+
with patch("ffbb_data_client.api.get_client", return_value=mock_client):
|
|
106
|
+
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
107
|
+
r = await ac.get("/api/v1/rencontre/12345")
|
|
108
|
+
assert r.status_code == 200
|
|
109
|
+
assert r.json().get("id") == "12345"
|
|
110
|
+
|
|
111
|
+
# Test alias /match
|
|
112
|
+
r_alias = await ac.get("/api/v1/match/12345")
|
|
113
|
+
assert r_alias.status_code == 200
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@pytest.mark.asyncio
|
|
117
|
+
async def test_salle_and_competition_endpoints_caching():
|
|
118
|
+
transport = ASGITransport(app=app)
|
|
119
|
+
mock_client = MagicMock()
|
|
120
|
+
mock_client.get_salle_async = AsyncMock(
|
|
121
|
+
return_value={"id": "6543", "libelle": "Gymnase Fleury"}
|
|
122
|
+
)
|
|
123
|
+
mock_client.get_competition_async = AsyncMock(
|
|
124
|
+
return_value={"id": "999", "nom": "DMU13"}
|
|
125
|
+
)
|
|
126
|
+
mock_client.get_saisons_async = AsyncMock(
|
|
127
|
+
return_value=[{"id": "1037", "nom": "2026-2027"}]
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
with patch("ffbb_data_client.api.get_client", return_value=mock_client):
|
|
131
|
+
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
132
|
+
r_salle = await ac.get("/api/v1/salle/6543")
|
|
133
|
+
assert r_salle.status_code == 200
|
|
134
|
+
assert "Cache-Control" in r_salle.headers
|
|
135
|
+
assert "max-age=86400" in r_salle.headers["Cache-Control"]
|
|
136
|
+
|
|
137
|
+
r_comp = await ac.get("/api/v1/competition/999")
|
|
138
|
+
assert r_comp.status_code == 200
|
|
139
|
+
assert r_comp.json().get("nom") == "DMU13"
|
|
140
|
+
|
|
141
|
+
r_saisons = await ac.get("/api/v1/saisons")
|
|
142
|
+
assert r_saisons.status_code == 200
|
|
143
|
+
assert "Cache-Control" in r_saisons.headers
|
|
144
|
+
assert len(r_saisons.json()) == 1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/ISSUE_TEMPLATE/feature_request.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/check_wrapper_parity.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ffbb_data_client-2.4.29 → ffbb_data_client-2.4.31}/.github/workflows/update-ffbb-api-discovery.yml
RENAMED
|
File without changes
|
|
File without changes
|