classifier-general / docs /explanation /architecture.md
AyoubChLin's picture
feat: update classifier model to local zero-shot NLI and enhance language detection with local library
2d0ef3b

Architecture Explanation

1. Executive summary

classifier-general is a single FastAPI service that classifies text and files with local extraction/preprocessing, a local Hugging Face zero-shot NLI model, and local language detection.

Evidence:

  • app/main.py
  • app/routers/classification.py
  • app/services/classifier_service.py
  • app/services/language_service.py

2. Purpose and scope

What exists

  • Contract-compatible endpoints for classify/language/transform flows.
  • Pipeline split into preprocess, extraction, classification orchestration.
  • Configurable runtime through environment variables.

Evidence:

  • app/routers/classification.py
  • app/pipelines/classification_pipeline.py
  • app/core/config.py

How it works

  • Router accepts JSON or multipart requests.
  • Files are written to disk (static/uploads).
  • Extraction service parses document/image/text into plain text.
  • Text preprocessing enforces minimum quality.
  • Pipeline calls language and classifier services.

Evidence:

  • app/services/file_storage_service.py
  • app/services/extraction_service.py
  • app/pipelines/text_pipeline.py
  • app/pipelines/classification_pipeline.py

Why designed this way (inferred)

  • Maintain old API contract while introducing modular services and safer config handling.

3. C4-style views

Context view

Actors/systems:

  • API client sending text/files.
  • Hugging Face model hub (model download/auth when needed).
  • Local filesystem for uploaded files.

Evidence:

  • app/core/config.py
  • app/services/classifier_service.py
  • app/services/language_service.py

Container view

  • One container/service (classifier-api) with FastAPI + OCR binary.

Evidence:

  • docker-compose.yml
  • Dockerfile

Component view

  • API routing: app/routers/*
  • Orchestration pipelines: app/pipelines/*
  • Integration services: app/services/classifier_service.py, app/services/language_service.py
  • Extraction + storage services: app/services/extraction_service.py, app/services/file_storage_service.py
  • Config/exceptions/schemas: app/core/*, app/schemas/*

Code-level workflow: file classification

  1. POST /classify receives file.
  2. File saved to upload directory.
  3. Text extracted by extension-specific handlers.
    • For /classify, PDF extraction is first-page only.
  4. Text preprocessed (regex cleanup + min words).
  5. Local language detector called.
  6. Zero-shot NLI classifier scores runtime labels and selects top label.
  7. Response returns {label, language} plus type=not english when applicable.

Evidence:

  • app/routers/classification.py
  • app/services/file_storage_service.py
  • app/services/extraction_service.py
  • app/pipelines/text_pipeline.py
  • app/pipelines/classification_pipeline.py

4. Cross-cutting concerns

Validation and error mapping

  • Input schemas use strict extra=forbid.
  • Error mapping explicitly separates validation/extraction (400) from classifier/language inference failures (502).

Evidence:

  • app/schemas/classification.py
  • app/routers/classification.py

Configuration and secrets

  • Runtime config sourced from env.
  • HF token optional and no hardcoded secret in current service code.

Evidence:

  • app/core/config.py
  • app/services/classifier_service.py

Concurrency and mutable state

  • Labels guarded by thread lock (LabelConfig._lock).
  • State is still process-local; multi-instance deployments can diverge.

Evidence:

  • app/models/label_config.py
  • app/services/label_service.py

Testing strategy

  • Route contract tests monkeypatch pipeline methods for deterministic tests.
  • Tests validate response shape and key endpoint behavior, not remote network calls.

Evidence:

  • tests/test_routes.py

5. Risks, gaps, and technical debt

  • Local model initialization can fail if model/token/resources are invalid.
  • No upload retention/cleanup process.
  • Readiness check does not probe external AI services, only local label readiness.
  • No authentication/authorization layer on API endpoints.

Evidence:

  • app/services/language_service.py
  • app/services/classifier_service.py
  • app/routers/health.py
  • app/routers/classification.py

6. Unknown or inferred

  • Unknown: expected SLA and acceptable latency.
  • Unknown: intended persistence/retention policy for uploaded files.
  • Inferred: service is optimized for local/dev contract compatibility and integration testing.