spb/company-atlas
Public
Python 66.3%
TypeScript 22.7%
JavaScript 8.6%
HTML 1.4%
CSS 0.7%
1"""Industry Atlas: `/industries`, `/industries/{slug}` (cached 300 s)."""2from __future__ import annotations34from typing import Any56from fastapi import APIRouter, HTTPException, Request78from companyatlas.api import aggregates as agg9from companyatlas.api import queries as q10from companyatlas.api import serializers as ser11from companyatlas.api.common import cached, cached_response12from companyatlas.db import connection, fetch_all, fetch_one1314ORDER = 2015router = APIRouter(prefix="/api/v1", tags=["industries"])161718@router.get("/industries", summary="Living index per industry")19async def industries(request: Request) -> Any:20 return cached_response(request, {"items": await agg.cached_industry_rows()}, 300)212223@router.get("/industries/{slug}", summary="Industry detail")24async def industry_detail(slug: str, request: Request) -> Any:25 slug = slug.strip().lower()[:80]2627 async def produce() -> dict[str, Any] | None:28 rows = await agg.cached_industry_rows()29 row = next((r for r in rows if r["slug"] == slug), None)30 async with connection() as conn:31 if row is None:32 tax = await fetch_one(conn, "select slug, name, parent_slug, description from industries where slug = :s", s=slug)33 if tax is None:34 return None35 row = {**tax, "companies": 0, "events_7d": 0, "events_30d": 0, "hiring_momentum_30d": None, "activity_score": None, "ai_adoption": None,36 "top_event_types": []}37 where, params = q.company_filters(industry=slug, status="ACTIVE")38 ids, _total = await q.company_page_ids(conn, where, params, sort="activity", limit=24)39 companies = [ser.company_card(r) for r in await q.fetch_cards_by_ids(conn, ids, sparkline=True)]40 events = await agg.live_events(conn, 20, industry=slug)41 d30 = q.days_ago(30)42 h = await fetch_one(conn, "select count(*) filter (where j.status = 'open') as open, count(*) filter (where j.first_seen_at >= :d) as new_30d, "43 "count(*) filter (where j.removed_at >= :d) as removed_30d from jobs j join companies c on c.id = j.company_id "44 "where cast(:s as text) = any(c.industries)", d=d30, s=slug) or {}45 series = await fetch_all(conn, "select ms.day, avg(ms.value) as value, avg(ms.confidence) as confidence from metric_series ms "46 "join companies c on c.id = ms.company_id where ms.metric = 'activity_score' and cast(:s as text) = any(c.industries) "47 "and ms.day >= :d group by ms.day order by ms.day", s=slug, d=q.days_ago(90).date())48 countries = await fetch_all(conn, "select country, count(*) as companies from companies c where cast(:s as text) = any(c.industries) and "49 "country is not null and status = 'ACTIVE' group by country order by companies desc limit 50", s=slug)50 children = await fetch_all(conn, "select slug, name from industries where parent_slug = :s order by sort_order, name", s=slug)51 signals = await fetch_all(conn, "select * from signals where scope = 'industry' and scope_key = :s and status = 'active' order by detected_at desc limit 10", s=slug)52 return {**row, "companies_total": row["companies"], "companies": companies, "events": events,53 "hiring": {"open": int(h.get("open") or 0), "new_30d": int(h.get("new_30d") or 0), "removed_30d": int(h.get("removed_30d") or 0),54 "momentum_30d": row.get("hiring_momentum_30d")},55 "series": [ser.metric_point(r) for r in series], "countries": [{"country": r["country"], "companies": int(r["companies"])} for r in countries],56 "trending": [], "children": children, "signals": [ser.signal(s) for s in signals]}57 payload = await cached(f"industry:{slug}", 300, produce)58 if payload is None:59 raise HTTPException(status_code=404, detail="industry not found")60 return cached_response(request, payload, 300)61