Coverage for narrative_harm_classifier/api/routes/classify.py: 91%

23 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-07-20 13:25 +0000

1""" 

2api/routes/classify.py — Classification endpoints. 

3""" 

4 

5from fastapi import APIRouter, Depends, HTTPException 

6from narrative_harm_classifier.core.models import ClassifyRequest, ClassificationResult, BatchClassifyRequest, BatchClassificationResult 

7from narrative_harm_classifier.core.config import get_settings, Settings 

8from narrative_harm_classifier.classifier.taxonomy.loader import load_taxonomy 

9from narrative_harm_classifier.classifier.rules.engine import ClassificationEngine 

10from narrative_harm_classifier.classifier.factory import build_engine 

11from datetime import datetime 

12 

13router = APIRouter() 

14 

15 

16def get_engine(settings: Settings = Depends(get_settings)) -> ClassificationEngine: 

17 return build_engine(settings) 

18 

19 

20@router.post( 

21 "/", 

22 response_model=ClassificationResult, 

23 summary="Classify a single text item", 

24 description=( 

25 "Runs multi-dimensional classification against the active taxonomy. " 

26 "Returns harm category, confidence, matched signals, and decision rationale." 

27 ), 

28) 

29def classify_text( 

30 request: ClassifyRequest, 

31 engine: ClassificationEngine = Depends(get_engine), 

32) -> ClassificationResult: 

33 try: 

34 return engine.classify(request) 

35 except Exception as e: 

36 raise HTTPException(status_code=500, detail=str(e)) 

37 

38 

39@router.post( 

40 "/batch", 

41 response_model=BatchClassificationResult, 

42 summary="Classify a batch of text items (max 100)", 

43) 

44def classify_batch( 

45 request: BatchClassifyRequest, 

46 engine: ClassificationEngine = Depends(get_engine), 

47) -> BatchClassificationResult: 

48 results = [engine.classify(item) for item in request.items] 

49 harmful = sum(1 for r in results if r.is_harmful) 

50 settings = get_settings() 

51 taxonomy = load_taxonomy(settings.taxonomy_config_path) 

52 

53 return BatchClassificationResult( 

54 results=results, 

55 total=len(results), 

56 harmful_count=harmful, 

57 taxonomy_version=taxonomy.version, 

58 processed_at=datetime.utcnow(), 

59 )