{"id":51548763,"url":"https://github.com/lindseystead/ai-pdf-autofiller","last_synced_at":"2026-07-09T21:03:32.320Z","repository":{"id":338116964,"uuid":"1115087869","full_name":"lindseystead/ai-pdf-autofiller","owner":"lindseystead","description":"Automated PDF form filling with intelligent field mapping using AI-assisted semantic inference","archived":false,"fork":false,"pushed_at":"2026-07-09T01:55:31.000Z","size":262,"stargazers_count":11,"open_issues_count":10,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-09T02:11:17.408Z","etag":null,"topics":["ai-automation","backend","data-mapping","developer-tools","document-automation","llm","openai","pdf","pdf-forms","production-ready","pydantic","python","semantic-mapping","workflow-automation"],"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/lindseystead.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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":"2025-12-12T10:19:01.000Z","updated_at":"2026-07-09T01:55:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/lindseystead/ai-pdf-autofiller","commit_stats":null,"previous_names":["lindseystead/ai-pdf-autofiller"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/lindseystead/ai-pdf-autofiller","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lindseystead%2Fai-pdf-autofiller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lindseystead%2Fai-pdf-autofiller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lindseystead%2Fai-pdf-autofiller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lindseystead%2Fai-pdf-autofiller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lindseystead","download_url":"https://codeload.github.com/lindseystead/ai-pdf-autofiller/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lindseystead%2Fai-pdf-autofiller/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35312545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["ai-automation","backend","data-mapping","developer-tools","document-automation","llm","openai","pdf","pdf-forms","production-ready","pydantic","python","semantic-mapping","workflow-automation"],"created_at":"2026-07-09T21:03:31.720Z","updated_at":"2026-07-09T21:03:32.311Z","avatar_url":"https://github.com/lindseystead.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# PDF Autofiller\n\n**Fill AcroForm PDFs from JSON — no manual field mapping.**\n\nOpen-source FastAPI service with deterministic-first mapping, optional AI inference, and a browser playground.\n\n[![CI](https://github.com/lindseystead/ai-pdf-autofiller/actions/workflows/test.yml/badge.svg)](https://github.com/lindseystead/ai-pdf-autofiller/actions/workflows/test.yml)\n[![Release](https://img.shields.io/github/v/release/lindseystead/ai-pdf-autofiller?label=release)](https://github.com/lindseystead/ai-pdf-autofiller/releases)\n[![Python 3.11+](https://img.shields.io/badge/python-3.11%20%7C%203.12-blue.svg)](https://www.python.org/downloads/)\n[![Coverage](https://img.shields.io/badge/coverage-%E2%89%A585%25-brightgreen.svg)](https://github.com/lindseystead/ai-pdf-autofiller)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n[Try in Codespaces](#try-it-now) · [Install](#install) · [API](#api) · [Docs](docs/) · [Recipes](recipes/)\n\n[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/lindseystead/ai-pdf-autofiller)\n\n\u003c/div\u003e\n\n---\n\n## Overview\n\nGovernment, HR, and insurance PDFs all use different field names for the same data. Your app stores `first_name`; the form wants `txtFName`, `givenName`, or `field_12`.\n\nPDF Autofiller maps JSON to AcroForm fields automatically:\n\n1. **Normalize** keys and match against alias packs (W-9, HR onboarding, and more)\n2. **Coerce** values to the correct type (dates, numbers, booleans)\n3. **Optionally infer** field meaning with AI — only when you enable it\n4. **Reject** incomplete output when required fields are unresolved\n\nDeterministic mapping is the default path: auditable, repeatable, and free to run without an API key.\n\n## Features\n\n- HTTP API with structured error codes and fill-outcome response headers\n- Browser playground at `/playground` for drag-and-drop testing\n- Python SDK (`fill()` helper and `PDFAutofillerClient`)\n- Community alias packs and copy-paste recipes for common forms\n- Docker image on GHCR, Render blueprint, and GitHub Release wheels\n- Auth, rate limits, and DoS guards enabled by default\n\n## Try it now\n\n**Fastest path — GitHub Codespaces** (free tier, no local install):\n\n1. Click **Open in GitHub Codespaces** above\n2. Wait ~60 seconds for setup\n3. Browser opens **`/playground`** — upload a PDF, paste JSON, download the result\n\n**One-line terminal demo** (after the API is running):\n\n```bash\ncurl -s -X POST http://localhost:8000/fill \\\n  -F \"pdf_file=@samples/sample_form.pdf;type=application/pdf\" \\\n  -F 'user_data={\"firstname\":\"Jane\",\"lastname\":\"Doe\",\"dob\":\"1990-01-01\"}' \\\n  -F \"strict=true\" -o filled.pdf\n```\n\n## Install\n\n### Docker\n\n```bash\ndocker run --rm -p 8000:8000 \\\n  -e API_AUTH_ENABLED=false \\\n  ghcr.io/lindseystead/ai-pdf-autofiller:latest\n```\n\nOpen `http://localhost:8000/playground`.\n\n### From source\n\n```bash\ngit clone https://github.com/lindseystead/ai-pdf-autofiller.git\ncd ai-pdf-autofiller\npip install -r requirements-dev.txt\nmake run-api\n```\n\n### Python package\n\n```bash\n# GitHub Release wheel (no PyPI account required)\ncurl -fsSL https://raw.githubusercontent.com/lindseystead/ai-pdf-autofiller/main/scripts/install-from-release.sh | bash\n\n# PyPI (when published)\npip install pdf-autofiller\n```\n\n```python\nfrom pdf_autofiller import fill\n\nfill(\"form.pdf\", {\"firstname\": \"Jane\", \"lastname\": \"Doe\"}, \"filled.pdf\")\n```\n\nRemote API with authentication:\n\n```python\nfrom pdf_autofiller.client import PDFAutofillerClient\n\nclient = PDFAutofillerClient(\"https://your-api.example.com\", api_key=\"your-token\")\nclient.fill_to_file(\"w9.pdf\", {\"name_line_1\": \"Jane Doe\"}, \"w9-filled.pdf\")\n```\n\nCopy `.env.example` to `.env` and set `API_AUTH_TOKEN` before running in production.\n\n## API\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/playground` | Browser UI for testing fills |\n| `GET` | `/health` | Service health and dependency checks |\n| `GET` | `/version` | Service version |\n| `POST` | `/fill` | Upload PDF + JSON, receive filled PDF |\n\n```bash\ncurl -s -X POST http://localhost:8000/fill \\\n  -H \"X-API-Key: $API_AUTH_TOKEN\" \\\n  -F \"pdf_file=@samples/sample_form.pdf;type=application/pdf\" \\\n  -F 'user_data={\"firstname\":\"Jane\",\"lastname\":\"Doe\",\"dob\":\"1990-01-01\"}' \\\n  -F \"strict=true\" \\\n  -o filled.pdf\n```\n\nSuccessful responses include diagnostic headers (`X-PDF-Fields-Written`, `X-PDF-Fields-Skipped-Review`, and more). Full contract: [docs/API.md](docs/API.md).\n\n## Configuration\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `API_AUTH_ENABLED` | `true` | Require API key on `POST /fill` |\n| `API_AUTH_TOKEN` | — | Expected API key value |\n| `API_KEY_HEADER` | `X-API-Key` | Header name for the token |\n| `MODEL_PROVIDER_API_KEY` | — | Enables optional AI inference and fallback |\n| `MAX_UPLOAD_BYTES` | `5242880` | Max PDF upload size (5 MiB) |\n| `MAX_PDF_PAGES` | `200` | Page-count limit |\n| `PDF_READ_TIMEOUT_SECONDS` | `20` | Parse/extraction time budget |\n| `MAX_PDF_TEXT_CHARS` | `2000000` | Cap on extracted text volume |\n| `RATE_LIMIT_PER_MINUTE` | `60` | Per-client fill budget (`0` = off) |\n| `TRUST_PROXY_HEADERS` | `false` | Use `X-Forwarded-For` behind a trusted proxy |\n| `FORM_ALIASES_DIR` | — | Optional directory of JSON alias packs |\n| `LOG_LEVEL` | `INFO` | Process log level |\n\nSee [.env.example](.env.example) and [docs/OPERATIONS.md](docs/OPERATIONS.md).\n\n## Architecture\n\n```mermaid\nflowchart LR\n    A[PDF + JSON] --\u003e B[pipeline]\n    B --\u003e C[pdf_reader]\n    C --\u003e D{AI inference?}\n    D --\u003e|optional| E[field_semantics]\n    D --\u003e|skip| F[mapping]\n    E --\u003e F\n    F --\u003e G[pdf_writer]\n    G --\u003e H[Filled PDF]\n```\n\n| Module | Role |\n|--------|------|\n| `acroform_fields.py` | Shared AcroForm field extraction |\n| `pdf_reader.py` | Metadata, fields, and page text |\n| `field_semantics.py` | Optional AI field-meaning inference |\n| `mapping.py` | Deterministic matching, aliases, coercion |\n| `pdf_writer.py` | Write values, enforce required fields |\n| `pipeline.py` | Orchestrates extract → enrich → map → write |\n| `api_service.py` | HTTP API, auth, rate limits, validation |\n\nDetails: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n\n## Recipes\n\n| Recipe | Description |\n|--------|-------------|\n| [recipes/w9.md](recipes/w9.md) | IRS Form W-9 |\n| [recipes/hr-onboarding.md](recipes/hr-onboarding.md) | Employee intake packets |\n| [recipes/sample-form.sh](recipes/sample-form.sh) | Bundled sample in one curl |\n\nCommunity alias packs: [forms/README.md](forms/README.md)\n\n## Documentation\n\n| Doc | Contents |\n|-----|----------|\n| [docs/API.md](docs/API.md) | Endpoints, errors, response headers |\n| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Modules and data flow |\n| [docs/OPERATIONS.md](docs/OPERATIONS.md) | Config, deployment, security |\n| [docs/TESTING.md](docs/TESTING.md) | Local validation and CI |\n| [docs/PURPOSE.md](docs/PURPOSE.md) | Problem statement and scope |\n| [docs/integrations/](docs/integrations/) | n8n, Zapier, LangChain |\n| [SECURITY.md](SECURITY.md) | Vulnerability reporting |\n| [CONTRIBUTING.md](CONTRIBUTING.md) | Contributor guide |\n| [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) | Community standards |\n| [CHANGELOG.md](CHANGELOG.md) | Release history |\n\n## Development\n\n```bash\nmake test          # pytest\nmake lint          # ruff + mypy\nmake smoke-check   # import and mapping smoke test\nmake run-sample    # fill samples/sample_form.pdf\n```\n\nCI runs ruff, mypy, pip-audit, and pytest (85% coverage floor) on Python 3.11 and 3.12.\n\n## Scope\n\n**Supported:** AcroForm PDFs, JSON profiles, HTTP API, playground, Docker, Python SDK.\n\n**Not supported today:** Scanned PDFs / OCR, saved templates, digital signatures, bulk job queues.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flindseystead%2Fai-pdf-autofiller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flindseystead%2Fai-pdf-autofiller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flindseystead%2Fai-pdf-autofiller/lists"}