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.