Files
yfinance-fork/cli/yfin/commands/industry.py
T
goldyard 057bc4493e Add yfin CLI + tool catalog + CLAUDE.md
Wraps the entire yfinance public API behind a single binary `yfin` with
51 subcommands across 13 namespaces (ticker, download, tickers, search,
lookup, market, sector, industry, calendars, screen, live, auth, config).
Output renders as Rich tables on TTY, JSON when piped; --format / --out
support table | json | ndjson | csv | tsv | parquet | yaml.

Highlights:
- 1857 LOC across 18 Python files under cli/yfin/
- Typer + Rich, packaged via hatchling + uv
- Install globally: `cd cli && uv tool install -e .`
- ~/.yfin/config.toml for persistent proxy/cookies/locale defaults
- Friendly YFRateLimitError handler (exit 2, no Rich traceback)
- Validated end-to-end with 33 live tests against Yahoo from a
  residential exit (AAPL, MSFT, NVDA, options, screens, calendars,
  financials, news, holders, parquet round-trip)

yfinance-tools.yaml is the single source of truth:
- tools (49)       — every public yfinance entry point with parameters
- cli (13 groups)  — exact CLI invocations, mapped back to tool names
- outputSchemas (27) — actual return shapes captured from live calls
- learnings (19)   — IP rate-limit, crumb handshake, Typer gotchas,
                     screen-build wrapping rules, upstream stubs, etc.

CLAUDE.md documents the upstream codebase layout for future agents.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:36:56 +08:00

51 lines
1.5 KiB
Python

"""`yfin industry ...` — industry aggregates."""
from __future__ import annotations
from enum import Enum
from typing import Optional
import typer
import yfinance as yf
from .._shared import render_via_state
class Attribute(str, Enum):
overview = "overview"
top_companies = "top_companies"
top_performing_companies = "top_performing_companies"
top_growth_companies = "top_growth_companies"
research_reports = "research_reports"
sector_key = "sector_key"
sector_name = "sector_name"
app = typer.Typer(no_args_is_help=True, help="Industry aggregates.")
@app.command("info")
def industry(
ctx: typer.Context,
key: str = typer.Argument(..., help='Industry slug (e.g. "software-infrastructure").'),
attribute: Optional[Attribute] = typer.Option(None, "--attribute"),
region: str = typer.Option("US", "--region"),
):
"""Industry aggregates (top performing / growth companies)."""
i = yf.Industry(key, region=region)
if attribute is None:
out = {
"key": i.key,
"name": i.name,
"symbol": i.symbol,
"sector_key": i.sector_key,
"sector_name": i.sector_name,
"overview": i.overview,
"top_companies": i.top_companies,
"top_performing_companies": i.top_performing_companies,
"top_growth_companies": i.top_growth_companies,
"research_reports": i.research_reports,
}
else:
out = getattr(i, attribute.value)
render_via_state(ctx, out)