ffbb-data-client 2.4.30__tar.gz → 2.4.32__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.
Files changed (403) hide show
  1. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/PKG-INFO +1 -1
  2. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/api.py +260 -7
  3. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client.egg-info/PKG-INFO +1 -1
  4. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client.egg-info/scm_version.json +2 -2
  5. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/test_314_api_endpoints.py +58 -6
  6. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.agents/rules/antigravity-rtk-rules.md +0 -0
  7. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.coveragerc +0 -0
  8. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.gitattributes +0 -0
  9. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/FUNDING.yml +0 -0
  10. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  11. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  12. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  13. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/dependabot.yml +0 -0
  14. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/scripts/ai-pr-reviewer.cjs +0 -0
  15. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/scripts/check_wrapper_parity.py +0 -0
  16. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/ai-pr-reviewer.yml +0 -0
  17. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/check_wrapper_parity.yml +0 -0
  18. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/ci.yml +0 -0
  19. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/codeql.yml +0 -0
  20. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/deploy-pages.yml +0 -0
  21. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/keep-ffbb-api-discovery-alive.yml +0 -0
  22. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/publish.yml +0 -0
  23. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/release-after-discovery-merge.yml +0 -0
  24. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.github/workflows/update-ffbb-api-discovery.yml +0 -0
  25. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.gitignore +0 -0
  26. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.isort.cfg +0 -0
  27. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.jules/bolt.md +0 -0
  28. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.omc/skills/codeql-security-hardening-expertise.md +0 -0
  29. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.omc/skills/pypi-immutable-release-workflow.md +0 -0
  30. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.omc/skills/terminal-output-hygiene-expertise.md +0 -0
  31. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.pre-commit-config.yaml +0 -0
  32. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/.readthedocs.yml +0 -0
  33. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/AGENTS.md +0 -0
  34. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/AUTHORS.rst +0 -0
  35. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/CHANGELOG.md +0 -0
  36. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/CODE_OF_CONDUCT.md +0 -0
  37. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/CONTRIBUTING.rst +0 -0
  38. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/DESIGN.md +0 -0
  39. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/Dockerfile +0 -0
  40. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/LICENSE.txt +0 -0
  41. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/LOCAL_CI_GUIDE.md +0 -0
  42. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/README.md +0 -0
  43. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/RELEASE_NOTES.md +0 -0
  44. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/SECURITY.md +0 -0
  45. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/api.ffbb.app.json +0 -0
  46. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/api_update_summary.md +0 -0
  47. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/collections.json +0 -0
  48. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/endpoint_discovery.json +0 -0
  49. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/field_dictionary.json +0 -0
  50. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/indexes.json +0 -0
  51. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/meilisearch-prod.ffbb.app.json +0 -0
  52. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/openapi.json +0 -0
  53. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/openapi_full.json +0 -0
  54. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/permission_drift_summary.md +0 -0
  55. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/permission_matrix.json +0 -0
  56. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/data/type_discovery_corrections.json +0 -0
  57. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/Makefile +0 -0
  58. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/_static/.gitignore +0 -0
  59. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/architecture.rst +0 -0
  60. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/authors.rst +0 -0
  61. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/changelog.rst +0 -0
  62. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/conf.py +0 -0
  63. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/contributing.rst +0 -0
  64. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/data_dictionary.rst +0 -0
  65. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/examples.rst +0 -0
  66. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/index.rst +0 -0
  67. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/license.rst +0 -0
  68. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/migration.rst +0 -0
  69. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/readme.rst +0 -0
  70. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/requirements.txt +0 -0
  71. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/test_strategy.md +0 -0
  72. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/docs/testing_conventions.md +0 -0
  73. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/examples/README.md +0 -0
  74. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/examples/complete_usage_example.py +0 -0
  75. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/examples/quick_start.py +0 -0
  76. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/examples/team_ranking_analysis.py +0 -0
  77. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/pyproject.toml +0 -0
  78. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/run-ci-locally.sh +0 -0
  79. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/scripts/benchmark_concurrent_pagination.py +0 -0
  80. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/scripts/benchmark_search_organisme.py +0 -0
  81. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/scripts/discover_endpoints.py +0 -0
  82. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/scripts/discover_permissions.py +0 -0
  83. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/scripts/discover_types.py +0 -0
  84. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/setup.cfg +0 -0
  85. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/setup.py +0 -0
  86. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/__init__.py +0 -0
  87. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/__init__.py +0 -0
  88. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_helpers.py +0 -0
  89. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_mixins/__init__.py +0 -0
  90. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_mixins/competition.py +0 -0
  91. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_mixins/external.py +0 -0
  92. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_mixins/getters.py +0 -0
  93. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_mixins/list_methods.py +0 -0
  94. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_mixins/organisme.py +0 -0
  95. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_rest_facade.py +0 -0
  96. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/_search_facade.py +0 -0
  97. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/api_ffbb_app_client.py +0 -0
  98. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/ffbb_data_client.py +0 -0
  99. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/meilisearch_client.py +0 -0
  100. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/clients/meilisearch_ffbb_client.py +0 -0
  101. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/config.py +0 -0
  102. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/data/__init__.py +0 -0
  103. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/data/collections.json +0 -0
  104. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/data/endpoint_discovery.json +0 -0
  105. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/data/field_dictionary.json +0 -0
  106. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/data/indexes.json +0 -0
  107. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/data/openapi.json +0 -0
  108. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/data/permission_matrix.json +0 -0
  109. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/exceptions.py +0 -0
  110. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/helpers/__init__.py +0 -0
  111. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/helpers/http_requests_helper.py +0 -0
  112. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/helpers/http_requests_utils.py +0 -0
  113. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/helpers/meilisearch_client_extension.py +0 -0
  114. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/helpers/multi_search_query_helper.py +0 -0
  115. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/helpers/normalization.py +0 -0
  116. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/__init__.py +0 -0
  117. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/affiche.py +0 -0
  118. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/cartographie.py +0 -0
  119. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/categorie.py +0 -0
  120. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/categorie_type.py +0 -0
  121. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/clock.py +0 -0
  122. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/club_contacts.py +0 -0
  123. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/code.py +0 -0
  124. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/commune.py +0 -0
  125. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_fields.py +0 -0
  126. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_id.py +0 -0
  127. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_id_categorie.py +0 -0
  128. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_id_sexe.py +0 -0
  129. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_id_type_competition.py +0 -0
  130. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_id_type_competition_generique.py +0 -0
  131. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_origine.py +0 -0
  132. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_origine_categorie.py +0 -0
  133. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_origine_type_competition.py +0 -0
  134. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_origine_type_competition_generique.py +0 -0
  135. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competition_type.py +0 -0
  136. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competitions_facet_distribution.py +0 -0
  137. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competitions_facet_stats.py +0 -0
  138. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competitions_hit.py +0 -0
  139. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competitions_multi_search_query.py +0 -0
  140. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/competitions_query.py +0 -0
  141. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/configuration_models.py +0 -0
  142. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/contact_info.py +0 -0
  143. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/content_multi_search_query.py +0 -0
  144. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/coordonnees.py +0 -0
  145. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/coordonnees_type.py +0 -0
  146. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/document_flyer.py +0 -0
  147. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/document_flyer_type.py +0 -0
  148. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/engagement_contacts.py +0 -0
  149. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/engagements_facet_distribution.py +0 -0
  150. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/engagements_facet_stats.py +0 -0
  151. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/engagements_hit.py +0 -0
  152. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/engagements_multi_search_query.py +0 -0
  153. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/etat.py +0 -0
  154. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/external_competition_id.py +0 -0
  155. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/external_id.py +0 -0
  156. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/facet_distribution.py +0 -0
  157. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/facet_stats.py +0 -0
  158. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/field_set.py +0 -0
  159. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/folder.py +0 -0
  160. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/formation_session.py +0 -0
  161. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/formations_facet_distribution.py +0 -0
  162. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/formations_facet_stats.py +0 -0
  163. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/formations_hit.py +0 -0
  164. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/formations_multi_search_query.py +0 -0
  165. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/game_stats_model.py +0 -0
  166. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/game_stats_models.py +0 -0
  167. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/generic_search.py +0 -0
  168. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/geo.py +0 -0
  169. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/geo_sort_order.py +0 -0
  170. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_commune_response.py +0 -0
  171. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_competition_response.py +0 -0
  172. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_configuration_response.py +0 -0
  173. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_engagement_response.py +0 -0
  174. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_entraineur_response.py +0 -0
  175. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_formation_response.py +0 -0
  176. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_officiel_response.py +0 -0
  177. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_organisme_response.py +0 -0
  178. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_poule_response.py +0 -0
  179. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_pratique_response.py +0 -0
  180. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_rencontre_response.py +0 -0
  181. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_saisons_response.py +0 -0
  182. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_salle_response.py +0 -0
  183. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_terrain_response.py +0 -0
  184. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/get_tournoi_response.py +0 -0
  185. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/gradient_color.py +0 -0
  186. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/hit.py +0 -0
  187. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/id_engagement_equipe.py +0 -0
  188. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/id_organisme_equipe.py +0 -0
  189. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/id_organisme_equipe1_logo.py +0 -0
  190. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/id_poule.py +0 -0
  191. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/jour.py +0 -0
  192. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/label.py +0 -0
  193. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/labellisation.py +0 -0
  194. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/live.py +0 -0
  195. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/lives.py +0 -0
  196. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/logo.py +0 -0
  197. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_queries.py +0 -0
  198. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_query.py +0 -0
  199. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_competitions.py +0 -0
  200. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_engagements.py +0 -0
  201. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_formations.py +0 -0
  202. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_organismes.py +0 -0
  203. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_pratiques.py +0 -0
  204. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_rencontres.py +0 -0
  205. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_salles.py +0 -0
  206. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_terrains.py +0 -0
  207. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_result_tournois.py +0 -0
  208. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_results.py +0 -0
  209. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/multi_search_results_class.py +0 -0
  210. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/nature_sol.py +0 -0
  211. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/niveau.py +0 -0
  212. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/niveau_class.py +0 -0
  213. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/niveau_extractor.py +0 -0
  214. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/niveau_info.py +0 -0
  215. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/niveau_models.py +0 -0
  216. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/niveau_type.py +0 -0
  217. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/objectif.py +0 -0
  218. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organisateur.py +0 -0
  219. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organisateur_type.py +0 -0
  220. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organisme_fields.py +0 -0
  221. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organisme_id_pere.py +0 -0
  222. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organismes_facet_distribution.py +0 -0
  223. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organismes_facet_stats.py +0 -0
  224. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organismes_hit.py +0 -0
  225. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organismes_multi_search_query.py +0 -0
  226. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/organismes_query.py +0 -0
  227. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/phase_code.py +0 -0
  228. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/poule.py +0 -0
  229. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/poule_fields.py +0 -0
  230. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/poule_rencontre_item_model.py +0 -0
  231. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/poules_models.py +0 -0
  232. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/poules_query.py +0 -0
  233. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/pratique.py +0 -0
  234. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/pratiques_facet_distribution.py +0 -0
  235. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/pratiques_facet_stats.py +0 -0
  236. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/pratiques_hit.py +0 -0
  237. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/pratiques_hit_type.py +0 -0
  238. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/pratiques_multi_search_query.py +0 -0
  239. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/pratiques_type_class.py +0 -0
  240. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/publication_internet.py +0 -0
  241. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/purple_logo.py +0 -0
  242. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/query_fields_manager.py +0 -0
  243. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/ranking_engagement.py +0 -0
  244. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/rankings_models.py +0 -0
  245. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/rencontres_engagement.py +0 -0
  246. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/rencontres_facet_distribution.py +0 -0
  247. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/rencontres_facet_stats.py +0 -0
  248. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/rencontres_hit.py +0 -0
  249. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/rencontres_multi_search_query.py +0 -0
  250. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/saison.py +0 -0
  251. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/saison_fields.py +0 -0
  252. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/saisons_models.py +0 -0
  253. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/saisons_query.py +0 -0
  254. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/salle.py +0 -0
  255. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/salles_facet_distribution.py +0 -0
  256. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/salles_facet_stats.py +0 -0
  257. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/salles_hit.py +0 -0
  258. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/salles_multi_search_query.py +0 -0
  259. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/sexe.py +0 -0
  260. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/sexe_class.py +0 -0
  261. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/source.py +0 -0
  262. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/status.py +0 -0
  263. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/team_engagement.py +0 -0
  264. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/team_ranking.py +0 -0
  265. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/terrains_categorie_championnat_3x3_libelle.py +0 -0
  266. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/terrains_facet_distribution.py +0 -0
  267. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/terrains_facet_stats.py +0 -0
  268. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/terrains_hit.py +0 -0
  269. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/terrains_multi_search_query.py +0 -0
  270. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/terrains_name.py +0 -0
  271. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/terrains_sexe_enum.py +0 -0
  272. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/terrains_storage.py +0 -0
  273. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournoi_type_class.py +0 -0
  274. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournoi_type_enum.py +0 -0
  275. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournoi_types_3x3.py +0 -0
  276. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournoi_types_3x3_libelle.py +0 -0
  277. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournoi_types_3x3_libelle_enum.py +0 -0
  278. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournois_facet_distribution.py +0 -0
  279. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournois_facet_stats.py +0 -0
  280. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournois_hit.py +0 -0
  281. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournois_hit_type.py +0 -0
  282. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournois_libelle.py +0 -0
  283. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/tournois_multi_search_query.py +0 -0
  284. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/type_association.py +0 -0
  285. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/type_association_libelle.py +0 -0
  286. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/type_class.py +0 -0
  287. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/type_competition.py +0 -0
  288. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/type_competition_generique.py +0 -0
  289. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/type_enum.py +0 -0
  290. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/models/type_league.py +0 -0
  291. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/py.typed +0 -0
  292. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/utils/__init__.py +0 -0
  293. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/utils/cache_manager.py +0 -0
  294. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/utils/concurrency_utils.py +0 -0
  295. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/utils/converter_utils.py +0 -0
  296. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/utils/input_validation.py +0 -0
  297. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/utils/retry_utils.py +0 -0
  298. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/utils/secure_logging.py +0 -0
  299. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client/utils/token_manager.py +0 -0
  300. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client.egg-info/SOURCES.txt +0 -0
  301. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client.egg-info/dependency_links.txt +0 -0
  302. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client.egg-info/not-zip-safe +0 -0
  303. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client.egg-info/requires.txt +0 -0
  304. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client.egg-info/scm_file_list.json +0 -0
  305. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/src/ffbb_data_client.egg-info/top_level.txt +0 -0
  306. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/conftest.py +0 -0
  307. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/e2e/__init__.py +0 -0
  308. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/e2e/conftest.py +0 -0
  309. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/__init__.py +0 -0
  310. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/conftest.py +0 -0
  311. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/test_500_user_journey.py +0 -0
  312. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/test_501_user_journey_v3.py +0 -0
  313. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/test_502_enhanced_integration.py +0 -0
  314. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/test_503_secure_logging.py +0 -0
  315. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/test_504_input_validation.py +0 -0
  316. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/test_505_retry_timeout.py +0 -0
  317. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/integration/test_506_raw_json_model_conversion.py +0 -0
  318. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/__init__.py +0 -0
  319. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/__init__.py +0 -0
  320. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_200_api_ffbb_app_client.py +0 -0
  321. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_201_unit_tests_core.py +0 -0
  322. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_202_meilisearch_client.py +0 -0
  323. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_203_meilisearch_client_extension.py +0 -0
  324. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_204_ffbb_data_client.py +0 -0
  325. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_205_meilisearch_ffbb_client.py +0 -0
  326. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_206_coverage_gaps_clients.py +0 -0
  327. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_207_coverage_clients_extended.py +0 -0
  328. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_208_new_methods_coverage.py +0 -0
  329. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_209_automatic_token_resolution.py +0 -0
  330. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_210_targeted_clients_helpers_coverage.py +0 -0
  331. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_api_optimizations.py +0 -0
  332. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_async_methods.py +0 -0
  333. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_meilisearch_async.py +0 -0
  334. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_search_many.py +0 -0
  335. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_v2_backport_search.py +0 -0
  336. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_v3_new_features.py +0 -0
  337. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_v4_aiter_and_contacts.py +0 -0
  338. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/clients/test_warm_cache.py +0 -0
  339. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/conftest.py +0 -0
  340. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/helpers/__init__.py +0 -0
  341. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/helpers/test_400_http_helpers.py +0 -0
  342. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/helpers/test_meilisearch_client_extension_recursive_pagination.py +0 -0
  343. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/helpers/test_meilisearch_pagination_concurrent.py +0 -0
  344. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/helpers/test_normalization.py +0 -0
  345. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/__init__.py +0 -0
  346. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_100_competition_id_categorie.py +0 -0
  347. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_101_competition_id_sexe.py +0 -0
  348. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_102_competition_id_type_competition.py +0 -0
  349. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_103_competition_id_type_competition_generique.py +0 -0
  350. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_104_competition_origine_categorie.py +0 -0
  351. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_105_competition_origine_type_competition_generique.py +0 -0
  352. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_106_competition_origine.py +0 -0
  353. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_107_id_engagement_equipe.py +0 -0
  354. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_108_id_organisme_equipe.py +0 -0
  355. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_109_id_organisme_equipe1_logo.py +0 -0
  356. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_110_labellisation.py +0 -0
  357. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_111_niveau_class.py +0 -0
  358. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_112_purple_logo.py +0 -0
  359. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_113_salle.py +0 -0
  360. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_114_tournoi_type_class.py +0 -0
  361. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_115_type_association_libelle.py +0 -0
  362. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_116_type_competition_generique.py +0 -0
  363. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_117_organisateur.py +0 -0
  364. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_118_competition_id.py +0 -0
  365. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_119_terrains_inner_models.py +0 -0
  366. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_120_pratiques_inner_models.py +0 -0
  367. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_121_to_dict_round_trip.py +0 -0
  368. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_122_coverage_gaps.py +0 -0
  369. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_123_missing_coverage.py +0 -0
  370. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_123_v2_backport.py +0 -0
  371. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_124_targeted_coverage_gains.py +0 -0
  372. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/models/test_dx_aliases.py +0 -0
  373. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/test_310_discover_endpoints.py +0 -0
  374. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/test_311_normalize_team_name.py +0 -0
  375. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/test_312_api_cors.py +0 -0
  376. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/test_313_api_metrics.py +0 -0
  377. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/test_314_discover_permissions.py +0 -0
  378. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/__init__.py +0 -0
  379. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_300_secure_logging.py +0 -0
  380. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_301_input_validation.py +0 -0
  381. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_302_retry_utils.py +0 -0
  382. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_303_cache_manager.py +0 -0
  383. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_304_config.py +0 -0
  384. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_305_token_manager.py +0 -0
  385. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_306_converter_utils.py +0 -0
  386. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_307_coverage_gaps_utils.py +0 -0
  387. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_308_converter_utils_extended.py +0 -0
  388. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tests/unit/utils/test_309_concurrency_utils.py +0 -0
  389. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tools/update_agents_md.py +0 -0
  390. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/tox.ini +0 -0
  391. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/assets/apple-touch-icon.png +0 -0
  392. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/assets/favicon-192x192.png +0 -0
  393. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/assets/favicon-48x48.png +0 -0
  394. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/assets/favicon-96x96.png +0 -0
  395. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/assets/favicon.ico +0 -0
  396. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/assets/logo.webp +0 -0
  397. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/css/style.css +0 -0
  398. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/favicon.ico +0 -0
  399. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/index.html +0 -0
  400. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/llms-full.txt +0 -0
  401. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/llms.txt +0 -0
  402. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/website/robots.txt +0 -0
  403. {ffbb_data_client-2.4.30 → ffbb_data_client-2.4.32}/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.30
3
+ Version: 2.4.32
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,10 +22,13 @@ 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.openapi.utils import get_openapi
29
+ from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
28
30
  from fastapi.staticfiles import StaticFiles
31
+ from pydantic import BaseModel, Field
29
32
 
30
33
  from .clients.ffbb_data_client import FFBBDataClient
31
34
  from .helpers.normalization import parse_categorie
@@ -75,14 +78,71 @@ TAGS_METADATA = [
75
78
  },
76
79
  ]
77
80
 
81
+
82
+ # ---------------------------------------------------------------------------
83
+ # OpenAPI 3.1 Components & Models (https://www.openapis.org/)
84
+ # ---------------------------------------------------------------------------
85
+ class ErrorDetail(BaseModel):
86
+ code: str = Field(
87
+ description="Code d'erreur machine RFC 7807 (ex: NOT_FOUND, BAD_REQUEST)"
88
+ )
89
+ message: str = Field(
90
+ description="Message d'erreur descriptif lisible pour l'humain"
91
+ )
92
+ status: int = Field(description="Code statut HTTP (ex: 404, 400, 500)")
93
+ errors: list[dict[str, Any]] | None = Field(
94
+ default=None, description="Détails complémentaires de validation si applicable"
95
+ )
96
+
97
+
98
+ class ErrorResponse(BaseModel):
99
+ detail: Any = Field(description="Détail brut rétro-compatible FastAPI")
100
+ error: ErrorDetail = Field(description="Enveloppe d'erreur standardisée")
101
+
102
+
103
+ class HealthResponse(BaseModel):
104
+ status: str = Field(description="Statut du service ('healthy')")
105
+ service: str = Field(description="Nom du service")
106
+ timestamp: str = Field(description="Horodatage ISO-8601 UTC")
107
+
108
+
109
+ class ReadinessResponse(BaseModel):
110
+ status: str = Field(description="Statut de préparation ('ready' ou 'not_ready')")
111
+ service: str = Field(description="Nom du service")
112
+ timestamp: str = Field(description="Horodatage ISO-8601 UTC")
113
+ checks: dict[str, str] = Field(
114
+ description="État individuel des dépendances amont (Directus, Meilisearch)"
115
+ )
116
+
117
+
118
+ COMMON_RESPONSES = {
119
+ 400: {
120
+ "model": ErrorResponse,
121
+ "description": "Requête invalide ou paramètre manquant",
122
+ },
123
+ 404: {"model": ErrorResponse, "description": "Ressource demandée introuvable"},
124
+ 422: {
125
+ "model": ErrorResponse,
126
+ "description": "Erreur de validation sémantique des paramètres",
127
+ },
128
+ 500: {
129
+ "model": ErrorResponse,
130
+ "description": "Erreur interne du serveur ou indisponibilité amont FFBB",
131
+ },
132
+ 503: {
133
+ "model": ErrorResponse,
134
+ "description": "Dépendance amont FFBB temporairement indisponible",
135
+ },
136
+ }
78
137
  app = FastAPI(
79
138
  title="FFBB REST API — Données Officielles du Basket Français",
139
+ summary="API REST officielle & Open Data Basketball pour la Fédération Française de BasketBall",
80
140
  description="""
81
141
  # 🏀 API REST FFBB & Open Data Basketball
82
142
 
83
143
  Bienvenue sur la documentation interactive officielle de l'API **FFBB Data Client**.
84
144
 
85
- Cette API REST moderne et asynchrone (FastAPI + Pydantic v2) permet d'interroger directement
145
+ Cette API REST moderne et asynchrone (FastAPI + Pydantic v2, spécification OpenAPI 3.1) permet d'interroger directement
86
146
  l'ensemble des données publiques de la **Fédération Française de BasketBall** :
87
147
  - **Clubs & Équipes** : fiches, contacts, adresses et engagements (du niveau départemental à la Betclic Élite).
88
148
  - **Compétitions & Poules** : calendriers, résultats, feuilles de match et classements officiels.
@@ -97,7 +157,18 @@ l'ensemble des données publiques de la **Fédération Française de BasketBall*
97
157
  - ⭐ **Code Source GitHub** : [`https://github.com/nickdesi/ffbb-data-client`](https://github.com/nickdesi/ffbb-data-client)
98
158
  - 📖 **Documentation Sphinx complète** : [`https://nickdesi.github.io/ffbb-data-client/`](https://nickdesi.github.io/ffbb-data-client/)
99
159
  """,
100
- version="2.4.30",
160
+ version="2.4.32",
161
+ contact={
162
+ "name": "FFBB Data Client — Support & Open Data",
163
+ "url": "https://github.com/nickdesi/ffbb-data-client/issues",
164
+ "email": "nicolas.desimone@gmail.com",
165
+ },
166
+ license_info={
167
+ "name": "Apache-2.0",
168
+ "identifier": "Apache-2.0",
169
+ "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
170
+ },
171
+ terms_of_service="https://github.com/nickdesi/ffbb-data-client/blob/master/LICENSE.txt",
101
172
  openapi_tags=TAGS_METADATA,
102
173
  docs_url=None,
103
174
  redoc_url=None,
@@ -112,9 +183,97 @@ l'ensemble des données publiques de la **Fédération Française de BasketBall*
112
183
  "description": "Serveur Local de Développement",
113
184
  },
114
185
  ],
186
+ responses=COMMON_RESPONSES,
115
187
  lifespan=lifespan,
116
188
  )
117
189
 
190
+
191
+ def custom_openapi():
192
+ if app.openapi_schema:
193
+ return app.openapi_schema
194
+ openapi_schema = get_openapi(
195
+ title=app.title,
196
+ version=app.version,
197
+ openapi_version=app.openapi_version,
198
+ summary=app.summary,
199
+ description=app.description,
200
+ routes=app.routes,
201
+ tags=app.openapi_tags,
202
+ servers=app.servers,
203
+ terms_of_service=app.terms_of_service,
204
+ contact=app.contact,
205
+ license_info=app.license_info,
206
+ )
207
+ openapi_schema["externalDocs"] = {
208
+ "description": "Documentation Sphinx & Spécifications Officielles",
209
+ "url": "https://nickdesi.github.io/ffbb-data-client/",
210
+ }
211
+ app.openapi_schema = openapi_schema
212
+ return app.openapi_schema
213
+
214
+
215
+ app.openapi = custom_openapi
216
+
217
+
218
+ # ---------------------------------------------------------------------------
219
+ # Standard Error Formatting Handlers (REST Best Practices RFC 7807)
220
+ # ---------------------------------------------------------------------------
221
+ @app.exception_handler(HTTPException)
222
+ async def http_exception_handler(request: Request, exc: HTTPException):
223
+ code_map = {
224
+ 400: "BAD_REQUEST",
225
+ 401: "UNAUTHORIZED",
226
+ 403: "FORBIDDEN",
227
+ 404: "NOT_FOUND",
228
+ 409: "CONFLICT",
229
+ 422: "UNPROCESSABLE_ENTITY",
230
+ 429: "RATE_LIMIT_EXCEEDED",
231
+ 500: "INTERNAL_SERVER_ERROR",
232
+ 502: "BAD_GATEWAY",
233
+ 503: "SERVICE_UNAVAILABLE",
234
+ }
235
+ error_code = code_map.get(exc.status_code, f"HTTP_{exc.status_code}")
236
+ message = str(exc.detail)
237
+ return JSONResponse(
238
+ status_code=exc.status_code,
239
+ content={
240
+ "detail": exc.detail,
241
+ "error": {
242
+ "code": error_code,
243
+ "message": message,
244
+ "status": exc.status_code,
245
+ },
246
+ },
247
+ headers=getattr(exc, "headers", None),
248
+ )
249
+
250
+
251
+ @app.exception_handler(RequestValidationError)
252
+ async def validation_exception_handler(request: Request, exc: RequestValidationError):
253
+ errors = []
254
+ for err in exc.errors():
255
+ field = ".".join(str(loc) for loc in err.get("loc", []))
256
+ errors.append(
257
+ {
258
+ "field": field,
259
+ "message": err.get("msg", ""),
260
+ "type": err.get("type", ""),
261
+ }
262
+ )
263
+ return JSONResponse(
264
+ status_code=422,
265
+ content={
266
+ "detail": exc.errors(),
267
+ "error": {
268
+ "code": "VALIDATION_ERROR",
269
+ "message": "Erreur de validation des paramètres de la requête.",
270
+ "status": 422,
271
+ "errors": errors,
272
+ },
273
+ },
274
+ )
275
+
276
+
118
277
  _cors_env = os.getenv("FFBB_CORS_ORIGINS", "*")
119
278
  _cors_origins = [origin.strip() for origin in _cors_env.split(",") if origin.strip()]
120
279
  if "*" in _cors_origins:
@@ -578,7 +737,11 @@ async def resolve_exact_salle_address_async(
578
737
 
579
738
 
580
739
  @app.get(
581
- "/health", tags=["Monitoring & Diagnostic"], summary="Diagnostic de l'API (/health)"
740
+ "/health",
741
+ tags=["Monitoring & Diagnostic"],
742
+ summary="Diagnostic de l'API (/health)",
743
+ operation_id="getHealth",
744
+ response_model=HealthResponse,
582
745
  )
583
746
  async def health():
584
747
  """Vérifie l'état de fonctionnement et la disponibilité de l'API REST."""
@@ -589,6 +752,44 @@ async def health():
589
752
  }
590
753
 
591
754
 
755
+ @app.get(
756
+ "/health/ready",
757
+ tags=["Monitoring & Diagnostic"],
758
+ summary="Readiness probe avec dépendances (/health/ready)",
759
+ operation_id="getReadiness",
760
+ response_model=ReadinessResponse,
761
+ )
762
+ async def health_ready(response: Response):
763
+ """Vérifie la disponibilité réelle du serveur et de ses dépendances amont (Directus & Meilisearch)."""
764
+ client = get_client()
765
+ checks: dict[str, str] = {}
766
+ is_ready = True
767
+
768
+ try:
769
+ saisons = await client.get_saisons_async()
770
+ checks["directus"] = "ok" if saisons else "empty"
771
+ except Exception as e:
772
+ checks["directus"] = f"error: {e}"
773
+ is_ready = False
774
+
775
+ try:
776
+ res = client.multi_search(name="Clermont")
777
+ checks["meilisearch"] = "ok" if res else "empty"
778
+ except Exception as e:
779
+ checks["meilisearch"] = f"error: {e}"
780
+ is_ready = False
781
+
782
+ if not is_ready:
783
+ response.status_code = 503
784
+
785
+ return {
786
+ "status": "ready" if is_ready else "not_ready",
787
+ "service": "ffbb-data-client-api",
788
+ "timestamp": datetime.now(timezone.utc).isoformat(),
789
+ "checks": checks,
790
+ }
791
+
792
+
592
793
  @app.head("/health", include_in_schema=False)
593
794
  async def health_head():
594
795
  return Response(status_code=200)
@@ -598,6 +799,7 @@ async def health_head():
598
799
  "/metrics",
599
800
  tags=["Monitoring & Diagnostic"],
600
801
  summary="Métriques Prometheus de l'API (/metrics)",
802
+ operation_id="getPrometheusMetrics",
601
803
  response_class=Response,
602
804
  )
603
805
  async def metrics():
@@ -660,6 +862,7 @@ async def metrics():
660
862
 
661
863
  @app.get(
662
864
  "/api/v1/search",
865
+ operation_id="searchFFBB",
663
866
  tags=["Recherche & Meilisearch"],
664
867
  summary="Recherche universelle (Clubs, Compétitions, Salles)",
665
868
  response_description="Résultats multi-index Meilisearch groupés par typologie",
@@ -717,11 +920,13 @@ async def search_ffbb(
717
920
 
718
921
  @app.get(
719
922
  "/api/v1/club/{organisme_id}/matches",
923
+ operation_id="getClubMatches",
720
924
  tags=["Matchs & Calendriers"],
721
925
  summary="Calendrier & Matchs d'un club",
722
926
  response_description="Liste ordonnée des rencontres avec adresses et logos",
723
927
  )
724
928
  async def get_club_matches(
929
+ response: Response,
725
930
  organisme_id: int = PathParam(
726
931
  ...,
727
932
  ge=1,
@@ -733,6 +938,19 @@ async def get_club_matches(
733
938
  description="Filtrer par équipe (ex: 'SENIOR M1', 'U18 M1', 'ALL')",
734
939
  examples=["SENIOR M1"],
735
940
  ),
941
+ limit: int | None = Query(
942
+ None,
943
+ ge=1,
944
+ le=500,
945
+ description="Nombre maximal de rencontres à renvoyer (pagination)",
946
+ examples=[50],
947
+ ),
948
+ offset: int = Query(
949
+ 0,
950
+ ge=0,
951
+ description="Décalage de pagination",
952
+ examples=[0],
953
+ ),
736
954
  ):
737
955
  """
738
956
  Récupère l'ensemble des rencontres officielles FFBB d'un club,
@@ -1033,17 +1251,33 @@ async def get_club_matches(
1033
1251
  matches_list = [m for m in built_matches if m is not None]
1034
1252
 
1035
1253
  matches_list.sort(key=lambda x: (x.get("dateISO", ""), x.get("time", "")))
1254
+ response.headers["Cache-Control"] = "public, max-age=180, stale-while-revalidate=60"
1255
+
1256
+ total_count = len(matches_list)
1257
+ paged_matches = (
1258
+ matches_list[offset : offset + limit]
1259
+ if limit is not None
1260
+ else matches_list[offset:]
1261
+ )
1036
1262
 
1037
1263
  return {
1038
1264
  "organisme_id": organisme_id,
1039
1265
  "club": club_name,
1040
- "matches": matches_list,
1041
- "count": len(matches_list),
1266
+ "matches": paged_matches,
1267
+ "count": len(paged_matches),
1268
+ "total": total_count,
1269
+ "pagination": {
1270
+ "total": total_count,
1271
+ "limit": limit if limit is not None else total_count,
1272
+ "offset": offset,
1273
+ "has_more": (offset + len(paged_matches)) < total_count,
1274
+ },
1042
1275
  }
1043
1276
 
1044
1277
 
1045
1278
  @app.get(
1046
1279
  "/api/v1/club/{organisme_id}/teams",
1280
+ operation_id="getClubTeams",
1047
1281
  tags=["Clubs"],
1048
1282
  summary="Équipes engagées d'un club",
1049
1283
  response_description="Liste des équipes engagées par championnat",
@@ -1093,6 +1327,7 @@ async def get_club_teams(
1093
1327
 
1094
1328
  @app.get(
1095
1329
  "/api/v1/club/{organisme_id}",
1330
+ operation_id="getClubDetails",
1096
1331
  tags=["Clubs"],
1097
1332
  summary="Fiche détaillée d'un club",
1098
1333
  response_description="Informations administratives, contacts et salle",
@@ -1120,6 +1355,7 @@ async def get_club_details(
1120
1355
 
1121
1356
  @app.get(
1122
1357
  "/api/v1/poule/{poule_id}",
1358
+ operation_id="getPoule",
1123
1359
  tags=["Compétitions & Poules"],
1124
1360
  summary="Détails complets d'une poule",
1125
1361
  response_description="Composition, classements et rencontres",
@@ -1144,11 +1380,13 @@ async def get_poule(
1144
1380
 
1145
1381
  @app.get(
1146
1382
  "/api/v1/poule/{poule_id}/classement",
1383
+ operation_id="getPouleClassement",
1147
1384
  tags=["Compétitions & Poules"],
1148
1385
  summary="Classement officiel d'une poule",
1149
1386
  response_description="Classement détaillé avec points, victoires et goal-average",
1150
1387
  )
1151
1388
  async def get_poule_classement(
1389
+ response: Response,
1152
1390
  poule_id: int = PathParam(
1153
1391
  ..., ge=1, description="ID de la poule FFBB", examples=[129759]
1154
1392
  ),
@@ -1167,6 +1405,9 @@ async def get_poule_classement(
1167
1405
  or getattr(poule, "classements", [])
1168
1406
  or []
1169
1407
  )
1408
+ response.headers["Cache-Control"] = (
1409
+ "public, max-age=300, stale-while-revalidate=60"
1410
+ )
1170
1411
  return {
1171
1412
  "poule_id": poule_id,
1172
1413
  "nom": getattr(poule, "nom", "") or getattr(poule, "libelle", ""),
@@ -1181,6 +1422,7 @@ async def get_poule_classement(
1181
1422
 
1182
1423
  @app.get(
1183
1424
  "/api/v1/lives",
1425
+ operation_id="getLives",
1184
1426
  tags=["Scores en Direct"],
1185
1427
  summary="Scores en direct du week-end (Lives)",
1186
1428
  response_description="Matchs en direct avec scores temps réel",
@@ -1196,6 +1438,7 @@ async def get_lives():
1196
1438
 
1197
1439
  @app.get(
1198
1440
  "/api/v1/rencontre/{rencontre_id}",
1441
+ operation_id="getRencontreDetail",
1199
1442
  tags=["Matchs & Calendriers"],
1200
1443
  summary="Détails complets d'une rencontre FFBB",
1201
1444
  response_description="Fiche officielle détaillée de la rencontre, scores, salle et officiels",
@@ -1230,11 +1473,13 @@ async def get_rencontre_detail(
1230
1473
 
1231
1474
  @app.get(
1232
1475
  "/api/v1/salle/{salle_id}",
1476
+ operation_id="getSalleDetail",
1233
1477
  tags=["Clubs"],
1234
1478
  summary="Détails d'une salle / gymnase",
1235
1479
  response_description="Fiche gymnase avec adresse complète et géolocalisation",
1236
1480
  )
1237
1481
  async def get_salle_detail(
1482
+ response: Response,
1238
1483
  salle_id: str = PathParam(
1239
1484
  ...,
1240
1485
  description="ID FFBB de la salle (ex: '6543')",
@@ -1249,6 +1494,9 @@ async def get_salle_detail(
1249
1494
  raise HTTPException(
1250
1495
  status_code=404, detail=f"Salle {salle_id} introuvable."
1251
1496
  )
1497
+ response.headers["Cache-Control"] = (
1498
+ "public, max-age=86400, stale-while-revalidate=3600"
1499
+ )
1252
1500
  return salle
1253
1501
  except HTTPException:
1254
1502
  raise
@@ -1258,6 +1506,7 @@ async def get_salle_detail(
1258
1506
 
1259
1507
  @app.get(
1260
1508
  "/api/v1/competition/{competition_id}",
1509
+ operation_id="getCompetitionDetail",
1261
1510
  tags=["Compétitions & Poules"],
1262
1511
  summary="Détails d'une compétition",
1263
1512
  response_description="Informations sur la compétition et composition des poules",
@@ -1288,14 +1537,18 @@ async def get_competition_detail(
1288
1537
 
1289
1538
  @app.get(
1290
1539
  "/api/v1/saisons",
1540
+ operation_id="getSaisons",
1291
1541
  tags=["Compétitions & Poules"],
1292
1542
  summary="Liste des saisons officielles FFBB",
1293
1543
  response_description="Historique et saison active",
1294
1544
  )
1295
- async def get_saisons():
1545
+ async def get_saisons(response: Response):
1296
1546
  """Retourne la liste des saisons officielles FFBB avec indication de la saison en cours."""
1297
1547
  client = get_client()
1298
1548
  try:
1549
+ response.headers["Cache-Control"] = (
1550
+ "public, max-age=86400, stale-while-revalidate=3600"
1551
+ )
1299
1552
  return await client.get_saisons_async()
1300
1553
  except Exception as e:
1301
1554
  raise HTTPException(status_code=500, detail=str(e))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ffbb-data-client
3
- Version: 2.4.30
3
+ Version: 2.4.32
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
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "2.4.30",
2
+ "tag": "2.4.32",
3
3
  "distance": 0,
4
- "node": "gfaf1a9cb9c6837dac2689031d7e582829983f79e",
4
+ "node": "g24e96acb7b546a3849ce648403f9d1152ff2c860",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-09-23"
@@ -1,4 +1,4 @@
1
- """Tests for the new REST endpoints and match card enrichment in api.py."""
1
+ """Tests for the REST endpoints, Best Practices, error envelopes, and caching in api.py."""
2
2
 
3
3
  from unittest.mock import AsyncMock, MagicMock, patch
4
4
 
@@ -21,14 +21,60 @@ async def test_search_acronym_expansion():
21
21
  async with AsyncClient(transport=transport, base_url="http://test") as ac:
22
22
  r = await ac.get("/api/v1/search?query=SCBA")
23
23
  assert r.status_code == 200
24
- # Ensure multi_search was called with expanded name
25
24
  mock_client.multi_search.assert_called_with(
26
25
  name="Stade Clermontois Basket Auvergne"
27
26
  )
28
27
 
29
28
 
30
29
  @pytest.mark.asyncio
31
- async def test_match_card_enrichment():
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():
32
78
  transport = ASGITransport(app=app)
33
79
  mock_client = MagicMock()
34
80
  mock_org = MagicMock()
@@ -39,10 +85,14 @@ async def test_match_card_enrichment():
39
85
 
40
86
  with patch("ffbb_data_client.api.get_client", return_value=mock_client):
41
87
  async with AsyncClient(transport=transport, base_url="http://test") as ac:
42
- r = await ac.get("/api/v1/club/9326/matches")
88
+ r = await ac.get("/api/v1/club/9326/matches?limit=10&offset=0")
43
89
  assert r.status_code == 200
90
+ assert "Cache-Control" in r.headers
44
91
  data = r.json()
45
92
  assert "matches" in data
93
+ assert "pagination" in data
94
+ assert data["pagination"]["limit"] == 10
95
+ assert data["pagination"]["offset"] == 0
46
96
 
47
97
 
48
98
  @pytest.mark.asyncio
@@ -64,7 +114,7 @@ async def test_rencontre_endpoint():
64
114
 
65
115
 
66
116
  @pytest.mark.asyncio
67
- async def test_salle_and_competition_endpoints():
117
+ async def test_salle_and_competition_endpoints_caching():
68
118
  transport = ASGITransport(app=app)
69
119
  mock_client = MagicMock()
70
120
  mock_client.get_salle_async = AsyncMock(
@@ -81,7 +131,8 @@ async def test_salle_and_competition_endpoints():
81
131
  async with AsyncClient(transport=transport, base_url="http://test") as ac:
82
132
  r_salle = await ac.get("/api/v1/salle/6543")
83
133
  assert r_salle.status_code == 200
84
- assert r_salle.json().get("libelle") == "Gymnase Fleury"
134
+ assert "Cache-Control" in r_salle.headers
135
+ assert "max-age=86400" in r_salle.headers["Cache-Control"]
85
136
 
86
137
  r_comp = await ac.get("/api/v1/competition/999")
87
138
  assert r_comp.status_code == 200
@@ -89,4 +140,5 @@ async def test_salle_and_competition_endpoints():
89
140
 
90
141
  r_saisons = await ac.get("/api/v1/saisons")
91
142
  assert r_saisons.status_code == 200
143
+ assert "Cache-Control" in r_saisons.headers
92
144
  assert len(r_saisons.json()) == 1