{"id":23281980,"url":"https://github.com/parthapray/pii_scrubbing_llm","last_synced_at":"2026-05-10T02:51:32.225Z","repository":{"id":268882084,"uuid":"905744997","full_name":"ParthaPRay/PII_Scrubbing_LLM","owner":"ParthaPRay","description":"This repo contains codes about PII scrubbing heuristics search before calling to LLM (local and remote)","archived":false,"fork":false,"pushed_at":"2024-12-19T13:07:25.000Z","size":58,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T14:14:52.370Z","etag":null,"topics":["chatgpt-api","claude-api","cloud","edge","fastapi","hybrid","llm","ner-spacy","ollama-api","pii","pii-detection","scrubbing","spacy","sqlalchemy","uvicorn"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ParthaPRay.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}},"created_at":"2024-12-19T12:43:26.000Z","updated_at":"2024-12-19T13:07:29.000Z","dependencies_parsed_at":"2024-12-19T13:48:39.906Z","dependency_job_id":"9412596f-af3d-436a-9412-954643773b29","html_url":"https://github.com/ParthaPRay/PII_Scrubbing_LLM","commit_stats":null,"previous_names":["parthapray/pii_scrubbing_llm"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ParthaPRay%2FPII_Scrubbing_LLM","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ParthaPRay%2FPII_Scrubbing_LLM/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ParthaPRay%2FPII_Scrubbing_LLM/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ParthaPRay%2FPII_Scrubbing_LLM/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ParthaPRay","download_url":"https://codeload.github.com/ParthaPRay/PII_Scrubbing_LLM/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247492543,"owners_count":20947545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["chatgpt-api","claude-api","cloud","edge","fastapi","hybrid","llm","ner-spacy","ollama-api","pii","pii-detection","scrubbing","spacy","sqlalchemy","uvicorn"],"created_at":"2024-12-20T00:13:16.814Z","updated_at":"2026-05-10T02:51:32.183Z","avatar_url":"https://github.com/ParthaPRay.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PII Scrubbing Service with spaCy NER and Flexible LLM Integration (Local and Remote)\n\nThis FastAPI-based service accepts text input and a model name, scrubs Personally Identifiable Information (PII) using spaCy Named Entity Recognition (NER) and regex patterns, then sends the sanitized input to a specified Large Language Model (LLM) endpoint. The results (including performance metrics, CPU usage, and PII detection details) are logged to both a local SQLite database and returned as a JSON response. \n\nNER using Spacy is the Python-based Natural Language Processing task that focuses on detecting and categorizing named entities.\n\nCurrently, the code supports legacy Text Completaions (https://docs.anthropic.com/en/api/complete) by Anthropic and chat completion (https://platform.openai.com/docs/api-reference/chat) by OpenAI. It supports text generation (https://github.com/ollama/ollama/blob/main/docs/api.md#generate-a-completion) of Ollama.\n\n## Key Features\n\n1. **PII Scrubbing:**\n   - Uses spaCy's `en_core_web_sm` model to detect named entities that could be considered sensitive (e.g., `PERSON`, `GPE`, `ORG`, `DATE`, `TIME`, `MONEY`, `NORP`, `LOC`, `FAC`).\n   - Additional PII patterns like `IP_ADDRESS`, `SSN`, `CREDIT_CARD`, and `PASSWORD` are detected using custom regex patterns.\n   - All detected PII are replaced with placeholder tags (e.g., `\u003cPERSON\u003e`, `\u003cIP_ADDRESS\u003e`).\n\n2. **Flexible LLM Backend:**\n   - **Local LLM (Ollama):** For model names that do **not** start with `\"gpt-\"` or `\"claude-\"`, the service assumes a locally running Ollama LLM endpoint at `http://0.0.0.0:11434/api/generate`.\n   - **OpenAI ChatGPT:** For model names starting with `\"gpt-\"`, it calls the OpenAI ChatCompletion API. Requires `OPENAI_API_KEY` to be set as an environment variable.\n   - **Anthropic Claude:** For model names starting with `\"claude-\"`, it calls the Anthropic API endpoint. Requires `ANTHROPIC_API_KEY` to be set as an environment variable.\n\n3. **Performance and Metadata Logging:**\n   - Logs details about execution (timestamps, CPU usage, network latency, token usage) and the chosen model into a SQLite database.\n   - Information is returned as a JSON response including scrubbed input, detected entities, and LLM output.\n\n4. **Local SQLite Database Logging:**\n   - The code uses SQLAlchemy to store metadata of each request.\n   - Columns include prompt, scrubbed PII, timestamps, durations, CPU usage, model name, and performance statistics.\n\n## How It Works\n\n1. **Receive Request:**  \n   The `/process` endpoint accepts a JSON payload with:\n   - `text`: The user-provided text containing potential PII.\n   - `model`: The LLM model identifier (e.g., `\"qwen2.5:0.5b-instruct-q4_K_M\"`, `\"gpt-4o\"`, `gpt-4o-mini`, `\"claude-2.1\"`).\n\n2. **Scrub PII:**\n   - The code uses spaCy NER to find entities labeled as PII.  \n   - Additional regex patterns detect things like IP addresses, SSNs, credit cards, and passwords.\n   - Detected PII entities are replaced with placeholders (e.g., `\u003cPERSON\u003e`, `\u003cIP_ADDRESS\u003e`).\n   - The scrubbed text and a list of detected entities are retained.\n\n3. **LLM Call:**\n   - Based on the `model` string, the service decides which API to call:\n     - **Local/Ollama:** If no prefix (`gpt-` or `claude-`), calls the Ollama endpoint.\n     - **OpenAI:** If the model name starts with `\"gpt-\"`, calls OpenAI's API. Requires `OPENAI_API_KEY`.\n     - **Anthropic:** If the model name starts with `\"claude-\"`, calls Anthropic's API. Requires `ANTHROPIC_API_KEY`.\n   - Measures CPU usage and network latency before and after the request.\n   - Extracts response text and performance metrics (e.g., tokens processed).\n\n4. **Logging and Response:**\n   - All relevant data (prompt, scrubbed text, PII details, performance metrics, CPU usage, model name) are inserted into the local SQLite database.\n   - The final JSON response returns:\n     - `scrubbed_input`: The sanitized input.\n     - `detected_entities`: A list of detected PII and their types.\n     - `response`: The LLM's generated output.\n     - `log`: A dictionary of metadata (durations, CPU usage, tokens/second, etc.).\n\n## System Requirements\n\n- Python 3.9+\n- `pip install fastapi uvicorn spacy requests sqlalchemy` or `pip install -r requirements.txt`\n- SpaCy English model: `python -m spacy download en_core_web_sm`\n- Access to desired LLM endpoints (Ollama, OpenAI, Anthropic).  \n- Appropriate API keys set as environment variables (if using OpenAI or Anthropic).\n- For Ollama, first install it as per https://github.com/ollama/ollama and then pull or run some models. For Ollama only PII scrubbing run python3 pii_scrub_ner_eng_ollama.py and then call it via curl as per later given process.\n## Running the Application\n\n1. **Install Dependencies:**\n   ```bash\n   pip install -r requirements.txt\n   python -m spacy download en_core_web_sm\n   ```\n\n2. **Set Environment Variables for Remote LLMs:**\n   - For OpenAI:\n     ```bash\n     export OPENAI_API_KEY=\"your_openai_api_key\"\n     ```\n   - For Anthropic:\n     ```bash\n     export ANTHROPIC_API_KEY=\"your_anthropic_api_key\"\n     ```\n\n   If you're only using a local LLM (Ollama), you do not need these keys.\n\n   Run below (serial no. 4) for running FastAPI server on the same terminal.\n\n4. **Run the FastAPI Uvicron Server:**\n   ```bash\n   uvicorn __main__:app --host 0.0.0.0 --port 5000 --reload\n   ```\n   or\n\n   ```bash\n   python3 pii_scrub_ner_eng_hybrid.py\n   ```\n\n   This will start the FastAPI server on port 5000.\n\n5. **Database Setup:**\n   - On the first run, `Base.metadata.create_all(bind=engine)` creates the `requests` table in `ollama_log.db`.\n   - If you change the schema, remove or rename `ollama_log.db` before restarting to recreate the schema.\n\n## Example `curl` Calls\n\n**Local LLM (Ollama):**\n```bash\ncurl -X POST \"http://127.0.0.1:5000/process\" \\\n-H \"Content-Type: application/json\" \\\n-d '{\"text\": \"Here is my password: super_secret123 and IP address 172.16.254.1.\", \"model\": \"qwen2.5:0.5b-instruct-q4_K_M\"}'\n```\n\n**OpenAI (ChatGPT):**\n```bash\nexport OPENAI_API_KEY=\"your_openai_api_key\"\ncurl -X POST \"http://127.0.0.1:5000/process\" \\\n-H \"Content-Type: application/json\" \\\n-d '{\"text\": \"John Doe has an email johndoe@example.com\", \"model\": \"gpt-4o-mini\"}'\n```\n\n**Anthropic (Claude):**\n```bash\nexport ANTHROPIC_API_KEY=\"your_anthropic_api_key\"\ncurl -X POST \"http://127.0.0.1:5000/process\" \\\n-H \"Content-Type: application/json\" \\\n-d '{\"text\": \"Alice from California, email alice123@gmail.com\", \"model\": \"claude-2.1\"}'\n```\n\n## Entity Types and PII\n\nCommon entities recognized by spaCy and custom logic:\n\n- **PERSON**: Individual human names (fictional or real).\n- **GPE**: Geo-political entities like countries, states, and cities.\n- **ORG**: Organizations, companies, agencies.\n- **DATE**: Specific dates or date ranges.\n- **TIME**: Times of day or durations within a day.\n- **MONEY**: Monetary values and currencies.\n- **NORP**: Nationalities, religious groups, political organizations.\n- **LOC**: Non-GPE locations like mountains, lakes, etc.\n- **FAC**: Facilities, buildings, airports.\n- **EMAIL**, **PHONE**: Can be recognized via custom rules or regex.\n- **IP_ADDRESS**, **SSN**, **CREDIT_CARD**, **PASSWORD**: Handled via regex patterns.\n\nThe service replaces these PII instances with placeholder tags (e.g., `\u003cPERSON\u003e`, `\u003cIP_ADDRESS\u003e`).\n\n## Notes\n\n- Make sure to run `uvicorn` and set API keys in the same environment and session.\n- If you encounter `no such table: requests`, remove `ollama_log.db` and restart the server.\n- Adjust the model name and LLM endpoint logic as needed for different providers.\n\n---\n\nThis README should help you understand how to use and extend this PII scrubbing and LLM integration service.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparthapray%2Fpii_scrubbing_llm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparthapray%2Fpii_scrubbing_llm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparthapray%2Fpii_scrubbing_llm/lists"}