An open API service indexing awesome lists of open source software.

https://github.com/nktkln/ai-notes-api

FastAPI backend for managing AI-related notes, prompts, conversations, and LLM workflows.
https://github.com/nktkln/ai-notes-api

celery docker fastapi minio openai pgvector rag sqlalchemy

Last synced: 2 days ago
JSON representation

FastAPI backend for managing AI-related notes, prompts, conversations, and LLM workflows.

Awesome Lists containing this project

README

          

# โšก AI Notes API

[![Python](https://img.shields.io/badge/python-3.13+-3776AB?logo=python&logoColor=white)](https://www.python.org/downloads/)
[![FastAPI](https://img.shields.io/badge/FastAPI-009688?logo=fastapi&logoColor=white)](https://fastapi.tiangolo.com/)
[![SQLAlchemy](https://img.shields.io/badge/SQLAlchemy-D71F00?logo=sqlalchemy&logoColor=white)](https://www.sqlalchemy.org/)
[![Pydantic](https://img.shields.io/badge/Pydantic-E92063?logo=pydantic&logoColor=white)](https://docs.pydantic.dev/)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-4169E1?logo=postgresql&logoColor=white)](https://www.postgresql.org/)
[![pgvector](https://img.shields.io/badge/pgvector-008bb9?logo=postgresql&logoColor=white)](https://github.com/pgvector/pgvector)
[![Redis](https://img.shields.io/badge/Redis-FF4438?logo=redis&logoColor=white)](https://redis.io/)
[![Celery](https://img.shields.io/badge/Celery-37814A?logo=celery&logoColor=white)](https://docs.celeryq.dev/)
[![OpenAI](https://img.shields.io/badge/OpenAI-412991?logo=openai&logoColor=white)](https://platform.openai.com/)
[![Docker](https://img.shields.io/badge/Docker-2496ED?logo=docker&logoColor=white)](https://www.docker.com/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE.md)
[![uv](https://img.shields.io/badge/uv-managed-261230?logo=uv&logoColor=white)](https://docs.astral.sh/uv/)
[![Ruff](https://img.shields.io/badge/linting-ruff-D7FF64?logo=ruff&logoColor=black)](https://docs.astral.sh/ruff/)
[![Checked with mypy](https://img.shields.io/badge/mypy-checked-2A6DB2.svg)](https://mypy-lang.org/)
[![Tested with pytest](https://img.shields.io/badge/testing-pytest-0A9EDC?logo=pytest&logoColor=white)](https://docs.pytest.org/)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-FAB040?logo=pre-commit&logoColor=black)](https://pre-commit.com/)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-FE5196?logo=conventionalcommits&logoColor=white)](https://www.conventionalcommits.org/)

**AI Notes API** is a production-oriented FastAPI backend for managing AI-related notes, prompts, conversations, documents, and LLM workflows. The project demonstrates clean architecture, async development, PostgreSQL + pgvector integration, and practical backend patterns for AI engineering.

The assistant is agentic: during chat completions it can call a built-in note toolkit (search, create, read, update, delete notes), and every chat session keeps a long-term memory built from extracted facts and rolling conversation summaries.

Chat sessions are also document-aware: uploaded documents are stored in S3-compatible storage and processed in the background (text extraction, chunking, and embedding generation), then retrieved as grounding context through pgvector similarity search to power retrieval-augmented generation (RAG).

## ๐Ÿ“ฆ Dependencies

* [Python 3.13+](https://www.python.org/downloads/)
* [uv](https://docs.astral.sh/uv/getting-started/installation/)
* [Docker](https://docs.docker.com/get-docker/)
* [Task](https://taskfile.dev/)

Runtime services:

* [PostgreSQL](https://www.postgresql.org/) - primary data store
* [Redis](https://redis.io/) - Celery broker and result backend
* [Celery](https://docs.celeryq.dev/) - background worker for async LLM generation jobs and chat memory updates
* [MinIO](https://min.io/) - S3-compatible object storage for uploaded documents

## ๐Ÿ“Œ API endpoints

The API is mounted under `/api/v1`.

Authentication endpoints:

* `POST /api/v1/auth/register` - register a new user
* `POST /api/v1/auth/login` - authenticate a user and receive a JWT access token
* `GET /api/v1/auth/me` - get the current authenticated user

Notes endpoints (authenticated):

* `POST /api/v1/notes` - create a note
* `GET /api/v1/notes` - list notes with pagination and filters
* `GET /api/v1/notes/{note_id}` - get a note by ID
* `PATCH /api/v1/notes/{note_id}` - update a note by ID
* `DELETE /api/v1/notes/{note_id}` - delete a note by ID

Chat session endpoints (authenticated):

* `POST /api/v1/chat/sessions` - create a chat session
* `GET /api/v1/chat/sessions` - list chat sessions with pagination and filters
* `GET /api/v1/chat/sessions/{session_id}` - get a chat session by ID
* `PATCH /api/v1/chat/sessions/{session_id}` - update a chat session by ID
* `DELETE /api/v1/chat/sessions/{session_id}` - delete a chat session by ID
* `GET /api/v1/chat/sessions/{session_id}/messages` - list messages in a session
* `GET /api/v1/chat/sessions/{session_id}/memory` - get the long-term memory for a chat session

Chat message endpoints (authenticated):

* `GET /api/v1/chat/messages/{message_id}` - get a message by ID
* `DELETE /api/v1/chat/messages/{message_id}` - delete a message by ID

Chat completion endpoints (authenticated):

* `POST /api/v1/chat/completions/stream` - stream an assistant response over SSE
* `POST /api/v1/chat/completions/jobs` - enqueue an async LLM generation job (Celery)
* `GET /api/v1/chat/completions/jobs/{job_id}` - get the status and result of a generation job

Document endpoints (authenticated):

* `POST /api/v1/chat/sessions/{session_id}/documents` - upload a document to a chat session
* `GET /api/v1/chat/sessions/{session_id}/documents` - list documents in a chat session
* `GET /api/v1/chat/sessions/{session_id}/documents/{document_id}` - get a document by ID
* `GET /api/v1/chat/sessions/{session_id}/documents/{document_id}/download` - download a document by ID
* `DELETE /api/v1/chat/sessions/{session_id}/documents/{document_id}` - delete a document by ID

Health endpoint:

* `GET /api/v1/health` - service health check

Authentication details:

* Use `Authorization: Bearer ` for protected endpoints
* Tokens are issued by `POST /api/v1/auth/login`
* User registration is handled by `POST /api/v1/auth/register`

Documentation is available at:

* Swagger UI: `http://127.0.0.1:8000/docs`
* Redoc: `http://127.0.0.1:8000/redoc`

## ๐Ÿ”ง Environment variables

The application loads settings from a `.env` file using `pydantic-settings`. Copy `.env.example` to `.env` and update the values before running the app.

Required variables:

* `DISABLE_LOGGING` - `false` or `true`
* `LOG_LEVEL` - e.g. `INFO`, `DEBUG`
* `LOG_PATH` - optional path for file logging
* `POSTGRES_HOST` - PostgreSQL host
* `POSTGRES_PORT` - PostgreSQL port
* `POSTGRES_USER` - PostgreSQL username
* `POSTGRES_PASSWORD` - PostgreSQL password
* `POSTGRES_DB` - PostgreSQL database name
* `JWT_SECRET_KEY` - secret key for signing JWT tokens
* `JWT_ALGORITHM` - JWT signing algorithm, default `HS256`
* `ACCESS_TOKEN_EXPIRE_MINUTES` - token lifetime in minutes
* `OPEN_AI_API_KEY` - OpenAI API key
* `OPEN_AI_MODEL` - chat completion model, e.g. `gpt-4o-mini`
* `OPEN_AI_EMBEDDING_MODEL` - embedding model, e.g. `text-embedding-3-small`
* `OPEN_AI_API_URL` - optional custom OpenAI-compatible base URL
* `OPEN_AI_MAX_OUTPUT_TOKENS` - max tokens per completion
* `LLM_CONTEXT_MESSAGES_LIMIT` - number of recent messages sent as context
* `CELERY_BROKER_URL` - Redis URL for the Celery broker
* `CELERY_RESULT_BACKEND` - Redis URL for the Celery result backend
* `S3_ENDPOINT_URL` - S3 endpoint URL
* `S3_ACCESS_KEY_ID` - S3 access key ID
* `S3_SECRET_ACCESS_KEY` - S3 secret access key
* `S3_REGION` - S3 region name, default `us-east-1`
* `S3_BUCKET_NAME` - bucket used to store documents, default `documents`
* `S3_PRESIGNED_URL_EXPIRE_SECONDS` - presigned document URL lifetime in seconds

The database connection URL is composed automatically from the `POSTGRES_*` values.

## ๐Ÿš€ Local development

1. Install dependencies and development tools:

```bash
task sync
```

2. Install Git hooks:

```bash
task init
```

3. Start the application locally:

```bash
task run
```

4. Start the Celery worker (requires a running Redis) for async generation jobs:

```bash
task run-celery
```

## ๐Ÿณ Docker

Build and run the Docker services:

```bash
task docker
```

Stop Docker services:

```bash
task docker-down
```

## ๐Ÿงช Tests and quality checks

* Run tests:

```bash
task test
```

* Run tests with coverage:

```bash
task test-cov
```

* Run linting and type checking:

```bash
task lint
```

* Run full quality gate:

```bash
task check
```

## ๐Ÿ—„ Database schema

Entity-relationship diagram for the database models:

```mermaid
erDiagram
users {
uuid id PK
string email UK
string username "null"
string hashed_password
bool is_active
bool is_superuser
datetime created_at
datetime updated_at
}

notes {
uuid id PK
uuid user_id FK
string title
text content
string_array tags
enum source "model_source"
string model_name "null"
jsonb model_metadata
datetime created_at
datetime updated_at
datetime deleted_at "null"
}

chat_sessions {
uuid id PK
uuid user_id FK
string title
enum generation_status "chat_session_generation_status"
uuid generation_id "null"
datetime generation_started_at "null"
datetime created_at
datetime updated_at
datetime deleted_at "null"
}

messages {
uuid id PK
uuid session_id FK
text content
enum role "message_role"
string provider "null"
string model_name "null"
int prompt_tokens "null"
int completion_tokens "null"
int total_tokens "null"
datetime created_at
datetime updated_at
datetime deleted_at "null"
}

chat_memories {
uuid id PK
uuid session_id FK,UK
text summary
jsonb facts
bool is_summarizing
uuid last_summarized_message_id FK "null"
datetime created_at
datetime updated_at
}

generation_jobs {
uuid id PK
uuid user_id FK
uuid session_id FK
enum status "generation_job_status"
text input_message
uuid output_message_id FK "null"
text error "null"
datetime started_at "null"
datetime finished_at "null"
datetime created_at
datetime updated_at
}

documents {
uuid id PK
uuid user_id FK
uuid session_id FK
string filename
string content_type
int file_size
string checksum_sha256
string storage_bucket
string storage_object_name
enum status "document_status"
text error_message "null"
datetime created_at
datetime updated_at
datetime deleted_at "null"
}

document_processing_jobs {
uuid id PK
uuid document_id FK
enum status "document_processing_job_status"
datetime started_at "null"
datetime finished_at "null"
text error "null"
datetime created_at
datetime updated_at
}

document_chunks {
uuid id PK
uuid user_id FK
uuid session_id FK
uuid document_id FK
int chunk_index
text content
string content_hash
vector embedding
string embedding_model
int token_count "null"
datetime created_at
datetime updated_at
datetime deleted_at "null"
}

rag_queries {
uuid id PK
uuid user_id FK
uuid session_id FK
text question
text answer "null"
string provider "null"
string model "null"
int prompt_tokens "null"
int completion_tokens "null"
int total_tokens "null"
int top_k
enum status "rag_query_status"
datetime finished_at "null"
text error_message "null"
datetime created_at
datetime updated_at
}

rag_query_sources {
uuid id PK
uuid rag_query_id FK
uuid document_id FK
uuid chunk_id FK
float score
int rank
text content_preview
datetime created_at
datetime updated_at
}

users ||--o{ notes : owns
users ||--o{ chat_sessions : owns
users ||--o{ generation_jobs : owns
users ||--o{ documents : owns
users ||--o{ document_chunks : owns
users ||--o{ rag_queries : owns

chat_sessions ||--o{ messages : contains
chat_sessions ||--o| chat_memories : has
chat_sessions ||--o{ generation_jobs : contains
chat_sessions ||--o{ documents : contains
chat_sessions ||--o{ document_chunks : contains
chat_sessions ||--o{ rag_queries : contains

messages ||--o| generation_jobs : "output of"
messages ||--o| chat_memories : "last summarized"

documents ||--o{ document_processing_jobs : "processed by"
documents ||--o{ document_chunks : "split into"
documents ||--o{ rag_query_sources : "referenced by"
document_chunks ||--o{ rag_query_sources : "referenced by"
rag_queries ||--o{ rag_query_sources : "retrieved"
```

## ๐Ÿ›  Database migrations

* Create a new Alembic revision:

```bash
task alembic-revision -- ""
```

* Apply migrations:

```bash
task alembic-upgrade
```

* Downgrade one revision:

```bash
task alembic-downgrade
```

## ๐Ÿ“œ License

This project is licensed under the MIT License. See [LICENSE.md](./LICENSE.md) for details.