Conversation
📝 WalkthroughWalkthrough뉴스 칼럼 관리 기능을 확장하는 변경사항입니다. 정확한 뉴스 매칭을 위해 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
regenerate_all_columns.py (2)
9-9: BASE_URL을 설정 가능하도록 개선 권장현재
BASE_URL이 하드코딩되어 있어 프로덕션 환경이나 다른 환경에서 실행할 때 코드 수정이 필요합니다. 환경 변수나 CLI 인자로 받도록 개선하는 것을 권장합니다.다음과 같이 개선할 수 있습니다:
+import os + -BASE_URL = "http://localhost:8000" +BASE_URL = os.getenv("API_BASE_URL", "http://localhost:8000")
27-27: 불필요한 f-string 접두사 제거Line 27의 문자열에 플레이스홀더가 없으므로
f접두사가 불필요합니다.- print(f"✅ 칼럼 재생성 완료:") + print("✅ 칼럼 재생성 완료:")app/services/news/news_db_repository.py (1)
164-166: 에러 발생 시 0 반환이 실패를 숨김에러가 발생했을 때 0을 반환하면, 호출자가 삭제가 실패했는지 아니면 삭제할 행이 없었는지 구분할 수 없습니다. 예외를 재발생시키거나 별도의 에러 표시를 반환하는 것을 고려해보세요.
다음과 같이 개선할 수 있습니다:
async def delete_all_columns(self) -> int: try: query = "DELETE FROM news_columns" result = await self.db_service.execute(query) deleted_count = int(result.split()[-1]) if result else 0 logger.info("all_columns_deleted", deleted_count=deleted_count) return deleted_count except Exception as e: - logger.error("delete_all_columns_failed", error=str(e)) - return 0 + logger.exception("delete_all_columns_failed", error=str(e)) + raiseapp/routers/news.py (1)
271-273: 요청마다 서비스 인스턴스 생성 비효율각 요청마다 새로운
MassiveService인스턴스를 생성하는 것은 비효율적입니다. 모듈 레벨의 전역 서비스 인스턴스를 사용하거나init_services를 통해 초기화하는 것을 권장합니다.다음과 같이 개선할 수 있습니다:
+# 모듈 상단의 전역 서비스 인스턴스 섹션에 추가 +massive_service: MassiveService = None +# init_services 함수에 추가 def init_services( db: DatabaseService, liquid_stocks: LiquidStocksService, correlation: CorrelationService, news_column: NewsColumnService, - rate_limiter: Limiter + rate_limiter: Limiter, + massive: MassiveService ): - global db_service, liquid_stocks_service, correlation_service, news_column_service, limiter + global db_service, liquid_stocks_service, correlation_service, news_column_service, limiter, massive_service + massive_service = massive # ... 기존 코드 ... # 엔드포인트에서 async def get_massive_news_exact(...): try: - from app.services.external import MassiveService - - massive_service = MassiveService() - + if not massive_service: + raise Exception("Massive 서비스가 초기화되지 않았습니다.") + news_list = await massive_service.get_news_exact_match(
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
app/config.py(2 hunks)app/routers/news.py(5 hunks)app/services/external/massive_service.py(1 hunks)app/services/news/chatgpt_client.py(2 hunks)app/services/news/news_column_service.py(2 hunks)app/services/news/news_db_repository.py(1 hunks)regenerate_all_columns.py(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
app/services/news/news_db_repository.py (3)
regenerate_all_columns.py (1)
delete_all_columns(11-18)app/routers/news.py (1)
delete_all_columns(58-85)app/services/database/db_service.py (1)
execute(41-43)
app/routers/news.py (2)
app/services/news/news_db_repository.py (1)
delete_all_columns(157-166)app/services/external/massive_service.py (1)
get_news_exact_match(306-402)
app/services/news/news_column_service.py (1)
app/services/external/massive_service.py (1)
get_news_exact_match(306-402)
app/services/news/chatgpt_client.py (1)
app/models/column_schema.py (1)
ColumnContent(16-20)
regenerate_all_columns.py (2)
app/services/news/news_db_repository.py (1)
delete_all_columns(157-166)app/services/news/news_column_service.py (1)
generate_all_columns(38-83)
🪛 Ruff (0.14.4)
app/services/news/news_db_repository.py
163-163: Consider moving this statement to an else block
(TRY300)
164-164: Do not catch blind exception: Exception
(BLE001)
165-165: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
app/routers/news.py
70-70: Abstract raise to an inner function
(TRY301)
70-70: Create your own exception
(TRY002)
70-70: Avoid specifying long messages outside the exception class
(TRY003)
74-78: Consider moving this statement to an else block
(TRY300)
80-80: Do not catch blind exception: Exception
(BLE001)
81-81: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
82-85: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
84-84: Use explicit conversion flag
Replace with conversion flag
(RUF010)
296-296: Do not catch blind exception: Exception
(BLE001)
297-297: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
298-301: Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
(B904)
300-300: Use explicit conversion flag
Replace with conversion flag
(RUF010)
396-396: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
regenerate_all_columns.py
27-27: f-string without any placeholders
Remove extraneous f prefix
(F541)
app/services/external/massive_service.py
388-393: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
395-395: Do not catch blind exception: Exception
(BLE001)
396-401: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test-and-build
🔇 Additional comments (10)
app/config.py (1)
2-2: LGTM!Optional 타입 임포트 추가 및 버전 업데이트가 정확합니다. 변경사항이 PR의 다른 파일들(source_ticker 파라미터 추가)과 일관성 있게 연동됩니다.
Also applies to: 44-44
app/services/news/chatgpt_client.py (2)
84-112: LGTM!
source_ticker파라미터 추가와 조건부 프롬프트 생성 로직이 잘 구현되었습니다. 상관종목의 뉴스를 사용하는 경우와 직접 뉴스를 사용하는 경우를 명확히 구분하여 ChatGPT에 컨텍스트를 제공하는 것이 적절합니다.
115-123: LGTM!
generate_column메서드에source_ticker파라미터가 올바르게 추가되고 프롬프트 생성에 전달됩니다.app/services/news/news_column_service.py (2)
141-146: LGTM!Pass 1에서
get_news_exact_match로 변경하여 정확히 일치하는 뉴스만 검색하도록 개선되었습니다. PR 목표에 부합합니다.
199-203: LGTM!
source_ticker파라미터가 Pass 1과 Pass 2에서 일관되게 전달되고, Line 382에서 동일한 티커인 경우 None으로 설정하여 중복 정보를 방지하는 로직이 적절합니다.Also applies to: 362-363, 382-382
app/services/external/massive_service.py (1)
305-402: LGTM!
get_news_exact_match메서드가 잘 구현되었습니다. 주요 특징:
- tickers[0]이 검색 종목과 정확히 일치하는 뉴스만 필터링
- 필터링을 위해 3배 많은 결과를 가져온 후 제한 (Line 324)
- 429 Rate Limit 에러 적절히 처리
- 정확한 매칭 결과 로깅
PR의 핵심 기능이 올바르게 구현되었습니다.
app/routers/news.py (3)
53-85: LGTM!전체 칼럼 삭제 엔드포인트가 잘 구현되었습니다. 관리자용 기능으로 적절하며, 에러 처리와 로깅이 포함되어 있습니다.
246-301: LGTM!Massive API 뉴스 조회 엔드포인트가 잘 구현되었습니다. 정확한 매칭 기능을 테스트하기 위한 유용한 엔드포인트입니다. (단, 서비스 인스턴스 생성 방식은 별도 코멘트를 참조하세요)
386-393: LGTM!칼럼 추천 플로우의 로깅이 개선되어 디버깅과 모니터링이 더욱 용이해졌습니다.
Also applies to: 415-419
app/services/news/news_db_repository.py (1)
157-166: 파싱 로직은 asyncpg 명세에 부합하며 정상 작동검증 결과,
db_service.execute()는 asyncpg의conn.execute()를 직접 위임하며, DELETE 쿼리에 대해"DELETE <n>"형식의 문자열을 반환합니다. 예:"DELETE 5". 현재 코드의result.split()[-1]파싱은 이 형식에서 숫자를 올바르게 추출하고 있습니다.결과가 없는 경우를 처리하는 조건부 검사(
if result else 0)도 적절합니다. 코드는 asyncpg의 문서화된 동작과 일치하며 정상 작동합니다.
| from pydantic import BaseModel | ||
| import structlog | ||
| import random | ||
| from datetime import datetime, timedelta |
There was a problem hiding this comment.
🧩 Analysis chain
미사용 임포트 확인 필요
datetime와 timedelta 임포트가 추가되었으나 현재 코드에서 사용되지 않는 것으로 보입니다.
다음 스크립트로 사용 여부를 확인해주세요:
사용되지 않는다면 임포트를 제거하세요.
🏁 Script executed:
#!/bin/bash
# Description: Check if datetime and timedelta are used in this file
# Search for datetime usage
rg -n "\bdatetime\b" app/routers/news.py
# Search for timedelta usage
rg -n "\btimedelta\b" app/routers/news.pyLength of output: 85
미사용 임포트 제거 필요
검증 결과, datetime과 timedelta는 파일 내에서 사용되지 않고 있습니다. 임포트 검색에서 line 7의 임포트 문만 반환되었으며, 다른 라인에서의 사용은 없습니다.
app/routers/news.py line 7에서 미사용 임포트를 제거하세요:
from datetime import datetime, timedelta🤖 Prompt for AI Agents
In app/routers/news.py around line 7, the imports "from datetime import
datetime, timedelta" are unused; remove that import line to clean up dead code
and avoid linter warnings—simply delete the "from datetime import datetime,
timedelta" statement and run tests/lint to confirm no other references remain.
🎯 목적
정확한 뉴스 매칭 및 상관종목 칼럼 생성 개선을 위해 칼럼 추천 로직을 수정함.
📝 주요 변경사항
🔗 관련 이슈/PR
🔄 버전 검토
🧪 테스트
📋 체크리스트
📝 커밋 메시지 규칙
featfixrefactorstyledocstestchoreperfciconfig예시:
feat: 뉴스 칼럼 추천 API 추가Summary by CodeRabbit
릴리즈 노트
새로운 기능
Chores