backend
This commit is contained in:
commit
d7666f7b2c
44 changed files with 2246 additions and 0 deletions
97
backend/routers/france_travail_offers.py
Normal file
97
backend/routers/france_travail_offers.py
Normal file
|
@ -0,0 +1,97 @@
|
|||
# backend/routers/france_travail_offers.py
|
||||
from typing import List, Optional
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
||||
|
||||
from services.france_travail_offer_service import france_travail_offer_service
|
||||
from core.security import get_current_user
|
||||
from models.user import User
|
||||
from schemas.france_travail import FranceTravailSearchResponse, OffreDetail, Offre
|
||||
|
||||
import logging
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@router.get("/search", response_model=FranceTravailSearchResponse)
|
||||
async def search_france_travail_offers(
|
||||
motsCles: Optional[str] = Query(None, description="Mots-clés de recherche (ex: 'développeur full stack')"),
|
||||
commune_nom_ou_code: Optional[str] = Query(None, alias="commune", description="Nom, code postal ou code INSEE de la commune"),
|
||||
distance: Optional[int] = Query(10, description="Distance maximale en km autour de la commune"),
|
||||
page: int = Query(0, description="Numéro de la page de résultats (commence à 0)"),
|
||||
limit: int = Query(15, description="Nombre d'offres par page (max 100 pour l'API France Travail)"), # Max 100 est une limite courante pour une seule requête à l'API FT
|
||||
contrat: Optional[str] = Query(None, description="Type de contrat (ex: 'CDI', 'CDD', 'MIS')"),
|
||||
experience: Optional[str] = Query(None, description="Niveau d'expérience (ex: '1' pour débutant, '2' pour 1-3 ans, '3' pour >3 ans)"),
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""
|
||||
Recherche des offres d'emploi via l'API France Travail.
|
||||
Convertit le nom de ville en code INSEE si nécessaire et gère la pagination.
|
||||
Nécessite une authentification.
|
||||
"""
|
||||
if limit > 100: # La limite de l'API France Travail pour 'range' est souvent 150 ou 100 items par requête.
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="La limite de résultats par page ne peut pas dépasser 100 pour une seule requête API."
|
||||
)
|
||||
|
||||
commune_param_for_api = None
|
||||
|
||||
if commune_nom_ou_code:
|
||||
if commune_nom_ou_code.isdigit() and len(commune_nom_ou_code) == 5:
|
||||
commune_param_for_api = commune_nom_ou_code
|
||||
logger.info(f"Recherche par code postal: {commune_nom_ou_code}")
|
||||
else:
|
||||
logger.info(f"Tentative de récupération du code INSEE pour la ville: {commune_nom_ou_code}")
|
||||
insee_code = await france_travail_offer_service.get_insee_code_for_commune(commune_nom_ou_code)
|
||||
if not insee_code:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Code INSEE non trouvé pour la ville '{commune_nom_ou_code}'. Veuillez vérifier l'orthographe ou utiliser un code postal."
|
||||
)
|
||||
commune_param_for_api = insee_code
|
||||
logger.info(f"Code INSEE '{insee_code}' trouvé pour '{commune_nom_ou_code}'.")
|
||||
|
||||
if (commune_param_for_api is not None) and (distance is None):
|
||||
distance = 10
|
||||
|
||||
# Calcul du paramètre 'range' pour l'API France Travail
|
||||
start_index = page * limit
|
||||
end_index = start_index + limit - 1
|
||||
api_range_param = f"{start_index}-{end_index}"
|
||||
logger.info(f"Paramètre 'range' calculé pour l'API France Travail: {api_range_param}")
|
||||
|
||||
try:
|
||||
response = await france_travail_offer_service.search_offers(
|
||||
motsCles=motsCles,
|
||||
commune=commune_param_for_api,
|
||||
distance=distance,
|
||||
range=api_range_param, # On passe le 'range' calculé
|
||||
typeContrat=contrat,
|
||||
# experience=experience # Vérifiez si ce paramètre est géré par l'API France Travail ou doit être mappé
|
||||
)
|
||||
return response
|
||||
except RuntimeError as e:
|
||||
logger.error(f"Erreur lors de la recherche d'offres France Travail: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Impossible de récupérer les offres de France Travail: {e}"
|
||||
)
|
||||
|
||||
@router.get("/{offer_id}", response_model=OffreDetail)
|
||||
async def get_france_travail_offer_details(
|
||||
offer_id: str,
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""
|
||||
Récupère les détails d'une offre d'emploi spécifique de l'API France Travail par son ID.
|
||||
Nécessite une authentification.
|
||||
"""
|
||||
try:
|
||||
details = await france_travail_offer_service.get_offer_details(offer_id)
|
||||
return details
|
||||
except RuntimeError as e:
|
||||
logger.error(f"Erreur lors de la récupération des détails de l'offre {offer_id} de France Travail: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Impossible de récupérer les détails de l'offre: {e}"
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue