Skip to content

Commit 465ae5f

Browse files
committed
대표 함수 편의성 강화 — OAuth URL 출력 + ask traceback 제거 + 에러 안내 개선
- setup('chatgpt') OAuth: 브라우저 열기 전 URL 항상 콘솔 출력, 타임아웃 시 URL 재출력 - ask(): raise 대신 print + return None (노트북 traceback 제거) - Company(): 에러 메시지에 예시/검색/목록 안내 추가 - scan 4종: 빈 결과 시 downloadAll 안내 출력 - no_provider_message: "설정 후 다시 실행하세요" flow 개선
1 parent 1431f0d commit 465ae5f

4 files changed

Lines changed: 57 additions & 20 deletions

File tree

src/dartlab/__init__.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,11 @@ def governance():
181181
"""
182182
from dartlab.market.governance import scan_governance
183183

184-
return scan_governance()
184+
result = scan_governance()
185+
if result is not None and hasattr(result, "is_empty") and result.is_empty():
186+
print("\n 거버넌스 스캔 결과가 없습니다.")
187+
print(" 전체 시장 데이터가 필요합니다: dartlab.downloadAll('report')\n")
188+
return result
185189

186190

187191
def workforce():
@@ -194,7 +198,11 @@ def workforce():
194198
"""
195199
from dartlab.market.workforce import scan_workforce
196200

197-
return scan_workforce()
201+
result = scan_workforce()
202+
if result is not None and hasattr(result, "is_empty") and result.is_empty():
203+
print("\n 인력 스캔 결과가 없습니다.")
204+
print(" 전체 시장 데이터가 필요합니다: dartlab.downloadAll('report')\n")
205+
return result
198206

199207

200208
def capital():
@@ -207,7 +215,11 @@ def capital():
207215
"""
208216
from dartlab.market.capital import scan_capital
209217

210-
return scan_capital()
218+
result = scan_capital()
219+
if result is not None and hasattr(result, "is_empty") and result.is_empty():
220+
print("\n 주주환원 스캔 결과가 없습니다.")
221+
print(" 전체 시장 데이터가 필요합니다: dartlab.downloadAll('report')\n")
222+
return result
211223

212224

213225
def debt():
@@ -220,7 +232,11 @@ def debt():
220232
"""
221233
from dartlab.market.debt import scan_debt
222234

223-
return scan_debt()
235+
result = scan_debt()
236+
if result is not None and hasattr(result, "is_empty") and result.is_empty():
237+
print("\n 부채 스캔 결과가 없습니다.")
238+
print(" 전체 시장 데이터가 필요합니다: dartlab.downloadAll('report')\n")
239+
return result
224240

225241

226242
def screen(preset: str = "가치주"):
@@ -493,7 +509,7 @@ def ask(
493509
reflect: True면 답변 자체 검증 (1회 reflection).
494510
495511
Returns:
496-
str: 전체 답변 텍스트. (raw=True일 때만 Generator[str])
512+
str | None: 전체 답변 텍스트. 설정 오류 시 None. (raw=True일 때만 Generator[str])
497513
498514
Example::
499515
@@ -526,9 +542,8 @@ def ask(
526542
if detected is None:
527543
from dartlab.core.ai.guide import no_provider_message
528544

529-
msg = no_provider_message()
530-
print(msg)
531-
raise RuntimeError("AI provider가 설정되지 않았습니다. dartlab.setup()을 실행하세요.")
545+
print(no_provider_message())
546+
return None
532547
provider = detected
533548

534549
if len(args) == 2:
@@ -539,15 +554,21 @@ def ask(
539554

540555
company, question = resolve_from_text(args[0])
541556
if company is None:
542-
raise ValueError(
543-
f"종목을 찾을 수 없습니다: '{args[0]}'\n"
544-
"종목명 또는 종목코드를 포함해 주세요.\n"
545-
"예: dartlab.ask('삼성전자 재무건전성 분석해줘')"
546-
)
557+
print(f"\n 종목을 찾을 수 없습니다: '{args[0]}'")
558+
print(" 종목명 또는 종목코드를 포함해 주세요.")
559+
print(" 예: dartlab.ask('삼성전자 재무건전성 분석해줘')")
560+
print(f" 검색: dartlab.search('{args[0]}')\n")
561+
return None
547562
elif len(args) == 0:
548-
raise TypeError("질문을 입력해 주세요. 예: dartlab.ask('삼성전자 분석해줘')")
563+
print("\n 질문을 입력해 주세요.")
564+
print(" 예: dartlab.ask('삼성전자 재무건전성 분석해줘')")
565+
print(" 예: dartlab.ask('005930', '영업이익률 추세는?')\n")
566+
return None
549567
else:
550-
raise TypeError(f"인자는 1~2개만 허용됩니다 (받은 수: {len(args)})")
568+
print(f"\n 인자는 1~2개만 허용됩니다 (받은 수: {len(args)})")
569+
print(" 예: dartlab.ask('삼성전자 분석해줘')")
570+
print(" 예: dartlab.ask('005930', '영업이익률 추세는?')\n")
571+
return None
551572

552573
if raw:
553574
return _ask(

src/dartlab/cli/commands/setup.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,12 @@ def serve():
212212

213213
print(" 브라우저에서 ChatGPT 로그인 페이지를 엽니다...")
214214
print(" (120초 안에 로그인을 완료하세요)\n")
215-
webbrowser.open(auth_url)
215+
print(" 브라우저가 자동으로 열리지 않으면 아래 URL을 직접 여세요:")
216+
print(f" {auth_url}\n")
217+
try:
218+
webbrowser.open(auth_url)
219+
except Exception:
220+
pass
216221

217222
# 완료 대기
218223
for _ in range(120):
@@ -233,7 +238,9 @@ def serve():
233238
print(' dartlab ask 005930 "재무 건전성 분석"\n')
234239
else:
235240
print("\n ✗ 시간 초과 — 120초 안에 로그인하지 못했습니다.\n")
236-
print(" 다시 시도: dartlab setup oauth-codex\n")
241+
print(" 아래 URL을 브라우저에 직접 붙여넣어 보세요:")
242+
print(f" {auth_url}\n")
243+
print(" 또는 다시 시도: dartlab.setup('chatgpt')\n")
237244

238245

239246
def _setup_codex(info: dict) -> None:

src/dartlab/company.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ def Company(codeOrName: str) -> CompanyProtocol:
4343

4444
normalized = codeOrName.strip()
4545
if not normalized:
46-
raise ValueError("종목코드 또는 회사명을 입력해 주세요.")
46+
raise ValueError(
47+
"종목코드 또는 회사명을 입력해 주세요.\n"
48+
" 예: Company('삼성전자') 또는 Company('005930')\n"
49+
" 검색: dartlab.search('삼성')"
50+
)
4751

4852
# canHandle 체인: priority 순으로 시도
4953
firstError: Exception | None = None
@@ -70,4 +74,8 @@ def Company(codeOrName: str) -> CompanyProtocol:
7074
continue
7175

7276
cause = f" (원인: {firstError})" if firstError else ""
73-
raise ValueError(f"'{codeOrName}'을(를) 찾을 수 없습니다{cause}. dartlab.search('{codeOrName}')로 검색해 보세요.")
77+
raise ValueError(
78+
f"'{codeOrName}'을(를) 찾을 수 없습니다{cause}.\n"
79+
f" 검색: dartlab.search('{codeOrName}')\n"
80+
" 전체 목록: dartlab.listing()"
81+
)

src/dartlab/core/ai/guide.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ def no_provider_message() -> str:
163163
' 6. OpenAI API — dartlab.setup("openai")',
164164
' 7. 로컬 LLM — dartlab.setup("ollama")',
165165
"",
166-
' 설정 후: dartlab.ask("삼성전자 재무건전성 분석해줘")',
166+
" 설정 후 다시 실행하세요:",
167+
' dartlab.ask("삼성전자 재무건전성 분석해줘")',
167168
"",
168169
]
169170
return "\n".join(lines)

0 commit comments

Comments
 (0)