stock-common

한국 주식 분석 마이크로서비스 플랫폼의 공유 라이브러리. 모든 백엔드 서비스(stock-dart-collector, stock-kis-collector, stock-screener 등)가 이 패키지에 의존합니다.

주요 기능

  • 데이터 모델: Pydantic v2 기반 도메인 모델 (Stock, DailyPrice, Valuation, Financial, Screening 등)
  • 데이터베이스: PostgreSQL (asyncpg) + MongoDB (motor) 커넥션 풀 관리
  • Redis Streams: 서비스 간 비동기 메시지 큐 (publish/consume/ack)
  • API 팩토리: FastAPI 앱 생성 (/health, /streams 엔드포인트 자동 포함)
  • Collector 베이스 클래스: Rate limiting, 자동 재시도, HTTP 세션 관리
  • 설정 관리: pydantic-settings 기반 환경변수 로딩

설치

pip install -e .

다른 서비스에서 의존성으로 사용:

# pyproject.toml
[project]
dependencies = ["stock-common"]

Docker 빌드 시:

COPY stock-common/ /tmp/stock-common/
RUN pip install --no-cache-dir /tmp/stock-common/

모듈 구조

src/stock_common/
├── __init__.py
├── config.py              # Settings (pydantic-settings) - 환경변수 관리
├── logging_config.py      # structlog 기반 로깅 설정
├── api_base.py            # FastAPI 앱 팩토리 (create_app)
├── collector_base.py      # BaseCollector ABC (rate limit, retry)
├── database/
│   ├── __init__.py
│   ├── postgres.py        # asyncpg 커넥션 풀 (get_pg_pool)
│   └── mongodb.py         # motor 클라이언트 (get_mongo_database)
├── queue/
│   ├── __init__.py
│   ├── redis_client.py    # Redis 싱글턴 (get_redis)
│   └── streams.py         # publish / consume / ack
└── models/
    ├── __init__.py
    ├── stock.py           # Stock, Market
    ├── price.py           # DailyPrice
    ├── valuation.py       # Valuation (PER, PBR, ROE...)
    ├── financial.py       # Financial, PeriodType
    ├── screening.py       # ScreeningResult, ScreeningStrategy
    ├── analysis.py        # LLMAnalysis, Recommendation
    ├── disclosure.py      # Disclosure, Sentiment
    └── news.py            # News

핵심 컴포넌트

Settings (config.py)

pydantic-settings로 환경변수를 자동 로딩합니다. .env 파일도 지원합니다.

from stock_common.config import settings

# 데이터베이스
settings.postgres_dsn     # postgresql://stock:stock@localhost:5432/stockdb
settings.mongodb_uri      # mongodb://localhost:27017
settings.redis_url        # redis://localhost:6379/0

# API 키
settings.dart_api_key
settings.kis_app_key
settings.anthropic_api_key

# Rate Limits
settings.dart_rate_limit  # 10.0 req/s
settings.kis_rate_limit   # 20.0 req/s

API 팩토리 (api_base.py)

모든 서비스는 create_app()으로 FastAPI 인스턴스를 생성합니다. 자동으로 포함되는 엔드포인트:

엔드포인트 설명
GET /health 서비스 상태, Redis 연결, uptime
GET /streams 관련 Redis Stream 큐 길이
from stock_common.api_base import create_app

app = create_app(
    title="stock-dart-collector",
    streams=["queue:trigger-dart", "queue:raw-financials"],
)

# 서비스별 엔드포인트 추가
@app.post("/collect/financials")
async def collect_financials(...):
    ...

BaseCollector (collector_base.py)

HTTP API 수집기의 공통 패턴:

  • Rate Limiting: aiolimiter.AsyncLimiter로 초당 요청 수 제한
  • 자동 재시도: tenacity로 최대 3회, 지수 백오프 (1~30초)
  • 429 처리: Retry-After 헤더 존중
  • 세션 관리: async with 컨텍스트 매니저
from stock_common.collector_base import BaseCollector

class DARTCollector(BaseCollector):
    def __init__(self):
        super().__init__(rate_limit=10.0, timeout=30)

    async def collect(self, **kwargs):
        data = await self._request("GET", url, params=params)
        binary = await self._download_binary(url)

Redis Streams (queue/streams.py)

서비스 간 비동기 메시지 전달:

from stock_common.queue import publish, consume, ack

# 메시지 발행
msg_id = await publish("queue:trigger-dart", {"type": "financials", "stock_codes": ["005930"]})

# 메시지 소비 (consumer group)
messages = await consume("queue:trigger-dart", "dart-collectors", "worker-1", count=10, block=5000)
for msg in messages:
    process(msg.data)
    await ack("queue:trigger-dart", "dart-collectors", msg.message_id)

Database

from stock_common.database import get_pg_pool, get_mongo_database

# PostgreSQL (asyncpg)
pool = await get_pg_pool()
async with pool.acquire() as conn:
    rows = await conn.fetch("SELECT * FROM stock WHERE is_active = true")

# MongoDB (motor)
db = get_mongo_database()
cursor = db.llm_analysis.find({"stock_code": "005930"})
docs = await cursor.to_list(10)

의존성

패키지 용도
pydantic >= 2.0 데이터 모델
pydantic-settings >= 2.0 환경변수 설정
asyncpg >= 0.29 PostgreSQL 비동기 드라이버
motor >= 3.3 MongoDB 비동기 드라이버
redis >= 5.0 Redis 클라이언트
fastapi >= 0.115 REST API 프레임워크
uvicorn >= 0.34 ASGI 서버
aiohttp >= 3.9 비동기 HTTP 클라이언트
aiolimiter >= 1.1 Rate limiting
tenacity >= 8.2 재시도 로직
structlog >= 24.0 구조화된 로깅

요구사항

  • Python >= 3.12
  • 빌드: hatchling
Description
No description provided
Readme 40 KiB
Languages
Python 100%