ffbb-data-client 2.0.0__py3-none-any.whl

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 (207) hide show
  1. ffbb_api_client_v3/__init__.py +25 -0
  2. ffbb_data_client/__init__.py +175 -0
  3. ffbb_data_client/clients/__init__.py +13 -0
  4. ffbb_data_client/clients/api_ffbb_app_client.py +2475 -0
  5. ffbb_data_client/clients/ffbb_data_client.py +2789 -0
  6. ffbb_data_client/clients/meilisearch_client.py +218 -0
  7. ffbb_data_client/clients/meilisearch_ffbb_client.py +647 -0
  8. ffbb_data_client/config.py +153 -0
  9. ffbb_data_client/data/__init__.py +25 -0
  10. ffbb_data_client/data/collections.json +1364 -0
  11. ffbb_data_client/data/endpoint_discovery.json +1875 -0
  12. ffbb_data_client/data/indexes.json +501 -0
  13. ffbb_data_client/data/openapi.json +35713 -0
  14. ffbb_data_client/data/openapi_full.json +37622 -0
  15. ffbb_data_client/helpers/__init__.py +27 -0
  16. ffbb_data_client/helpers/http_requests_helper.py +73 -0
  17. ffbb_data_client/helpers/http_requests_utils.py +502 -0
  18. ffbb_data_client/helpers/meilisearch_client_extension.py +153 -0
  19. ffbb_data_client/helpers/multi_search_query_helper.py +35 -0
  20. ffbb_data_client/models/__init__.py +241 -0
  21. ffbb_data_client/models/affiche.py +45 -0
  22. ffbb_data_client/models/cartographie.py +82 -0
  23. ffbb_data_client/models/categorie.py +55 -0
  24. ffbb_data_client/models/categorie_type.py +42 -0
  25. ffbb_data_client/models/clock.py +38 -0
  26. ffbb_data_client/models/club_contacts.py +77 -0
  27. ffbb_data_client/models/code.py +7 -0
  28. ffbb_data_client/models/commune.py +66 -0
  29. ffbb_data_client/models/competition_fields.py +309 -0
  30. ffbb_data_client/models/competition_id.py +116 -0
  31. ffbb_data_client/models/competition_id_categorie.py +31 -0
  32. ffbb_data_client/models/competition_id_sexe.py +31 -0
  33. ffbb_data_client/models/competition_id_type_competition.py +27 -0
  34. ffbb_data_client/models/competition_id_type_competition_generique.py +24 -0
  35. ffbb_data_client/models/competition_origine.py +69 -0
  36. ffbb_data_client/models/competition_origine_categorie.py +23 -0
  37. ffbb_data_client/models/competition_origine_type_competition.py +14 -0
  38. ffbb_data_client/models/competition_origine_type_competition_generique.py +24 -0
  39. ffbb_data_client/models/competition_type.py +6 -0
  40. ffbb_data_client/models/competitions_facet_distribution.py +65 -0
  41. ffbb_data_client/models/competitions_facet_stats.py +14 -0
  42. ffbb_data_client/models/competitions_hit.py +232 -0
  43. ffbb_data_client/models/competitions_multi_search_query.py +40 -0
  44. ffbb_data_client/models/competitions_query.py +11 -0
  45. ffbb_data_client/models/configuration_models.py +5 -0
  46. ffbb_data_client/models/contact_info.py +18 -0
  47. ffbb_data_client/models/content_multi_search_query.py +93 -0
  48. ffbb_data_client/models/coordonnees.py +27 -0
  49. ffbb_data_client/models/coordonnees_type.py +5 -0
  50. ffbb_data_client/models/document_flyer.py +205 -0
  51. ffbb_data_client/models/document_flyer_type.py +6 -0
  52. ffbb_data_client/models/engagement_contacts.py +97 -0
  53. ffbb_data_client/models/engagements_facet_distribution.py +59 -0
  54. ffbb_data_client/models/engagements_facet_stats.py +14 -0
  55. ffbb_data_client/models/engagements_hit.py +192 -0
  56. ffbb_data_client/models/engagements_multi_search_query.py +41 -0
  57. ffbb_data_client/models/etat.py +6 -0
  58. ffbb_data_client/models/external_competition_id.py +42 -0
  59. ffbb_data_client/models/external_id.py +72 -0
  60. ffbb_data_client/models/facet_distribution.py +13 -0
  61. ffbb_data_client/models/facet_stats.py +13 -0
  62. ffbb_data_client/models/field_set.py +10 -0
  63. ffbb_data_client/models/folder.py +35 -0
  64. ffbb_data_client/models/formation_session.py +60 -0
  65. ffbb_data_client/models/formations_facet_distribution.py +61 -0
  66. ffbb_data_client/models/formations_facet_stats.py +14 -0
  67. ffbb_data_client/models/formations_hit.py +277 -0
  68. ffbb_data_client/models/formations_multi_search_query.py +41 -0
  69. ffbb_data_client/models/game_stats_model.py +57 -0
  70. ffbb_data_client/models/game_stats_models.py +5 -0
  71. ffbb_data_client/models/generic_search.py +92 -0
  72. ffbb_data_client/models/geo.py +27 -0
  73. ffbb_data_client/models/geo_sort_order.py +6 -0
  74. ffbb_data_client/models/get_commune_response.py +18 -0
  75. ffbb_data_client/models/get_competition_response.py +523 -0
  76. ffbb_data_client/models/get_configuration_response.py +45 -0
  77. ffbb_data_client/models/get_engagement_response.py +23 -0
  78. ffbb_data_client/models/get_entraineur_response.py +18 -0
  79. ffbb_data_client/models/get_formation_response.py +28 -0
  80. ffbb_data_client/models/get_officiel_response.py +18 -0
  81. ffbb_data_client/models/get_organisme_response.py +476 -0
  82. ffbb_data_client/models/get_poule_response.py +68 -0
  83. ffbb_data_client/models/get_pratique_response.py +18 -0
  84. ffbb_data_client/models/get_rencontre_response.py +93 -0
  85. ffbb_data_client/models/get_saisons_response.py +56 -0
  86. ffbb_data_client/models/get_salle_response.py +20 -0
  87. ffbb_data_client/models/get_terrain_response.py +16 -0
  88. ffbb_data_client/models/get_tournoi_response.py +16 -0
  89. ffbb_data_client/models/gradient_color.py +27 -0
  90. ffbb_data_client/models/hit.py +16 -0
  91. ffbb_data_client/models/id_engagement_equipe.py +32 -0
  92. ffbb_data_client/models/id_organisme_equipe.py +51 -0
  93. ffbb_data_client/models/id_organisme_equipe1_logo.py +28 -0
  94. ffbb_data_client/models/id_poule.py +27 -0
  95. ffbb_data_client/models/jour.py +11 -0
  96. ffbb_data_client/models/label.py +15 -0
  97. ffbb_data_client/models/labellisation.py +30 -0
  98. ffbb_data_client/models/live.py +192 -0
  99. ffbb_data_client/models/lives.py +6 -0
  100. ffbb_data_client/models/logo.py +28 -0
  101. ffbb_data_client/models/multi_search_queries.py +24 -0
  102. ffbb_data_client/models/multi_search_query.py +96 -0
  103. ffbb_data_client/models/multi_search_result_competitions.py +14 -0
  104. ffbb_data_client/models/multi_search_result_engagements.py +14 -0
  105. ffbb_data_client/models/multi_search_result_formations.py +12 -0
  106. ffbb_data_client/models/multi_search_result_organismes.py +12 -0
  107. ffbb_data_client/models/multi_search_result_pratiques.py +12 -0
  108. ffbb_data_client/models/multi_search_result_rencontres.py +12 -0
  109. ffbb_data_client/models/multi_search_result_salles.py +12 -0
  110. ffbb_data_client/models/multi_search_result_terrains.py +12 -0
  111. ffbb_data_client/models/multi_search_result_tournois.py +12 -0
  112. ffbb_data_client/models/multi_search_results.py +103 -0
  113. ffbb_data_client/models/multi_search_results_class.py +96 -0
  114. ffbb_data_client/models/nature_sol.py +57 -0
  115. ffbb_data_client/models/niveau.py +10 -0
  116. ffbb_data_client/models/niveau_class.py +27 -0
  117. ffbb_data_client/models/niveau_extractor.py +214 -0
  118. ffbb_data_client/models/niveau_info.py +64 -0
  119. ffbb_data_client/models/niveau_models.py +14 -0
  120. ffbb_data_client/models/niveau_type.py +10 -0
  121. ffbb_data_client/models/objectif.py +7 -0
  122. ffbb_data_client/models/organisateur.py +197 -0
  123. ffbb_data_client/models/organisateur_type.py +6 -0
  124. ffbb_data_client/models/organisme_fields.py +327 -0
  125. ffbb_data_client/models/organisme_id_pere.py +177 -0
  126. ffbb_data_client/models/organismes_facet_distribution.py +46 -0
  127. ffbb_data_client/models/organismes_facet_stats.py +14 -0
  128. ffbb_data_client/models/organismes_hit.py +196 -0
  129. ffbb_data_client/models/organismes_multi_search_query.py +41 -0
  130. ffbb_data_client/models/organismes_query.py +8 -0
  131. ffbb_data_client/models/phase_code.py +23 -0
  132. ffbb_data_client/models/poule.py +35 -0
  133. ffbb_data_client/models/poule_fields.py +261 -0
  134. ffbb_data_client/models/poule_rencontre_item_model.py +69 -0
  135. ffbb_data_client/models/poules_models.py +6 -0
  136. ffbb_data_client/models/poules_query.py +9 -0
  137. ffbb_data_client/models/pratique.py +7 -0
  138. ffbb_data_client/models/pratiques_facet_distribution.py +29 -0
  139. ffbb_data_client/models/pratiques_facet_stats.py +14 -0
  140. ffbb_data_client/models/pratiques_hit.py +310 -0
  141. ffbb_data_client/models/pratiques_hit_type.py +9 -0
  142. ffbb_data_client/models/pratiques_multi_search_query.py +41 -0
  143. ffbb_data_client/models/pratiques_type_class.py +45 -0
  144. ffbb_data_client/models/publication_internet.py +6 -0
  145. ffbb_data_client/models/purple_logo.py +24 -0
  146. ffbb_data_client/models/query_fields_manager.py +75 -0
  147. ffbb_data_client/models/ranking_engagement.py +41 -0
  148. ffbb_data_client/models/rankings_models.py +6 -0
  149. ffbb_data_client/models/rencontres_engagement.py +23 -0
  150. ffbb_data_client/models/rencontres_facet_distribution.py +65 -0
  151. ffbb_data_client/models/rencontres_facet_stats.py +14 -0
  152. ffbb_data_client/models/rencontres_hit.py +271 -0
  153. ffbb_data_client/models/rencontres_multi_search_query.py +41 -0
  154. ffbb_data_client/models/saison.py +23 -0
  155. ffbb_data_client/models/saison_fields.py +36 -0
  156. ffbb_data_client/models/saisons_models.py +6 -0
  157. ffbb_data_client/models/saisons_query.py +9 -0
  158. ffbb_data_client/models/salle.py +56 -0
  159. ffbb_data_client/models/salles_facet_distribution.py +14 -0
  160. ffbb_data_client/models/salles_facet_stats.py +14 -0
  161. ffbb_data_client/models/salles_hit.py +153 -0
  162. ffbb_data_client/models/salles_multi_search_query.py +40 -0
  163. ffbb_data_client/models/sexe.py +9 -0
  164. ffbb_data_client/models/sexe_class.py +31 -0
  165. ffbb_data_client/models/source.py +5 -0
  166. ffbb_data_client/models/status.py +5 -0
  167. ffbb_data_client/models/team_engagement.py +56 -0
  168. ffbb_data_client/models/team_ranking.py +108 -0
  169. ffbb_data_client/models/terrains_categorie_championnat_3x3_libelle.py +5 -0
  170. ffbb_data_client/models/terrains_facet_distribution.py +41 -0
  171. ffbb_data_client/models/terrains_facet_stats.py +14 -0
  172. ffbb_data_client/models/terrains_hit.py +223 -0
  173. ffbb_data_client/models/terrains_multi_search_query.py +42 -0
  174. ffbb_data_client/models/terrains_name.py +5 -0
  175. ffbb_data_client/models/terrains_sexe_enum.py +7 -0
  176. ffbb_data_client/models/terrains_storage.py +5 -0
  177. ffbb_data_client/models/tournoi_type_class.py +35 -0
  178. ffbb_data_client/models/tournoi_type_enum.py +7 -0
  179. ffbb_data_client/models/tournoi_types_3x3.py +43 -0
  180. ffbb_data_client/models/tournoi_types_3x3_libelle.py +60 -0
  181. ffbb_data_client/models/tournoi_types_3x3_libelle_enum.py +10 -0
  182. ffbb_data_client/models/tournois_facet_distribution.py +41 -0
  183. ffbb_data_client/models/tournois_facet_stats.py +14 -0
  184. ffbb_data_client/models/tournois_hit.py +132 -0
  185. ffbb_data_client/models/tournois_hit_type.py +5 -0
  186. ffbb_data_client/models/tournois_libelle.py +7 -0
  187. ffbb_data_client/models/tournois_multi_search_query.py +40 -0
  188. ffbb_data_client/models/type_association.py +23 -0
  189. ffbb_data_client/models/type_association_libelle.py +30 -0
  190. ffbb_data_client/models/type_class.py +23 -0
  191. ffbb_data_client/models/type_competition.py +8 -0
  192. ffbb_data_client/models/type_competition_generique.py +31 -0
  193. ffbb_data_client/models/type_enum.py +7 -0
  194. ffbb_data_client/models/type_league.py +6 -0
  195. ffbb_data_client/py.typed +0 -0
  196. ffbb_data_client/utils/__init__.py +27 -0
  197. ffbb_data_client/utils/cache_manager.py +393 -0
  198. ffbb_data_client/utils/converter_utils.py +329 -0
  199. ffbb_data_client/utils/input_validation.py +360 -0
  200. ffbb_data_client/utils/retry_utils.py +478 -0
  201. ffbb_data_client/utils/secure_logging.py +153 -0
  202. ffbb_data_client/utils/token_manager.py +115 -0
  203. ffbb_data_client-2.0.0.dist-info/METADATA +339 -0
  204. ffbb_data_client-2.0.0.dist-info/RECORD +207 -0
  205. ffbb_data_client-2.0.0.dist-info/WHEEL +5 -0
  206. ffbb_data_client-2.0.0.dist-info/licenses/LICENSE.txt +201 -0
  207. ffbb_data_client-2.0.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,65 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+ from ..utils.converter_utils import from_obj
7
+ from .competition_id_sexe import CompetitionIDSexe
8
+ from .competition_id_type_competition import CompetitionIDTypeCompetition
9
+ from .facet_distribution import FacetDistribution
10
+ from .niveau_class import NiveauClass
11
+
12
+
13
+ @dataclass
14
+ class RencontresFacetDistribution(FacetDistribution):
15
+ competition_id_categorie_code: dict[str, int] | None = None
16
+ competition_id_nom_extended: dict[str, int] | None = None
17
+ competition_id_sexe: CompetitionIDSexe | None = None
18
+ competition_id_type_competition: CompetitionIDTypeCompetition | None = None
19
+ niveau: NiveauClass | None = None
20
+ organisateur_id: dict[str, int] | None = None
21
+ organisateur_nom: dict[str, int] | None = None
22
+
23
+ @staticmethod
24
+ def from_dict(obj: Any) -> RencontresFacetDistribution:
25
+ assert isinstance(obj, dict)
26
+ competition_id_categorie_code = obj.get("competitionId.categorie.code")
27
+ competition_id_nom_extended = obj.get("competitionId.nomExtended")
28
+ competition_id_sexe = from_obj(
29
+ CompetitionIDSexe.from_dict, obj, "competitionId.sexe"
30
+ )
31
+ competition_id_type_competition = from_obj(
32
+ CompetitionIDTypeCompetition.from_dict, obj, "competitionId.typeCompetition"
33
+ )
34
+ niveau = from_obj(NiveauClass.from_dict, obj, "niveau")
35
+ organisateur_id = obj.get("organisateur.id")
36
+ organisateur_nom = obj.get("organisateur.nom")
37
+ return RencontresFacetDistribution(
38
+ competition_id_categorie_code=competition_id_categorie_code,
39
+ competition_id_nom_extended=competition_id_nom_extended,
40
+ competition_id_sexe=competition_id_sexe,
41
+ competition_id_type_competition=competition_id_type_competition,
42
+ niveau=niveau,
43
+ organisateur_id=organisateur_id,
44
+ organisateur_nom=organisateur_nom,
45
+ )
46
+
47
+ def to_dict(self) -> dict:
48
+ result: dict = {}
49
+ if self.competition_id_categorie_code is not None:
50
+ result["competitionId.categorie.code"] = self.competition_id_categorie_code
51
+ if self.competition_id_nom_extended is not None:
52
+ result["competitionId.nomExtended"] = self.competition_id_nom_extended
53
+ if self.competition_id_sexe is not None:
54
+ result["competitionId.sexe"] = self.competition_id_sexe.to_dict()
55
+ if self.competition_id_type_competition is not None:
56
+ result["competitionId.typeCompetition"] = (
57
+ self.competition_id_type_competition.to_dict()
58
+ )
59
+ if self.niveau is not None:
60
+ result["niveau"] = self.niveau.to_dict()
61
+ if self.organisateur_id is not None:
62
+ result["organisateur.id"] = self.organisateur_id
63
+ if self.organisateur_nom is not None:
64
+ result["organisateur.nom"] = self.organisateur_nom
65
+ return result
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from .facet_stats import FacetStats
6
+
7
+
8
+ class RencontresFacetStats(FacetStats):
9
+ @staticmethod
10
+ def from_dict(obj: Any) -> RencontresFacetStats:
11
+ return RencontresFacetStats()
12
+
13
+ def to_dict(self) -> dict:
14
+ return super().to_dict()
@@ -0,0 +1,271 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from datetime import datetime, time
5
+ from typing import Any
6
+
7
+ from ..utils.converter_utils import (
8
+ from_datetime,
9
+ from_enum,
10
+ from_int,
11
+ from_obj,
12
+ from_officiels_list,
13
+ from_str,
14
+ from_time,
15
+ )
16
+ from .competition_id import CompetitionID
17
+ from .geo import Geo
18
+ from .hit import Hit
19
+ from .id_engagement_equipe import IDEngagementEquipe
20
+ from .id_organisme_equipe import IDOrganismeEquipe
21
+ from .id_poule import IDPoule
22
+ from .niveau import Niveau
23
+ from .organisateur import Organisateur
24
+ from .pratique import Pratique
25
+ from .saison import Saison
26
+ from .salle import Salle
27
+
28
+
29
+ @dataclass
30
+ class RencontresHit(Hit):
31
+ niveau: Niveau | None = None
32
+ id: str | None = None
33
+ date: datetime | None = None
34
+ date_rencontre: datetime | None = None
35
+ horaire: time | None = None
36
+ nom_equipe1: str | None = None
37
+ nom_equipe2: str | None = None
38
+ numero_journee: int | None = None
39
+ pratique: Pratique | None = None
40
+ gs_id: str | None = None
41
+ officiels: list[str] | None = None
42
+ competition_id: CompetitionID | None = None
43
+ id_organisme_equipe1: IDOrganismeEquipe | None = None
44
+ id_organisme_equipe2: IDOrganismeEquipe | None = None
45
+ id_poule: IDPoule | None = None
46
+ saison: Saison | None = None
47
+ salle: Salle | None = None
48
+ id_engagement_equipe1: IDEngagementEquipe | None = None
49
+ id_engagement_equipe2: IDEngagementEquipe | None = None
50
+ geo: Geo | None = None
51
+ date_timestamp: int | None = None
52
+ date_rencontre_timestamp: int | None = None
53
+ creation_timestamp: int | None = None
54
+ date_saisie_resultat_timestamp: int | None = None
55
+ modification_timestamp: int | None = None
56
+ thumbnail: str | None = None
57
+ organisateur: Organisateur | None = None
58
+ niveau_nb: int | None = None
59
+ lower_id: str | None = field(init=False, default=None, repr=False)
60
+ lower_nom_equipe1: str | None = field(init=False, default=None, repr=False)
61
+ lower_nom_equipe2: str | None = field(init=False, default=None, repr=False)
62
+ lower_gs_id: str | None = field(init=False, default=None, repr=False)
63
+ lower_officiels: list[str] | None = field(init=False, default=None, repr=False)
64
+
65
+ @property
66
+ def name(self) -> str | None:
67
+ """Alias for convenience — returns 'Team A vs Team B'."""
68
+ if self.nom_equipe1 and self.nom_equipe2:
69
+ return f"{self.nom_equipe1} vs {self.nom_equipe2}"
70
+ return self.nom_equipe1 or self.nom_equipe2
71
+
72
+ @property
73
+ def team1_name(self) -> str | None:
74
+ """Alias for .nom_equipe1 for DX consistency."""
75
+ return self.nom_equipe1
76
+
77
+ @property
78
+ def team2_name(self) -> str | None:
79
+ """Alias for .nom_equipe2 for DX consistency."""
80
+ return self.nom_equipe2
81
+
82
+ def __post_init__(self) -> None:
83
+ self._normalize_string_fields()
84
+ self._normalize_officiels()
85
+
86
+ def _normalize_string_fields(self) -> None:
87
+ """Normalize string fields to lowercase."""
88
+ self.lower_id = self.id.lower() if self.id else None
89
+ self.lower_nom_equipe1 = self.nom_equipe1.lower() if self.nom_equipe1 else None
90
+ self.lower_nom_equipe2 = self.nom_equipe2.lower() if self.nom_equipe2 else None
91
+ self.lower_gs_id = self.gs_id.lower() if self.gs_id else None
92
+
93
+ def _normalize_officiels(self) -> None:
94
+ """Normalize the officiels list for search and consistency.
95
+
96
+ Handles both old format (list of strings) and new format (list of dicts).
97
+ """
98
+ if not self.officiels:
99
+ self.lower_officiels = None
100
+ return
101
+
102
+ lower_officiels = []
103
+ for o in self.officiels:
104
+ if isinstance(o, str):
105
+ lower_officiels.append(o.lower())
106
+ elif isinstance(o, dict):
107
+ off = o.get("officiel", {})
108
+ name = f"{off.get('nom', '')} {off.get('prenom', '')}".strip()
109
+ lower_officiels.append(name.lower() if name else "")
110
+
111
+ self.lower_officiels = lower_officiels if lower_officiels else None
112
+
113
+ @staticmethod
114
+ def from_dict(obj: Any) -> RencontresHit:
115
+ try:
116
+ assert isinstance(obj, dict)
117
+ niveau = from_enum(Niveau, obj, "niveau")
118
+ id = from_str(obj, "id")
119
+ date = from_datetime(obj, "date")
120
+ date_rencontre = from_datetime(obj, "date_rencontre")
121
+ horaire = from_time(obj, "horaire")
122
+ nom_equipe1 = from_str(obj, "nomEquipe1")
123
+ nom_equipe2 = from_str(obj, "nomEquipe2")
124
+
125
+ numero_journee = from_int(obj, "numeroJournee")
126
+ pratique = from_enum(Pratique, obj, "pratique")
127
+ gs_id = from_str(obj, "gsId")
128
+ officiels = from_officiels_list(obj.get("officiels"))
129
+ competition_id = from_obj(CompetitionID.from_dict, obj, "competitionId")
130
+ id_organisme_equipe1 = from_obj(
131
+ IDOrganismeEquipe.from_dict, obj, "idOrganismeEquipe1"
132
+ )
133
+ id_organisme_equipe2 = from_obj(
134
+ IDOrganismeEquipe.from_dict, obj, "idOrganismeEquipe2"
135
+ )
136
+ id_poule = from_obj(IDPoule.from_dict, obj, "idPoule")
137
+ saison = from_obj(Saison.from_dict, obj, "saison")
138
+ salle = from_obj(Salle.from_dict, obj, "salle")
139
+ id_engagement_equipe1 = from_obj(
140
+ IDEngagementEquipe.from_dict, obj, "idEngagementEquipe1"
141
+ )
142
+ id_engagement_equipe2 = from_obj(
143
+ IDEngagementEquipe.from_dict, obj, "idEngagementEquipe2"
144
+ )
145
+ geo = from_obj(Geo.from_dict, obj, "_geo")
146
+ date_timestamp = from_int(obj, "date_timestamp")
147
+ date_rencontre_timestamp = from_int(obj, "date_rencontre_timestamp")
148
+ creation_timestamp = from_int(obj, "creation_timestamp")
149
+ date_saisie_resultat_timestamp = from_int(
150
+ obj, "dateSaisieResultat_timestamp"
151
+ )
152
+ modification_timestamp = from_int(obj, "modification_timestamp")
153
+ thumbnail = from_str(obj, "thumbnail")
154
+ organisateur = from_obj(Organisateur.from_dict, obj, "organisateur")
155
+ niveau_nb = from_int(obj, "niveau_nb")
156
+ return RencontresHit(
157
+ niveau=niveau,
158
+ id=id,
159
+ date=date,
160
+ date_rencontre=date_rencontre,
161
+ horaire=horaire,
162
+ nom_equipe1=nom_equipe1,
163
+ nom_equipe2=nom_equipe2,
164
+ numero_journee=numero_journee,
165
+ pratique=pratique,
166
+ gs_id=gs_id,
167
+ officiels=officiels,
168
+ competition_id=competition_id,
169
+ id_organisme_equipe1=id_organisme_equipe1,
170
+ id_organisme_equipe2=id_organisme_equipe2,
171
+ id_poule=id_poule,
172
+ saison=saison,
173
+ salle=salle,
174
+ id_engagement_equipe1=id_engagement_equipe1,
175
+ id_engagement_equipe2=id_engagement_equipe2,
176
+ geo=geo,
177
+ date_timestamp=date_timestamp,
178
+ date_rencontre_timestamp=date_rencontre_timestamp,
179
+ creation_timestamp=creation_timestamp,
180
+ date_saisie_resultat_timestamp=date_saisie_resultat_timestamp,
181
+ modification_timestamp=modification_timestamp,
182
+ thumbnail=thumbnail,
183
+ organisateur=organisateur,
184
+ niveau_nb=niveau_nb,
185
+ )
186
+ except Exception as e:
187
+ raise ValueError(f"Invalid `Hit` object: {e}") from e
188
+
189
+ def to_dict(self) -> dict:
190
+ result: dict = {}
191
+ if self.niveau is not None:
192
+ result["niveau"] = self.niveau.value
193
+ if self.id is not None:
194
+ result["id"] = self.id
195
+ if self.date is not None:
196
+ result["date"] = self.date.isoformat()
197
+ if self.date_rencontre is not None:
198
+ result["date_rencontre"] = self.date_rencontre.isoformat()
199
+ if self.horaire is not None:
200
+ result["horaire"] = self.horaire.isoformat()
201
+ if self.nom_equipe1 is not None:
202
+ result["nomEquipe1"] = self.nom_equipe1
203
+ if self.nom_equipe2 is not None:
204
+ result["nomEquipe2"] = self.nom_equipe2
205
+ if self.numero_journee is not None:
206
+ result["numeroJournee"] = str(self.numero_journee)
207
+ if self.pratique is not None:
208
+ result["pratique"] = self.pratique.value
209
+ if self.gs_id is not None:
210
+ result["gsId"] = self.gs_id
211
+ if self.officiels is not None:
212
+ result["officiels"] = self.officiels
213
+ if self.competition_id is not None:
214
+ result["competitionId"] = self.competition_id.to_dict()
215
+ if self.id_organisme_equipe1 is not None:
216
+ result["idOrganismeEquipe1"] = self.id_organisme_equipe1.to_dict()
217
+ if self.id_organisme_equipe2 is not None:
218
+ result["idOrganismeEquipe2"] = self.id_organisme_equipe2.to_dict()
219
+ if self.id_poule is not None:
220
+ result["idPoule"] = self.id_poule.to_dict()
221
+ if self.saison is not None:
222
+ result["saison"] = self.saison.to_dict()
223
+ if self.salle is not None:
224
+ result["salle"] = self.salle.to_dict()
225
+ if self.id_engagement_equipe1 is not None:
226
+ result["idEngagementEquipe1"] = self.id_engagement_equipe1.to_dict()
227
+ if self.id_engagement_equipe2 is not None:
228
+ result["idEngagementEquipe2"] = self.id_engagement_equipe2.to_dict()
229
+ if self.geo is not None:
230
+ result["_geo"] = self.geo.to_dict()
231
+ if self.date_timestamp is not None:
232
+ result["date_timestamp"] = self.date_timestamp
233
+ if self.date_rencontre_timestamp is not None:
234
+ result["date_rencontre_timestamp"] = self.date_rencontre_timestamp
235
+ if self.creation_timestamp is not None:
236
+ result["creation_timestamp"] = self.creation_timestamp
237
+ if self.date_saisie_resultat_timestamp is not None:
238
+ result["dateSaisieResultat_timestamp"] = self.date_saisie_resultat_timestamp
239
+ if self.modification_timestamp is not None:
240
+ result["modification_timestamp"] = self.modification_timestamp
241
+ if self.thumbnail is not None:
242
+ result["thumbnail"] = self.thumbnail
243
+ if self.organisateur is not None:
244
+ result["organisateur"] = self.organisateur.to_dict()
245
+ if self.niveau_nb is not None:
246
+ result["niveau_nb"] = str(self.niveau_nb)
247
+ return result
248
+
249
+ def is_valid_for_query(self, query: str) -> bool:
250
+ return bool(
251
+ not query
252
+ or (self.lower_gs_id and query in self.lower_gs_id)
253
+ or (self.lower_id and query in self.lower_id)
254
+ or (self.lower_nom_equipe1 and query in self.lower_nom_equipe1)
255
+ or (self.lower_nom_equipe2 and query in self.lower_nom_equipe2)
256
+ or (
257
+ self.lower_officiels
258
+ and any(query in off for off in self.lower_officiels)
259
+ )
260
+ or (
261
+ self.salle
262
+ and (
263
+ (self.salle.lower_adresse and query in self.salle.lower_adresse)
264
+ or (
265
+ self.salle.lower_adresse_complement
266
+ and query in self.salle.lower_adresse_complement
267
+ )
268
+ or (self.salle.lower_libelle and query in self.salle.lower_libelle)
269
+ )
270
+ )
271
+ )
@@ -0,0 +1,41 @@
1
+ from __future__ import annotations
2
+
3
+ from ..config import MEILISEARCH_FACETS_RENCONTRES, MEILISEARCH_INDEX_RENCONTRES
4
+ from .multi_search_query import MultiSearchQuery
5
+ from .multi_search_result_rencontres import RencontresMultiSearchResult
6
+ from .multi_search_results import MultiSearchResult
7
+ from .rencontres_facet_distribution import RencontresFacetDistribution
8
+ from .rencontres_facet_stats import RencontresFacetStats
9
+
10
+
11
+ class RencontresMultiSearchQuery(MultiSearchQuery):
12
+ def __init__(
13
+ self,
14
+ q: str | None,
15
+ limit: int | None = 10,
16
+ offset: int | None = 0,
17
+ filter: list[str] | None = None,
18
+ sort: list[str] | None = None,
19
+ ):
20
+ super().__init__(
21
+ index_uid=MEILISEARCH_INDEX_RENCONTRES,
22
+ q=q,
23
+ facets=MEILISEARCH_FACETS_RENCONTRES,
24
+ limit=limit,
25
+ offset=offset,
26
+ filter=filter,
27
+ sort=sort,
28
+ )
29
+
30
+ def is_valid_result(self, result: MultiSearchResult):
31
+ return result and (
32
+ isinstance(result, RencontresMultiSearchResult)
33
+ and (
34
+ result.facet_distribution is None
35
+ or isinstance(result.facet_distribution, RencontresFacetDistribution)
36
+ )
37
+ and (
38
+ result.facet_stats is None
39
+ or isinstance(result.facet_stats, RencontresFacetStats)
40
+ )
41
+ )
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+ from ..utils.converter_utils import from_str
7
+
8
+
9
+ @dataclass
10
+ class Saison:
11
+ code: str | None = None
12
+
13
+ @staticmethod
14
+ def from_dict(obj: Any) -> Saison:
15
+ assert isinstance(obj, dict)
16
+ code = from_str(obj, "code")
17
+ return Saison(code=code)
18
+
19
+ def to_dict(self) -> dict:
20
+ result: dict = {}
21
+ if self.code is not None:
22
+ result["code"] = self.code
23
+ return result
@@ -0,0 +1,36 @@
1
+ class SaisonFields:
2
+ """Default fields for saison queries."""
3
+
4
+ # Basic fields
5
+ ID = "id"
6
+ NOM = "nom"
7
+ ACTIF = "actif"
8
+ DEBUT = "debut"
9
+ FIN = "fin"
10
+ CODE = "code"
11
+ LIBELLE = "libelle"
12
+ EN_COURS = "enCours"
13
+ DATE_CREATED = "date_created"
14
+ DATE_UPDATED = "date_updated"
15
+
16
+ @classmethod
17
+ def get_default_fields(cls) -> list[str]:
18
+ """Get default fields for saison queries."""
19
+ return [
20
+ cls.ID,
21
+ cls.NOM,
22
+ cls.ACTIF,
23
+ cls.DEBUT,
24
+ cls.FIN,
25
+ cls.CODE,
26
+ cls.LIBELLE,
27
+ cls.EN_COURS,
28
+ ]
29
+
30
+ @classmethod
31
+ def get_detailed_fields(cls) -> list[str]:
32
+ """Get detailed fields for saison queries."""
33
+ return cls.get_default_fields() + [
34
+ cls.DATE_CREATED,
35
+ cls.DATE_UPDATED,
36
+ ]
@@ -0,0 +1,6 @@
1
+ """Backward-compatibility re-export shim for saisons models."""
2
+
3
+ from .get_saisons_response import GetSaisonsResponse
4
+ from .saisons_query import SaisonsQuery
5
+
6
+ __all__ = ["GetSaisonsResponse", "SaisonsQuery"]
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+
6
+ @dataclass
7
+ class SaisonsQuery:
8
+ fields_: list[str] | None = field(default=None) # Original: fields[]
9
+ filter: str | None = '{"actif":{"_eq":true}}' # Original: filter
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Any
5
+
6
+ from ..utils.converter_utils import from_obj, from_str
7
+ from .cartographie import Cartographie
8
+
9
+
10
+ @dataclass
11
+ class Salle:
12
+ id: str | None = None
13
+ libelle: str | None = None
14
+ adresse: str | None = None
15
+ adresse_complement: str | None = None
16
+ cartographie: Cartographie | None = None
17
+ lower_libelle: str | None = field(init=False, default=None, repr=False)
18
+ lower_adresse: str | None = field(init=False, default=None, repr=False)
19
+ lower_adresse_complement: str | None = field(init=False, default=None, repr=False)
20
+
21
+ def __post_init__(self) -> None:
22
+ self.lower_libelle = self.libelle.lower() if self.libelle else None
23
+ self.lower_adresse = self.adresse.lower() if self.adresse else None
24
+ self.lower_adresse_complement = (
25
+ self.adresse_complement.lower() if self.adresse_complement else None
26
+ )
27
+
28
+ @staticmethod
29
+ def from_dict(obj: Any) -> Salle:
30
+ assert isinstance(obj, dict)
31
+ id = from_str(obj, "id")
32
+ libelle = from_str(obj, "libelle")
33
+ adresse = from_str(obj, "adresse")
34
+ adresse_complement = from_str(obj, "adresseComplement")
35
+ cartographie = from_obj(Cartographie.from_dict, obj, "cartographie")
36
+ return Salle(
37
+ id=id,
38
+ libelle=libelle,
39
+ adresse=adresse,
40
+ adresse_complement=adresse_complement,
41
+ cartographie=cartographie,
42
+ )
43
+
44
+ def to_dict(self) -> dict:
45
+ result: dict = {}
46
+ if self.id is not None:
47
+ result["id"] = self.id
48
+ if self.libelle is not None:
49
+ result["libelle"] = self.libelle
50
+ if self.adresse is not None:
51
+ result["adresse"] = self.adresse
52
+ if self.adresse_complement is not None:
53
+ result["adresseComplement"] = self.adresse_complement
54
+ if self.cartographie is not None:
55
+ result["cartographie"] = self.cartographie.to_dict()
56
+ return result
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from .facet_distribution import FacetDistribution
6
+
7
+
8
+ class SallesFacetDistribution(FacetDistribution):
9
+ @staticmethod
10
+ def from_dict(obj: Any) -> SallesFacetDistribution:
11
+ return SallesFacetDistribution()
12
+
13
+ def to_dict(self) -> dict:
14
+ return super().to_dict()
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from .facet_stats import FacetStats
6
+
7
+
8
+ class SallesFacetStats(FacetStats):
9
+ @staticmethod
10
+ def from_dict(obj: Any) -> SallesFacetStats:
11
+ return SallesFacetStats()
12
+
13
+ def to_dict(self) -> dict:
14
+ return super().to_dict()