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.
- ffbb_api_client_v3/__init__.py +25 -0
- ffbb_data_client/__init__.py +175 -0
- ffbb_data_client/clients/__init__.py +13 -0
- ffbb_data_client/clients/api_ffbb_app_client.py +2475 -0
- ffbb_data_client/clients/ffbb_data_client.py +2789 -0
- ffbb_data_client/clients/meilisearch_client.py +218 -0
- ffbb_data_client/clients/meilisearch_ffbb_client.py +647 -0
- ffbb_data_client/config.py +153 -0
- ffbb_data_client/data/__init__.py +25 -0
- ffbb_data_client/data/collections.json +1364 -0
- ffbb_data_client/data/endpoint_discovery.json +1875 -0
- ffbb_data_client/data/indexes.json +501 -0
- ffbb_data_client/data/openapi.json +35713 -0
- ffbb_data_client/data/openapi_full.json +37622 -0
- ffbb_data_client/helpers/__init__.py +27 -0
- ffbb_data_client/helpers/http_requests_helper.py +73 -0
- ffbb_data_client/helpers/http_requests_utils.py +502 -0
- ffbb_data_client/helpers/meilisearch_client_extension.py +153 -0
- ffbb_data_client/helpers/multi_search_query_helper.py +35 -0
- ffbb_data_client/models/__init__.py +241 -0
- ffbb_data_client/models/affiche.py +45 -0
- ffbb_data_client/models/cartographie.py +82 -0
- ffbb_data_client/models/categorie.py +55 -0
- ffbb_data_client/models/categorie_type.py +42 -0
- ffbb_data_client/models/clock.py +38 -0
- ffbb_data_client/models/club_contacts.py +77 -0
- ffbb_data_client/models/code.py +7 -0
- ffbb_data_client/models/commune.py +66 -0
- ffbb_data_client/models/competition_fields.py +309 -0
- ffbb_data_client/models/competition_id.py +116 -0
- ffbb_data_client/models/competition_id_categorie.py +31 -0
- ffbb_data_client/models/competition_id_sexe.py +31 -0
- ffbb_data_client/models/competition_id_type_competition.py +27 -0
- ffbb_data_client/models/competition_id_type_competition_generique.py +24 -0
- ffbb_data_client/models/competition_origine.py +69 -0
- ffbb_data_client/models/competition_origine_categorie.py +23 -0
- ffbb_data_client/models/competition_origine_type_competition.py +14 -0
- ffbb_data_client/models/competition_origine_type_competition_generique.py +24 -0
- ffbb_data_client/models/competition_type.py +6 -0
- ffbb_data_client/models/competitions_facet_distribution.py +65 -0
- ffbb_data_client/models/competitions_facet_stats.py +14 -0
- ffbb_data_client/models/competitions_hit.py +232 -0
- ffbb_data_client/models/competitions_multi_search_query.py +40 -0
- ffbb_data_client/models/competitions_query.py +11 -0
- ffbb_data_client/models/configuration_models.py +5 -0
- ffbb_data_client/models/contact_info.py +18 -0
- ffbb_data_client/models/content_multi_search_query.py +93 -0
- ffbb_data_client/models/coordonnees.py +27 -0
- ffbb_data_client/models/coordonnees_type.py +5 -0
- ffbb_data_client/models/document_flyer.py +205 -0
- ffbb_data_client/models/document_flyer_type.py +6 -0
- ffbb_data_client/models/engagement_contacts.py +97 -0
- ffbb_data_client/models/engagements_facet_distribution.py +59 -0
- ffbb_data_client/models/engagements_facet_stats.py +14 -0
- ffbb_data_client/models/engagements_hit.py +192 -0
- ffbb_data_client/models/engagements_multi_search_query.py +41 -0
- ffbb_data_client/models/etat.py +6 -0
- ffbb_data_client/models/external_competition_id.py +42 -0
- ffbb_data_client/models/external_id.py +72 -0
- ffbb_data_client/models/facet_distribution.py +13 -0
- ffbb_data_client/models/facet_stats.py +13 -0
- ffbb_data_client/models/field_set.py +10 -0
- ffbb_data_client/models/folder.py +35 -0
- ffbb_data_client/models/formation_session.py +60 -0
- ffbb_data_client/models/formations_facet_distribution.py +61 -0
- ffbb_data_client/models/formations_facet_stats.py +14 -0
- ffbb_data_client/models/formations_hit.py +277 -0
- ffbb_data_client/models/formations_multi_search_query.py +41 -0
- ffbb_data_client/models/game_stats_model.py +57 -0
- ffbb_data_client/models/game_stats_models.py +5 -0
- ffbb_data_client/models/generic_search.py +92 -0
- ffbb_data_client/models/geo.py +27 -0
- ffbb_data_client/models/geo_sort_order.py +6 -0
- ffbb_data_client/models/get_commune_response.py +18 -0
- ffbb_data_client/models/get_competition_response.py +523 -0
- ffbb_data_client/models/get_configuration_response.py +45 -0
- ffbb_data_client/models/get_engagement_response.py +23 -0
- ffbb_data_client/models/get_entraineur_response.py +18 -0
- ffbb_data_client/models/get_formation_response.py +28 -0
- ffbb_data_client/models/get_officiel_response.py +18 -0
- ffbb_data_client/models/get_organisme_response.py +476 -0
- ffbb_data_client/models/get_poule_response.py +68 -0
- ffbb_data_client/models/get_pratique_response.py +18 -0
- ffbb_data_client/models/get_rencontre_response.py +93 -0
- ffbb_data_client/models/get_saisons_response.py +56 -0
- ffbb_data_client/models/get_salle_response.py +20 -0
- ffbb_data_client/models/get_terrain_response.py +16 -0
- ffbb_data_client/models/get_tournoi_response.py +16 -0
- ffbb_data_client/models/gradient_color.py +27 -0
- ffbb_data_client/models/hit.py +16 -0
- ffbb_data_client/models/id_engagement_equipe.py +32 -0
- ffbb_data_client/models/id_organisme_equipe.py +51 -0
- ffbb_data_client/models/id_organisme_equipe1_logo.py +28 -0
- ffbb_data_client/models/id_poule.py +27 -0
- ffbb_data_client/models/jour.py +11 -0
- ffbb_data_client/models/label.py +15 -0
- ffbb_data_client/models/labellisation.py +30 -0
- ffbb_data_client/models/live.py +192 -0
- ffbb_data_client/models/lives.py +6 -0
- ffbb_data_client/models/logo.py +28 -0
- ffbb_data_client/models/multi_search_queries.py +24 -0
- ffbb_data_client/models/multi_search_query.py +96 -0
- ffbb_data_client/models/multi_search_result_competitions.py +14 -0
- ffbb_data_client/models/multi_search_result_engagements.py +14 -0
- ffbb_data_client/models/multi_search_result_formations.py +12 -0
- ffbb_data_client/models/multi_search_result_organismes.py +12 -0
- ffbb_data_client/models/multi_search_result_pratiques.py +12 -0
- ffbb_data_client/models/multi_search_result_rencontres.py +12 -0
- ffbb_data_client/models/multi_search_result_salles.py +12 -0
- ffbb_data_client/models/multi_search_result_terrains.py +12 -0
- ffbb_data_client/models/multi_search_result_tournois.py +12 -0
- ffbb_data_client/models/multi_search_results.py +103 -0
- ffbb_data_client/models/multi_search_results_class.py +96 -0
- ffbb_data_client/models/nature_sol.py +57 -0
- ffbb_data_client/models/niveau.py +10 -0
- ffbb_data_client/models/niveau_class.py +27 -0
- ffbb_data_client/models/niveau_extractor.py +214 -0
- ffbb_data_client/models/niveau_info.py +64 -0
- ffbb_data_client/models/niveau_models.py +14 -0
- ffbb_data_client/models/niveau_type.py +10 -0
- ffbb_data_client/models/objectif.py +7 -0
- ffbb_data_client/models/organisateur.py +197 -0
- ffbb_data_client/models/organisateur_type.py +6 -0
- ffbb_data_client/models/organisme_fields.py +327 -0
- ffbb_data_client/models/organisme_id_pere.py +177 -0
- ffbb_data_client/models/organismes_facet_distribution.py +46 -0
- ffbb_data_client/models/organismes_facet_stats.py +14 -0
- ffbb_data_client/models/organismes_hit.py +196 -0
- ffbb_data_client/models/organismes_multi_search_query.py +41 -0
- ffbb_data_client/models/organismes_query.py +8 -0
- ffbb_data_client/models/phase_code.py +23 -0
- ffbb_data_client/models/poule.py +35 -0
- ffbb_data_client/models/poule_fields.py +261 -0
- ffbb_data_client/models/poule_rencontre_item_model.py +69 -0
- ffbb_data_client/models/poules_models.py +6 -0
- ffbb_data_client/models/poules_query.py +9 -0
- ffbb_data_client/models/pratique.py +7 -0
- ffbb_data_client/models/pratiques_facet_distribution.py +29 -0
- ffbb_data_client/models/pratiques_facet_stats.py +14 -0
- ffbb_data_client/models/pratiques_hit.py +310 -0
- ffbb_data_client/models/pratiques_hit_type.py +9 -0
- ffbb_data_client/models/pratiques_multi_search_query.py +41 -0
- ffbb_data_client/models/pratiques_type_class.py +45 -0
- ffbb_data_client/models/publication_internet.py +6 -0
- ffbb_data_client/models/purple_logo.py +24 -0
- ffbb_data_client/models/query_fields_manager.py +75 -0
- ffbb_data_client/models/ranking_engagement.py +41 -0
- ffbb_data_client/models/rankings_models.py +6 -0
- ffbb_data_client/models/rencontres_engagement.py +23 -0
- ffbb_data_client/models/rencontres_facet_distribution.py +65 -0
- ffbb_data_client/models/rencontres_facet_stats.py +14 -0
- ffbb_data_client/models/rencontres_hit.py +271 -0
- ffbb_data_client/models/rencontres_multi_search_query.py +41 -0
- ffbb_data_client/models/saison.py +23 -0
- ffbb_data_client/models/saison_fields.py +36 -0
- ffbb_data_client/models/saisons_models.py +6 -0
- ffbb_data_client/models/saisons_query.py +9 -0
- ffbb_data_client/models/salle.py +56 -0
- ffbb_data_client/models/salles_facet_distribution.py +14 -0
- ffbb_data_client/models/salles_facet_stats.py +14 -0
- ffbb_data_client/models/salles_hit.py +153 -0
- ffbb_data_client/models/salles_multi_search_query.py +40 -0
- ffbb_data_client/models/sexe.py +9 -0
- ffbb_data_client/models/sexe_class.py +31 -0
- ffbb_data_client/models/source.py +5 -0
- ffbb_data_client/models/status.py +5 -0
- ffbb_data_client/models/team_engagement.py +56 -0
- ffbb_data_client/models/team_ranking.py +108 -0
- ffbb_data_client/models/terrains_categorie_championnat_3x3_libelle.py +5 -0
- ffbb_data_client/models/terrains_facet_distribution.py +41 -0
- ffbb_data_client/models/terrains_facet_stats.py +14 -0
- ffbb_data_client/models/terrains_hit.py +223 -0
- ffbb_data_client/models/terrains_multi_search_query.py +42 -0
- ffbb_data_client/models/terrains_name.py +5 -0
- ffbb_data_client/models/terrains_sexe_enum.py +7 -0
- ffbb_data_client/models/terrains_storage.py +5 -0
- ffbb_data_client/models/tournoi_type_class.py +35 -0
- ffbb_data_client/models/tournoi_type_enum.py +7 -0
- ffbb_data_client/models/tournoi_types_3x3.py +43 -0
- ffbb_data_client/models/tournoi_types_3x3_libelle.py +60 -0
- ffbb_data_client/models/tournoi_types_3x3_libelle_enum.py +10 -0
- ffbb_data_client/models/tournois_facet_distribution.py +41 -0
- ffbb_data_client/models/tournois_facet_stats.py +14 -0
- ffbb_data_client/models/tournois_hit.py +132 -0
- ffbb_data_client/models/tournois_hit_type.py +5 -0
- ffbb_data_client/models/tournois_libelle.py +7 -0
- ffbb_data_client/models/tournois_multi_search_query.py +40 -0
- ffbb_data_client/models/type_association.py +23 -0
- ffbb_data_client/models/type_association_libelle.py +30 -0
- ffbb_data_client/models/type_class.py +23 -0
- ffbb_data_client/models/type_competition.py +8 -0
- ffbb_data_client/models/type_competition_generique.py +31 -0
- ffbb_data_client/models/type_enum.py +7 -0
- ffbb_data_client/models/type_league.py +6 -0
- ffbb_data_client/py.typed +0 -0
- ffbb_data_client/utils/__init__.py +27 -0
- ffbb_data_client/utils/cache_manager.py +393 -0
- ffbb_data_client/utils/converter_utils.py +329 -0
- ffbb_data_client/utils/input_validation.py +360 -0
- ffbb_data_client/utils/retry_utils.py +478 -0
- ffbb_data_client/utils/secure_logging.py +153 -0
- ffbb_data_client/utils/token_manager.py +115 -0
- ffbb_data_client-2.0.0.dist-info/METADATA +339 -0
- ffbb_data_client-2.0.0.dist-info/RECORD +207 -0
- ffbb_data_client-2.0.0.dist-info/WHEEL +5 -0
- ffbb_data_client-2.0.0.dist-info/licenses/LICENSE.txt +201 -0
- ffbb_data_client-2.0.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from .facet_distribution import FacetDistribution
|
|
8
|
+
from .facet_stats import FacetStats
|
|
9
|
+
from .hit import Hit
|
|
10
|
+
from .multi_search_results import MultiSearchResult
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class GenericSearchHit(Hit):
|
|
15
|
+
"""Meilisearch hit for content indexes whose schema changes frequently."""
|
|
16
|
+
|
|
17
|
+
data: dict[str, Any] = field(default_factory=dict)
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def id(self) -> Any | None:
|
|
21
|
+
return self.data.get("id")
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def title(self) -> str | None:
|
|
25
|
+
title = self.data.get("title")
|
|
26
|
+
return str(title) if title is not None else None
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def type(self) -> str | None:
|
|
30
|
+
value = self.data.get("type")
|
|
31
|
+
return str(value) if value is not None else None
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def from_dict(obj: Any) -> GenericSearchHit:
|
|
35
|
+
return GenericSearchHit(data=dict(obj) if isinstance(obj, dict) else {})
|
|
36
|
+
|
|
37
|
+
def to_dict(self) -> dict[str, Any]:
|
|
38
|
+
return dict(self.data)
|
|
39
|
+
|
|
40
|
+
def is_valid_for_query(self, query: str) -> bool:
|
|
41
|
+
if not query:
|
|
42
|
+
return True
|
|
43
|
+
haystack = json.dumps(self.data, ensure_ascii=False, default=str).lower()
|
|
44
|
+
return query.lower() in haystack
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass
|
|
48
|
+
class GenericFacetDistribution(FacetDistribution):
|
|
49
|
+
data: dict[str, Any] = field(default_factory=dict)
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def from_dict(obj: Any) -> GenericFacetDistribution:
|
|
53
|
+
return GenericFacetDistribution(data=dict(obj) if isinstance(obj, dict) else {})
|
|
54
|
+
|
|
55
|
+
def to_dict(self) -> dict[str, Any]:
|
|
56
|
+
return dict(self.data)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass
|
|
60
|
+
class GenericFacetStats(FacetStats):
|
|
61
|
+
data: dict[str, Any] = field(default_factory=dict)
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def from_dict(obj: Any) -> GenericFacetStats:
|
|
65
|
+
return GenericFacetStats(data=dict(obj) if isinstance(obj, dict) else {})
|
|
66
|
+
|
|
67
|
+
def to_dict(self) -> dict[str, Any]:
|
|
68
|
+
return dict(self.data)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class NewsMultiSearchResult(
|
|
72
|
+
MultiSearchResult[GenericSearchHit, GenericFacetDistribution, GenericFacetStats]
|
|
73
|
+
):
|
|
74
|
+
"""MultiSearchResult for ffbbsite_news."""
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class YoutubeVideosMultiSearchResult(
|
|
78
|
+
MultiSearchResult[GenericSearchHit, GenericFacetDistribution, GenericFacetStats]
|
|
79
|
+
):
|
|
80
|
+
"""MultiSearchResult for youtube_videos."""
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class RssMultiSearchResult(
|
|
84
|
+
MultiSearchResult[GenericSearchHit, GenericFacetDistribution, GenericFacetStats]
|
|
85
|
+
):
|
|
86
|
+
"""MultiSearchResult for ffbbnational_rss."""
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class GaleriesMultiSearchResult(
|
|
90
|
+
MultiSearchResult[GenericSearchHit, GenericFacetDistribution, GenericFacetStats]
|
|
91
|
+
):
|
|
92
|
+
"""MultiSearchResult for ffbbnational_galeries."""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from ..utils.converter_utils import from_float
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class Geo:
|
|
11
|
+
lat: float | None = None
|
|
12
|
+
lng: float | None = None
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def from_dict(obj: Any) -> Geo:
|
|
16
|
+
assert isinstance(obj, dict)
|
|
17
|
+
lat = from_float(obj, "lat")
|
|
18
|
+
lng = from_float(obj, "lng")
|
|
19
|
+
return Geo(lat=lat, lng=lng)
|
|
20
|
+
|
|
21
|
+
def to_dict(self) -> dict:
|
|
22
|
+
result: dict = {}
|
|
23
|
+
if self.lat is not None:
|
|
24
|
+
result["lat"] = self.lat
|
|
25
|
+
if self.lng is not None:
|
|
26
|
+
result["lng"] = self.lng
|
|
27
|
+
return result
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class GetCommuneResponse:
|
|
6
|
+
id: str
|
|
7
|
+
libelle: str | None = None
|
|
8
|
+
codePostal: str | None = None
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def from_dict(cls, data: dict) -> "GetCommuneResponse | None":
|
|
12
|
+
if not data or not isinstance(data, dict):
|
|
13
|
+
return None
|
|
14
|
+
return cls(
|
|
15
|
+
id=str(data.get("id", "")),
|
|
16
|
+
libelle=data.get("libelle"),
|
|
17
|
+
codePostal=data.get("codePostal"),
|
|
18
|
+
)
|
|
@@ -0,0 +1,523 @@
|
|
|
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 .game_stats_model import GameStatsModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class GetCompetitionResponse:
|
|
12
|
+
id: str
|
|
13
|
+
nom: str
|
|
14
|
+
sexe: str
|
|
15
|
+
saison: str
|
|
16
|
+
code: str
|
|
17
|
+
typeCompetition: str
|
|
18
|
+
liveStat: int
|
|
19
|
+
competition_origine: str
|
|
20
|
+
competition_origine_nom: str
|
|
21
|
+
publicationInternet: str
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class CategorieModel:
|
|
25
|
+
code: str
|
|
26
|
+
ordre: int
|
|
27
|
+
|
|
28
|
+
categorie: CategorieModel | None = None
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class TypecompetitiongeneriqueModel:
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class LogoModel:
|
|
35
|
+
id: str
|
|
36
|
+
gradient_color: str
|
|
37
|
+
|
|
38
|
+
logo: LogoModel | None = None
|
|
39
|
+
|
|
40
|
+
typeCompetitionGenerique: TypecompetitiongeneriqueModel | None = None
|
|
41
|
+
logo: Any | None = None
|
|
42
|
+
id_competition_pere: int | None = None
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class PoulesitemModel:
|
|
46
|
+
id: str
|
|
47
|
+
nom: str
|
|
48
|
+
|
|
49
|
+
poules: list[PoulesitemModel] = field(default_factory=list)
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class PhasesitemModel:
|
|
53
|
+
id: str
|
|
54
|
+
nom: str
|
|
55
|
+
liveStat: int
|
|
56
|
+
phase_code: str
|
|
57
|
+
|
|
58
|
+
@dataclass
|
|
59
|
+
class PoulesitemModel:
|
|
60
|
+
id: str
|
|
61
|
+
nom: str
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class RencontresitemModel:
|
|
65
|
+
id: str
|
|
66
|
+
numero: str
|
|
67
|
+
numeroJournee: str
|
|
68
|
+
idPoule: str
|
|
69
|
+
competitionId: str
|
|
70
|
+
resultatEquipe1: str
|
|
71
|
+
resultatEquipe2: str
|
|
72
|
+
joue: int
|
|
73
|
+
nomEquipe1: str
|
|
74
|
+
nomEquipe2: str
|
|
75
|
+
date_rencontre: datetime
|
|
76
|
+
|
|
77
|
+
@dataclass
|
|
78
|
+
class Idorganismeequipe1Model:
|
|
79
|
+
logo: Any | None = None
|
|
80
|
+
|
|
81
|
+
idOrganismeEquipe1: Idorganismeequipe1Model | None = None
|
|
82
|
+
|
|
83
|
+
@dataclass
|
|
84
|
+
class Idorganismeequipe2Model:
|
|
85
|
+
logo: Any | None = None
|
|
86
|
+
|
|
87
|
+
idOrganismeEquipe2: Idorganismeequipe2Model | None = None
|
|
88
|
+
gsId: GameStatsModel | None = None
|
|
89
|
+
|
|
90
|
+
@dataclass
|
|
91
|
+
class Idengagementequipe1Model:
|
|
92
|
+
nom: str
|
|
93
|
+
id: str
|
|
94
|
+
nomOfficiel: str
|
|
95
|
+
nomUsuel: str
|
|
96
|
+
codeAbrege: str
|
|
97
|
+
logo: Any | None = None
|
|
98
|
+
|
|
99
|
+
idEngagementEquipe1: Idengagementequipe1Model | None = None
|
|
100
|
+
|
|
101
|
+
@dataclass
|
|
102
|
+
class Idengagementequipe2Model:
|
|
103
|
+
nom: str
|
|
104
|
+
id: str
|
|
105
|
+
nomOfficiel: str
|
|
106
|
+
nomUsuel: str
|
|
107
|
+
codeAbrege: str
|
|
108
|
+
logo: Any | None = None
|
|
109
|
+
|
|
110
|
+
idEngagementEquipe2: Idengagementequipe2Model | None = None
|
|
111
|
+
|
|
112
|
+
@dataclass
|
|
113
|
+
class SalleModel:
|
|
114
|
+
id: str
|
|
115
|
+
numero: str
|
|
116
|
+
libelle: str
|
|
117
|
+
libelle2: str
|
|
118
|
+
adresse: str
|
|
119
|
+
adresseComplement: str
|
|
120
|
+
|
|
121
|
+
@dataclass
|
|
122
|
+
class CommuneModel:
|
|
123
|
+
codePostal: str
|
|
124
|
+
libelle: str
|
|
125
|
+
|
|
126
|
+
commune: CommuneModel | None = None
|
|
127
|
+
|
|
128
|
+
@dataclass
|
|
129
|
+
class CartographieModel:
|
|
130
|
+
latitude: float
|
|
131
|
+
longitude: float
|
|
132
|
+
|
|
133
|
+
cartographie: CartographieModel | None = None
|
|
134
|
+
|
|
135
|
+
salle: SalleModel | None = None
|
|
136
|
+
|
|
137
|
+
@dataclass
|
|
138
|
+
class OfficielsitemModel:
|
|
139
|
+
ordre: int
|
|
140
|
+
|
|
141
|
+
@dataclass
|
|
142
|
+
class FonctionModel:
|
|
143
|
+
libelle: str
|
|
144
|
+
|
|
145
|
+
fonction: FonctionModel | None = None
|
|
146
|
+
|
|
147
|
+
@dataclass
|
|
148
|
+
class OfficielModel:
|
|
149
|
+
nom: str
|
|
150
|
+
prenom: str
|
|
151
|
+
|
|
152
|
+
officiel: OfficielModel | None = None
|
|
153
|
+
|
|
154
|
+
officiels: list[OfficielsitemModel] = field(default_factory=list)
|
|
155
|
+
|
|
156
|
+
rencontres: list[RencontresitemModel] = field(default_factory=list)
|
|
157
|
+
|
|
158
|
+
@dataclass
|
|
159
|
+
class EngagementsitemModel:
|
|
160
|
+
id: str
|
|
161
|
+
|
|
162
|
+
@dataclass
|
|
163
|
+
class IdorganismeModel:
|
|
164
|
+
id: str
|
|
165
|
+
|
|
166
|
+
idOrganisme: IdorganismeModel | None = None
|
|
167
|
+
|
|
168
|
+
engagements: list[EngagementsitemModel] = field(default_factory=list)
|
|
169
|
+
|
|
170
|
+
poules: list[PoulesitemModel] = field(default_factory=list)
|
|
171
|
+
|
|
172
|
+
phases: list[PhasesitemModel] = field(default_factory=list)
|
|
173
|
+
|
|
174
|
+
@classmethod
|
|
175
|
+
def from_dict(cls, data: dict) -> GetCompetitionResponse | None:
|
|
176
|
+
"""Convert dictionary to CompetitionsModel instance."""
|
|
177
|
+
if not data:
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
# Handle case where data is not a dictionary
|
|
181
|
+
if not isinstance(data, dict):
|
|
182
|
+
return None
|
|
183
|
+
|
|
184
|
+
# Handle API error responses
|
|
185
|
+
if "errors" in data:
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
# Extract nested categorie data
|
|
189
|
+
categorie_data = data.get("categorie", {})
|
|
190
|
+
categorie = (
|
|
191
|
+
cls.CategorieModel(
|
|
192
|
+
code=str(categorie_data.get("code", "")),
|
|
193
|
+
ordre=int(categorie_data.get("ordre", 0)),
|
|
194
|
+
)
|
|
195
|
+
if categorie_data
|
|
196
|
+
else None
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# Extract nested typeCompetitionGenerique data
|
|
200
|
+
type_comp_generique_data = data.get("typeCompetitionGenerique", {})
|
|
201
|
+
type_comp_generique = None
|
|
202
|
+
if type_comp_generique_data:
|
|
203
|
+
logo_data = type_comp_generique_data.get("logo", {})
|
|
204
|
+
logo_tcg = (
|
|
205
|
+
cls.TypecompetitiongeneriqueModel.LogoModel(
|
|
206
|
+
id=str(logo_data.get("id", "")),
|
|
207
|
+
gradient_color=str(logo_data.get("gradient_color", "")),
|
|
208
|
+
)
|
|
209
|
+
if logo_data
|
|
210
|
+
else None
|
|
211
|
+
)
|
|
212
|
+
type_comp_generique = cls.TypecompetitiongeneriqueModel(logo=logo_tcg)
|
|
213
|
+
|
|
214
|
+
# Extract poules data (basic level)
|
|
215
|
+
poules = []
|
|
216
|
+
for poule_data in data.get("poules", []):
|
|
217
|
+
if poule_data:
|
|
218
|
+
poule = cls.PoulesitemModel(
|
|
219
|
+
id=str(poule_data.get("id", "")),
|
|
220
|
+
nom=str(poule_data.get("nom", "")),
|
|
221
|
+
)
|
|
222
|
+
poules.append(poule)
|
|
223
|
+
|
|
224
|
+
# Extract phases data with complete nested structure
|
|
225
|
+
phases = []
|
|
226
|
+
for phase_data in data.get("phases", []):
|
|
227
|
+
if phase_data:
|
|
228
|
+
# Process poules within phases
|
|
229
|
+
phase_poules = []
|
|
230
|
+
for phase_poule_data in phase_data.get("poules", []):
|
|
231
|
+
if phase_poule_data:
|
|
232
|
+
# Process rencontres within phase poules
|
|
233
|
+
rencontres = []
|
|
234
|
+
for rencontre_data in phase_poule_data.get("rencontres", []):
|
|
235
|
+
if rencontre_data:
|
|
236
|
+
# Extract gsId (GameStats) data
|
|
237
|
+
gs_id_data = rencontre_data.get("gsId", {})
|
|
238
|
+
gs_id = (
|
|
239
|
+
GameStatsModel.from_dict(gs_id_data)
|
|
240
|
+
if gs_id_data
|
|
241
|
+
else None
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# Extract idOrganismeEquipe1 data
|
|
245
|
+
org_equipe1_data = rencontre_data.get(
|
|
246
|
+
"idOrganismeEquipe1", {}
|
|
247
|
+
)
|
|
248
|
+
id_organisme_equipe1 = (
|
|
249
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.Idorganismeequipe1Model(
|
|
250
|
+
logo=org_equipe1_data.get("logo")
|
|
251
|
+
)
|
|
252
|
+
if org_equipe1_data
|
|
253
|
+
else None
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
# Extract idOrganismeEquipe2 data
|
|
257
|
+
org_equipe2_data = rencontre_data.get(
|
|
258
|
+
"idOrganismeEquipe2", {}
|
|
259
|
+
)
|
|
260
|
+
id_organisme_equipe2 = (
|
|
261
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.Idorganismeequipe2Model(
|
|
262
|
+
logo=org_equipe2_data.get("logo")
|
|
263
|
+
)
|
|
264
|
+
if org_equipe2_data
|
|
265
|
+
else None
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Extract idEngagementEquipe1 data
|
|
269
|
+
eng_equipe1_data = rencontre_data.get(
|
|
270
|
+
"idEngagementEquipe1", {}
|
|
271
|
+
)
|
|
272
|
+
id_engagement_equipe1 = (
|
|
273
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.Idengagementequipe1Model(
|
|
274
|
+
nom=str(eng_equipe1_data.get("nom", "")),
|
|
275
|
+
id=str(eng_equipe1_data.get("id", "")),
|
|
276
|
+
nomOfficiel=str(
|
|
277
|
+
eng_equipe1_data.get("nomOfficiel", "")
|
|
278
|
+
),
|
|
279
|
+
nomUsuel=str(
|
|
280
|
+
eng_equipe1_data.get("nomUsuel", "")
|
|
281
|
+
),
|
|
282
|
+
codeAbrege=str(
|
|
283
|
+
eng_equipe1_data.get("codeAbrege", "")
|
|
284
|
+
),
|
|
285
|
+
logo=eng_equipe1_data.get("logo"),
|
|
286
|
+
)
|
|
287
|
+
if eng_equipe1_data
|
|
288
|
+
else None
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
# Extract idEngagementEquipe2 data
|
|
292
|
+
eng_equipe2_data = rencontre_data.get(
|
|
293
|
+
"idEngagementEquipe2", {}
|
|
294
|
+
)
|
|
295
|
+
id_engagement_equipe2 = (
|
|
296
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.Idengagementequipe2Model(
|
|
297
|
+
nom=str(eng_equipe2_data.get("nom", "")),
|
|
298
|
+
id=str(eng_equipe2_data.get("id", "")),
|
|
299
|
+
nomOfficiel=str(
|
|
300
|
+
eng_equipe2_data.get("nomOfficiel", "")
|
|
301
|
+
),
|
|
302
|
+
nomUsuel=str(
|
|
303
|
+
eng_equipe2_data.get("nomUsuel", "")
|
|
304
|
+
),
|
|
305
|
+
codeAbrege=str(
|
|
306
|
+
eng_equipe2_data.get("codeAbrege", "")
|
|
307
|
+
),
|
|
308
|
+
logo=eng_equipe2_data.get("logo"),
|
|
309
|
+
)
|
|
310
|
+
if eng_equipe2_data
|
|
311
|
+
else None
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
# Extract salle data
|
|
315
|
+
salle_data = rencontre_data.get("salle", {})
|
|
316
|
+
salle = None
|
|
317
|
+
if salle_data:
|
|
318
|
+
salle_commune_data = salle_data.get("commune", {})
|
|
319
|
+
salle_commune = (
|
|
320
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.SalleModel.CommuneModel(
|
|
321
|
+
codePostal=str(
|
|
322
|
+
salle_commune_data.get("codePostal", "")
|
|
323
|
+
),
|
|
324
|
+
libelle=str(
|
|
325
|
+
salle_commune_data.get("libelle", "")
|
|
326
|
+
),
|
|
327
|
+
)
|
|
328
|
+
if salle_commune_data
|
|
329
|
+
else None
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
salle_cartographie_data = salle_data.get(
|
|
333
|
+
"cartographie", {}
|
|
334
|
+
)
|
|
335
|
+
salle_cartographie = (
|
|
336
|
+
(
|
|
337
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.SalleModel.CartographieModel
|
|
338
|
+
)(
|
|
339
|
+
latitude=float(
|
|
340
|
+
salle_cartographie_data.get(
|
|
341
|
+
"latitude", 0.0
|
|
342
|
+
)
|
|
343
|
+
),
|
|
344
|
+
longitude=float(
|
|
345
|
+
salle_cartographie_data.get(
|
|
346
|
+
"longitude", 0.0
|
|
347
|
+
)
|
|
348
|
+
),
|
|
349
|
+
)
|
|
350
|
+
if salle_cartographie_data
|
|
351
|
+
else None
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
salle = cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.SalleModel(
|
|
355
|
+
id=str(salle_data.get("id", "")),
|
|
356
|
+
numero=str(salle_data.get("numero", "")),
|
|
357
|
+
libelle=str(salle_data.get("libelle", "")),
|
|
358
|
+
libelle2=str(salle_data.get("libelle2", "")),
|
|
359
|
+
adresse=str(salle_data.get("adresse", "")),
|
|
360
|
+
adresseComplement=str(
|
|
361
|
+
salle_data.get("adresseComplement", "")
|
|
362
|
+
),
|
|
363
|
+
commune=salle_commune,
|
|
364
|
+
cartographie=salle_cartographie,
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
# Extract officiels data
|
|
368
|
+
officiels = []
|
|
369
|
+
for officiel_data in rencontre_data.get(
|
|
370
|
+
"officiels", []
|
|
371
|
+
):
|
|
372
|
+
if officiel_data:
|
|
373
|
+
fonction_data = officiel_data.get(
|
|
374
|
+
"fonction", {}
|
|
375
|
+
)
|
|
376
|
+
fonction = (
|
|
377
|
+
(
|
|
378
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.OfficielsitemModel.FonctionModel
|
|
379
|
+
)(
|
|
380
|
+
libelle=str(
|
|
381
|
+
fonction_data.get("libelle", "")
|
|
382
|
+
),
|
|
383
|
+
)
|
|
384
|
+
if fonction_data
|
|
385
|
+
else None
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
officiel_person_data = officiel_data.get(
|
|
389
|
+
"officiel", {}
|
|
390
|
+
)
|
|
391
|
+
officiel_person = (
|
|
392
|
+
(
|
|
393
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.OfficielsitemModel.OfficielModel
|
|
394
|
+
)(
|
|
395
|
+
nom=str(
|
|
396
|
+
officiel_person_data.get("nom", "")
|
|
397
|
+
),
|
|
398
|
+
prenom=str(
|
|
399
|
+
officiel_person_data.get(
|
|
400
|
+
"prenom", ""
|
|
401
|
+
)
|
|
402
|
+
),
|
|
403
|
+
)
|
|
404
|
+
if officiel_person_data
|
|
405
|
+
else None
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
officiel = (
|
|
409
|
+
cls.PhasesitemModel.PoulesitemModel.RencontresitemModel.OfficielsitemModel
|
|
410
|
+
)(
|
|
411
|
+
ordre=int(officiel_data.get("ordre") or 0),
|
|
412
|
+
fonction=fonction,
|
|
413
|
+
officiel=officiel_person,
|
|
414
|
+
)
|
|
415
|
+
officiels.append(officiel)
|
|
416
|
+
|
|
417
|
+
# Create the rencontre object with proper date handling
|
|
418
|
+
date_str = rencontre_data.get(
|
|
419
|
+
"date_rencontre", "1970-01-01T00:00:00"
|
|
420
|
+
)
|
|
421
|
+
try:
|
|
422
|
+
date_rencontre = datetime.fromisoformat(
|
|
423
|
+
date_str.replace("Z", "+00:00")
|
|
424
|
+
)
|
|
425
|
+
except (ValueError, AttributeError):
|
|
426
|
+
date_rencontre = datetime.fromisoformat(
|
|
427
|
+
"1970-01-01T00:00:00"
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
rencontre = cls.PhasesitemModel.PoulesitemModel.RencontresitemModel(
|
|
431
|
+
id=str(rencontre_data.get("id", "")),
|
|
432
|
+
numero=str(rencontre_data.get("numero", "")),
|
|
433
|
+
numeroJournee=str(
|
|
434
|
+
rencontre_data.get("numeroJournee", "")
|
|
435
|
+
),
|
|
436
|
+
idPoule=str(rencontre_data.get("idPoule", "")),
|
|
437
|
+
competitionId=str(
|
|
438
|
+
rencontre_data.get("competitionId", "")
|
|
439
|
+
),
|
|
440
|
+
resultatEquipe1=str(
|
|
441
|
+
rencontre_data.get("resultatEquipe1", "")
|
|
442
|
+
),
|
|
443
|
+
resultatEquipe2=str(
|
|
444
|
+
rencontre_data.get("resultatEquipe2", "")
|
|
445
|
+
),
|
|
446
|
+
joue=int(rencontre_data.get("joue", 0)),
|
|
447
|
+
nomEquipe1=str(
|
|
448
|
+
rencontre_data.get("nomEquipe1", "")
|
|
449
|
+
),
|
|
450
|
+
nomEquipe2=str(
|
|
451
|
+
rencontre_data.get("nomEquipe2", "")
|
|
452
|
+
),
|
|
453
|
+
date_rencontre=date_rencontre,
|
|
454
|
+
idOrganismeEquipe1=id_organisme_equipe1,
|
|
455
|
+
idOrganismeEquipe2=id_organisme_equipe2,
|
|
456
|
+
gsId=gs_id,
|
|
457
|
+
idEngagementEquipe1=id_engagement_equipe1,
|
|
458
|
+
idEngagementEquipe2=id_engagement_equipe2,
|
|
459
|
+
salle=salle,
|
|
460
|
+
officiels=officiels,
|
|
461
|
+
)
|
|
462
|
+
rencontres.append(rencontre)
|
|
463
|
+
|
|
464
|
+
# Extract engagements within phase poules
|
|
465
|
+
engagements = []
|
|
466
|
+
for engagement_data in phase_poule_data.get("engagements", []):
|
|
467
|
+
if engagement_data:
|
|
468
|
+
id_organisme_data = engagement_data.get(
|
|
469
|
+
"idOrganisme", {}
|
|
470
|
+
)
|
|
471
|
+
id_organisme = (
|
|
472
|
+
cls.PhasesitemModel.PoulesitemModel.EngagementsitemModel.IdorganismeModel(
|
|
473
|
+
id=str(id_organisme_data.get("id", "")),
|
|
474
|
+
)
|
|
475
|
+
if id_organisme_data
|
|
476
|
+
else None
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
engagement = cls.PhasesitemModel.PoulesitemModel.EngagementsitemModel(
|
|
480
|
+
id=str(engagement_data.get("id", "")),
|
|
481
|
+
idOrganisme=id_organisme,
|
|
482
|
+
)
|
|
483
|
+
engagements.append(engagement)
|
|
484
|
+
|
|
485
|
+
phase_poule = cls.PhasesitemModel.PoulesitemModel(
|
|
486
|
+
id=str(phase_poule_data.get("id", "")),
|
|
487
|
+
nom=str(phase_poule_data.get("nom", "")),
|
|
488
|
+
rencontres=rencontres,
|
|
489
|
+
engagements=engagements,
|
|
490
|
+
)
|
|
491
|
+
phase_poules.append(phase_poule)
|
|
492
|
+
|
|
493
|
+
phase = cls.PhasesitemModel(
|
|
494
|
+
id=str(phase_data.get("id", "")),
|
|
495
|
+
nom=str(phase_data.get("nom", "")),
|
|
496
|
+
liveStat=int(phase_data.get("liveStat", 0)),
|
|
497
|
+
phase_code=str(phase_data.get("phase_code", "")),
|
|
498
|
+
poules=phase_poules,
|
|
499
|
+
)
|
|
500
|
+
phases.append(phase)
|
|
501
|
+
|
|
502
|
+
return cls(
|
|
503
|
+
id=str(data.get("id", "")),
|
|
504
|
+
nom=str(data.get("nom", "")),
|
|
505
|
+
sexe=str(data.get("sexe", "")),
|
|
506
|
+
saison=str(data.get("saison", "")),
|
|
507
|
+
code=str(data.get("code", "")),
|
|
508
|
+
typeCompetition=str(data.get("typeCompetition", "")),
|
|
509
|
+
liveStat=int(data.get("liveStat", 0)),
|
|
510
|
+
competition_origine=str(data.get("competition_origine", "")),
|
|
511
|
+
competition_origine_nom=str(data.get("competition_origine_nom", "")),
|
|
512
|
+
publicationInternet=str(data.get("publicationInternet", "")),
|
|
513
|
+
categorie=categorie,
|
|
514
|
+
typeCompetitionGenerique=type_comp_generique,
|
|
515
|
+
logo=data.get("logo"),
|
|
516
|
+
id_competition_pere=(
|
|
517
|
+
int(data["idCompetitionPere"])
|
|
518
|
+
if data.get("idCompetitionPere")
|
|
519
|
+
else None
|
|
520
|
+
),
|
|
521
|
+
poules=poules,
|
|
522
|
+
phases=phases,
|
|
523
|
+
)
|