1qwsd commited on
Commit
c89ab4a
Β·
verified Β·
1 Parent(s): 3f396c3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -57
app.py CHANGED
@@ -15,7 +15,7 @@ logger.info("=" * 80)
15
  logger.info("πŸš€ Job Application Agent - Startup")
16
  logger.info("=" * 80)
17
 
18
- # Add src to Python path - FIXED PATH HANDLING
19
  current_dir = os.path.dirname(os.path.abspath(__file__))
20
  src_path = os.path.join(current_dir, 'src')
21
  if src_path not in sys.path:
@@ -28,7 +28,8 @@ logger.info(f"βœ“ Python path updated")
28
  # Import Gradio
29
  try:
30
  import gradio as gr
31
- logger.info("βœ“ Gradio imported successfully")
 
32
  except ImportError as e:
33
  logger.error(f"βœ— Failed to import Gradio: {e}")
34
  logger.error("Install with: pip install gradio")
@@ -43,10 +44,9 @@ except ImportError as e:
43
  logger.error("Install with: pip install torch")
44
  sys.exit(1)
45
 
46
- # Import application components - WITH ERROR HANDLING
47
  logger.info("\nπŸ“¦ Attempting to import application modules...")
48
 
49
- # Create fallback/mock classes if imports fail
50
  mayini_model = None
51
  vocab = None
52
  customizer = None
@@ -63,7 +63,6 @@ except ImportError as e:
63
  logger.warning(f" ⚠️ Could not import MAYINI: {e}")
64
  logger.warning(" Creating mock MAYINI classes...")
65
 
66
- # Create mock classes
67
  class MAYINIVocabulary:
68
  def __init__(self, vocab_size=5000):
69
  self.vocab_size = vocab_size
@@ -120,8 +119,6 @@ except ImportError as e:
120
  return self.jobs
121
  def search_jobs(self, keywords=None, location=None, limit=10):
122
  return self.jobs[:limit]
123
- def filter_by_experience(self, jobs, min_years=0, max_years=10):
124
- return [j for j in jobs if min_years <= j.get('experience_required', 0) <= max_years]
125
 
126
  logger.info(" βœ“ Mock Scraper class created")
127
 
@@ -201,7 +198,7 @@ except ImportError as e:
201
  logger.info(" βœ“ Mock Agent class created")
202
 
203
  logger.info("\n" + "=" * 80)
204
- logger.info("βœ… All components loaded (using mock classes if needed)")
205
  logger.info("=" * 80)
206
 
207
  # ============================================================================
@@ -213,55 +210,23 @@ logger.info("\nπŸ”§ Initializing components...")
213
  try:
214
  vocab = MAYINIVocabulary(vocab_size=5000)
215
  logger.info("βœ“ MAYINI Vocabulary initialized")
216
- except Exception as e:
217
- logger.error(f"Error initializing vocabulary: {e}")
218
- vocab = MAYINIVocabulary()
219
-
220
- try:
221
- mayini_model = MAYINIModel(
222
- vocab_size=5000,
223
- hidden_dim=256,
224
- num_heads=8,
225
- num_layers=4
226
- )
227
  mayini_model.eval()
228
  logger.info("βœ“ MAYINI Model initialized")
229
- except Exception as e:
230
- logger.error(f"Error initializing model: {e}")
231
- mayini_model = MAYINIModel()
232
-
233
- try:
234
  scraper = JobScraper()
235
  logger.info("βœ“ Job Scraper initialized")
236
- except Exception as e:
237
- logger.error(f"Error initializing scraper: {e}")
238
- scraper = JobScraper()
239
-
240
- try:
241
  customizer = ResumeCustomizer(mayini_model, vocab)
242
  logger.info("βœ“ Resume Customizer initialized")
243
- except Exception as e:
244
- logger.error(f"Error initializing customizer: {e}")
245
- customizer = ResumeCustomizer(mayini_model, vocab)
246
-
247
- try:
248
  classifier = JobRelevanceClassifier()
249
- if hasattr(classifier, 'mayini_model'):
250
- classifier.mayini_model = mayini_model
251
  logger.info("βœ“ Job Classifier initialized")
252
- except Exception as e:
253
- logger.error(f"Error initializing classifier: {e}")
254
- classifier = JobRelevanceClassifier()
255
-
256
- try:
257
  agent = JobApplicationAgent(scraper, customizer, classifier)
258
  logger.info("βœ“ Application Agent initialized")
259
  except Exception as e:
260
- logger.error(f"Error initializing agent: {e}")
261
- agent = JobApplicationAgent(scraper, customizer, classifier)
262
 
263
  logger.info("\n" + "=" * 80)
264
- logger.info("βœ… INITIALIZATION COMPLETE - Application ready to serve!")
265
  logger.info("=" * 80 + "\n")
266
 
267
  # ============================================================================
@@ -397,39 +362,82 @@ with gr.Blocks(title="Job Application Agent", theme=gr.themes.Soft()) as demo:
397
  gr.Markdown("Find jobs matching your skills using AI-powered matching.")
398
  with gr.Row():
399
  with gr.Column():
400
- search_keywords = gr.Textbox(label="Keywords", placeholder="python docker aws", value="python")
401
- search_location = gr.Textbox(label="Location", placeholder="Remote", value="Remote")
402
- search_num = gr.Slider(minimum=1, maximum=20, value=5, step=1, label="Number of Jobs")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  search_btn = gr.Button("πŸ” Search", variant="primary")
404
  with gr.Column():
405
  search_output = gr.Markdown(value="### Results will appear here...")
406
 
407
- search_btn.click(fn=search_jobs_interface, inputs=[search_keywords, search_location, search_num], outputs=search_output)
 
 
 
 
408
 
409
  with gr.Tab("πŸ“„ Customize Resume"):
410
  gr.Markdown("Tailor your resume for specific job opportunities.")
411
  with gr.Row():
412
  with gr.Column():
413
- customize_title = gr.Textbox(label="Job Title", placeholder="Senior Python Developer")
414
- customize_company = gr.Textbox(label="Company", placeholder="Tech Inc")
415
- customize_req = gr.Textbox(label="Requirements", placeholder="Python, Docker, AWS", lines=2)
 
 
 
 
 
 
 
 
 
 
416
  customize_btn = gr.Button("✨ Customize", variant="primary")
417
  with gr.Column():
418
  customize_output = gr.Markdown(value="### Customized resume will appear here...")
419
 
420
- customize_btn.click(fn=customize_resume_interface, inputs=[customize_title, customize_company, customize_req], outputs=customize_output)
 
 
 
 
421
 
422
  with gr.Tab("🎯 Classify Job"):
423
  gr.Markdown("Check job relevance to your skills.")
424
  with gr.Row():
425
  with gr.Column():
426
- classify_title = gr.Textbox(label="Job Title", placeholder="ML Engineer")
427
- classify_req = gr.Textbox(label="Requirements", placeholder="Python, PyTorch", lines=2)
 
 
 
 
 
 
 
428
  classify_btn = gr.Button("🎯 Classify", variant="primary")
429
  with gr.Column():
430
  classify_output = gr.Markdown(value="### Results will appear here...")
431
 
432
- classify_btn.click(fn=classify_job_interface, inputs=[classify_title, classify_req], outputs=classify_output)
 
 
 
 
433
 
434
  with gr.Tab("ℹ️ About"):
435
  gr.Markdown("""
@@ -455,7 +463,7 @@ with gr.Blocks(title="Job Application Agent", theme=gr.themes.Soft()) as demo:
455
  logger.info("βœ“ Gradio interface built successfully\n")
456
 
457
  # ============================================================================
458
- # LAUNCH
459
  # ============================================================================
460
 
461
  if __name__ == "__main__":
@@ -463,7 +471,9 @@ if __name__ == "__main__":
463
  logger.info("Access at: http://0.0.0.0:7860\n")
464
 
465
  try:
466
- demo.queue(max_size=32, concurrency_count=4).launch(
 
 
467
  server_name="0.0.0.0",
468
  server_port=7860,
469
  show_error=True,
 
15
  logger.info("πŸš€ Job Application Agent - Startup")
16
  logger.info("=" * 80)
17
 
18
+ # Add src to Python path
19
  current_dir = os.path.dirname(os.path.abspath(__file__))
20
  src_path = os.path.join(current_dir, 'src')
21
  if src_path not in sys.path:
 
28
  # Import Gradio
29
  try:
30
  import gradio as gr
31
+ gradio_version = gr.__version__
32
+ logger.info(f"βœ“ Gradio imported successfully (version: {gradio_version})")
33
  except ImportError as e:
34
  logger.error(f"βœ— Failed to import Gradio: {e}")
35
  logger.error("Install with: pip install gradio")
 
44
  logger.error("Install with: pip install torch")
45
  sys.exit(1)
46
 
47
+ # Import application components
48
  logger.info("\nπŸ“¦ Attempting to import application modules...")
49
 
 
50
  mayini_model = None
51
  vocab = None
52
  customizer = None
 
63
  logger.warning(f" ⚠️ Could not import MAYINI: {e}")
64
  logger.warning(" Creating mock MAYINI classes...")
65
 
 
66
  class MAYINIVocabulary:
67
  def __init__(self, vocab_size=5000):
68
  self.vocab_size = vocab_size
 
119
  return self.jobs
120
  def search_jobs(self, keywords=None, location=None, limit=10):
121
  return self.jobs[:limit]
 
 
122
 
123
  logger.info(" βœ“ Mock Scraper class created")
124
 
 
198
  logger.info(" βœ“ Mock Agent class created")
199
 
200
  logger.info("\n" + "=" * 80)
201
+ logger.info("βœ… All components loaded")
202
  logger.info("=" * 80)
203
 
204
  # ============================================================================
 
210
  try:
211
  vocab = MAYINIVocabulary(vocab_size=5000)
212
  logger.info("βœ“ MAYINI Vocabulary initialized")
213
+ mayini_model = MAYINIModel(vocab_size=5000, hidden_dim=256, num_heads=8, num_layers=4)
 
 
 
 
 
 
 
 
 
 
214
  mayini_model.eval()
215
  logger.info("βœ“ MAYINI Model initialized")
 
 
 
 
 
216
  scraper = JobScraper()
217
  logger.info("βœ“ Job Scraper initialized")
 
 
 
 
 
218
  customizer = ResumeCustomizer(mayini_model, vocab)
219
  logger.info("βœ“ Resume Customizer initialized")
 
 
 
 
 
220
  classifier = JobRelevanceClassifier()
 
 
221
  logger.info("βœ“ Job Classifier initialized")
 
 
 
 
 
222
  agent = JobApplicationAgent(scraper, customizer, classifier)
223
  logger.info("βœ“ Application Agent initialized")
224
  except Exception as e:
225
+ logger.error(f"Error during initialization: {e}")
226
+ logger.error(traceback.format_exc())
227
 
228
  logger.info("\n" + "=" * 80)
229
+ logger.info("βœ… INITIALIZATION COMPLETE - Ready to serve!")
230
  logger.info("=" * 80 + "\n")
231
 
232
  # ============================================================================
 
362
  gr.Markdown("Find jobs matching your skills using AI-powered matching.")
363
  with gr.Row():
364
  with gr.Column():
365
+ search_keywords = gr.Textbox(
366
+ label="Keywords",
367
+ placeholder="python docker aws",
368
+ value="python"
369
+ )
370
+ search_location = gr.Textbox(
371
+ label="Location",
372
+ placeholder="Remote",
373
+ value="Remote"
374
+ )
375
+ search_num = gr.Slider(
376
+ minimum=1,
377
+ maximum=20,
378
+ value=5,
379
+ step=1,
380
+ label="Number of Jobs"
381
+ )
382
  search_btn = gr.Button("πŸ” Search", variant="primary")
383
  with gr.Column():
384
  search_output = gr.Markdown(value="### Results will appear here...")
385
 
386
+ search_btn.click(
387
+ fn=search_jobs_interface,
388
+ inputs=[search_keywords, search_location, search_num],
389
+ outputs=search_output
390
+ )
391
 
392
  with gr.Tab("πŸ“„ Customize Resume"):
393
  gr.Markdown("Tailor your resume for specific job opportunities.")
394
  with gr.Row():
395
  with gr.Column():
396
+ customize_title = gr.Textbox(
397
+ label="Job Title",
398
+ placeholder="Senior Python Developer"
399
+ )
400
+ customize_company = gr.Textbox(
401
+ label="Company",
402
+ placeholder="Tech Inc"
403
+ )
404
+ customize_req = gr.Textbox(
405
+ label="Requirements",
406
+ placeholder="Python, Docker, AWS",
407
+ lines=2
408
+ )
409
  customize_btn = gr.Button("✨ Customize", variant="primary")
410
  with gr.Column():
411
  customize_output = gr.Markdown(value="### Customized resume will appear here...")
412
 
413
+ customize_btn.click(
414
+ fn=customize_resume_interface,
415
+ inputs=[customize_title, customize_company, customize_req],
416
+ outputs=customize_output
417
+ )
418
 
419
  with gr.Tab("🎯 Classify Job"):
420
  gr.Markdown("Check job relevance to your skills.")
421
  with gr.Row():
422
  with gr.Column():
423
+ classify_title = gr.Textbox(
424
+ label="Job Title",
425
+ placeholder="ML Engineer"
426
+ )
427
+ classify_req = gr.Textbox(
428
+ label="Requirements",
429
+ placeholder="Python, PyTorch",
430
+ lines=2
431
+ )
432
  classify_btn = gr.Button("🎯 Classify", variant="primary")
433
  with gr.Column():
434
  classify_output = gr.Markdown(value="### Results will appear here...")
435
 
436
+ classify_btn.click(
437
+ fn=classify_job_interface,
438
+ inputs=[classify_title, classify_req],
439
+ outputs=classify_output
440
+ )
441
 
442
  with gr.Tab("ℹ️ About"):
443
  gr.Markdown("""
 
463
  logger.info("βœ“ Gradio interface built successfully\n")
464
 
465
  # ============================================================================
466
+ # LAUNCH - FIXED FOR GRADIO COMPATIBILITY
467
  # ============================================================================
468
 
469
  if __name__ == "__main__":
 
471
  logger.info("Access at: http://0.0.0.0:7860\n")
472
 
473
  try:
474
+ # FIXED: Removed invalid 'concurrency_count' parameter
475
+ # Using only valid parameters for Gradio 4.0+
476
+ demo.launch(
477
  server_name="0.0.0.0",
478
  server_port=7860,
479
  show_error=True,