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,153 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from datetime import datetime
5
+ from typing import Any
6
+
7
+ from ..utils.converter_utils import (
8
+ from_datetime,
9
+ from_obj,
10
+ from_str,
11
+ )
12
+ from .cartographie import Cartographie
13
+ from .commune import Commune
14
+ from .geo import Geo
15
+ from .hit import Hit
16
+ from .type_association import TypeAssociation
17
+
18
+
19
+ @dataclass
20
+ class SallesHit(Hit):
21
+ libelle: str | None = None
22
+ adresse: str | None = None
23
+ id: str | None = None
24
+ adresse_complement: str | None = None
25
+ capacite_spectateur: str | None = None
26
+ date_created: datetime | None = None
27
+ date_updated: datetime | None = None
28
+ libelle2: str | None = None
29
+ mail: str | None = None
30
+ numero: str | None = None
31
+ telephone: str | None = None
32
+ cartographie: Cartographie | None = None
33
+ commune: Commune | None = None
34
+ geo: Geo | None = None
35
+ thumbnail: str | None = None
36
+ type: str | None = None
37
+ type_association: TypeAssociation | None = None
38
+ lower_libelle: str | None = field(init=False, default=None, repr=False)
39
+ lower_addresse: str | None = field(init=False, default=None, repr=False)
40
+ lower_adresse_complement: str | None = field(init=False, default=None, repr=False)
41
+ lower_libelle2: str | None = field(init=False, default=None, repr=False)
42
+
43
+ @property
44
+ def name(self) -> str | None:
45
+ """Alias for .libelle — unified name accessor across all Hit types."""
46
+ return self.libelle
47
+
48
+ def __post_init__(self) -> None:
49
+ self.lower_libelle = self.libelle.lower() if self.libelle else None
50
+ self.lower_addresse = self.adresse.lower() if self.adresse else None
51
+ self.lower_adresse_complement = (
52
+ self.adresse_complement.lower() if self.adresse_complement else None
53
+ )
54
+ self.lower_libelle2 = self.libelle2.lower() if self.libelle2 else None
55
+
56
+ @staticmethod
57
+ def from_dict(obj: Any) -> SallesHit:
58
+ assert isinstance(obj, dict)
59
+ libelle = from_str(obj, "libelle")
60
+ adresse = from_str(obj, "adresse")
61
+ id = from_str(obj, "id")
62
+ adresse_complement = from_str(obj, "adresseComplement")
63
+ capacite_spectateur = from_str(obj, "capaciteSpectateur")
64
+ date_created = from_datetime(obj, "date_created")
65
+ date_updated = from_datetime(obj, "date_updated")
66
+ libelle2 = from_str(obj, "libelle2")
67
+ mail = from_str(obj, "mail")
68
+ numero = from_str(obj, "numero")
69
+ telephone = from_str(obj, "telephone")
70
+ cartographie = from_obj(Cartographie.from_dict, obj, "cartographie")
71
+ commune = from_obj(Commune.from_dict, obj, "commune")
72
+ geo = from_obj(Geo.from_dict, obj, "_geo")
73
+ thumbnail = from_str(obj, "thumbnail")
74
+ type = from_str(obj, "type")
75
+ type_association = from_obj(TypeAssociation.from_dict, obj, "type_association")
76
+ return SallesHit(
77
+ libelle=libelle,
78
+ adresse=adresse,
79
+ id=id,
80
+ adresse_complement=adresse_complement,
81
+ capacite_spectateur=capacite_spectateur,
82
+ date_created=date_created,
83
+ date_updated=date_updated,
84
+ libelle2=libelle2,
85
+ mail=mail,
86
+ numero=numero,
87
+ telephone=telephone,
88
+ cartographie=cartographie,
89
+ commune=commune,
90
+ geo=geo,
91
+ thumbnail=thumbnail,
92
+ type=type,
93
+ type_association=type_association,
94
+ )
95
+
96
+ def to_dict(self) -> dict:
97
+ result: dict = {}
98
+ if self.libelle is not None:
99
+ result["libelle"] = self.libelle
100
+ if self.adresse is not None:
101
+ result["adresse"] = self.adresse
102
+ if self.id is not None:
103
+ result["id"] = self.id
104
+ if self.adresse_complement is not None:
105
+ result["adresseComplement"] = self.adresse_complement
106
+ if self.capacite_spectateur is not None:
107
+ result["capaciteSpectateur"] = self.capacite_spectateur
108
+ if self.date_created is not None:
109
+ result["date_created"] = self.date_created.isoformat()
110
+ if self.date_updated is not None:
111
+ result["date_updated"] = self.date_updated.isoformat()
112
+ if self.libelle2 is not None:
113
+ result["libelle2"] = self.libelle2
114
+ if self.mail is not None:
115
+ result["mail"] = self.mail
116
+ if self.numero is not None:
117
+ result["numero"] = self.numero
118
+ if self.telephone is not None:
119
+ result["telephone"] = self.telephone
120
+ if self.cartographie is not None:
121
+ result["cartographie"] = self.cartographie.to_dict()
122
+ if self.commune is not None:
123
+ result["commune"] = self.commune.to_dict()
124
+ if self.geo is not None:
125
+ result["_geo"] = self.geo.to_dict()
126
+ if self.thumbnail is not None:
127
+ result["thumbnail"] = self.thumbnail
128
+ if self.type is not None:
129
+ result["type"] = self.type
130
+ if self.type_association is not None:
131
+ result["type_association"] = self.type_association.to_dict()
132
+ return result
133
+
134
+ def is_valid_for_query(self, query: str) -> bool:
135
+ return bool(
136
+ not query
137
+ or (self.lower_addresse and query in self.lower_addresse)
138
+ or (
139
+ self.lower_adresse_complement and query in self.lower_adresse_complement
140
+ )
141
+ or (self.lower_libelle and query in self.lower_libelle)
142
+ or (self.lower_libelle2 and query in self.lower_libelle2)
143
+ or (
144
+ self.commune
145
+ and (
146
+ (self.commune.lower_libelle and query in self.commune.lower_libelle)
147
+ or (
148
+ self.commune.lower_departement
149
+ and query in self.commune.lower_departement
150
+ )
151
+ )
152
+ )
153
+ )
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from ..config import MEILISEARCH_INDEX_SALLES
4
+ from .multi_search_query import MultiSearchQuery
5
+ from .multi_search_result_salles import SallesMultiSearchResult
6
+ from .multi_search_results import MultiSearchResult
7
+ from .salles_facet_distribution import SallesFacetDistribution
8
+ from .salles_facet_stats import SallesFacetStats
9
+
10
+
11
+ class SallesMultiSearchQuery(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_SALLES,
22
+ q=q,
23
+ limit=limit,
24
+ offset=offset,
25
+ filter=filter,
26
+ sort=sort,
27
+ )
28
+
29
+ def is_valid_result(self, result: MultiSearchResult):
30
+ return result and (
31
+ isinstance(result, SallesMultiSearchResult)
32
+ and (
33
+ result.facet_distribution is None
34
+ or isinstance(result.facet_distribution, SallesFacetDistribution)
35
+ )
36
+ and (
37
+ result.facet_stats is None
38
+ or isinstance(result.facet_stats, SallesFacetStats)
39
+ )
40
+ )
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import Enum
4
+
5
+
6
+ class Sexe(Enum):
7
+ FEMININE = "Féminin"
8
+ MASCULINE = "Masculin"
9
+ MIXED = "Mixte"
@@ -0,0 +1,31 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+ from ..utils.converter_utils import from_int
7
+
8
+
9
+ @dataclass
10
+ class SexeClass:
11
+ feminine: int | None = None
12
+ masculine: int | None = None
13
+ mixed: int | None = None
14
+
15
+ @staticmethod
16
+ def from_dict(obj: Any) -> SexeClass:
17
+ assert isinstance(obj, dict)
18
+ feminine = from_int(obj, "Féminin")
19
+ masculine = from_int(obj, "Masculin")
20
+ mixed = from_int(obj, "Mixte")
21
+ return SexeClass(feminine=feminine, masculine=masculine, mixed=mixed)
22
+
23
+ def to_dict(self) -> dict:
24
+ result: dict = {}
25
+ if self.feminine is not None:
26
+ result["Féminin"] = self.feminine
27
+ if self.masculine is not None:
28
+ result["Masculin"] = self.masculine
29
+ if self.mixed is not None:
30
+ result["Mixte"] = self.mixed
31
+ return result
@@ -0,0 +1,5 @@
1
+ from enum import Enum
2
+
3
+
4
+ class Source(Enum):
5
+ FFBB_SERVEUR = "FFBB Serveur"
@@ -0,0 +1,5 @@
1
+ from enum import Enum
2
+
3
+
4
+ class Status(Enum):
5
+ DRAFT = "draft"
@@ -0,0 +1,56 @@
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, from_str
7
+ from .logo import Logo
8
+
9
+
10
+ @dataclass
11
+ class TeamEngagement:
12
+ nom_officiel: str | None = None
13
+ nom_usuel: str | None = None
14
+ code_abrege: str | None = None
15
+ logo: Logo | None = None
16
+
17
+ @staticmethod
18
+ def from_dict(obj: Any) -> TeamEngagement:
19
+ """
20
+ Convert a dictionary object to a TeamEngagement instance.
21
+
22
+ Args:
23
+ obj (Any): The dictionary object to convert.
24
+
25
+ Returns:
26
+ TeamEngagement: The converted TeamEngagement instance.
27
+ """
28
+ assert isinstance(obj, dict)
29
+ nom_officiel = from_str(obj, "nomOfficiel")
30
+ nom_usuel = from_str(obj, "nomUsuel")
31
+ code_abrege = from_str(obj, "codeAbrege")
32
+ logo = from_obj(Logo.from_dict, obj, "logo")
33
+ return TeamEngagement(
34
+ nom_officiel=nom_officiel,
35
+ nom_usuel=nom_usuel,
36
+ code_abrege=code_abrege,
37
+ logo=logo,
38
+ )
39
+
40
+ def to_dict(self) -> dict:
41
+ """
42
+ Convert the TeamEngagement instance to a dictionary object.
43
+
44
+ Returns:
45
+ dict: The converted dictionary object.
46
+ """
47
+ result: dict = {}
48
+ if self.nom_officiel is not None:
49
+ result["nomOfficiel"] = self.nom_officiel
50
+ if self.nom_usuel is not None:
51
+ result["nomUsuel"] = self.nom_usuel
52
+ if self.code_abrege is not None:
53
+ result["codeAbrege"] = self.code_abrege
54
+ if self.logo is not None:
55
+ result["logo"] = self.logo.to_dict()
56
+ return result
@@ -0,0 +1,108 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+ from ..utils.converter_utils import from_bool, from_float, from_int, from_str
6
+ from .ranking_engagement import RankingEngagement
7
+
8
+
9
+ @dataclass
10
+ class TeamRanking:
11
+ """Modèle pour un classement d'équipe."""
12
+
13
+ # Fields with defaults for lightweight API responses
14
+ id: str = ""
15
+ id_engagement: RankingEngagement | str | None = None
16
+ position: int = 0
17
+ points: int = 0
18
+ match_joues: int = 0
19
+ gagnes: int = 0
20
+ perdus: int = 0
21
+ nombre_forfaits: int = 0
22
+ paniers_marques: int = 0
23
+ paniers_encaisses: int = 0
24
+ difference: int = 0
25
+ quotient: float = 0.0
26
+ # Optional fields with defaults
27
+ nuls: int | None = None
28
+ nombre_defauts: int | None = None
29
+ point_initiaux: int | None = None
30
+ penalites_arbitrage: int | None = None
31
+ penalites_entraineur: int | None = None
32
+ penalites_diverses: int | None = None
33
+ hors_classement: bool | None = None
34
+ # Relation fields
35
+ organisme_id: str | None = None
36
+ organisme_nom: str | None = None
37
+ organisme_logo_id: str | None = None
38
+ organisme_nom_simple: str | None = None
39
+ id_competition: str | None = None
40
+ id_poule: str | None = None
41
+ id_poule_id: str | None = None
42
+
43
+ @classmethod
44
+ def from_dict(cls, data: dict) -> TeamRanking | None:
45
+ """Convert dictionary to TeamRanking instance."""
46
+ if not data:
47
+ return None
48
+
49
+ # Handle case where data is not a dictionary
50
+ if not isinstance(data, dict):
51
+ return None
52
+
53
+ id_engagement_raw = data.get("idEngagement")
54
+ if isinstance(id_engagement_raw, dict):
55
+ id_engagement = RankingEngagement.from_dict(id_engagement_raw)
56
+ elif isinstance(id_engagement_raw, (str, int)):
57
+ id_engagement = str(id_engagement_raw)
58
+ else:
59
+ id_engagement = None
60
+
61
+ # Handle organisme data
62
+ organisme_data = data.get("organisme", {})
63
+ if not isinstance(organisme_data, dict):
64
+ organisme_data = {}
65
+ organisme_id = from_str(organisme_data, "id")
66
+ organisme_nom = from_str(organisme_data, "nom")
67
+ organisme_nom_simple = from_str(organisme_data, "nom_simple")
68
+
69
+ # Handle organisme logo
70
+ organisme_logo_data = organisme_data.get("logo", {})
71
+ if not isinstance(organisme_logo_data, dict):
72
+ organisme_logo_data = {}
73
+ organisme_logo_id = from_str(organisme_logo_data, "id")
74
+
75
+ # Handle idPoule data
76
+ id_poule_data = data.get("idPoule", {})
77
+ if not isinstance(id_poule_data, dict):
78
+ id_poule_data = {}
79
+ id_poule_id = from_str(id_poule_data, "id")
80
+
81
+ return cls(
82
+ id=from_str(data, "id") or "",
83
+ id_engagement=id_engagement,
84
+ position=from_int(data, "position") or 0,
85
+ points=from_int(data, "points") or 0,
86
+ match_joues=from_int(data, "matchJoues") or 0,
87
+ gagnes=from_int(data, "gagnes") or 0,
88
+ perdus=from_int(data, "perdus") or 0,
89
+ nuls=from_int(data, "nuls"),
90
+ nombre_forfaits=from_int(data, "nombreForfaits") or 0,
91
+ nombre_defauts=from_int(data, "nombreDefauts"),
92
+ paniers_marques=from_int(data, "paniersMarques") or 0,
93
+ paniers_encaisses=from_int(data, "paniersEncaisses") or 0,
94
+ difference=from_int(data, "difference") or 0,
95
+ quotient=from_float(data, "quotient") or 0.0,
96
+ point_initiaux=from_int(data, "pointInitiaux"),
97
+ penalites_arbitrage=from_int(data, "penalitesArbitrage"),
98
+ penalites_entraineur=from_int(data, "penalitesEntraineur"),
99
+ penalites_diverses=from_int(data, "penalitesDiverses"),
100
+ hors_classement=from_bool(data, "horsClassement"),
101
+ organisme_id=organisme_id,
102
+ organisme_nom=organisme_nom,
103
+ organisme_logo_id=organisme_logo_id,
104
+ organisme_nom_simple=organisme_nom_simple,
105
+ id_competition=from_str(data, "idCompetition"),
106
+ id_poule=from_str(data, "idPoule"),
107
+ id_poule_id=id_poule_id,
108
+ )
@@ -0,0 +1,5 @@
1
+ from enum import Enum
2
+
3
+
4
+ class CategorieChampionnat3X3Libelle(Enum):
5
+ U18 = "U18"
@@ -0,0 +1,41 @@
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 .facet_distribution import FacetDistribution
8
+ from .sexe_class import SexeClass
9
+ from .tournoi_type_class import TournoiTypeClass
10
+ from .tournoi_types_3x3_libelle import TournoiTypes3X3Libelle
11
+
12
+
13
+ @dataclass
14
+ class TerrainsFacetDistribution(FacetDistribution):
15
+ sexe: SexeClass | None = None
16
+ tournoi_type: TournoiTypeClass | None = None
17
+ tournoi_types3_x3_libelle: TournoiTypes3X3Libelle | None = None
18
+
19
+ @staticmethod
20
+ def from_dict(obj: Any) -> TerrainsFacetDistribution:
21
+ assert isinstance(obj, dict)
22
+ sexe = from_obj(SexeClass.from_dict, obj, "sexe")
23
+ tournoi_type = from_obj(TournoiTypeClass.from_dict, obj, "tournoiType")
24
+ tournoi_types3_x3_libelle = from_obj(
25
+ TournoiTypes3X3Libelle.from_dict, obj, "tournoiTypes3x3.libelle"
26
+ )
27
+ return TerrainsFacetDistribution(
28
+ sexe=sexe,
29
+ tournoi_type=tournoi_type,
30
+ tournoi_types3_x3_libelle=tournoi_types3_x3_libelle,
31
+ )
32
+
33
+ def to_dict(self) -> dict:
34
+ result: dict = {}
35
+ if self.sexe is not None:
36
+ result["sexe"] = self.sexe.to_dict()
37
+ if self.tournoi_type is not None:
38
+ result["tournoiType"] = self.tournoi_type.to_dict()
39
+ if self.tournoi_types3_x3_libelle is not None:
40
+ result["tournoiTypes3x3.libelle"] = self.tournoi_types3_x3_libelle.to_dict()
41
+ 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 TerrainsFacetStats(FacetStats):
9
+ @staticmethod
10
+ def from_dict(obj: Any) -> TerrainsFacetStats:
11
+ return TerrainsFacetStats()
12
+
13
+ def to_dict(self) -> dict:
14
+ return super().to_dict()