Skip to content

Commit 9c2f36c

Browse files
committed
노출 개선: HF Spaces Docker + llms.txt 강화 + Try Online CTA
- Dockerfile + __main__.py + hfPreload.py: HuggingFace Spaces 데모 배포 준비 - .github/workflows/hfSpaces.yml: 릴리즈 시 HF Spaces 자동 배포 - pyproject.toml: URLs에 Documentation, Demo, Changelog 추가 - generateSpec.py: llms.txt를 영문 중심으로 대폭 강화 (AI 크롤러 최적화) - Hero.svelte: Try Online 버튼 1순위 배치 - brand.ts: spaces URL 추가
1 parent 7f71bd6 commit 9c2f36c

10 files changed

Lines changed: 264 additions & 39 deletions

File tree

.dockerignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.git
2+
.github
3+
.venv
4+
.venv-wsl
5+
__pycache__
6+
*.pyc
7+
.pytest_cache
8+
.ruff_cache
9+
experiments
10+
notebooks
11+
tests
12+
docs
13+
blog
14+
landing
15+
data
16+
.claude
17+
*.egg-info

.github/workflows/hfSpaces.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Deploy to HuggingFace Spaces
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
deploy:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Push to HuggingFace Spaces
18+
env:
19+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
20+
run: |
21+
git clone --depth 1 https://user:${HF_TOKEN}@huggingface.co/spaces/eddmpython/dartlab hf-space
22+
23+
# Dockerfile + 필요 파일만 복사
24+
cp Dockerfile hf-space/
25+
cp .dockerignore hf-space/
26+
mkdir -p hf-space/scripts
27+
cp scripts/hfPreload.py hf-space/scripts/
28+
29+
# HF Spaces README (앱 설정)
30+
cat > hf-space/README.md << 'EOF'
31+
---
32+
title: DartLab
33+
emoji: 📊
34+
colorFrom: red
35+
colorTo: orange
36+
sdk: docker
37+
app_port: 7860
38+
pinned: true
39+
license: mit
40+
short_description: "DART + EDGAR disclosure analysis — try without install"
41+
---
42+
EOF
43+
44+
cd hf-space
45+
git config user.name "github-actions[bot]"
46+
git config user.email "github-actions[bot]@users.noreply.github.com"
47+
git add -A
48+
git diff --cached --quiet || (git commit -m "sync from $(git -C .. describe --tags --always 2>/dev/null || echo 'latest')" && git push)

Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# HuggingFace Spaces — DartLab 데모
2+
# CPU free tier (16GB RAM), port 7860
3+
4+
FROM python:3.12-slim
5+
6+
WORKDIR /app
7+
8+
# 시스템 의존성
9+
RUN apt-get update && apt-get install -y --no-install-recommends \
10+
build-essential \
11+
&& rm -rf /var/lib/apt/lists/*
12+
13+
# dartlab 설치
14+
RUN pip install --no-cache-dir dartlab
15+
16+
# 샘플 데이터 프리로드 스크립트
17+
COPY scripts/hfPreload.py scripts/hfPreload.py
18+
RUN python scripts/hfPreload.py
19+
20+
# HF Spaces 기본 포트
21+
EXPOSE 7860
22+
23+
# 서버 실행
24+
CMD ["python", "-m", "dartlab.server"]

landing/src/lib/brand.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const brand = {
99
pypi: 'https://pypi.org/project/dartlab/',
1010
coffee: 'https://buymeacoffee.com/eddmpython',
1111
desktop: 'https://github.com/eddmpython/dartlab-desktop/releases/latest/download/DartLab.exe',
12+
spaces: 'https://huggingface.co/spaces/eddmpython/dartlab',
1213
author: 'eddmpython',
1314

1415
hfRepo: 'eddmpython/dartlab-data',

landing/src/lib/components/sections/Hero.svelte

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { brand } from '$lib/brand';
44
import { Button } from '$lib/components/ui/button';
55
import { Badge } from '$lib/components/ui/badge';
6-
import { Download } from 'lucide-svelte';
6+
import { Download, Globe } from 'lucide-svelte';
77
</script>
88

99
<section class="relative pt-32 pb-20 px-6 overflow-hidden">
@@ -45,13 +45,16 @@
4545
</p>
4646

4747
<div class="flex flex-wrap items-center justify-center gap-3 mb-16">
48-
<Button href={brand.desktop}>
48+
<Button href={brand.spaces}>
49+
<Globe class="w-4 h-4" />
50+
Try Online
51+
</Button>
52+
<Button variant="secondary" href={brand.desktop}>
4953
<Download class="w-4 h-4" />
5054
Windows Download
5155
</Button>
5256
<Button variant="secondary" href="#install">pip / uv Install</Button>
5357
<Button variant="secondary" href="{base}/docs/">Docs</Button>
54-
<Button variant="secondary" href="{base}/docs/getting-started/quickstart">Quick Start</Button>
5558
</div>
5659

5760
<div class="grid grid-cols-2 md:grid-cols-4 gap-3 max-w-3xl mx-auto">

landing/static/llms.txt

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,55 @@
1-
# dartlab
1+
# DartLab — DART + EDGAR Disclosure Analysis Python Library
22

3-
> DART 전자공시 데이터를 활용한 한국 상장기업 재무 분석 Python 라이브러리.
3+
> Turn Korean DART and US SEC EDGAR filings into one structured company map.
4+
> 한국 DART 전자공시와 미국 SEC EDGAR 공시를 하나의 회사 맵으로 바꾸는 Python 라이브러리.
45

5-
## 설치
6+
DartLab parses corporate disclosure filings — annual reports, 10-K, 10-Q — into structured,
7+
comparable data. Financial statements (BS/IS/CF), 47 financial ratios, 7-area insight grades,
8+
narrative text, and structured reports are all accessible with a single stock code.
9+
Covers 2,700+ Korean listed companies and 970+ US companies.
610

7-
```
11+
## Install
12+
13+
```bash
814
pip install dartlab
15+
# or
16+
uv add dartlab
917
```
1018

11-
## 빠른 시작
19+
## Quick Start
1220

1321
```python
1422
import dartlab
1523

16-
c = dartlab.Company("005930")
17-
c.index # 회사 구조 인덱스
18-
c.show("BS") # topic payload 보기
19-
c.trace("dividend") # source 추적
24+
# Korean company (DART)
25+
c = dartlab.Company("005930") # Samsung Electronics
26+
c.index # company structure index
27+
c.show("BS") # balance sheet
28+
c.show("executiveCompensation") # topic payload
29+
c.trace("dividend") # source provenance
30+
c.ratios # 47 financial ratios
31+
c.insights # 7-area A~F grades
32+
33+
# US company (EDGAR)
34+
us = dartlab.Company("AAPL") # Apple Inc.
35+
us.BS # balance sheet
36+
us.ratios # financial ratios
37+
us.sections # 10-K sections map
2038
```
2139

22-
## 주요 기능
40+
## Key Features
41+
42+
- **Sections-first architecture**: Every company becomes a topic × period DataFrame
43+
- **Dual market**: DART (Korea) + EDGAR (US) with identical interface
44+
- **One stock code**: `dartlab.Company('005930')` or `dartlab.Company('AAPL')`
45+
- **Financial statements**: BS, IS, CF, CIS, SCE — XBRL-normalized, quarterly standalone
46+
- **47 financial ratios**: ROE, ROA, operating margin, debt ratio, PER, PBR, FCF, etc.
47+
- **7-area insight grades**: Performance, profitability, stability, cash flow, governance, risk, opportunity
48+
- **AI analysis**: `dartlab ask '삼성전자 분석해줘'` — natural language company analysis
49+
- **MCP server**: Expose company data as MCP tools for Claude Desktop, ChatGPT, Cursor
50+
- **329 topics per company**: From dividend policy to segment breakdown
51+
52+
## Data Modules
2353

2454
### 시계열 재무제표
2555

@@ -106,15 +136,19 @@ c.trace("dividend") # source 추적
106136
- **sector** (섹터분류): WICS 11대 섹터 분류. 대분류/중분류 + 섹터별 파라미터.
107137
- **rank** (시장순위): 전체 시장 및 섹터 내 매출/자산/성장률 순위.
108138

109-
## 분석 엔진
139+
## Analysis Engines
110140

111-
- **섹터 분류**: WICS 11섹터 자동 분류 (오버라이드 → 키워드 → KSIC 3단계)
112-
- **인사이트 등급**: 7영역 A~F 등급 (실적, 수익성, 건전성, 현금흐름, 지배구조, 리스크, 기회)
113-
- **시장 순위**: 매출/자산/성장률 전체+섹터내 순위
114-
- **재무비율**: ROE, ROA, 영업이익률, 부채비율, PER, PBR, FCF 등 자동 계산
141+
- **Sector classification**: WICS 11 sectors (override → keyword → KSIC 3-stage)
142+
- **Insight grades**: 7-area A~F grades (performance, profitability, stability, cash flow, governance, risk, opportunity)
143+
- **Market rank**: Revenue/assets/growth ranking — overall + within sector
144+
- **Financial ratios**: ROE, ROA, operating margin, debt ratio, PER, PBR, FCF — auto-calculated
145+
- **Supply chain**: Disclosed supplier/customer relationship mapping
146+
- **ESG**: ESG disclosure extraction and scoring
147+
- **Event study**: Abnormal return around disclosure dates
115148

116-
## 링크
149+
## Links
117150

118-
- 문서: https://eddmpython.github.io/dartlab/docs/
151+
- Documentation: https://eddmpython.github.io/dartlab/docs/
119152
- GitHub: https://github.com/eddmpython/dartlab
120153
- PyPI: https://pypi.org/project/dartlab/
154+
- Demo: https://huggingface.co/spaces/eddmpython/dartlab

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,12 @@ dartlab = "dartlab.cli.main:main"
124124
[project.entry-points."dartlab.plugins"]
125125

126126
[project.urls]
127-
Homepage = "https://github.com/eddmpython/dartlab"
127+
Homepage = "https://eddmpython.github.io/dartlab/"
128128
Repository = "https://github.com/eddmpython/dartlab"
129+
Documentation = "https://eddmpython.github.io/dartlab/docs/"
129130
Issues = "https://github.com/eddmpython/dartlab/issues"
131+
Changelog = "https://eddmpython.github.io/dartlab/docs/changelog"
132+
Demo = "https://huggingface.co/spaces/eddmpython/dartlab"
130133

131134
[build-system]
132135
requires = ["hatchling"]

scripts/generateSpec.py

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import sys
1818
import textwrap
1919
from pathlib import Path
20-
from typing import Optional, get_type_hints
20+
from typing import get_type_hints
2121

2222
ROOT = Path(__file__).resolve().parent.parent
2323
sys.path.insert(0, str(ROOT / "src"))
@@ -256,28 +256,58 @@ def generateApiSpec() -> str:
256256
def generateLlmsTxt() -> str:
257257
"""llms.txt 생성 — AI 크롤러용."""
258258
lines = [
259-
"# dartlab",
259+
"# DartLab — DART + EDGAR Disclosure Analysis Python Library",
260260
"",
261-
"> DART 전자공시 데이터를 활용한 한국 상장기업 재무 분석 Python 라이브러리.",
261+
"> Turn Korean DART and US SEC EDGAR filings into one structured company map.",
262+
"> 한국 DART 전자공시와 미국 SEC EDGAR 공시를 하나의 회사 맵으로 바꾸는 Python 라이브러리.",
262263
"",
263-
"## 설치",
264+
"DartLab parses corporate disclosure filings — annual reports, 10-K, 10-Q — into structured,",
265+
"comparable data. Financial statements (BS/IS/CF), 47 financial ratios, 7-area insight grades,",
266+
"narrative text, and structured reports are all accessible with a single stock code.",
267+
"Covers 2,700+ Korean listed companies and 970+ US companies.",
264268
"",
265-
"```",
269+
"## Install",
270+
"",
271+
"```bash",
266272
"pip install dartlab",
273+
"# or",
274+
"uv add dartlab",
267275
"```",
268276
"",
269-
"## 빠른 시작",
277+
"## Quick Start",
270278
"",
271279
"```python",
272280
"import dartlab",
273281
"",
274-
'c = dartlab.Company("005930")',
275-
"c.index # 회사 구조 인덱스",
276-
'c.show("BS") # topic payload 보기',
277-
'c.trace("dividend") # source 추적',
282+
"# Korean company (DART)",
283+
'c = dartlab.Company("005930") # Samsung Electronics',
284+
"c.index # company structure index",
285+
'c.show("BS") # balance sheet',
286+
'c.show("executiveCompensation") # topic payload',
287+
'c.trace("dividend") # source provenance',
288+
"c.ratios # 47 financial ratios",
289+
"c.insights # 7-area A~F grades",
290+
"",
291+
"# US company (EDGAR)",
292+
'us = dartlab.Company("AAPL") # Apple Inc.',
293+
"us.BS # balance sheet",
294+
"us.ratios # financial ratios",
295+
"us.sections # 10-K sections map",
278296
"```",
279297
"",
280-
"## 주요 기능",
298+
"## Key Features",
299+
"",
300+
"- **Sections-first architecture**: Every company becomes a topic × period DataFrame",
301+
"- **Dual market**: DART (Korea) + EDGAR (US) with identical interface",
302+
"- **One stock code**: `dartlab.Company('005930')` or `dartlab.Company('AAPL')`",
303+
"- **Financial statements**: BS, IS, CF, CIS, SCE — XBRL-normalized, quarterly standalone",
304+
"- **47 financial ratios**: ROE, ROA, operating margin, debt ratio, PER, PBR, FCF, etc.",
305+
"- **7-area insight grades**: Performance, profitability, stability, cash flow, governance, risk, opportunity",
306+
"- **AI analysis**: `dartlab ask '삼성전자 분석해줘'` — natural language company analysis",
307+
"- **MCP server**: Expose company data as MCP tools for Claude Desktop, ChatGPT, Cursor",
308+
"- **329 topics per company**: From dividend policy to segment breakdown",
309+
"",
310+
"## Data Modules",
281311
"",
282312
]
283313

@@ -291,18 +321,22 @@ def generateLlmsTxt() -> str:
291321

292322
lines.extend(
293323
[
294-
"## 분석 엔진",
324+
"## Analysis Engines",
295325
"",
296-
"- **섹터 분류**: WICS 11섹터 자동 분류 (오버라이드 → 키워드 → KSIC 3단계)",
297-
"- **인사이트 등급**: 7영역 A~F 등급 (실적, 수익성, 건전성, 현금흐름, 지배구조, 리스크, 기회)",
298-
"- **시장 순위**: 매출/자산/성장률 전체+섹터내 순위",
299-
"- **재무비율**: ROE, ROA, 영업이익률, 부채비율, PER, PBR, FCF 등 자동 계산",
326+
"- **Sector classification**: WICS 11 sectors (override → keyword → KSIC 3-stage)",
327+
"- **Insight grades**: 7-area A~F grades (performance, profitability, stability, cash flow, governance, risk, opportunity)",
328+
"- **Market rank**: Revenue/assets/growth ranking — overall + within sector",
329+
"- **Financial ratios**: ROE, ROA, operating margin, debt ratio, PER, PBR, FCF — auto-calculated",
330+
"- **Supply chain**: Disclosed supplier/customer relationship mapping",
331+
"- **ESG**: ESG disclosure extraction and scoring",
332+
"- **Event study**: Abnormal return around disclosure dates",
300333
"",
301-
"## 링크",
334+
"## Links",
302335
"",
303-
"- 문서: https://eddmpython.github.io/dartlab/docs/",
336+
"- Documentation: https://eddmpython.github.io/dartlab/docs/",
304337
"- GitHub: https://github.com/eddmpython/dartlab",
305338
"- PyPI: https://pypi.org/project/dartlab/",
339+
"- Demo: https://huggingface.co/spaces/eddmpython/dartlab",
306340
"",
307341
]
308342
)

scripts/hfPreload.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""HuggingFace Spaces Docker 빌드 시 샘플 데이터 프리로드.
2+
3+
삼성전자(005930)와 AAPL 데이터를 미리 다운로드하여
4+
cold start 시간을 줄인다.
5+
"""
6+
7+
from __future__ import annotations
8+
9+
import os
10+
import sys
11+
12+
# Docker 빌드 환경에서는 dartlab이 이미 pip install된 상태
13+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
14+
15+
SAMPLES = ["005930", "AAPL"]
16+
17+
18+
def main() -> None:
19+
from dartlab.core.dataLoader import download
20+
21+
for code in SAMPLES:
22+
print(f" preloading {code}...")
23+
try:
24+
download(code)
25+
print(f" {code} done")
26+
except Exception as e: # noqa: BLE001
27+
print(f" {code} skipped: {e}")
28+
29+
30+
if __name__ == "__main__":
31+
main()

0 commit comments

Comments
 (0)