ginipick commited on
Commit
71c328b
·
verified ·
1 Parent(s): e41b021

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +117 -49
app.py CHANGED
@@ -45,13 +45,19 @@ logging.basicConfig(level=logging.INFO,
45
  format="%(asctime)s - %(levelname)s - %(message)s")
46
 
47
  # ──────────────────────────────── OpenAI Client ──────────────────────────
 
 
48
  @st.cache_resource
49
  def get_openai_client():
50
- """Create an OpenAI client."""
51
  if not OPENAI_API_KEY:
52
  raise RuntimeError("⚠️ OPENAI_API_KEY 환경 변수가 설정되지 않았습니다.")
53
- return OpenAI(api_key=OPENAI_API_KEY)
54
-
 
 
 
 
55
  # ──────────────────────────────── Blog Creation System Prompt ─────────────
56
  def get_system_prompt(template="ginigen", tone="professional", word_count=1750, include_search_results=False, include_uploaded_files=False) -> str:
57
  """
@@ -788,64 +794,126 @@ def process_input(prompt: str, uploaded_files):
788
  # 사용자 메시지 추가
789
  api_messages.append({"role": "user", "content": user_content})
790
 
791
- # OpenAI API 호출
792
- try:
793
- response = client.chat.completions.create(
794
- model=st.session_state.ai_model,
795
- messages=api_messages,
796
- temperature=1,
797
- max_tokens=MAX_TOKENS,
798
- top_p=1
799
- )
800
-
801
- # 응답 추출
802
- answer = response.choices[0].message.content
803
- status.update(label="Blog generated successfully!", state="complete")
804
-
805
- except Exception as api_error:
806
- error_message = str(api_error)
807
- logging.error(f"OpenAI API error: {error_message}")
808
- status.update(label=f"API Error: {error_message}", state="error")
809
- raise Exception(f"OpenAI API error: {error_message}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
810
 
811
  # 결과 표시
812
  placeholder.markdown(answer)
813
 
814
  # 이미지 생성
815
  answer_entry_saved = False
816
- if st.session_state.generate_image:
817
  with st.spinner("Generating image..."):
818
- ip = extract_image_prompt(answer, prompt)
819
- img, cap = generate_image(ip)
820
- if img:
821
- st.image(img, caption=cap)
822
- st.session_state.messages.append({
823
- "role": "assistant",
824
- "content": answer,
825
- "image": img,
826
- "image_caption": cap
827
- })
828
- answer_entry_saved = True
 
 
 
 
829
 
830
  # Save the answer if not saved above
831
- if not answer_entry_saved:
832
  st.session_state.messages.append({"role": "assistant", "content": answer})
833
 
834
  # Download buttons
835
- st.subheader("Download This Blog")
836
- c1, c2 = st.columns(2)
837
- c1.download_button(
838
- "Markdown",
839
- data=answer,
840
- file_name=f"{prompt[:30]}.md",
841
- mime="text/markdown"
842
- )
843
- c2.download_button(
844
- "HTML",
845
- data=md_to_html(answer, prompt[:30]),
846
- file_name=f"{prompt[:30]}.html",
847
- mime="text/html"
848
- )
 
849
 
850
  # Auto save
851
  if st.session_state.auto_save and st.session_state.messages:
 
45
  format="%(asctime)s - %(levelname)s - %(message)s")
46
 
47
  # ──────────────────────────────── OpenAI Client ──────────────────────────
48
+
49
+ # OpenAI 클라이언트에 타임아웃과 재시도 로직 추가
50
  @st.cache_resource
51
  def get_openai_client():
52
+ """Create an OpenAI client with timeout and retry settings."""
53
  if not OPENAI_API_KEY:
54
  raise RuntimeError("⚠️ OPENAI_API_KEY 환경 변수가 설정되지 않았습니다.")
55
+ return OpenAI(
56
+ api_key=OPENAI_API_KEY,
57
+ timeout=60.0, # 타임아웃 60초로 설정
58
+ max_retries=3 # 재시도 횟수 3회로 설정
59
+ )
60
+
61
  # ──────────────────────────────── Blog Creation System Prompt ─────────────
62
  def get_system_prompt(template="ginigen", tone="professional", word_count=1750, include_search_results=False, include_uploaded_files=False) -> str:
63
  """
 
794
  # 사용자 메시지 추가
795
  api_messages.append({"role": "user", "content": user_content})
796
 
797
+ # OpenAI API 호출 - 재시도 로직 추가
798
+ max_retries = 3
799
+ retry_delay = 2 # 초 단위
800
+ answer = None
801
+ used_model = st.session_state.ai_model
802
+
803
+ for retry in range(max_retries):
804
+ try:
805
+ status.update(label=f"Generating blog with {used_model} (attempt {retry+1}/{max_retries})...")
806
+ response = client.chat.completions.create(
807
+ model=used_model,
808
+ messages=api_messages,
809
+ temperature=1,
810
+ max_tokens=MAX_TOKENS,
811
+ top_p=1,
812
+ request_timeout=90 # 타임아웃 90초로 설정
813
+ )
814
+
815
+ # 응답 추출
816
+ answer = response.choices[0].message.content
817
+ status.update(label=f"Blog generated successfully with {used_model}!", state="complete")
818
+ break # 성공하면 반복문 종료
819
+
820
+ except Exception as api_error:
821
+ error_message = str(api_error)
822
+ logging.error(f"OpenAI API error (attempt {retry+1}/{max_retries}): {error_message}")
823
+
824
+ if retry < max_retries - 1:
825
+ wait_time = retry_delay * (retry + 1) # 점점 길어지는 대기 시간
826
+ status.update(label=f"API Error: {error_message}. Retrying in {wait_time}s... ({retry+1}/{max_retries})")
827
+ time.sleep(wait_time)
828
+ else:
829
+ # 마지막 시도에서도 실패하면 대체 모델 시도
830
+ fallback_models = ["gpt-3.5-turbo", "gpt-3.5-turbo-16k"]
831
+ if used_model in fallback_models:
832
+ fallback_models.remove(used_model)
833
+
834
+ # 대체 모델 시도
835
+ if fallback_models:
836
+ status.update(label="Primary model failed. Trying fallback models...")
837
+ for fb_model in fallback_models:
838
+ try:
839
+ status.update(label=f"Trying with fallback model: {fb_model}...")
840
+ response = client.chat.completions.create(
841
+ model=fb_model,
842
+ messages=api_messages,
843
+ temperature=1,
844
+ max_tokens=min(MAX_TOKENS, 4096 if "16k" not in fb_model else 16000),
845
+ top_p=1,
846
+ request_timeout=90
847
+ )
848
+ answer = response.choices[0].message.content
849
+ used_model = fb_model
850
+ status.update(label=f"Blog generated with fallback model: {used_model}", state="complete")
851
+ break
852
+ except Exception as fb_error:
853
+ logging.error(f"Fallback model {fb_model} also failed: {str(fb_error)}")
854
+
855
+ # 대체 모델 중 하나가 성공했는지 확인
856
+ if answer:
857
+ break
858
+
859
+ # 모든 모델이 실패한 경우
860
+ if not answer:
861
+ status.update(label="All models failed to generate content", state="error")
862
+ user_message = "OpenAI API 연결 문제가 발생했습니다. 인터넷 연결을 확인하거나 나중에 다시 시도해 주세요."
863
+ if "rate limit" in error_message.lower():
864
+ user_message = "OpenAI API 속도 제한에 도달했습니다. 잠시 후 다시 시도해 주세요."
865
+ elif "invalid api key" in error_message.lower():
866
+ user_message = "유효하지 않은 API 키입니다. API 키를 확인해 주세요."
867
+
868
+ raise Exception(user_message)
869
+
870
+ # 결과가 생성되지 않은 경우 오류 발생
871
+ if not answer:
872
+ raise Exception("블로그 콘텐츠를 생성하지 못했습니다.")
873
 
874
  # 결과 표시
875
  placeholder.markdown(answer)
876
 
877
  # 이미지 생성
878
  answer_entry_saved = False
879
+ if st.session_state.generate_image and answer:
880
  with st.spinner("Generating image..."):
881
+ try:
882
+ ip = extract_image_prompt(answer, prompt)
883
+ img, cap = generate_image(ip)
884
+ if img:
885
+ st.image(img, caption=cap)
886
+ st.session_state.messages.append({
887
+ "role": "assistant",
888
+ "content": answer,
889
+ "image": img,
890
+ "image_caption": cap
891
+ })
892
+ answer_entry_saved = True
893
+ except Exception as img_error:
894
+ logging.error(f"Image generation error: {str(img_error)}")
895
+ st.warning("이미지 생성에 실패했습니다. 블로그 콘텐츠만 저장됩니다.")
896
 
897
  # Save the answer if not saved above
898
+ if not answer_entry_saved and answer:
899
  st.session_state.messages.append({"role": "assistant", "content": answer})
900
 
901
  # Download buttons
902
+ if answer:
903
+ st.subheader("Download This Blog")
904
+ c1, c2 = st.columns(2)
905
+ c1.download_button(
906
+ "Markdown",
907
+ data=answer,
908
+ file_name=f"{prompt[:30]}.md",
909
+ mime="text/markdown"
910
+ )
911
+ c2.download_button(
912
+ "HTML",
913
+ data=md_to_html(answer, prompt[:30]),
914
+ file_name=f"{prompt[:30]}.html",
915
+ mime="text/html"
916
+ )
917
 
918
  # Auto save
919
  if st.session_state.auto_save and st.session_state.messages: