109 lines
No EOL
4.2 KiB
Python
109 lines
No EOL
4.2 KiB
Python
# backend/schemas/france_travail.py
|
|
from datetime import datetime
|
|
from typing import List, Optional, Dict, Any, Union
|
|
from pydantic import BaseModel, Field, field_validator, computed_field
|
|
|
|
# Modèles de données pour les structures communes (Lieu, Entreprise, etc.)
|
|
class LieuTravail(BaseModel):
|
|
libelle: Optional[str] = Field(None, example="Paris")
|
|
codePostal: Optional[str] = Field(None, example="75001")
|
|
commune: Optional[str] = Field(None, example="Paris")
|
|
|
|
class TypeContrat(BaseModel):
|
|
code: Optional[str] = Field(None, example="CDI")
|
|
libelle: Optional[str] = Field(None, example="Contrat à durée indéterminée")
|
|
|
|
class Appellation(BaseModel):
|
|
code: Optional[str] = Field(None, example="10034")
|
|
libelle: Optional[str] = Field(None, example="Développeur informatique")
|
|
|
|
class OrigineOffre(BaseModel):
|
|
url: Optional[str] = Field(None, example="https://candidat.francetravail.fr/candidature/offre/1234567")
|
|
typeOrigine: Optional[str] = Field(None, example="ONLINE")
|
|
|
|
class Entreprise(BaseModel):
|
|
nom: Optional[str] = Field(None, example="Ma Super Entreprise")
|
|
description: Optional[str] = None
|
|
url: Optional[str] = None
|
|
id: Optional[str] = None
|
|
|
|
class Salaire(BaseModel):
|
|
libelle: Optional[str] = Field(None, example="2500 EUR brut/mois")
|
|
commentaire: Optional[str] = None
|
|
typeForfait: Optional[str] = None
|
|
periode: Optional[str] = None
|
|
min: Optional[float] = None
|
|
max: Optional[float] = None
|
|
|
|
class Competence(BaseModel):
|
|
code: Optional[str] = None
|
|
libelle: Optional[str] = None
|
|
description: Optional[str] = None
|
|
exigence: Optional[str] = None
|
|
|
|
class Experience(BaseModel):
|
|
libelle: Optional[str] = Field(None, example="Débutant accepté")
|
|
code: Optional[str] = None
|
|
|
|
class Formation(BaseModel):
|
|
domaineLibelle: Optional[str] = None
|
|
niveaulibelle: Optional[str] = None
|
|
codeFormation: Optional[str] = None
|
|
|
|
class Permis(BaseModel):
|
|
libelle: Optional[str] = None
|
|
code: Optional[str] = None
|
|
|
|
# Modèle pour une offre individuelle
|
|
class Offre(BaseModel):
|
|
id: str = Field(..., example="1234567")
|
|
intitule: str = Field(..., example="Développeur Full Stack")
|
|
description: Optional[str] = None
|
|
dateActualisation: Optional[datetime] = Field(None, example="2024-01-15T10:00:00.000Z")
|
|
dateActualisation: datetime
|
|
lieuTravail: Optional[LieuTravail] = None
|
|
typeContrat: Optional[Union[TypeContrat, str]] = None
|
|
romeCode: Optional[str] = None
|
|
romeLibelle: Optional[str] = None
|
|
appellationLibelle: Optional[str] = None
|
|
entreprise: Optional[Entreprise] = None
|
|
origineOffre: Optional[OrigineOffre] = None
|
|
nbPostes: Optional[int] = None
|
|
nbResultats: Optional[int] = None
|
|
|
|
@field_validator('typeContrat', mode='before')
|
|
@classmethod
|
|
def validate_type_contrat(cls, v: Any) -> Any:
|
|
if isinstance(v, str):
|
|
return TypeContrat(code=v, libelle=None)
|
|
return v
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
@computed_field
|
|
def url_francetravail(self) -> str:
|
|
"""Génère l'URL de l'offre sur le site candidat.francetravail.fr."""
|
|
return f"https://candidat.francetravail.fr/offres/recherche/detail/{self.id}"
|
|
|
|
# Modèle pour les détails complets d'une offre
|
|
class OffreDetail(Offre):
|
|
# OffreDetail hérite de Offre, donc il aura automatiquement la propriété url_francetravail
|
|
description: str = Field(..., example="Description détaillée du poste...")
|
|
complementExercice: Optional[str] = None
|
|
urlDossierCandidature: Optional[str] = None # Ce champ vient directement de l'API s'il est fourni
|
|
qualification: Optional[str] = None
|
|
appellations: Optional[List[Appellation]] = None
|
|
competences: Optional[List[Competence]] = None
|
|
entreprise: Optional[Entreprise] = None
|
|
formations: Optional[List[Formation]] = None
|
|
langues: Optional[List[Dict[str, Any]]] = None
|
|
permis: Optional[List[Permis]] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class FranceTravailSearchResponse(BaseModel):
|
|
resultats: List[Offre] = Field(default_factory=list)
|
|
totalResults: Optional[int] = Field(None, description="Nombre total d'offres correspondant aux critères")
|
|
range: Optional[str] = Field(None, description="Plage des résultats actuels, ex: '0-14/100'") |