Trabis commited on
Commit
be356a8
·
verified ·
1 Parent(s): c96ef43

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +497 -315
app.py CHANGED
@@ -232,234 +232,358 @@ prompt_template = ChatPromptTemplate.from_messages([
232
  ])
233
 
234
 
235
- # def process_question(question: str):
236
- # """
237
- # Process the question and yield the answer progressively.
238
- # """
239
- # # Check cache first
240
- # if question in question_cache:
241
- # yield question_cache[question] # Retourne directement depuis le cache si disponible
242
-
243
- # relevant_docs = retriever(question)
244
- # context = "\n".join([doc.page_content for doc in relevant_docs])
245
-
246
- # prompt = prompt_template.format_messages(
247
- # context=context,
248
- # question=question
249
- # )
250
-
251
- # response = "" # Initialise la réponse
252
- # # Ici, nous supposons que 'llm.stream' est un générateur qui renvoie des chunks
253
- # for chunk in llm.stream(prompt): # suppose que llm.stream renvoie des chunks de réponse
254
- # if isinstance(chunk, str):
255
- # response += chunk # Accumulez la réponse si c'est déjà une chaîne
256
- # else:
257
- # response += chunk.content # Sinon, prenez le contenu du chunk (si chunk est un type d'objet spécifique)
258
-
259
- # yield response, context # Renvoie la réponse mise à jour et le contexte
260
 
261
- # # Mettez le résultat en cache à la fin
262
- # # question_cache[question] = (response, context)
263
-
264
- def process_question(question: str) -> Generator[Tuple[str, str], None, None]:
265
- """
266
- Process the question and yield the answer progressively.
267
- """
268
- # Check cache first
269
- if question in question_cache:
270
- yield question_cache[question]
271
-
272
- relevant_docs = retriever(question)
273
- context = "\n".join([doc.page_content for doc in relevant_docs])
274
-
275
- prompt = prompt_template.format_messages(
276
- context=context,
277
- question=question
278
- )
279
-
280
- current_response = ""
281
- for chunk in llm.stream(prompt):
282
- if isinstance(chunk, str):
283
- current_response += chunk
284
- else:
285
- current_response += chunk.content
286
- yield current_response, context
287
- # Mettez le résultat en cache à la fin
288
- question_cache[question] = (response, context)
289
-
290
- # CSS personnalisé avec l'importation de Google Fonts
291
- custom_css = """
292
- /* Import Google Fonts - Noto Sans Arabic */
293
- @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Arabic:wght@300;400;500;600;700&display=swap');
294
-
295
- /* Styles généraux */
296
- :root {
297
- --primary-color: #4299e1;
298
- --secondary-color: #666666;
299
- --accent-color: #4299E1;
300
- --background-color: #ffffff;
301
- --border-radius: 8px;
302
- --font-family-arabic: 'Noto Sans Arabic', Arial, sans-serif;
303
  }
304
 
305
- /* Style de base */
306
  body {
307
- font-family: var(--font-family-arabic);
308
- background-color: var(--background-color);
309
- color: var(--primary-color);
 
310
  }
311
 
312
- /* Styles pour le texte RTL */
313
- .rtl-text {
314
- text-align: right !important;
315
- direction: rtl !important;
316
- font-family: var(--font-family-arabic) !important;
317
  }
318
 
319
- .rtl-text textarea {
 
 
 
 
 
 
 
 
 
320
  text-align: right !important;
321
- direction: rtl !important;
322
- padding: 1rem !important;
323
- border-radius: var(--border-radius) !important;
324
- border: 1px solid #E2E8F0 !important;
325
- background-color: #ffffff !important;
326
- color: var(--primary-color) !important;
327
- font-size: 1.1rem !important;
328
- line-height: 1.6 !important;
329
- font-family: var(--font-family-arabic) !important;
330
  }
331
 
332
- /* Style du titre */
333
- .app-title {
334
- font-family: var(--font-family-arabic) !important;
335
- font-size: 2rem !important;
336
- font-weight: 700 !important;
337
- color: white !important; /* Texte en blanc */
338
- background-color: #3e2b1f !important; /* Fond marron foncé */
339
- margin-bottom: 1rem !important;
340
- margin-top: 1rem !important;
341
- text-align: center !important;
342
  }
343
 
344
- /* Styles des étiquettes */
345
- .rtl-text label {
346
- font-family: var(--font-family-arabic) !important;
347
- font-size: 1.2rem !important;
348
- font-weight: 600 !important;
349
- color: #000000 !important; /* Couleur noire pour les étiquettes */
350
- margin-bottom: 0.5rem !important;
 
 
 
 
351
  }
352
 
353
- /* Centrer le bouton */
354
- button.primary-button {
355
- font-family: var(--font-family-arabic) !important;
356
- background-color: var(--accent-color) !important;
357
- color: white !important;
358
- padding: 0.75rem 1.5rem !important;
359
- border-radius: var(--border-radius) !important;
360
- font-weight: 600 !important;
361
- font-size: 1.1rem !important;
362
- transition: all 0.3s ease !important;
363
- width: 200px !important; /* Réduit la largeur du bouton */
364
- margin: 0 auto !important; /* Centrage horizontal */
365
- display: block !important; /* Nécessaire pour que le margin auto fonctionne */
366
  }
367
 
368
-
369
- button.primary-button:hover {
370
- background-color: #3182CE !important;
371
- transform: translateY(-1px) !important;
 
 
 
 
 
372
  }
373
 
374
- /* Styles des boîtes de texte */
375
- .textbox-container {
376
- background-color: #b45f06 !important;
377
- padding: 1.5rem !important;
378
- border-radius: var(--border-radius) !important;
379
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
380
- margin-bottom: 1rem !important;
381
  }
382
 
383
- /* Animation de chargement */
384
- .loading {
385
- animation: pulse 2s infinite;
 
 
386
  }
387
 
388
- @keyframes pulse {
389
- 0% { opacity: 1; }
390
- 50% { opacity: 0.5; }
391
- 100% { opacity: 1; }
392
  }
393
 
394
- /* Style du statut */
395
- .status-text {
396
- font-family: var(--font-family-arabic) !important;
397
- text-align: center !important;
398
- color: var(--secondary-color) !important;
399
- font-size: 1rem !important;
400
- margin-top: 1rem !important;
401
  }
402
  """
403
 
404
- # Interface Gradio avec streaming
405
- with gr.Blocks(css=custom_css) as iface:
406
- with gr.Column(elem_classes="container"):
407
- gr.Markdown(
408
- "# نظام الأسئلة والأجوبة الذكي",
409
- elem_classes="app-title rtl-text"
410
- )
411
-
412
- with gr.Column(elem_classes="textbox-container"):
413
- input_text = gr.Textbox(
414
- label="السؤال",
415
- placeholder="اكتب سؤالك هنا...",
416
- lines=1,
417
- elem_classes="rtl-text"
418
- )
419
-
420
- with gr.Row():
421
- with gr.Column():
422
- answer_box = gr.Textbox(
423
- label="الإجابة",
424
- lines=5,
425
- elem_classes="rtl-text textbox-container"
426
- )
427
-
428
- submit_btn = gr.Button(
429
- "إرسال السؤال",
430
- elem_classes="primary-button",
431
- variant="primary"
432
- )
433
-
434
- # def stream_response(question):
435
- # response_stream = process_question(question)
436
- # for response, _ in response_stream:
437
- # gr.update(value=response)
438
- # yield response
439
-
440
- def stream_response(question):
441
- for chunk_response, _ in process_question(question):
442
- yield chunk_response
443
- time.sleep(0.05)
444
-
445
- submit_btn.click(
446
- fn=stream_response,
447
- inputs=input_text,
448
- outputs=answer_box,
449
- api_name="predict",
450
- queue=False
451
- )
452
-
453
- if __name__ == "__main__":
454
- iface.launch(
455
- share=True,
456
- server_name="0.0.0.0",
457
- server_port=7860,
458
- max_threads=3,
459
- show_error=True
460
  )
461
 
462
- # # Interface Gradio avec la correction
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  # with gr.Blocks(css=custom_css) as iface:
464
  # with gr.Column(elem_classes="container"):
465
  # gr.Markdown(
@@ -482,33 +606,31 @@ if __name__ == "__main__":
482
  # lines=5,
483
  # elem_classes="rtl-text textbox-container"
484
  # )
485
- # # with gr.Column(scale=1):
486
- # # context_box = gr.Textbox(
487
- # # label="السياق المستخدم",
488
- # # lines=4,
489
- # # elem_classes="rtl-text textbox-container"
490
- # # )
491
 
492
  # submit_btn = gr.Button(
493
  # "إرسال السؤال",
494
  # elem_classes="primary-button",
495
  # variant="primary"
496
  # )
497
-
498
 
499
- # def on_submit(question):
500
- # for response, context in process_question(question):
501
- # yield response # Yield À CHAQUE itération
 
 
 
 
 
 
 
502
 
503
-
504
  # submit_btn.click(
505
- # fn=on_submit,
506
  # inputs=input_text,
507
  # outputs=answer_box,
508
  # api_name="predict",
509
- # queue=False,
510
- # )
511
-
512
 
513
  # if __name__ == "__main__":
514
  # iface.launch(
@@ -516,113 +638,173 @@ if __name__ == "__main__":
516
  # server_name="0.0.0.0",
517
  # server_port=7860,
518
  # max_threads=3,
519
- # show_error=True,
520
  # )
521
 
522
- # def process_question(question: str):
523
- # """
524
- # Process the question and yield the answer progressively.
525
- # """
526
- # # Check cache first
527
- # if question in question_cache:
528
- # yield question_cache[question] # Retourne directement depuis le cache si disponible
529
-
530
- # relevant_docs = retriever(question)
531
- # context = "\n".join([doc.page_content for doc in relevant_docs])
532
-
533
- # prompt = prompt_template.format_messages(
534
- # context=context,
535
- # question=question
536
- # )
537
-
538
- # response = "" # Initialise la réponse
539
- # # Ici, nous supposons que 'llm.stream' est un générateur qui renvoie des chunks
540
- # for chunk in llm.stream(prompt): # suppose que llm.stream renvoie des chunks de réponse
541
- # if isinstance(chunk, str):
542
- # response += chunk # Accumulez la réponse si c'est déjà une chaîne
543
- # else:
544
- # response += chunk.content # Sinon, prenez le contenu du chunk (si chunk est un type d'objet spécifique)
545
-
546
- # yield response, context # Renvoie la réponse mise à jour et le contexte
547
-
548
- # # Mettez le résultat en cache à la fin
549
- # question_cache[question] = (response, context)
550
-
551
- # # Custom CSS for right-aligned text in textboxes
552
- # custom_css = """
553
- # .rtl-text {
554
- # text-align: right !important;
555
- # direction: rtl !important;
556
- # }
557
- # .rtl-text textarea {
558
- # text-align: right !important;
559
- # direction: rtl !important;
560
- # }
561
- # """
562
-
563
- # # Gradio interface with queue
564
- # with gr.Blocks(css=custom_css) as iface:
565
- # with gr.Column():
566
- # input_text = gr.Textbox(
567
- # label="السؤال",
568
- # placeholder="اكتب سؤالك هنا...",
569
- # lines=2,
570
- # elem_classes="rtl-text"
571
- # )
572
 
573
- # with gr.Row():
574
- # answer_box = gr.Textbox(
575
- # label="الإجابة",
576
- # lines=4,
577
- # elem_classes="rtl-text"
578
- # )
579
- # context_box = gr.Textbox(
580
- # label="السياق المستخدم",
581
- # lines=8,
582
- # elem_classes="rtl-text"
583
- # )
584
 
585
- # submit_btn = gr.Button("إرسال")
 
 
 
 
 
 
 
 
 
 
 
 
586
 
587
- # submit_btn.click(
588
- # fn=process_question,
589
- # inputs=input_text,
590
- # outputs=[answer_box, context_box],
591
- # api_name="predict",
592
- # queue=True # Utiliser le système de queue pour un traitement asynchrone
593
- # )
594
-
595
- # if __name__ == "__main__":
596
- # iface.launch(
597
- # share=True,
598
- # server_name="0.0.0.0",
599
- # server_port=7860,
600
- # max_threads=3, # Controls concurrency
601
- # show_error=True
602
- # )
603
-
604
 
 
 
 
605
 
606
- # def process_question(question: str):
607
- # """
608
- # Process the question and return the answer and context
609
- # """
610
- # # Check cache first
611
- # if question in question_cache:
612
- # return question_cache[question], "" # Retourne la réponse cachée et un statut vide
613
- # relevant_docs = retriever(question)
614
- # context = "\n".join([doc.page_content for doc in relevant_docs])
615
- # prompt = prompt_template.format_messages(
616
- # context=context,
617
- # question=question
618
- # )
619
- # response = ""
620
- # for chunk in llm.stream(prompt):
621
- # if isinstance(chunk, str):
622
- # response += chunk
623
- # else:
624
- # response += chunk.content
625
- # # Mettez le résultat en cache à la fin
626
- # question_cache[question] = (response, context)
627
- # return response, context
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
628
 
 
232
  ])
233
 
234
 
235
+ import gradio as gr
236
+ from typing import Iterator
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
 
238
+ # Ajouter du CSS pour personnaliser l'apparence
239
+ css = """
240
+ /* Reset RTL global */
241
+ *, *::before, *::after {
242
+ direction: rtl !important;
243
+ text-align: right !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  }
245
 
 
246
  body {
247
+ font-family: 'Amiri', sans-serif; /* Utilisation de la police Arabe andalouse */
248
+ background-color: white; /* Fond blanc */
249
+ color: black; /* Texte noir */
250
+ direction: rtl !important; /* Texte en arabe aligné à droite */
251
  }
252
 
253
+ .gradio-container {
254
+ direction: rtl !important; /* Alignement RTL pour toute l'interface */
 
 
 
255
  }
256
 
257
+ /* Éléments de formulaire */
258
+ input[type="text"],
259
+ .gradio-textbox input,
260
+ textarea {
261
+ border-radius: 20px;
262
+ padding: 10px 15px;
263
+ border: 2px solid #000;
264
+ font-size: 16px;
265
+ width: 80%;
266
+ margin: 0 auto;
267
  text-align: right !important;
 
 
 
 
 
 
 
 
 
268
  }
269
 
270
+ /* Surcharge des styles de placeholder */
271
+ input::placeholder,
272
+ textarea::placeholder {
273
+ text-align: right !important;
274
+ direction: rtl !important;
 
 
 
 
 
275
  }
276
 
277
+ /* Boutons */
278
+ .gradio-button {
279
+ border-radius: 20px;
280
+ font-size: 16px;
281
+ background-color: #007BFF;
282
+ color: white;
283
+ padding: 10px 20px;
284
+ margin: 10px auto;
285
+ border: none;
286
+ width: 80%;
287
+ display: block;
288
  }
289
 
290
+ .gradio-button:hover {
291
+ background-color: #0056b3;
 
 
 
 
 
 
 
 
 
 
 
292
  }
293
 
294
+ .gradio-chatbot .message {
295
+ border-radius: 20px;
296
+ padding: 10px;
297
+ margin: 10px 0;
298
+ background-color: #f1f1f1;
299
+ border: 1px solid #ddd;
300
+ width: 80%;
301
+ text-align: right !important;
302
+ direction: rtl !important;
303
  }
304
 
305
+ /* Messages utilisateur alignés à gauche */
306
+ .gradio-chatbot .user-message {
307
+ margin-right: auto;
308
+ background-color: #e3f2fd;
309
+ text-align: right !important;
310
+ direction: rtl !important;
 
311
  }
312
 
313
+ /* Messages assistant alignés à droite */
314
+ .gradio-chatbot .assistant-message {
315
+ margin-right: auto;
316
+ background-color: #f1f1f1;
317
+ text-align: right
318
  }
319
 
320
+ /* Corrections RTL pour les éléments spécifiques */
321
+ .gradio-textbox textarea {
322
+ text-align: right !important;
 
323
  }
324
 
325
+ .gradio-dropdown div {
326
+ text-align: right !important;
 
 
 
 
 
327
  }
328
  """
329
 
330
+ def process_question(question: str) -> Iterator[str]:
331
+ """
332
+ Process the question and return a response generator for streaming.
333
+ """
334
+ if question in question_cache:
335
+ yield question_cache[question][0]
336
+ return
337
+
338
+ relevant_docs = retriever(question)
339
+ context = "\n".join([doc.page_content for doc in relevant_docs])
340
+
341
+ prompt = prompt_template.format_messages(
342
+ context=context,
343
+ question=question
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  )
345
 
346
+ full_response = ""
347
+ try:
348
+ for chunk in llm.stream(prompt):
349
+ if isinstance(chunk, str):
350
+ current_chunk = chunk
351
+ else:
352
+ current_chunk = chunk.content
353
+
354
+ full_response += current_chunk
355
+ yield full_response # Send the updated response in streaming
356
+
357
+ question_cache[question] = (full_response, context)
358
+ except Exception as e:
359
+ yield f"Erreur lors du traitement : {str(e)}"
360
+
361
+
362
+ def gradio_stream(question: str, chat_history: list) -> Iterator[list]:
363
+ """
364
+ Format the output for Gradio Chatbot component with streaming.
365
+ """
366
+ full_response = ""
367
+ try:
368
+ for partial_response in process_question(question):
369
+ full_response = partial_response
370
+ # Append the latest assistant response to chat history
371
+ updated_chat = chat_history + [[question, partial_response]]
372
+ yield updated_chat
373
+ except Exception as e:
374
+ # Handle errors during streaming
375
+ updated_chat = chat_history + [[question, f"Erreur : {str(e)}"]]
376
+ yield updated_chat
377
+
378
+
379
+ # Gradio interface
380
+ with gr.Blocks(css=css) as demo:
381
+
382
+ gr.Markdown("<h2 style='text-align: center !important;'>مساعد الذكاء الاصطناعي</h2>")
383
+
384
+ # Organisation en 3 lignes
385
+ with gr.Row(): # Première ligne: Question
386
+ message = gr.Textbox(label="أدخل سؤالك", placeholder="اكتب سؤالك هنا", elem_id="question_input")
387
+
388
+ with gr.Row(): # Deuxième ligne: Bouton de recherche
389
+ send = gr.Button("بحث", elem_id="search_button")
390
+
391
+ with gr.Row(): # Troisième ligne: Affichage de la réponse
392
+ chatbot = gr.Chatbot(label="")
393
+
394
+ # Fonction de mise à jour pour l'utilisateur
395
+ def user_input(user_message, chat_history):
396
+ return "", chat_history + [[user_message, None]]
397
+
398
+ send.click(user_input, [message, chatbot], [message, chatbot], queue=False)
399
+ send.click(gradio_stream, [message, chatbot], chatbot)
400
+
401
+ demo.launch(share=True)
402
+
403
+
404
+
405
+
406
+
407
+
408
+
409
+
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+ # # def process_question(question: str):
418
+ # # """
419
+ # # Process the question and yield the answer progressively.
420
+ # # """
421
+ # # # Check cache first
422
+ # # if question in question_cache:
423
+ # # yield question_cache[question] # Retourne directement depuis le cache si disponible
424
+
425
+ # # relevant_docs = retriever(question)
426
+ # # context = "\n".join([doc.page_content for doc in relevant_docs])
427
+
428
+ # # prompt = prompt_template.format_messages(
429
+ # # context=context,
430
+ # # question=question
431
+ # # )
432
+
433
+ # # response = "" # Initialise la réponse
434
+ # # # Ici, nous supposons que 'llm.stream' est un générateur qui renvoie des chunks
435
+ # # for chunk in llm.stream(prompt): # suppose que llm.stream renvoie des chunks de réponse
436
+ # # if isinstance(chunk, str):
437
+ # # response += chunk # Accumulez la réponse si c'est déjà une chaîne
438
+ # # else:
439
+ # # response += chunk.content # Sinon, prenez le contenu du chunk (si chunk est un type d'objet spécifique)
440
+
441
+ # # yield response, context # Renvoie la réponse mise à jour et le contexte
442
+
443
+ # # # Mettez le résultat en cache à la fin
444
+ # # # question_cache[question] = (response, context)
445
+
446
+ # def process_question(question: str) -> Generator[Tuple[str, str], None, None]:
447
+ # """
448
+ # Process the question and yield the answer progressively.
449
+ # """
450
+ # # Check cache first
451
+ # if question in question_cache:
452
+ # yield question_cache[question]
453
+
454
+ # relevant_docs = retriever(question)
455
+ # context = "\n".join([doc.page_content for doc in relevant_docs])
456
+
457
+ # prompt = prompt_template.format_messages(
458
+ # context=context,
459
+ # question=question
460
+ # )
461
+
462
+ # current_response = ""
463
+ # for chunk in llm.stream(prompt):
464
+ # if isinstance(chunk, str):
465
+ # current_response += chunk
466
+ # else:
467
+ # current_response += chunk.content
468
+ # yield current_response, context
469
+ # # Mettez le résultat en cache à la fin
470
+ # question_cache[question] = (response, context)
471
+
472
+ # # CSS personnalisé avec l'importation de Google Fonts
473
+ # custom_css = """
474
+ # /* Import Google Fonts - Noto Sans Arabic */
475
+ # @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Arabic:wght@300;400;500;600;700&display=swap');
476
+
477
+ # /* Styles généraux */
478
+ # :root {
479
+ # --primary-color: #4299e1;
480
+ # --secondary-color: #666666;
481
+ # --accent-color: #4299E1;
482
+ # --background-color: #ffffff;
483
+ # --border-radius: 8px;
484
+ # --font-family-arabic: 'Noto Sans Arabic', Arial, sans-serif;
485
+ # }
486
+
487
+ # /* Style de base */
488
+ # body {
489
+ # font-family: var(--font-family-arabic);
490
+ # background-color: var(--background-color);
491
+ # color: var(--primary-color);
492
+ # }
493
+
494
+ # /* Styles pour le texte RTL */
495
+ # .rtl-text {
496
+ # text-align: right !important;
497
+ # direction: rtl !important;
498
+ # font-family: var(--font-family-arabic) !important;
499
+ # }
500
+
501
+ # .rtl-text textarea {
502
+ # text-align: right !important;
503
+ # direction: rtl !important;
504
+ # padding: 1rem !important;
505
+ # border-radius: var(--border-radius) !important;
506
+ # border: 1px solid #E2E8F0 !important;
507
+ # background-color: #ffffff !important;
508
+ # color: var(--primary-color) !important;
509
+ # font-size: 1.1rem !important;
510
+ # line-height: 1.6 !important;
511
+ # font-family: var(--font-family-arabic) !important;
512
+ # }
513
+
514
+ # /* Style du titre */
515
+ # .app-title {
516
+ # font-family: var(--font-family-arabic) !important;
517
+ # font-size: 2rem !important;
518
+ # font-weight: 700 !important;
519
+ # color: white !important; /* Texte en blanc */
520
+ # background-color: #3e2b1f !important; /* Fond marron foncé */
521
+ # margin-bottom: 1rem !important;
522
+ # margin-top: 1rem !important;
523
+ # text-align: center !important;
524
+ # }
525
+
526
+ # /* Styles des étiquettes */
527
+ # .rtl-text label {
528
+ # font-family: var(--font-family-arabic) !important;
529
+ # font-size: 1.2rem !important;
530
+ # font-weight: 600 !important;
531
+ # color: #000000 !important; /* Couleur noire pour les étiquettes */
532
+ # margin-bottom: 0.5rem !important;
533
+ # }
534
+
535
+ # /* Centrer le bouton */
536
+ # button.primary-button {
537
+ # font-family: var(--font-family-arabic) !important;
538
+ # background-color: var(--accent-color) !important;
539
+ # color: white !important;
540
+ # padding: 0.75rem 1.5rem !important;
541
+ # border-radius: var(--border-radius) !important;
542
+ # font-weight: 600 !important;
543
+ # font-size: 1.1rem !important;
544
+ # transition: all 0.3s ease !important;
545
+ # width: 200px !important; /* Réduit la largeur du bouton */
546
+ # margin: 0 auto !important; /* Centrage horizontal */
547
+ # display: block !important; /* Nécessaire pour que le margin auto fonctionne */
548
+ # }
549
+
550
+
551
+ # button.primary-button:hover {
552
+ # background-color: #3182CE !important;
553
+ # transform: translateY(-1px) !important;
554
+ # }
555
+
556
+ # /* Styles des boîtes de texte */
557
+ # .textbox-container {
558
+ # background-color: #b45f06 !important;
559
+ # padding: 1.5rem !important;
560
+ # border-radius: var(--border-radius) !important;
561
+ # box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
562
+ # margin-bottom: 1rem !important;
563
+ # }
564
+
565
+ # /* Animation de chargement */
566
+ # .loading {
567
+ # animation: pulse 2s infinite;
568
+ # }
569
+
570
+ # @keyframes pulse {
571
+ # 0% { opacity: 1; }
572
+ # 50% { opacity: 0.5; }
573
+ # 100% { opacity: 1; }
574
+ # }
575
+
576
+ # /* Style du statut */
577
+ # .status-text {
578
+ # font-family: var(--font-family-arabic) !important;
579
+ # text-align: center !important;
580
+ # color: var(--secondary-color) !important;
581
+ # font-size: 1rem !important;
582
+ # margin-top: 1rem !important;
583
+ # }
584
+ # """
585
+
586
+ # # Interface Gradio avec streaming
587
  # with gr.Blocks(css=custom_css) as iface:
588
  # with gr.Column(elem_classes="container"):
589
  # gr.Markdown(
 
606
  # lines=5,
607
  # elem_classes="rtl-text textbox-container"
608
  # )
 
 
 
 
 
 
609
 
610
  # submit_btn = gr.Button(
611
  # "إرسال السؤال",
612
  # elem_classes="primary-button",
613
  # variant="primary"
614
  # )
 
615
 
616
+ # # def stream_response(question):
617
+ # # response_stream = process_question(question)
618
+ # # for response, _ in response_stream:
619
+ # # gr.update(value=response)
620
+ # # yield response
621
+
622
+ # def stream_response(question):
623
+ # for chunk_response, _ in process_question(question):
624
+ # yield chunk_response
625
+ # time.sleep(0.05)
626
 
 
627
  # submit_btn.click(
628
+ # fn=stream_response,
629
  # inputs=input_text,
630
  # outputs=answer_box,
631
  # api_name="predict",
632
+ # queue=False
633
+ # )
 
634
 
635
  # if __name__ == "__main__":
636
  # iface.launch(
 
638
  # server_name="0.0.0.0",
639
  # server_port=7860,
640
  # max_threads=3,
641
+ # show_error=True
642
  # )
643
 
644
+ # # # Interface Gradio avec la correction
645
+ # # with gr.Blocks(css=custom_css) as iface:
646
+ # # with gr.Column(elem_classes="container"):
647
+ # # gr.Markdown(
648
+ # # "# نظام الأسئلة والأجوبة الذكي",
649
+ # # elem_classes="app-title rtl-text"
650
+ # # )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651
 
652
+ # # with gr.Column(elem_classes="textbox-container"):
653
+ # # input_text = gr.Textbox(
654
+ # # label="السؤال",
655
+ # # placeholder="اكتب سؤالك هنا...",
656
+ # # lines=1,
657
+ # # elem_classes="rtl-text"
658
+ # # )
 
 
 
 
659
 
660
+ # # with gr.Row():
661
+ # # with gr.Column():
662
+ # # answer_box = gr.Textbox(
663
+ # # label="الإجابة",
664
+ # # lines=5,
665
+ # # elem_classes="rtl-text textbox-container"
666
+ # # )
667
+ # # # with gr.Column(scale=1):
668
+ # # # context_box = gr.Textbox(
669
+ # # # label="السياق المستخدم",
670
+ # # # lines=4,
671
+ # # # elem_classes="rtl-text textbox-container"
672
+ # # # )
673
 
674
+ # # submit_btn = gr.Button(
675
+ # # "إرسال السؤال",
676
+ # # elem_classes="primary-button",
677
+ # # variant="primary"
678
+ # # )
679
+
 
 
 
 
 
 
 
 
 
 
 
680
 
681
+ # # def on_submit(question):
682
+ # # for response, context in process_question(question):
683
+ # # yield response # Yield À CHAQUE itération
684
 
685
+
686
+ # # submit_btn.click(
687
+ # # fn=on_submit,
688
+ # # inputs=input_text,
689
+ # # outputs=answer_box,
690
+ # # api_name="predict",
691
+ # # queue=False,
692
+ # # )
693
+
694
+
695
+ # # if __name__ == "__main__":
696
+ # # iface.launch(
697
+ # # share=True,
698
+ # # server_name="0.0.0.0",
699
+ # # server_port=7860,
700
+ # # max_threads=3,
701
+ # # show_error=True,
702
+ # # )
703
+
704
+ # # def process_question(question: str):
705
+ # # """
706
+ # # Process the question and yield the answer progressively.
707
+ # # """
708
+ # # # Check cache first
709
+ # # if question in question_cache:
710
+ # # yield question_cache[question] # Retourne directement depuis le cache si disponible
711
+
712
+ # # relevant_docs = retriever(question)
713
+ # # context = "\n".join([doc.page_content for doc in relevant_docs])
714
+
715
+ # # prompt = prompt_template.format_messages(
716
+ # # context=context,
717
+ # # question=question
718
+ # # )
719
+
720
+ # # response = "" # Initialise la réponse
721
+ # # # Ici, nous supposons que 'llm.stream' est un générateur qui renvoie des chunks
722
+ # # for chunk in llm.stream(prompt): # suppose que llm.stream renvoie des chunks de réponse
723
+ # # if isinstance(chunk, str):
724
+ # # response += chunk # Accumulez la réponse si c'est déjà une chaîne
725
+ # # else:
726
+ # # response += chunk.content # Sinon, prenez le contenu du chunk (si chunk est un type d'objet spécifique)
727
+
728
+ # # yield response, context # Renvoie la réponse mise à jour et le contexte
729
+
730
+ # # # Mettez le résultat en cache à la fin
731
+ # # question_cache[question] = (response, context)
732
+
733
+ # # # Custom CSS for right-aligned text in textboxes
734
+ # # custom_css = """
735
+ # # .rtl-text {
736
+ # # text-align: right !important;
737
+ # # direction: rtl !important;
738
+ # # }
739
+ # # .rtl-text textarea {
740
+ # # text-align: right !important;
741
+ # # direction: rtl !important;
742
+ # # }
743
+ # # """
744
+
745
+ # # # Gradio interface with queue
746
+ # # with gr.Blocks(css=custom_css) as iface:
747
+ # # with gr.Column():
748
+ # # input_text = gr.Textbox(
749
+ # # label="السؤال",
750
+ # # placeholder="اكتب سؤالك هنا...",
751
+ # # lines=2,
752
+ # # elem_classes="rtl-text"
753
+ # # )
754
+
755
+ # # with gr.Row():
756
+ # # answer_box = gr.Textbox(
757
+ # # label="الإجابة",
758
+ # # lines=4,
759
+ # # elem_classes="rtl-text"
760
+ # # )
761
+ # # context_box = gr.Textbox(
762
+ # # label="السياق المستخدم",
763
+ # # lines=8,
764
+ # # elem_classes="rtl-text"
765
+ # # )
766
+
767
+ # # submit_btn = gr.Button("إرسال")
768
+
769
+ # # submit_btn.click(
770
+ # # fn=process_question,
771
+ # # inputs=input_text,
772
+ # # outputs=[answer_box, context_box],
773
+ # # api_name="predict",
774
+ # # queue=True # Utiliser le système de queue pour un traitement asynchrone
775
+ # # )
776
+
777
+ # # if __name__ == "__main__":
778
+ # # iface.launch(
779
+ # # share=True,
780
+ # # server_name="0.0.0.0",
781
+ # # server_port=7860,
782
+ # # max_threads=3, # Controls concurrency
783
+ # # show_error=True
784
+ # # )
785
+
786
+
787
+
788
+ # # def process_question(question: str):
789
+ # # """
790
+ # # Process the question and return the answer and context
791
+ # # """
792
+ # # # Check cache first
793
+ # # if question in question_cache:
794
+ # # return question_cache[question], "" # Retourne la réponse cachée et un statut vide
795
+ # # relevant_docs = retriever(question)
796
+ # # context = "\n".join([doc.page_content for doc in relevant_docs])
797
+ # # prompt = prompt_template.format_messages(
798
+ # # context=context,
799
+ # # question=question
800
+ # # )
801
+ # # response = ""
802
+ # # for chunk in llm.stream(prompt):
803
+ # # if isinstance(chunk, str):
804
+ # # response += chunk
805
+ # # else:
806
+ # # response += chunk.content
807
+ # # # Mettez le résultat en cache à la fin
808
+ # # question_cache[question] = (response, context)
809
+ # # return response, context
810