QuentinL52 commited on
Commit
f9e10a2
·
verified ·
1 Parent(s): 1ebeab4

Update src/cv_parsing_agents.py

Browse files
Files changed (1) hide show
  1. src/cv_parsing_agents.py +1 -168
src/cv_parsing_agents.py CHANGED
@@ -50,59 +50,30 @@ class CvParserAgent:
50
  Cette classe traite un fichier PDF de CV et en extrait les informations
51
  structurées (compétences, expériences, formations, etc.)
52
  """
53
-
54
  def __init__(self, pdf_path: str):
55
- """
56
- Initialise l'agent de parsing de CV.
57
-
58
- Args:
59
- pdf_path (str): Chemin vers le fichier PDF à traiter
60
-
61
- Raises:
62
- ValueError: Si le chemin du fichier est invalide
63
- ImportError: Si les dépendances nécessaires ne sont pas disponibles
64
- """
65
  if not pdf_path or not isinstance(pdf_path, str):
66
  raise ValueError("Le chemin du fichier PDF doit être une chaîne non vide")
67
-
68
  self.pdf_path = pdf_path
69
-
70
- # Vérifier que les dépendances sont disponibles
71
  if not CREW_POOL_AVAILABLE:
72
  logger.warning("CrewAI crew_pool non disponible - mode dégradé")
73
  if not CONFIG_AVAILABLE:
74
  logger.warning("Module config non disponible - mode dégradé")
75
 
76
  def process(self) -> dict:
77
- """
78
- Traite le fichier PDF pour en extraire le contenu sous forme de JSON.
79
-
80
- Returns:
81
- dict: Dictionnaire contenant les données extraites du CV,
82
- ou données de fallback en cas d'erreur
83
- """
84
  logger.info(f"Début du traitement du CV : {self.pdf_path}")
85
-
86
- # Vérifier que le fichier existe
87
  if not os.path.exists(self.pdf_path):
88
  logger.error(f"Fichier PDF non trouvé: {self.pdf_path}")
89
  return self._create_fallback_data()
90
-
91
- # Vérifier les dépendances
92
  if not CREW_POOL_AVAILABLE or not CONFIG_AVAILABLE:
93
  logger.error("Dépendances manquantes pour le traitement complet")
94
  return self._create_fallback_data()
95
 
96
  try:
97
- # Charger le contenu du PDF
98
  cv_text_content = load_pdf(self.pdf_path)
99
  if not cv_text_content or not cv_text_content.strip():
100
  logger.error("Le PDF semble vide ou illisible")
101
  return self._create_fallback_data()
102
-
103
  logger.info(f"PDF chargé, {len(cv_text_content)} caractères extraits")
104
-
105
- # Analyser avec CrewAI
106
  crew_output = analyse_cv(cv_text_content)
107
 
108
  if not crew_output or not hasattr(crew_output, 'raw') or not crew_output.raw.strip():
@@ -132,26 +103,13 @@ class CvParserAgent:
132
  return self._create_fallback_data()
133
 
134
  def _clean_json_string(self, raw_string: str) -> str:
135
- """
136
- Nettoie une chaîne JSON brute en supprimant les blocs de code markdown.
137
-
138
- Args:
139
- raw_string (str): Chaîne brute à nettoyer
140
-
141
- Returns:
142
- str: Chaîne JSON nettoyée
143
- """
144
  json_string_cleaned = raw_string.strip()
145
-
146
- # Supprimer les blocs de code markdown si présents
147
  if '```' in raw_string:
148
  try:
149
- # Chercher le bloc json
150
  if '```json' in raw_string:
151
  json_part = raw_string.split('```json')[1].split('```')[0]
152
  json_string_cleaned = json_part.strip()
153
  else:
154
- # Prendre le premier bloc de code
155
  parts = raw_string.split('```')
156
  if len(parts) >= 3:
157
  json_string_cleaned = parts[1].strip()
@@ -160,132 +118,7 @@ class CvParserAgent:
160
 
161
  return json_string_cleaned
162
 
163
- def _create_fallback_data(self) -> dict:
164
- """
165
- Crée des données de CV de fallback en cas d'erreur de traitement.
166
-
167
- Returns:
168
- dict: Structure de données de CV par défaut
169
- """
170
- logger.info("Création de données de fallback pour le CV")
171
- return {
172
- "candidat": {
173
- "informations_personnelles": {
174
- "nom": "Candidat Test",
175
- "email": "test@example.com",
176
- "numero_de_telephone": "Non spécifié",
177
- "localisation": "Non spécifiée"
178
- },
179
- "compétences": {
180
- "hard_skills": ["Python", "FastAPI", "Data Analysis"],
181
- "soft_skills": ["Communication", "Travail d'équipe", "Adaptabilité"]
182
- },
183
- "expériences": [
184
- {
185
- "Poste": "Développeur",
186
- "Entreprise": "Entreprise Test",
187
- "start_date": "2022",
188
- "end_date": "Aujourd'hui",
189
- "responsabilités": ["Développement d'applications", "Maintenance du code"]
190
- }
191
- ],
192
- "projets": {
193
- "professional": [
194
- {
195
- "title": "Projet Test",
196
- "role": "Développeur principal",
197
- "technologies": ["Python", "FastAPI"],
198
- "outcomes": ["Application fonctionnelle"]
199
- }
200
- ],
201
- "personal": []
202
- },
203
- "formations": [
204
- {
205
- "degree": "Formation en Informatique",
206
- "institution": "École Test",
207
- "start_date": "2020",
208
- "end_date": "2022"
209
- }
210
- ],
211
- "reconversion": {
212
- "is_reconversion": False,
213
- "analysis": "Pas de reconversion détectée - données de test"
214
- }
215
- }
216
- }
217
-
218
- # Fonction utilitaire pour créer des données de fallback
219
- def create_fallback_cv_data(pdf_path: str = None) -> dict:
220
- """
221
- Fonction utilitaire pour créer des données de CV de fallback.
222
-
223
- Args:
224
- pdf_path (str, optional): Chemin du fichier PDF (non utilisé dans le fallback)
225
-
226
- Returns:
227
- dict: Structure de données de CV par défaut
228
- """
229
- return {
230
- "candidat": {
231
- "informations_personnelles": {
232
- "nom": "Candidat Test",
233
- "email": "test@example.com",
234
- "numero_de_telephone": "Non spécifié",
235
- "localisation": "Non spécifiée"
236
- },
237
- "compétences": {
238
- "hard_skills": ["Python", "FastAPI", "Data Analysis"],
239
- "soft_skills": ["Communication", "Travail d'équipe", "Adaptabilité"]
240
- },
241
- "expériences": [
242
- {
243
- "Poste": "Développeur",
244
- "Entreprise": "Entreprise Test",
245
- "start_date": "2022",
246
- "end_date": "Aujourd'hui",
247
- "responsabilités": ["Développement d'applications", "Maintenance du code"]
248
- }
249
- ],
250
- "projets": {
251
- "professional": [
252
- {
253
- "title": "Projet Test",
254
- "role": "Développeur principal",
255
- "technologies": ["Python", "FastAPI"],
256
- "outcomes": ["Application fonctionnelle"]
257
- }
258
- ],
259
- "personal": []
260
- },
261
- "formations": [
262
- {
263
- "degree": "Formation en Informatique",
264
- "institution": "École Test",
265
- "start_date": "2020",
266
- "end_date": "2022"
267
- }
268
- ],
269
- "reconversion": {
270
- "is_reconversion": False,
271
- "analysis": "Pas de reconversion détectée - données de test"
272
- }
273
- }
274
- }
275
-
276
- # Test des imports au chargement du module
277
  if __name__ == "__main__":
278
  logger.info("Test du module cv_parsing_agents")
279
  logger.info(f"CREW_POOL_AVAILABLE: {CREW_POOL_AVAILABLE}")
280
- logger.info(f"CONFIG_AVAILABLE: {CONFIG_AVAILABLE}")
281
-
282
- # Test de création d'une instance
283
- try:
284
- agent = CvParserAgent("/tmp/test.pdf")
285
- logger.info("✅ CvParserAgent créé avec succès")
286
- except Exception as e:
287
- logger.error(f"❌ Erreur création CvParserAgent: {e}")
288
-
289
- # Test des données de fallback
290
- fallback_data = create_fallback_cv_data()
291
- logger.info(f"✅ Données de fallback créées: {len(fallback_data)} clés")
 
50
  Cette classe traite un fichier PDF de CV et en extrait les informations
51
  structurées (compétences, expériences, formations, etc.)
52
  """
 
53
  def __init__(self, pdf_path: str):
 
 
 
 
 
 
 
 
 
 
54
  if not pdf_path or not isinstance(pdf_path, str):
55
  raise ValueError("Le chemin du fichier PDF doit être une chaîne non vide")
 
56
  self.pdf_path = pdf_path
 
 
57
  if not CREW_POOL_AVAILABLE:
58
  logger.warning("CrewAI crew_pool non disponible - mode dégradé")
59
  if not CONFIG_AVAILABLE:
60
  logger.warning("Module config non disponible - mode dégradé")
61
 
62
  def process(self) -> dict:
 
 
 
 
 
 
 
63
  logger.info(f"Début du traitement du CV : {self.pdf_path}")
 
 
64
  if not os.path.exists(self.pdf_path):
65
  logger.error(f"Fichier PDF non trouvé: {self.pdf_path}")
66
  return self._create_fallback_data()
 
 
67
  if not CREW_POOL_AVAILABLE or not CONFIG_AVAILABLE:
68
  logger.error("Dépendances manquantes pour le traitement complet")
69
  return self._create_fallback_data()
70
 
71
  try:
 
72
  cv_text_content = load_pdf(self.pdf_path)
73
  if not cv_text_content or not cv_text_content.strip():
74
  logger.error("Le PDF semble vide ou illisible")
75
  return self._create_fallback_data()
 
76
  logger.info(f"PDF chargé, {len(cv_text_content)} caractères extraits")
 
 
77
  crew_output = analyse_cv(cv_text_content)
78
 
79
  if not crew_output or not hasattr(crew_output, 'raw') or not crew_output.raw.strip():
 
103
  return self._create_fallback_data()
104
 
105
  def _clean_json_string(self, raw_string: str) -> str:
 
 
 
 
 
 
 
 
 
106
  json_string_cleaned = raw_string.strip()
 
 
107
  if '```' in raw_string:
108
  try:
 
109
  if '```json' in raw_string:
110
  json_part = raw_string.split('```json')[1].split('```')[0]
111
  json_string_cleaned = json_part.strip()
112
  else:
 
113
  parts = raw_string.split('```')
114
  if len(parts) >= 3:
115
  json_string_cleaned = parts[1].strip()
 
118
 
119
  return json_string_cleaned
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  if __name__ == "__main__":
122
  logger.info("Test du module cv_parsing_agents")
123
  logger.info(f"CREW_POOL_AVAILABLE: {CREW_POOL_AVAILABLE}")
124
+ logger.info(f"CONFIG_AVAILABLE: {CONFIG_AVAILABLE}")