{"id":49084369,"url":"https://github.com/robertocirillo/bias-detector-service","last_synced_at":"2026-04-20T14:15:10.662Z","repository":{"id":352615549,"uuid":"1139163894","full_name":"robertocirillo/bias-detector-service","owner":"robertocirillo","description":"Docker-ready FastAPI microservice for bias detection and text classification with Hugging Face","archived":false,"fork":false,"pushed_at":"2026-04-15T12:38:50.000Z","size":279,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-20T12:45:57.809Z","etag":null,"topics":["bias-detection","docker","fastapi","huggingface","nlp","python","text-classification"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robertocirillo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-21T15:53:29.000Z","updated_at":"2026-04-16T18:46:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/robertocirillo/bias-detector-service","commit_stats":null,"previous_names":["robertocirillo/bias-detector-service"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/robertocirillo/bias-detector-service","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertocirillo%2Fbias-detector-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertocirillo%2Fbias-detector-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertocirillo%2Fbias-detector-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertocirillo%2Fbias-detector-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robertocirillo","download_url":"https://codeload.github.com/robertocirillo/bias-detector-service/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertocirillo%2Fbias-detector-service/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32050572,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bias-detection","docker","fastapi","huggingface","nlp","python","text-classification"],"created_at":"2026-04-20T14:15:08.223Z","updated_at":"2026-04-20T14:15:10.644Z","avatar_url":"https://github.com/robertocirillo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bias-detector-service\n\nFastAPI microservice for text classification and bias detection with Hugging Face sequence-classification models.\n\n## Overview\n\n`bias-detector-service` loads a default Hugging Face classifier at startup and exposes a small HTTP API for inference and model introspection.\n\nIt is designed to be simple to run locally or in Docker:\n\n- serve one default model for text classification\n- optionally override or preload additional models\n- expose health, labels, and policy endpoints\n- support Hugging Face cache reuse and offline mode\n\nIt can run standalone or behind another service such as `mcp-bridge`, but the API below is the primary interface.\n\n## Main Features\n\n- FastAPI service for Hugging Face sequence-classification models\n- `POST /v1/bias/classify` for text inference\n- model label and policy introspection endpoints\n- optional in-memory preload for additional models\n- optional category and unsafe-label filtering during flagging\n- Docker-ready runtime with persistent Hugging Face cache support\n\n## Quickstart Local\n\nRequirements:\n\n- Python 3.12\n- `uv`\n\nInstall dependencies:\n\n```bash\nuv sync\n```\n\nStart the service with a real model:\n\n```bash\nexport MODEL_ID=cardiffnlp/twitter-roberta-base-hate-latest\nuv run uvicorn app.main:app --host 0.0.0.0 --port 9090\n```\n\nFor a local smoke test or docs check without downloading a model (`__mock__` is not a real inference model):\n\n```bash\nexport MODEL_ID=__mock__\nuv run uvicorn app.main:app --host 0.0.0.0 --port 9090\n```\n\nCheck that the service is up:\n\n```bash\ncurl -s http://localhost:9090/healthz\n```\n\nFastAPI docs are available at `http://localhost:9090/docs`.\n\n## Quickstart Docker\n\nRecommended for public use: run the published image instead of building locally.\n\nPublic image name: `robertocirillo/bias-detector-service`\n\nInitial public tags: `latest` and `0.1.0`\n\nPull the image:\n\n```bash\ndocker pull robertocirillo/bias-detector-service:latest\n```\n\nRun it:\n\n```bash\ndocker run --rm -p 9090:9090 \\\n  -e MODEL_ID=unitary/toxic-bert \\\n  -v bias-detector-cache:/root/.cache/huggingface \\\n  robertocirillo/bias-detector-service:latest\n```\n\nOn the first startup, the container may need to download the model, so initial startup and first requests can take longer.\n\nIf you need to test local changes or build the image yourself, use the local Docker path:\n\n```bash\ndocker build -t bias-detector-service .\n\ndocker run --rm -p 9090:9090 \\\n  -e MODEL_ID=unitary/toxic-bert \\\n  -e HF_HOME=/hf_cache \\\n  -v bias-detector-cache:/hf_cache \\\n  bias-detector-service\n```\n\nThe repository also includes Compose files for local development or integration scenarios, not as the primary public quickstart:\n\n- `docker-compose-mac.yml` publishes `9090:9090` for local access\n- `docker-compose.yml` keeps the service internal to Docker networks and expects the external network `mcp-net`\n\n## Publish to Docker Hub\n\nMaintainer note: authenticate first with `docker login`.\n\n```bash\nIMAGE=robertocirillo/bias-detector-service\nVERSION=0.1.0\n\n# One-time setup if you do not already have a buildx builder selected.\ndocker buildx create --name bias-detector-multiarch --driver docker-container --use\n\n# If the builder already exists, select it instead.\n# docker buildx use bias-detector-multiarch\n\ndocker buildx inspect --bootstrap\n\ndocker buildx build \\\n  --platform linux/amd64,linux/arm64 \\\n  -t \"$IMAGE:latest\" \\\n  -t \"$IMAGE:$VERSION\" \\\n  --push \\\n  .\n\ndocker buildx imagetools inspect \"$IMAGE:latest\"\ndocker buildx imagetools inspect \"$IMAGE:$VERSION\"\n```\n\n## Example Request\n\n```bash\ncurl -s -X POST http://localhost:9090/v1/bias/classify \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"text\": \"All people are the same. They always do that.\",\n    \"top_k\": 5,\n    \"threshold\": 0.5,\n    \"return_all_scores\": false,\n    \"return_char_spans\": true\n  }'\n```\n\nExample response shape:\n\n```json\n{\n  \"request_id\": \"7a4d4a74-6f7f-4a8e-8c55-0f4fd0d7d7f8\",\n  \"modality\": \"text\",\n  \"model\": {\n    \"model_id\": \"cardiffnlp/twitter-roberta-base-hate-latest\",\n    \"revision\": \"\"\n  },\n  \"inference_ms\": 12,\n  \"task_type\": \"multi_class\",\n  \"labels\": [\n    {\n      \"label\": \"LABEL_0\",\n      \"score\": 0.9,\n      \"is_flagged\": true,\n      \"spans\": []\n    }\n  ],\n  \"flagged\": true,\n  \"flagged_labels\": [\"LABEL_0\"]\n}\n```\n\nRequest fields supported by `/v1/bias/classify`:\n\n- required: `text`\n- optional model selection: `model_id`, `revision`\n- optional policy inputs: `active_categories`, `unsafe_labels`\n- optional inference controls: `top_k`, `threshold`, `return_all_scores`, `return_char_spans`, `mode`\n\n## Essential Configuration\n\n| Variable | Purpose | Default |\n| --- | --- | --- |\n| `MODEL_ID` | Default model loaded at startup | `cardiffnlp/twitter-roberta-base-hate-latest` |\n| `REVISION` | Optional model revision | unset |\n| `DEVICE` | Inference device (`cpu` or `cuda`) | `cpu` |\n| `HF_HOME` | Hugging Face cache directory | unset |\n| `HF_OFFLINE` | Load models from local cache only | `false` |\n| `THRESHOLD` | Default threshold for multi-label flagging | `0.5` |\n| `MAX_LENGTH` | Maximum token length used for truncation | `512` |\n| `MAX_INPUT_CHARS` | Maximum accepted input size | `20000` |\n| `WARMUP` | Run one startup inference | `true` |\n| `MAX_LOADED_MODELS` | Max override models kept in RAM (`0` = unlimited) | `0` |\n| `BIAS_CATEGORY_MAP_PATH` / `BIAS_CATEGORY_MAP_JSON` | Optional category-to-label mapping used by `active_categories` | unset |\n| `BIAS_LABEL_POLICY_PATH` / `BIAS_LABEL_POLICY_JSON` | Optional per-model unsafe-label policy | unset |\n\nNotes:\n\n- `HF_OFFLINE=true` requires model files to already exist in the local cache.\n- `active_categories` only has an effect when a category map is configured.\n- `unsafe_labels` must match labels exposed by the selected model.\n\n## API Endpoints\n\n| Method | Path | Description |\n| --- | --- | --- |\n| `GET` | `/healthz` | Service health and default model metadata |\n| `POST` | `/v1/bias/classify` | Classify text and compute flagged labels |\n| `GET` | `/v1/models/{model_id:path}/labels` | Return the ordered labels for a model |\n| `GET` | `/v1/models/{model_id:path}/policy` | Return configured unsafe labels for a model |\n| `POST` | `/v1/models/preload` | Preload one or more models into the in-memory pool |\n\nGenerated OpenAPI docs are available at `/docs` and `/openapi.json`.\n\n## Project Layout\n\n```text\napp/                    FastAPI application\npackages/detector_core/ Shared schemas and scoring helpers\ndocs/                   Minimal public architecture notes\ntests/                  API and runtime contract tests\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertocirillo%2Fbias-detector-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobertocirillo%2Fbias-detector-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertocirillo%2Fbias-detector-service/lists"}