Skip to content

Repository files navigation


KeepAI is a privacy-first, production-ready FastAPI backend for running large language models on your own infrastructure. JWT auth, database-driven RBAC, streaming, structured JSON extraction — all included. No data sent to third parties.


Why KeepAI?

Every AI SaaS sends your data to someone else's server. KeepAI runs entirely on your infrastructure — LLM inference, storage, auth.

KeepAIOpenAI API
Data privacyStays on your serverSent to OpenAI
CostFree (hardware only)Per-token billing
Model choice100+ via OllamaGPT family only
Auth & RBACBuilt-inNot included
StreamingSSE built-inSupported
PersistencePostgreSQLNo storage
LLM providerSwappableLocked in

Features

  • Local LLM inference — Llama 3, Mistral, CodeLlama, DeepSeek, Phi, and 100+ models via Ollama
  • JWT authentication — register, login, token-based auth with Argon2id password hashing
  • Database-driven RBAC — roles and permissions in PostgreSQL, enforced per-route
  • Streaming responses — Server-Sent Events (SSE) via POST /api/v1/prompts/stream
  • Structured JSON extraction — invoke InvoiceAgent to extract typed data from freeform text
  • Swappable LLM backend — implement LLMInterface to use OpenAI, Anthropic, or any provider
  • Connection pooling — SQLAlchemy async engine with configurable pool sizes
  • Rate limiting — per-user (JWT) or per-IP via slowapi
  • Permission caching — 5-minute in-memory cache for role lookups
  • Request tracingX-Request-ID and X-Response-Time-Ms on every response
  • Health checks/health/live (liveness) and /health/ready (DB + Ollama readiness)
  • Docker ready — one command to start the full stack
  • Production server — Gunicorn + UvicornWorker, auto-sized worker count
  • Testedpytest + asyncio + AsyncMock, no real DB or LLM required

Quick Start

Docker (recommended)

git clone https://github.com/yoosuf/KeepAI.git
cd KeepAI
docker compose -f docker/docker-compose.yml up --build -d
docker compose -f docker/docker-compose.yml exec ollama ollama pull llama3

API: http://localhost:8000 · Swagger: http://localhost:8000/docs

Local development

git clone https://github.com/yoosuf/KeepAI.git
cd KeepAI
python -m venv .venv &&source .venv/bin/activate
cd backend
pip install -r requirements.txt
cp .env.example .env # edit POSTGRES_* and OLLAMA_BASE_URL
alembic upgrade head
uvicorn src.main:app --reload --port 8000

First API call

# Register
curl -X POST http://localhost:8000/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "password": "yourpass"}'# Login — capture the token
TOKEN=$(curl -s -X POST http://localhost:8000/api/v1/auth/login \ -F "username=you@example.com" -F "password=yourpass" \| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")# Send a prompt
curl -X POST http://localhost:8000/api/v1/prompts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"prompt_text": "Explain quantum computing in 3 sentences."}'# Stream a response
curl -N -X POST http://localhost:8000/api/v1/prompts/stream \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"prompt_text": "Write a haiku about code."}'

API

MethodEndpointAuthDescription
GET/health/liveLiveness check
GET/health/readyReadiness (DB + Ollama)
POST/api/v1/auth/registerRegister a new user
POST/api/v1/auth/loginLogin, get JWT token
POST/api/v1/promptsJWTSend a prompt, save response
GET/api/v1/promptsJWTList your prompts
GET/api/v1/prompts/{id}JWTGet a specific prompt
POST/api/v1/prompts/streamJWTStream response as SSE
POST/api/v1/extract-invoiceJWTExtract structured JSON from text
GET/api/v1/admin/usersAdminList all users
GET/api/v1/admin/all-promptsAdminList all prompts across users

Full reference with examples: docs/api/reference.md


Architecture

Client
│
▼
Router FastAPI · Pydantic validation · JWT extraction
│
▼
Service Business logic · LLMInterface call
│
├──────────────────────────┐
▼ ▼
LLMInterface (port) PostgreSQL
│ async SQLAlchemy
▼
OllamaClient (adapter)
│
▼
Ollama HTTP API

Hexagonal (ports & adapters) — routers depend on services, services depend on interfaces, infrastructure implements interfaces. The domain layer has zero framework dependencies.

src/
├── core/
│ ├── config.py # Pydantic BaseSettings
│ ├── database.py # Async engine, session factory
│ ├── interfaces/
│ │ └── llm_interface.py # LLMInterface ABC (the port)
│ ├── middleware.py # Request ID + response time headers
│ └── rate_limit.py # slowapi limiter
├── infrastructure/
│ └── llm/
│ └── ollama_client.py # OllamaClient (the adapter)
└── modules/
├── auth/ # models · schemas · service · utils · router
├── prompts/ # models · schemas · service · agents · router
└── admin/ # router (permission-gated)

To swap the LLM backend: implement LLMInterface and inject it in get_prompt_service(). One file change. See docs/guides/extending-llm.md for complete OpenAI, Anthropic, and vLLM examples.

Full architecture doc: docs/architecture.md


Use Cases

Document intelligence — extract invoices, contracts, and forms as structured JSON without sending data to a cloud service.

Healthcare & legal — process patient records, clinical notes, or legal documents on-premises. HIPAA/GDPR-friendly by design.

Enterprise assistant — deploy behind your firewall with role-based access for different teams. Admins see everything; users see their own prompts.

Research — run AI workloads on sensitive datasets that cannot leave your environment.

LLM API gateway — use as a drop-in backend for your own frontend, with auth, rate limiting, and persistence already wired up.


Documentation

Getting StartedLocal setup, Docker, first API calls
ConfigurationAll environment variables
DeploymentProduction, HTTPS, hardening, backups
ArchitectureLayers, request flow, design decisions
API ReferenceAll endpoints with curl examples
Extending LLM ProvidersAdd OpenAI, Anthropic, vLLM
RBAC GuideRoles, permissions, migrations
Testing GuideAsyncMock patterns, fixtures
ContributingDev setup, standards, PR process
FAQCommon questions
TroubleshootingCommon issues and fixes
RoadmapPlanned features
ChangelogVersion history

Stack

LayerTechnology
API frameworkFastAPI + Uvicorn
LLM runtimeOllama
DatabasePostgreSQL 15 + asyncpg
ORM & migrationsSQLAlchemy 2.0 async + Alembic
Authpython-jose (JWT) + argon2-cffi
HTTP clienthttpx (async)
Rate limitingslowapi
Settingspydantic-settings
Production serverGunicorn + UvicornWorker
Testingpytest + pytest-asyncio + httpx
LintingRuff
ContainerDocker + Docker Compose

Roadmap

Completed in v1.0:

  • JWT auth, Argon2id hashing, database-driven RBAC
  • PostgreSQL persistence, Alembic migrations
  • Streaming SSE responses
  • Structured JSON extraction (InvoiceAgent)
  • Connection pooling, rate limiting, permission caching, request tracing
  • Docker Compose, Gunicorn production config, CI

Completed in v1.2:

  • Conversation history, WebSocket chat, React frontend (9 pages)
  • Multi-model routing, API key management, document RAG
  • Usage analytics and audit logging schema
  • Docker files consolidated in docker/ directory

Up next:

  • Semantic search (pgvector), context-aware document chat
  • Redis caching, async task queue
  • SSO/OAuth, multi-tenant support
  • Prometheus metrics, Grafana dashboards

Full roadmap →


Contributing

See Contributing Guide and Code of Conduct.

# Run tests (from backend/)cd backend && python -m pytest
# Lint (from backend/)cd backend && ruff check src/ tests/

PRs welcome — bug fixes, features, and documentation improvements.


Security

Found a vulnerability? Email mayoosuf@gmail.com — do not open a public issue. See Security Policy.


License

MIT — see LICENSE.


Yoosuf Mohamed · mayoosuf@gmail.com · github.com/yoosuf/KeepAI

About

Privacy-first local AI backend. Run 100+ LLMs (Llama 3, Mistral, etc.) on your infra via Ollama with JWT auth, RBAC, and PostgreSQL. No data leaves your server.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages