aiqcamp commited on
Commit
ff24b8f
·
verified ·
1 Parent(s): 95d0883

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -291
app.py CHANGED
@@ -448,296 +448,5 @@ with gr.Blocks(title="키워드 기반 창의적 변화 아이디어 생성기",
448
  outputs=processing_indicator
449
  )
450
 
451
- if __name__ == "__main__":
452
- demo.launch(debug=True)
453
-
454
- ],
455
-
456
- "환경 상호작용": [
457
- "온도 반응", "습도 반응", "기압 반응", "중력 반응", "자기장 반응",
458
- "빛 반응", "소리 반응", "화학 물질 감지", "기계적 자극 감지", "전기 자극 반응",
459
- "방사선 반응", "진동 감지", "pH 반응", "용매 반응", "기체 교환",
460
- "환경 오염 반응", "날씨 반응", "계절 변화 반응", "일주기 반응", "생태계 상호작용",
461
- "공생/경쟁 반응", "포식/피식 관계", "군집 형성", "영역 설정", "이주/정착 패턴"
462
- ],
463
-
464
- "센서 기능": [
465
- "시각 센서/감지", "청각 센서/감지", "촉각 센서/감지", "미각 센서/감지", "후각 센서/감지",
466
- "온도 센서/감지", "습도 센서/감지", "압력 센서/감지", "가속도 센서/감지", "회전 센서/감지",
467
- "근접 센서/감지", "위치 센서/감지", "운동 센서/감지", "가스 센서/감지", "적외선 센서/감지",
468
- "자외선 센서/감지", "방사선 센서/감지", "자기장 센서/감지", "전기장 센서/감지", "화학물질 센서/감지",
469
- "생체신호 센서/감지", "진동 센서/감지", "소음 센서/감지", "빛 세기 센서/감지", "빛 파장 센서/감지",
470
- "기울기 센서/감지", "pH 센서/감지", "전류 센서/감지", "전압 센서/감지", "이미지 센서/감지",
471
- "거리 센서/감지", "깊이 센서/감지", "중력 센서/감지", "속도 센서/감지", "흐름 센서/감지",
472
- "수위 센서/감지", "탁도 센서/감지", "염도 센서/감지", "금속 감지", "압전 센서/감지",
473
- "광전 센서/감지", "열전대 센서/감지", "홀 효과 센서/감지", "초음파 센서/감지", "레이더 센서/감지",
474
- "라이다 센서/감지", "터치 센서/감지", "제스처 센서/감지", "심박 센서/감지", "혈압 센서/감지"
475
- ]
476
- }
477
-
478
- ##############################################################################
479
- # Gemini API 호출 함수 (예: gemini-2.0-flash-thinking-exp-01-21 -> 다른 모델 사용 시 수정)
480
- ##############################################################################
481
- def query_gemini_api(prompt):
482
- try:
483
- # 예시: 기존 gemini-2.0... 대신, 다른 모델이 필요하다면 교체하세요.
484
- model = genai.GenerativeModel('gemini-2.0-flash-thinking-exp-01-21')
485
-
486
- response = model.generate_content(prompt)
487
-
488
- # 응답 구조 방어적으로 처리
489
- try:
490
- if hasattr(response, 'text'):
491
- return response.text
492
-
493
- if hasattr(response, 'candidates') and response.candidates:
494
- if len(response.candidates) > 0:
495
- candidate = response.candidates[0]
496
- if hasattr(candidate, 'content'):
497
- content = candidate.content
498
- if hasattr(content, 'parts') and content.parts:
499
- if len(content.parts) > 0:
500
- return content.parts[0].text
501
- if hasattr(response, 'parts') and response.parts:
502
- if len(response.parts) > 0:
503
- return response.parts[0].text
504
-
505
- return "Unable to generate a response. API response structure is different than expected."
506
-
507
- except Exception as inner_e:
508
- logger.error(f"Error processing response: {inner_e}")
509
- return f"An error occurred while processing the response: {str(inner_e)}"
510
-
511
- except Exception as e:
512
- logger.error(f"Error calling Gemini API: {e}")
513
- if "API key not valid" in str(e):
514
- return "API key is not valid. Please check your GEMINI_API_KEY environment variable."
515
- return f"An error occurred while calling the API: {str(e)}"
516
-
517
- ##############################################################################
518
- # 설명 확장 함수: "모델/컨셉/형상의 변화에 대한 이해와 혁신 포인트, 기능성 등을 중심"으로
519
- ##############################################################################
520
- def enhance_with_llm(base_description, obj_name, category):
521
- prompt = f"""
522
- 다음은 '{obj_name}'의 '{category}' 관련 간단한 설명입니다:
523
- "{base_description}"
524
- 위 내용을 보다 구체화하여,
525
- 1) 창의적인 모델/컨셉/형상의 변화에 대한 이해,
526
- 2) 혁신 포인트와 기능성 등을 중심으로
527
- 3~4문장의 아이디어로 확장해 주세요.
528
- """
529
- return query_gemini_api(prompt)
530
-
531
- ##############################################################################
532
- # 단일 키워드(오브젝트)에 대한 "창의적 변화 아이디어" 생성
533
- ##############################################################################
534
- def generate_single_object_transformations(obj):
535
- results = {}
536
- for category, transformations in physical_transformation_categories.items():
537
- transformation = choose_alternative(random.choice(transformations))
538
- base_description = f"{obj}이(가) {transformation} 현상을 보인다"
539
- results[category] = {"base": base_description, "enhanced": None}
540
- return results
541
-
542
- ##############################################################################
543
- # 두 키워드에 대한 "창의적 변화 아이디어" 생성
544
- ##############################################################################
545
- def generate_two_objects_interaction(obj1, obj2):
546
- results = {}
547
- for category, transformations in physical_transformation_categories.items():
548
- transformation = choose_alternative(random.choice(transformations))
549
- template = random.choice([
550
- "{obj1}이(가) {obj2}에 결합하여 {change}가 발생했다",
551
- "{obj1}과(와) {obj2}이(가) 충돌하면서 {change}가 일어났다"
552
- ])
553
- base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
554
- results[category] = {"base": base_description, "enhanced": None}
555
- return results
556
-
557
- ##############################################################################
558
- # 세 키워드에 대한 "창의적 변화 아이디어" 생성
559
- ##############################################################################
560
- def generate_three_objects_interaction(obj1, obj2, obj3):
561
- results = {}
562
- for category, transformations in physical_transformation_categories.items():
563
- transformation = choose_alternative(random.choice(transformations))
564
- template = random.choice([
565
- "{obj1}, {obj2}, {obj3}이(가) 삼각형 구조로 결합하여 {change}가 발생했다",
566
- "{obj1}이(가) {obj2}와(과) {obj3} 사이에서 매개체 역할을 하며 {change}를 촉진했다"
567
- ])
568
- base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
569
- results[category] = {"base": base_description, "enhanced": None}
570
- return results
571
-
572
- ##############################################################################
573
- # 생성된 기본 설명을 LLM을 통해 확장
574
- ##############################################################################
575
- def enhance_descriptions(results, objects):
576
- obj_name = " 및 ".join([obj for obj in objects if obj])
577
-
578
- for category, result in results.items():
579
- result["enhanced"] = enhance_with_llm(result["base"], obj_name, category)
580
-
581
- return results
582
-
583
- ##############################################################################
584
- # 사용자 입력(최대 3개 키워드)에 따라 창의적 변화 아이디어 생성
585
- ##############################################################################
586
- def generate_transformations(text1, text2=None, text3=None):
587
- if text2 and text3:
588
- results = generate_three_objects_interaction(text1, text2, text3)
589
- objects = [text1, text2, text3]
590
- elif text2:
591
- results = generate_two_objects_interaction(text1, text2)
592
- objects = [text1, text2]
593
- else:
594
- results = generate_single_object_transformations(text1)
595
- objects = [text1]
596
-
597
- return enhance_descriptions(results, objects)
598
-
599
- ##############################################################################
600
- # 결과 포맷팅
601
- ##############################################################################
602
- def format_results(results):
603
- formatted = ""
604
- for category, result in results.items():
605
- formatted += f"## {category}\n**기본 아이디어**: {result['base']}\n\n**확장된 아이디어**: {result['enhanced']}\n\n---\n\n"
606
- return formatted
607
-
608
- ##############################################################################
609
- # Gradio UI에서 호출할 함수
610
- ##############################################################################
611
- def process_inputs(text1, text2, text3, selected_category, progress=gr.Progress()):
612
- text1 = text1.strip() if text1 else None
613
- text2 = text2.strip() if text2 else None
614
- text3 = text3.strip() if text3 else None
615
-
616
- if not text1:
617
- return "오류: 최소 하나의 키워드를 입력해주세요."
618
-
619
- keyword_info = f"키워드: {text1}"
620
- if text2:
621
- keyword_info += f", {text2}"
622
- if text3:
623
- keyword_info += f", {text3}"
624
-
625
- progress(0.05, desc="아이디어 생성 준비 중...")
626
- time.sleep(0.3) # 시각적 효과를 위한 짧은 지연
627
-
628
- progress(0.1, desc="창의적인 모델/컨셉/형상 변화 아이디어 생성 시작...")
629
-
630
- results = generate_transformations(text1, text2, text3)
631
-
632
- # 선택한 카테고리에 해당하는 결과만 필터링
633
- if selected_category in results:
634
- results = {selected_category: results[selected_category]}
635
- else:
636
- return "선택한 카테고리가 결과에 존재하지 않습니다."
637
-
638
- progress(0.8, desc="결과 포맷팅 중...")
639
- formatted = format_results(results)
640
-
641
- progress(1.0, desc="완료!")
642
- return formatted
643
-
644
- ##############################################################################
645
- # API 키 경고 메시지
646
- ##############################################################################
647
- def get_warning_message():
648
- if not GEMINI_API_KEY:
649
- return "⚠️ 환경 변수 GEMINI_API_KEY가 설정되지 않았습니다. Gemini API 키를 설정하세요."
650
- return ""
651
-
652
- ##############################################################################
653
- # Gradio UI
654
- ##############################################################################
655
- with gr.Blocks(title="키워드 기반 창의적 변화 아이디어 생성기",
656
- theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")) as demo:
657
-
658
- gr.HTML("""
659
- <style>
660
- body { background: linear-gradient(135deg, #e0eafc, #cfdef3); font-family: 'Arial', sans-serif; }
661
- .gradio-container { padding: 20px; }
662
- h1, h2 { text-align: center; }
663
- h1 { color: #333; }
664
- h2 { color: #555; }
665
- .output { background-color: #ffffff; padding: 15px; border-radius: 8px; }
666
- .gr-button { background-color: #4CAF50; color: white; border: none; border-radius: 4px; padding: 8px 16px; }
667
- .progress-message { color: #2196F3; font-weight: bold; margin-top: 10px; }
668
- </style>
669
- """)
670
-
671
- gr.Markdown("# 🚀 키워드 기반 창의적 변화 아이디어 생성기")
672
- gr.Markdown("입력한 **키워드**(최대 3개)와 **카테고리**를 바탕으로, **창의적인 모델/컨셉/형상 변화**에 대한 이해와 **혁신 포인트**, **기능성** 등을 중심으로 확장된 아이디어를 제시합니다.")
673
-
674
- warning = gr.Markdown(get_warning_message())
675
-
676
- # 좌측 입력 영역
677
- with gr.Row():
678
- with gr.Column(scale=1):
679
- text_input1 = gr.Textbox(label="키워드 1 (필수)", placeholder="예: 스마트폰")
680
- text_input2 = gr.Textbox(label="키워드 2 (선택)", placeholder="예: 인공지능")
681
- text_input3 = gr.Textbox(label="키워드 3 (선택)", placeholder="예: 헬스케어")
682
- # 카테고리 선택 드롭다운 추가
683
- category_dropdown = gr.Dropdown(
684
- label="카테고리 선택",
685
- choices=list(physical_transformation_categories.keys()),
686
- value=list(physical_transformation_categories.keys())[0],
687
- info="출력할 카테고리를 선택하세요."
688
- )
689
-
690
- status_msg = gr.Markdown("💡 '아이디어 생성하기' 버튼을 클릭하면 아이디어 생성이 시작됩니다.")
691
-
692
- processing_indicator = gr.HTML("""
693
- <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
694
- <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
695
- <p style="margin-left: 10px; font-weight: bold; color: #3498db;">처리 중입니다...</p>
696
- </div>
697
- <style>
698
- @keyframes spin {
699
- 0% { transform: rotate(0deg); }
700
- 100% { transform: rotate(360deg); }
701
- }
702
- </style>
703
- """, visible=False)
704
-
705
- submit_button = gr.Button("아이디어 생성하기", variant="primary")
706
-
707
- # 우측 출력 영역
708
- with gr.Column(scale=2):
709
- idea_output = gr.Markdown(label="아이디어 결과")
710
-
711
- gr.Examples(
712
- examples=[
713
- ["스마트폰", "", "", list(physical_transformation_categories.keys())[0]],
714
- ["자동차", "", "", list(physical_transformation_categories.keys())[0]],
715
- ["자동차", "인공지능", "", list(physical_transformation_categories.keys())[0]],
716
- ["드론", "인공지능", "", list(physical_transformation_categories.keys())[0]],
717
- ["운동화", "웨어러블", "건강", list(physical_transformation_categories.keys())[0]],
718
- ],
719
- inputs=[text_input1, text_input2, text_input3, category_dropdown],
720
- )
721
-
722
- def show_processing_indicator():
723
- return gr.update(visible=True)
724
-
725
- def hide_processing_indicator():
726
- return gr.update(visible=False)
727
-
728
- submit_button.click(
729
- fn=show_processing_indicator,
730
- inputs=None,
731
- outputs=processing_indicator
732
- ).then(
733
- fn=process_inputs,
734
- inputs=[text_input1, text_input2, text_input3, category_dropdown],
735
- outputs=idea_output
736
- ).then(
737
- fn=hide_processing_indicator,
738
- inputs=None,
739
- outputs=processing_indicator
740
- )
741
-
742
  if __name__ == "__main__":
743
  demo.launch(debug=True)
 
448
  outputs=processing_indicator
449
  )
450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  if __name__ == "__main__":
452
  demo.launch(debug=True)