Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion postgres/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ifndef UV_VERSION
UV_VERSION := 0.7.21
endif

.PHONY: uv_check venv sync lock update format lint migrations example
.PHONY: uv_check venv sync lock update format lint migrations example example-vector database


# Check installed UV version and install if needed
Expand Down Expand Up @@ -81,3 +81,21 @@ migrations:

example:
@python -B -m example

example-vector:
@python -B -m example.vector

database:
@echo '# Starting PostgreSQL database with pgvector...'
@if docker ps -a --format '{{.Names}}' | grep -q '^postgres-draive-example$$'; then \
docker start postgres-draive-example; \
else \
docker run -d \
--name postgres-draive-example \
-e POSTGRES_USER=$(POSTGRES_USER) \
-e POSTGRES_PASSWORD=$(POSTGRES_PASSWORD) \
-e POSTGRES_DB=$(POSTGRES_DATABASE) \
-p $(POSTGRES_PORT):5432 \
pgvector/pgvector:pg16; \
fi
@echo '...database started!'
8 changes: 4 additions & 4 deletions postgres/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ build-backend = "uv_build"
[project]
name = "postgres-example"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["draive[openai, postgres]~=0.87.3"]
requires-python = ">=3.13"
dependencies = ["draive[openai, postgres]>=0.91.1", "pgvector"]

[project.urls]
Homepage = "https://miquido.com"
Expand All @@ -18,7 +18,7 @@ dev = ["bandit~=1.7", "pyright~=1.1", "ruff~=0.12"]
namespace = true

[tool.ruff]
target-version = "py312"
target-version = "py313"
line-length = 100
extend-exclude = [".venv", ".git", ".cache"]
lint.select = ["E", "F", "A", "I", "B", "PL", "W", "C", "RUF", "UP"]
Expand All @@ -28,7 +28,7 @@ lint.ignore = ["A005"]
"__init__.py" = ["F401", "E402"]

[tool.pyright]
pythonVersion = "3.12"
pythonVersion = "3.13"
venvPath = "./.venv"
include = ["./src"]
exclude = ["**/node_modules", "**/__pycache__"]
Expand Down
10 changes: 5 additions & 5 deletions postgres/src/example/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
from draive import (
Conversation,
ConversationMessage,
Instructions,
Template,
ctx,
)
from draive.openai import OpenAI, OpenAIResponsesConfig
from draive.postgres import (
PostgresConfigurationRepository,
PostgresConnectionPool,
PostgresInstructionsRepository,
PostgresModelMemory,
PostgresTemplatesRepository,
)


Expand All @@ -20,8 +20,8 @@ async def main() -> None:
"example",
# declare postgres as configuration provider
PostgresConfigurationRepository(),
# declare postgres as instructons repository
PostgresInstructionsRepository(),
# declare postgres as templates repository
PostgresTemplatesRepository(),
disposables=(
OpenAI(), # use OpenAI for LLM
PostgresConnectionPool(), # use postgres connection pool
Expand All @@ -31,7 +31,7 @@ async def main() -> None:
memory = PostgresModelMemory("example_session")
await memory.maintenance() # initialize session if needed
result: ConversationMessage = await Conversation.completion(
instructions=Instructions.of("example"),
instructions=Template.of("example"),
input="Hello!",
# declare postgres as conversation memory
# use actual session ID to distinct multiple sessions
Expand Down
4 changes: 4 additions & 0 deletions postgres/src/example/vector/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from draive import load_env, setup_logging

load_env()
setup_logging("example")
79 changes: 79 additions & 0 deletions postgres/src/example/vector/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from asyncio import run
from uuid import UUID, uuid4

from asyncpg.connection import Connection
from draive import DataModel, Default, ctx
from draive.openai import OpenAI
from draive.postgres import PostgresConnectionPool, PostgresVectorIndex
from draive.utils import VectorIndex
from pgvector.asyncpg import register_vector


# Inline model definition
class Chunk(DataModel):
identifier: UUID = Default(default_factory=uuid4)
text: str


# Inline pgvector initialization
async def initialize_pgvector(connection: Connection) -> None:
await register_vector(connection)


async def main() -> None:
async with ctx.scope(
"vector_example",
PostgresVectorIndex(),
disposables=(
OpenAI(), # Use OpenAI for embeddings
PostgresConnectionPool(
initialize=initialize_pgvector
), # Postgres with pgvector support
),
):
# Step 1: Create and index sample chunks
chunks = [
Chunk(text="Python is a high-level programming language"),
Chunk(text="PostgreSQL is a powerful relational database"),
Chunk(text="Machine learning is a subset of artificial intelligence"),
Chunk(text="Docker is a containerization platform"),
Chunk(text="FastAPI is a modern Python web framework"),
Chunk(text="Kubernetes orchestrates containerized applications"),
Chunk(text="GraphQL is a query language for APIs"),
Chunk(text="Redis is an in-memory data structure store"),
Chunk(text="Terraform enables infrastructure as code"),
Chunk(text="Nginx is a high-performance web server"),
]

ctx.log_info(f"Indexing {len(chunks)} chunks...")
await VectorIndex.index(
Chunk,
values=chunks,
attribute=Chunk._.text,
)
ctx.log_info("Indexing complete!")

# Step 2: Search for similar content
query = "What is Python?"
ctx.log_info(f"Searching for: '{query}'")

results = await VectorIndex.search(
Chunk,
query=query,
limit=3,
score_threshold=0.0,
rerank=False,
)

ctx.log_info(f"Found {len(results)} results:")
for idx, result in enumerate(results, 1):
ctx.log_info(f" {idx}. {result.text}")

# Step 3: Clean up indexed data
ctx.log_info("Cleaning up indexed data...")
await VectorIndex.delete(Chunk)
ctx.log_info("Cleanup complete!")


if __name__ == "__main__":
run(main())
12 changes: 6 additions & 6 deletions postgres/src/migrations/postgres/migration_0.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@ async def migration(connection: PostgresConnection) -> None:
"""
)

# instructions #
# templates #
await connection.execute(
"""
CREATE TABLE instructions (
name TEXT NOT NULL,
CREATE TABLE templates (
identifier TEXT NOT NULL,
description TEXT DEFAULT NULL,
content TEXT NOT NULL,
arguments JSONB NOT NULL DEFAULT '[]'::jsonb,
variables JSONB NOT NULL DEFAULT '{}'::jsonb,
meta JSONB NOT NULL DEFAULT '{}'::jsonb,
created TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (name, created)
PRIMARY KEY (identifier, created)
);
"""
)

await connection.execute(
"""
INSERT INTO instructions (name, description, content)
INSERT INTO templates (identifier, description, content)
VALUES (
'example',
'Example scenario prompt',
Expand Down
Loading