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,45 @@
|
|
|
1
|
+
"""Configuration models for FFBB API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class GetConfigurationResponse:
|
|
10
|
+
"""Response model for /items/configuration endpoint."""
|
|
11
|
+
|
|
12
|
+
id: int
|
|
13
|
+
key_dh: str
|
|
14
|
+
key_ms: str
|
|
15
|
+
key_directus_website: str | None = None
|
|
16
|
+
key_directus_competitions: str | None = None
|
|
17
|
+
ios_version: str | None = None
|
|
18
|
+
android_version: str | None = None
|
|
19
|
+
date_created: str | None = None
|
|
20
|
+
date_updated: str | None = None
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def from_dict(cls, data: dict) -> GetConfigurationResponse:
|
|
24
|
+
"""Create a GetConfigurationResponse from a dictionary."""
|
|
25
|
+
return cls(
|
|
26
|
+
id=data.get("id", 0),
|
|
27
|
+
key_dh=data.get("key_dh", ""),
|
|
28
|
+
key_ms=data.get("key_ms", ""),
|
|
29
|
+
key_directus_website=data.get("key_directus_website"),
|
|
30
|
+
key_directus_competitions=data.get("key_directus_competitions"),
|
|
31
|
+
ios_version=data.get("ios_version"),
|
|
32
|
+
android_version=data.get("android_version"),
|
|
33
|
+
date_created=data.get("date_created"),
|
|
34
|
+
date_updated=data.get("date_updated"),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def api_bearer_token(self) -> str:
|
|
39
|
+
"""Alias for key_dh - the API bearer token."""
|
|
40
|
+
return self.key_dh
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def meilisearch_token(self) -> str:
|
|
44
|
+
"""Alias for key_ms - the Meilisearch token."""
|
|
45
|
+
return self.key_ms
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class GetEngagementResponse:
|
|
7
|
+
id: str
|
|
8
|
+
numeroEquipe: str | None = None
|
|
9
|
+
idPoule: Any | None = None
|
|
10
|
+
idCompetition: Any | None = None
|
|
11
|
+
idOrganisme: Any | None = None
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def from_dict(cls, data: dict) -> "GetEngagementResponse | None":
|
|
15
|
+
if not data or not isinstance(data, dict):
|
|
16
|
+
return None
|
|
17
|
+
return cls(
|
|
18
|
+
id=str(data.get("id", "")),
|
|
19
|
+
numeroEquipe=data.get("numeroEquipe"),
|
|
20
|
+
idPoule=data.get("idPoule"),
|
|
21
|
+
idCompetition=data.get("idCompetition"),
|
|
22
|
+
idOrganisme=data.get("idOrganisme"),
|
|
23
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class GetEntraineurResponse:
|
|
6
|
+
id: str
|
|
7
|
+
nom: str | None = None
|
|
8
|
+
prenom: str | None = None
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def from_dict(cls, data: dict) -> "GetEntraineurResponse | None":
|
|
12
|
+
if not data or not isinstance(data, dict):
|
|
13
|
+
return None
|
|
14
|
+
return cls(
|
|
15
|
+
id=str(data.get("id", "")),
|
|
16
|
+
nom=data.get("nom"),
|
|
17
|
+
prenom=data.get("prenom"),
|
|
18
|
+
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class GetFormationResponse:
|
|
6
|
+
id: str
|
|
7
|
+
theme: str | None = None
|
|
8
|
+
type: str | None = None
|
|
9
|
+
domain: str | None = None
|
|
10
|
+
mode: str | None = None
|
|
11
|
+
place: str | None = None
|
|
12
|
+
date_start: str | None = None
|
|
13
|
+
date_end: str | None = None
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def from_dict(cls, data: dict) -> "GetFormationResponse | None":
|
|
17
|
+
if not data or not isinstance(data, dict):
|
|
18
|
+
return None
|
|
19
|
+
return cls(
|
|
20
|
+
id=str(data.get("id", "")),
|
|
21
|
+
theme=data.get("theme"),
|
|
22
|
+
type=data.get("type"),
|
|
23
|
+
domain=data.get("domain"),
|
|
24
|
+
mode=data.get("mode"),
|
|
25
|
+
place=data.get("place"),
|
|
26
|
+
date_start=data.get("date_start"),
|
|
27
|
+
date_end=data.get("date_end"),
|
|
28
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class GetOfficielResponse:
|
|
6
|
+
id: str
|
|
7
|
+
nom: str | None = None
|
|
8
|
+
prenom: str | None = None
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def from_dict(cls, data: dict) -> "GetOfficielResponse | None":
|
|
12
|
+
if not data or not isinstance(data, dict):
|
|
13
|
+
return None
|
|
14
|
+
return cls(
|
|
15
|
+
id=str(data.get("id", "")),
|
|
16
|
+
nom=data.get("nom"),
|
|
17
|
+
prenom=data.get("prenom"),
|
|
18
|
+
)
|
|
@@ -0,0 +1,476 @@
|
|
|
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 .niveau_models import NiveauInfo, get_niveau_from_idcompetition
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class GetOrganismeResponse:
|
|
12
|
+
id: str
|
|
13
|
+
nom: str
|
|
14
|
+
code: str
|
|
15
|
+
telephone: str
|
|
16
|
+
adresse: str
|
|
17
|
+
mail: str
|
|
18
|
+
type: str = ""
|
|
19
|
+
nom_simple: Any | None = None
|
|
20
|
+
urlSiteWeb: str = ""
|
|
21
|
+
nomClubPro: str = ""
|
|
22
|
+
adresseClubPro: Any | None = None
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class CommuneModel:
|
|
26
|
+
codePostal: str
|
|
27
|
+
libelle: str
|
|
28
|
+
|
|
29
|
+
commune: CommuneModel | None = None
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class CartographieModel:
|
|
33
|
+
latitude: float
|
|
34
|
+
longitude: float
|
|
35
|
+
|
|
36
|
+
cartographie: CartographieModel | None = None
|
|
37
|
+
communeClubPro: Any | None = None
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class MembresitemModel:
|
|
41
|
+
id: str
|
|
42
|
+
nom: str
|
|
43
|
+
prenom: str
|
|
44
|
+
adresse1: str
|
|
45
|
+
adresse2: Any | None = None
|
|
46
|
+
codePostal: str = ""
|
|
47
|
+
ville: str = ""
|
|
48
|
+
mail: str = ""
|
|
49
|
+
telephoneFixe: Any | None = None
|
|
50
|
+
telephonePortable: str = ""
|
|
51
|
+
codeFonction: str = ""
|
|
52
|
+
|
|
53
|
+
membres: list[MembresitemModel] = field(default_factory=list)
|
|
54
|
+
competitions: list[Any] = field(default_factory=list)
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class EngagementsitemModel:
|
|
58
|
+
id: str
|
|
59
|
+
numeroEquipe: str | None = None
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def poule_id(self) -> str | None:
|
|
63
|
+
"""Convenience property to access nested poule ID."""
|
|
64
|
+
return self.idPoule.id if self.idPoule else None
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def competition_nom(self) -> str | None:
|
|
68
|
+
"""Convenience property to access nested competition name."""
|
|
69
|
+
return self.idCompetition.nom if self.idCompetition else None
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def numero_equipe(self) -> str | None:
|
|
73
|
+
"""Convenience alias for .numeroEquipe."""
|
|
74
|
+
return self.numeroEquipe
|
|
75
|
+
|
|
76
|
+
@dataclass
|
|
77
|
+
class IdpouleModel:
|
|
78
|
+
id: str
|
|
79
|
+
|
|
80
|
+
idPoule: IdpouleModel | None = None
|
|
81
|
+
|
|
82
|
+
@dataclass
|
|
83
|
+
class IdcompetitionModel:
|
|
84
|
+
id: str
|
|
85
|
+
nom: str
|
|
86
|
+
code: str
|
|
87
|
+
sexe: str
|
|
88
|
+
competition_origine: str
|
|
89
|
+
competition_origine_nom: str
|
|
90
|
+
competition_origine_niveau: int
|
|
91
|
+
typeCompetition: str
|
|
92
|
+
logo: Any | None = None
|
|
93
|
+
|
|
94
|
+
@dataclass
|
|
95
|
+
class SaisonModel:
|
|
96
|
+
id: str
|
|
97
|
+
|
|
98
|
+
saison: SaisonModel | None = None
|
|
99
|
+
idCompetitionPere: Any | None = None
|
|
100
|
+
|
|
101
|
+
@dataclass
|
|
102
|
+
class OrganisateurModel:
|
|
103
|
+
type: str
|
|
104
|
+
|
|
105
|
+
organisateur: OrganisateurModel | None = None
|
|
106
|
+
|
|
107
|
+
@dataclass
|
|
108
|
+
class TypecompetitiongeneriqueModel:
|
|
109
|
+
|
|
110
|
+
@dataclass
|
|
111
|
+
class LogoModel:
|
|
112
|
+
id: str
|
|
113
|
+
gradient_color: str
|
|
114
|
+
|
|
115
|
+
logo: LogoModel | None = None
|
|
116
|
+
|
|
117
|
+
typeCompetitionGenerique: TypecompetitiongeneriqueModel | None = None
|
|
118
|
+
|
|
119
|
+
@dataclass
|
|
120
|
+
class CategorieModel:
|
|
121
|
+
code: str
|
|
122
|
+
ordre: int
|
|
123
|
+
|
|
124
|
+
categorie: CategorieModel | None = None
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def niveau(self) -> NiveauInfo | None:
|
|
128
|
+
"""Extrait automatiquement le niveau depuis le nom de la competition."""
|
|
129
|
+
return get_niveau_from_idcompetition(self)
|
|
130
|
+
|
|
131
|
+
idCompetition: IdcompetitionModel | None = None
|
|
132
|
+
|
|
133
|
+
engagements: list[EngagementsitemModel] = field(default_factory=list)
|
|
134
|
+
organismes_fils: list[Any] = field(default_factory=list)
|
|
135
|
+
|
|
136
|
+
@dataclass
|
|
137
|
+
class OffrespratiquesitemModel:
|
|
138
|
+
|
|
139
|
+
@dataclass
|
|
140
|
+
class Ffbbserver_Offres_Pratiques_IdModel:
|
|
141
|
+
id: str
|
|
142
|
+
title: str
|
|
143
|
+
categoriePratique: str
|
|
144
|
+
typePratique: str
|
|
145
|
+
|
|
146
|
+
ffbbserver_offres_pratiques_id: Ffbbserver_Offres_Pratiques_IdModel | None = (
|
|
147
|
+
None
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
offresPratiques: list[OffrespratiquesitemModel] = field(default_factory=list)
|
|
151
|
+
|
|
152
|
+
@dataclass
|
|
153
|
+
class LabellisationitemModel:
|
|
154
|
+
id: str
|
|
155
|
+
debut: datetime
|
|
156
|
+
fin: datetime
|
|
157
|
+
|
|
158
|
+
@dataclass
|
|
159
|
+
class IdlabellisationprogrammeModel:
|
|
160
|
+
id: str
|
|
161
|
+
libelle: str
|
|
162
|
+
labellisationLabel: str
|
|
163
|
+
logo_vertical: Any | None = None
|
|
164
|
+
|
|
165
|
+
idLabellisationProgramme: IdlabellisationprogrammeModel | None = None
|
|
166
|
+
|
|
167
|
+
labellisation: list[LabellisationitemModel] = field(default_factory=list)
|
|
168
|
+
|
|
169
|
+
@dataclass
|
|
170
|
+
class SalleModel:
|
|
171
|
+
id: str
|
|
172
|
+
numero: str
|
|
173
|
+
libelle: str
|
|
174
|
+
libelle2: str
|
|
175
|
+
adresse: str
|
|
176
|
+
adresseComplement: str
|
|
177
|
+
|
|
178
|
+
@dataclass
|
|
179
|
+
class CommuneModel:
|
|
180
|
+
codePostal: str
|
|
181
|
+
libelle: str
|
|
182
|
+
|
|
183
|
+
commune: CommuneModel | None = None
|
|
184
|
+
|
|
185
|
+
@dataclass
|
|
186
|
+
class CartographieModel:
|
|
187
|
+
latitude: float
|
|
188
|
+
longitude: float
|
|
189
|
+
|
|
190
|
+
cartographie: CartographieModel | None = None
|
|
191
|
+
|
|
192
|
+
salle: SalleModel | None = None
|
|
193
|
+
|
|
194
|
+
@dataclass
|
|
195
|
+
class LogoModel:
|
|
196
|
+
id: str
|
|
197
|
+
gradient_color: str
|
|
198
|
+
|
|
199
|
+
logo: LogoModel | None = None
|
|
200
|
+
|
|
201
|
+
@classmethod
|
|
202
|
+
def from_dict(cls, data: dict[str, Any]) -> GetOrganismeResponse | None:
|
|
203
|
+
"""Convert dictionary to OrganismesModel instance."""
|
|
204
|
+
if not data:
|
|
205
|
+
return None
|
|
206
|
+
|
|
207
|
+
# Handle case where data is not a dictionary
|
|
208
|
+
if not isinstance(data, dict):
|
|
209
|
+
return None
|
|
210
|
+
|
|
211
|
+
# Handle API error responses
|
|
212
|
+
if "errors" in data:
|
|
213
|
+
return None
|
|
214
|
+
|
|
215
|
+
# Extract nested commune data
|
|
216
|
+
commune_data = data.get("commune", {})
|
|
217
|
+
commune = (
|
|
218
|
+
cls.CommuneModel(
|
|
219
|
+
codePostal=commune_data.get("codePostal", ""),
|
|
220
|
+
libelle=commune_data.get("libelle", ""),
|
|
221
|
+
)
|
|
222
|
+
if commune_data
|
|
223
|
+
else None
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# Extract nested cartographie data
|
|
227
|
+
cartographie_data = data.get("cartographie", {})
|
|
228
|
+
cartographie = (
|
|
229
|
+
cls.CartographieModel(
|
|
230
|
+
latitude=float(cartographie_data.get("latitude", 0.0)),
|
|
231
|
+
longitude=float(cartographie_data.get("longitude", 0.0)),
|
|
232
|
+
)
|
|
233
|
+
if cartographie_data
|
|
234
|
+
else None
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# Extract membres data
|
|
238
|
+
membres = []
|
|
239
|
+
for membre_data in data.get("membres", []):
|
|
240
|
+
if membre_data:
|
|
241
|
+
membre = cls.MembresitemModel(
|
|
242
|
+
id=str(membre_data.get("id", "")),
|
|
243
|
+
nom=str(membre_data.get("nom", "")),
|
|
244
|
+
prenom=str(membre_data.get("prenom", "")),
|
|
245
|
+
adresse1=str(membre_data.get("adresse1", "")),
|
|
246
|
+
adresse2=membre_data.get("adresse2"),
|
|
247
|
+
codePostal=str(membre_data.get("codePostal", "")),
|
|
248
|
+
ville=str(membre_data.get("ville", "")),
|
|
249
|
+
mail=str(membre_data.get("mail", "")),
|
|
250
|
+
telephoneFixe=membre_data.get("telephoneFixe"),
|
|
251
|
+
telephonePortable=str(membre_data.get("telephonePortable", "")),
|
|
252
|
+
codeFonction=str(membre_data.get("codeFonction", "")),
|
|
253
|
+
)
|
|
254
|
+
membres.append(membre)
|
|
255
|
+
|
|
256
|
+
# Extract engagements data
|
|
257
|
+
engagements = []
|
|
258
|
+
for engagement_data in data.get("engagements", []):
|
|
259
|
+
if engagement_data:
|
|
260
|
+
# Extract idPoule
|
|
261
|
+
poule_data = engagement_data.get("idPoule", {})
|
|
262
|
+
id_poule = (
|
|
263
|
+
cls.EngagementsitemModel.IdpouleModel(
|
|
264
|
+
id=str(poule_data.get("id", ""))
|
|
265
|
+
)
|
|
266
|
+
if poule_data
|
|
267
|
+
else None
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
# Extract idCompetition
|
|
271
|
+
competition_data = engagement_data.get("idCompetition", {})
|
|
272
|
+
id_competition = None
|
|
273
|
+
if competition_data:
|
|
274
|
+
saison_data = competition_data.get("saison", {})
|
|
275
|
+
saison = (
|
|
276
|
+
cls.EngagementsitemModel.IdcompetitionModel.SaisonModel(
|
|
277
|
+
id=str(saison_data.get("id", ""))
|
|
278
|
+
)
|
|
279
|
+
if saison_data
|
|
280
|
+
else None
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
organisateur_data = competition_data.get("organisateur", {})
|
|
284
|
+
organisateur = (
|
|
285
|
+
cls.EngagementsitemModel.IdcompetitionModel.OrganisateurModel(
|
|
286
|
+
type=str(organisateur_data.get("type", ""))
|
|
287
|
+
)
|
|
288
|
+
if organisateur_data
|
|
289
|
+
else None
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
type_comp_generique_data = competition_data.get(
|
|
293
|
+
"typeCompetitionGenerique", {}
|
|
294
|
+
)
|
|
295
|
+
type_comp_generique = None
|
|
296
|
+
if type_comp_generique_data:
|
|
297
|
+
logo_data = type_comp_generique_data.get("logo", {})
|
|
298
|
+
# Use shorter aliases to avoid line length issues
|
|
299
|
+
IdComp = cls.EngagementsitemModel.IdcompetitionModel
|
|
300
|
+
LogoClass = IdComp.TypecompetitiongeneriqueModel.LogoModel
|
|
301
|
+
logo_tcg = (
|
|
302
|
+
LogoClass(
|
|
303
|
+
id=str(logo_data.get("id", "")),
|
|
304
|
+
gradient_color=str(logo_data.get("gradient_color", "")),
|
|
305
|
+
)
|
|
306
|
+
if logo_data
|
|
307
|
+
else None
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
TypeCompGenClass = IdComp.TypecompetitiongeneriqueModel
|
|
311
|
+
type_comp_generique = TypeCompGenClass(logo=logo_tcg)
|
|
312
|
+
|
|
313
|
+
categorie_data = competition_data.get("categorie", {})
|
|
314
|
+
categorie = (
|
|
315
|
+
cls.EngagementsitemModel.IdcompetitionModel.CategorieModel(
|
|
316
|
+
code=str(categorie_data.get("code", "")),
|
|
317
|
+
ordre=int(categorie_data.get("ordre", 0)),
|
|
318
|
+
)
|
|
319
|
+
if categorie_data
|
|
320
|
+
else None
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
id_competition = cls.EngagementsitemModel.IdcompetitionModel(
|
|
324
|
+
id=str(competition_data.get("id", "")),
|
|
325
|
+
nom=str(competition_data.get("nom", "")),
|
|
326
|
+
code=str(competition_data.get("code", "")),
|
|
327
|
+
sexe=str(competition_data.get("sexe", "")),
|
|
328
|
+
competition_origine=str(
|
|
329
|
+
competition_data.get("competition_origine", "")
|
|
330
|
+
),
|
|
331
|
+
competition_origine_nom=str(
|
|
332
|
+
competition_data.get("competition_origine_nom", "")
|
|
333
|
+
),
|
|
334
|
+
competition_origine_niveau=int(
|
|
335
|
+
competition_data.get("competition_origine_niveau", 0)
|
|
336
|
+
),
|
|
337
|
+
typeCompetition=str(
|
|
338
|
+
competition_data.get("typeCompetition", "")
|
|
339
|
+
),
|
|
340
|
+
logo=competition_data.get("logo"),
|
|
341
|
+
saison=saison,
|
|
342
|
+
idCompetitionPere=competition_data.get("idCompetitionPere"),
|
|
343
|
+
organisateur=organisateur,
|
|
344
|
+
typeCompetitionGenerique=type_comp_generique,
|
|
345
|
+
categorie=categorie,
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
engagement = cls.EngagementsitemModel(
|
|
349
|
+
id=str(engagement_data.get("id", "")),
|
|
350
|
+
numeroEquipe=engagement_data.get("numeroEquipe"),
|
|
351
|
+
idPoule=id_poule,
|
|
352
|
+
idCompetition=id_competition,
|
|
353
|
+
)
|
|
354
|
+
engagements.append(engagement)
|
|
355
|
+
|
|
356
|
+
# Extract offres pratiques
|
|
357
|
+
offres_pratiques = []
|
|
358
|
+
for offre_data in data.get("offresPratiques", []):
|
|
359
|
+
if offre_data:
|
|
360
|
+
ffbb_pratique_data = offre_data.get(
|
|
361
|
+
"ffbbserver_offres_pratiques_id", {}
|
|
362
|
+
)
|
|
363
|
+
ffbb_pratique = (
|
|
364
|
+
cls.OffrespratiquesitemModel.Ffbbserver_Offres_Pratiques_IdModel(
|
|
365
|
+
id=str(ffbb_pratique_data.get("id", "")),
|
|
366
|
+
title=str(ffbb_pratique_data.get("title", "")),
|
|
367
|
+
categoriePratique=str(
|
|
368
|
+
ffbb_pratique_data.get("categoriePratique", "")
|
|
369
|
+
),
|
|
370
|
+
typePratique=str(ffbb_pratique_data.get("typePratique", "")),
|
|
371
|
+
)
|
|
372
|
+
if ffbb_pratique_data
|
|
373
|
+
else None
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
offre = cls.OffrespratiquesitemModel(
|
|
377
|
+
ffbbserver_offres_pratiques_id=ffbb_pratique
|
|
378
|
+
)
|
|
379
|
+
offres_pratiques.append(offre)
|
|
380
|
+
|
|
381
|
+
# Extract labellisation
|
|
382
|
+
labellisations = []
|
|
383
|
+
for label_data in data.get("labellisation", []):
|
|
384
|
+
if label_data:
|
|
385
|
+
programme_data = label_data.get("idLabellisationProgramme", {})
|
|
386
|
+
programme = (
|
|
387
|
+
cls.LabellisationitemModel.IdlabellisationprogrammeModel(
|
|
388
|
+
id=str(programme_data.get("id", "")),
|
|
389
|
+
libelle=str(programme_data.get("libelle", "")),
|
|
390
|
+
labellisationLabel=str(
|
|
391
|
+
programme_data.get("labellisationLabel", "")
|
|
392
|
+
),
|
|
393
|
+
logo_vertical=programme_data.get("logo_vertical"),
|
|
394
|
+
)
|
|
395
|
+
if programme_data
|
|
396
|
+
else None
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
label = cls.LabellisationitemModel(
|
|
400
|
+
id=str(label_data.get("id", "")),
|
|
401
|
+
debut=datetime.fromisoformat(label_data.get("debut", "1970-01-01")),
|
|
402
|
+
fin=datetime.fromisoformat(label_data.get("fin", "1970-01-01")),
|
|
403
|
+
idLabellisationProgramme=programme,
|
|
404
|
+
)
|
|
405
|
+
labellisations.append(label)
|
|
406
|
+
|
|
407
|
+
# Extract salle
|
|
408
|
+
salle_data = data.get("salle", {})
|
|
409
|
+
salle = None
|
|
410
|
+
if salle_data:
|
|
411
|
+
salle_commune_data = salle_data.get("commune", {})
|
|
412
|
+
salle_commune = (
|
|
413
|
+
cls.SalleModel.CommuneModel(
|
|
414
|
+
codePostal=str(salle_commune_data.get("codePostal", "")),
|
|
415
|
+
libelle=str(salle_commune_data.get("libelle", "")),
|
|
416
|
+
)
|
|
417
|
+
if salle_commune_data
|
|
418
|
+
else None
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
salle_cartographie_data = salle_data.get("cartographie", {})
|
|
422
|
+
salle_cartographie = (
|
|
423
|
+
cls.SalleModel.CartographieModel(
|
|
424
|
+
latitude=float(salle_cartographie_data.get("latitude", 0.0)),
|
|
425
|
+
longitude=float(salle_cartographie_data.get("longitude", 0.0)),
|
|
426
|
+
)
|
|
427
|
+
if salle_cartographie_data
|
|
428
|
+
else None
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
salle = cls.SalleModel(
|
|
432
|
+
id=str(salle_data.get("id", "")),
|
|
433
|
+
numero=str(salle_data.get("numero", "")),
|
|
434
|
+
libelle=str(salle_data.get("libelle", "")),
|
|
435
|
+
libelle2=str(salle_data.get("libelle2", "")),
|
|
436
|
+
adresse=str(salle_data.get("adresse", "")),
|
|
437
|
+
adresseComplement=str(salle_data.get("adresseComplement", "")),
|
|
438
|
+
commune=salle_commune,
|
|
439
|
+
cartographie=salle_cartographie,
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
# Extract logo
|
|
443
|
+
logo_data = data.get("logo", {})
|
|
444
|
+
logo = (
|
|
445
|
+
cls.LogoModel(
|
|
446
|
+
id=str(logo_data.get("id", "")),
|
|
447
|
+
gradient_color=str(logo_data.get("gradient_color", "")),
|
|
448
|
+
)
|
|
449
|
+
if logo_data
|
|
450
|
+
else None
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
return cls(
|
|
454
|
+
id=str(data.get("id", "")),
|
|
455
|
+
nom=str(data.get("nom", "")),
|
|
456
|
+
code=str(data.get("code", "")),
|
|
457
|
+
telephone=str(data.get("telephone", "")),
|
|
458
|
+
adresse=str(data.get("adresse", "")),
|
|
459
|
+
mail=str(data.get("mail", "")),
|
|
460
|
+
type=str(data.get("type", "")),
|
|
461
|
+
nom_simple=data.get("nom_simple"),
|
|
462
|
+
urlSiteWeb=str(data.get("urlSiteWeb", "")),
|
|
463
|
+
nomClubPro=str(data.get("nomClubPro", "")),
|
|
464
|
+
adresseClubPro=data.get("adresseClubPro"),
|
|
465
|
+
commune=commune,
|
|
466
|
+
cartographie=cartographie,
|
|
467
|
+
communeClubPro=data.get("communeClubPro"),
|
|
468
|
+
membres=membres,
|
|
469
|
+
competitions=data.get("competitions", []),
|
|
470
|
+
engagements=engagements,
|
|
471
|
+
organismes_fils=data.get("organismes_fils", []),
|
|
472
|
+
offresPratiques=offres_pratiques,
|
|
473
|
+
labellisation=labellisations,
|
|
474
|
+
salle=salle,
|
|
475
|
+
logo=logo,
|
|
476
|
+
)
|
|
@@ -0,0 +1,68 @@
|
|
|
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 .poule_rencontre_item_model import PouleRencontreItemModel
|
|
8
|
+
from .team_ranking import TeamRanking
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class GetPouleResponse:
|
|
13
|
+
id: str
|
|
14
|
+
|
|
15
|
+
# Keep nested alias for backward compatibility
|
|
16
|
+
RencontresitemModel = PouleRencontreItemModel
|
|
17
|
+
|
|
18
|
+
rencontres: list[PouleRencontreItemModel] = field(default_factory=list)
|
|
19
|
+
classements: list[TeamRanking] | None = None
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def from_dict(cls, data: dict[str, Any]) -> GetPouleResponse | None:
|
|
23
|
+
"""Convert dictionary to PoulesModel instance."""
|
|
24
|
+
if not data:
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
# Handle case where data is not a dictionary
|
|
28
|
+
if not isinstance(data, dict):
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
# Handle API error responses
|
|
32
|
+
if "errors" in data:
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
# Basic implementation - can be expanded later
|
|
36
|
+
rencontres = []
|
|
37
|
+
for rencontre_data in data.get("rencontres", []):
|
|
38
|
+
if rencontre_data:
|
|
39
|
+
rencontre = PouleRencontreItemModel(
|
|
40
|
+
id=str(rencontre_data.get("id", "")),
|
|
41
|
+
numero=str(rencontre_data.get("numero", "")),
|
|
42
|
+
numeroJournee=str(rencontre_data.get("numeroJournee", "")),
|
|
43
|
+
idPoule=str(rencontre_data.get("idPoule", "")),
|
|
44
|
+
competitionId=str(rencontre_data.get("competitionId", "")),
|
|
45
|
+
resultatEquipe1=str(rencontre_data.get("resultatEquipe1", "")),
|
|
46
|
+
resultatEquipe2=str(rencontre_data.get("resultatEquipe2", "")),
|
|
47
|
+
joue=int(rencontre_data.get("joue", 0)),
|
|
48
|
+
nomEquipe1=str(rencontre_data.get("nomEquipe1", "")),
|
|
49
|
+
nomEquipe2=str(rencontre_data.get("nomEquipe2", "")),
|
|
50
|
+
date_rencontre=datetime.fromisoformat(
|
|
51
|
+
rencontre_data.get("date_rencontre", "1970-01-01")
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
rencontres.append(rencontre)
|
|
55
|
+
|
|
56
|
+
# Process classements
|
|
57
|
+
classements = []
|
|
58
|
+
for classement_data in data.get("classements", []):
|
|
59
|
+
if classement_data:
|
|
60
|
+
classement = TeamRanking.from_dict(classement_data)
|
|
61
|
+
if classement:
|
|
62
|
+
classements.append(classement)
|
|
63
|
+
|
|
64
|
+
return cls(
|
|
65
|
+
id=str(data.get("id", "")),
|
|
66
|
+
rencontres=rencontres,
|
|
67
|
+
classements=classements if classements else None,
|
|
68
|
+
)
|