Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
3cd5106
update product recommendation example description
badmonster0 May 18, 2025
e32cfea
rename folder
badmonster0 May 18, 2025
dddee93
Update README.md
badmonster0 May 18, 2025
e43a28e
Update README.md
badmonster0 May 18, 2025
ade9afb
Update README.md
badmonster0 May 19, 2025
2bead87
Update README.md
badmonster0 May 19, 2025
a374650
update text_embedding with new query handler
badmonster0 May 20, 2025
3df050d
Update main.py
badmonster0 May 20, 2025
0471abe
Update README.md
badmonster0 May 20, 2025
c3c09b0
Update README.md
badmonster0 May 20, 2025
bab25a4
Update README.md
badmonster0 May 20, 2025
4f0b607
Update README.md
badmonster0 May 20, 2025
9ffe7ed
Update README.md
badmonster0 May 20, 2025
631cad7
Update README.md
badmonster0 May 20, 2025
8008d85
Update README.md
badmonster0 May 20, 2025
2aa1bc8
qdrant
badmonster0 May 20, 2025
c76db2d
Update README.md
badmonster0 May 20, 2025
f5e965d
Update README.md
badmonster0 May 20, 2025
eed7a25
Update README.md
badmonster0 May 20, 2025
12fc9be
Update README.md
badmonster0 May 20, 2025
407eda2
Update README.md
badmonster0 May 20, 2025
44d93dd
Update README.md
badmonster0 May 20, 2025
689d359
Update README.md
badmonster0 May 20, 2025
a72270c
Merge branch 'jelly-ex2' of https://github.com/cocoindex-io/cocoindex…
badmonster0 May 20, 2025
eb56fe2
Update main.py
badmonster0 May 20, 2025
e69c212
Update main.py
badmonster0 May 20, 2025
9272a8a
Update main.py
badmonster0 May 20, 2025
7967914
Update main.py
badmonster0 May 20, 2025
35b19ba
Merge branch 'main' into jelly-ex2
badmonster0 May 20, 2025
3577694
upgrade query handling for pdf embedding
badmonster0 May 20, 2025
f127c54
Merge branch 'main' into jelly-ex2
badmonster0 May 20, 2025
9741fa8
Update README.md
badmonster0 May 20, 2025
818b806
Update README.md
badmonster0 May 20, 2025
b5fbae6
Update README.md
badmonster0 May 20, 2025
3ab5ddc
Update README.md
badmonster0 May 20, 2025
58d7cba
Merge branch 'main' into jelly-ex2
badmonster0 May 20, 2025
331e0e2
Merge branch 'main' into jelly-ex2
badmonster0 May 20, 2025
ff43f46
Update main.py
badmonster0 May 20, 2025
55ebc4a
google drive example update query handler
badmonster0 May 20, 2025
a79d279
Merge branch 'main' into jelly-ex2
badmonster0 May 20, 2025
6e72fb2
Update README.md
badmonster0 May 21, 2025
b46cf77
Update README.md
badmonster0 May 21, 2025
d2725e0
Merge branch 'main' into jelly-ex2
badmonster0 May 21, 2025
b874512
rename to image_search (to be more consistent with other examples)
badmonster0 May 21, 2025
2402c78
update query handling for image search
badmonster0 May 21, 2025
87bd37b
Merge branch 'main' into jelly-ex2
badmonster0 May 21, 2025
ac43f78
Update README.md
badmonster0 May 21, 2025
b645bb1
Update README.md
badmonster0 May 21, 2025
979cde9
Merge branch 'main' into jelly-ex2
badmonster0 May 21, 2025
4bc0486
Merge branch 'jelly-ex2' of https://github.com/cocoindex-io/cocoindex…
badmonster0 May 21, 2025
0b5da66
Merge branch 'main' into jelly-ex2
badmonster0 May 21, 2025
32fcd4d
simplify the fast api example
badmonster0 May 21, 2025
5a01dc8
upgrade query handling
badmonster0 May 21, 2025
99a1e38
Update README.md
badmonster0 May 21, 2025
57ac81d
Update README.md
badmonster0 May 21, 2025
d8b364f
fix docker
badmonster0 May 21, 2025
a8e94ba
Update README.md
badmonster0 May 21, 2025
a208c8e
Update README.md
badmonster0 May 21, 2025
12bd609
Merge branch 'main' into jelly-ex2
badmonster0 May 21, 2025
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
6 changes: 5 additions & 1 deletion examples/fastapi_server_docker/.env
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
COCOINDEX_DATABASE_URL=postgres://cocoindex:cocoindex@coco_db:5432/cocoindex
# for docker
COCOINDEX_DATABASE_URL=postgres://cocoindex:cocoindex@coco_db:5436/cocoindex

# For local testing
# COCOINDEX_DATABASE_URL=postgres://cocoindex:cocoindex@localhost/cocoindex
69 changes: 62 additions & 7 deletions examples/fastapi_server_docker/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,65 @@
## Run cocoindex docker container with a simple query endpoint via fastapi
In this example, we provide a simple docker container using docker compose to build pgvector17 along with a simple python fastapi script than runs a simple query endpoint. This example uses the code from the code embedding example.
## Run docker container with a simple query endpoint via fastapi

## How to run
Edit the sample code directory to include the code you want to query over in
```sample_code/```
In this example, we will build index for text embedding from local markdown files, and provide a simple query endpoint via fastapi.
We provide a simple docker container using docker compose to build pgvector17 along with a simple python fastapi script

Edit the configuration code from the file ```src/cocoindex_funs.py``` line 23 to 25.
We appreciate a star ⭐ at [CocoIndex Github](https://github.com/cocoindex-io/cocoindex) if this is helpful.

Finally build the docker container via: ```docker compose up``` while inside the directory of the example.

## Run locally without docker

In the `.env` file, use local Postgres URL

```
# For local testing
COCOINDEX_DATABASE_URL=postgres://cocoindex:cocoindex@localhost/cocoindex
```

- Install dependencies:

```bash
pip install -e .
```

- Setup:

```bash
cocoindex setup main.py
```

- Update index:

```bash
cocoindex update main.py
```

- Run:

```bash
uvicorn main:fastapi_app --reload --host 0.0.0.0 --port 8000
```

## Query the endpoint

```bash
curl "http://localhost:8000/search?q=model&limit=3"
```


## Run Docker

In the `.env` file, use Docker Postgres URL

```
COCOINDEX_DATABASE_URL=postgres://cocoindex:cocoindex@coco_db:5436/cocoindex
```

Build the docker container via:
```bash
docker compose up --build
```

Test the endpoint:
```bash
curl "http://0.0.0.0:8080/search?q=model&limit=3"
```
4 changes: 3 additions & 1 deletion examples/fastapi_server_docker/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ services:
POSTGRES_USER: cocoindex
POSTGRES_PASSWORD: cocoindex
POSTGRES_DB: cocoindex
POSTGRES_PORT: 5436
ports:
- "5432:5432"
- "5436:5436"
command: postgres -p 5436

coco_api:
build:
Expand Down
6 changes: 6 additions & 0 deletions examples/fastapi_server_docker/dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ FROM python:3.11-slim

WORKDIR /app

# Install PostgreSQL client libraries
RUN apt-get update && apt-get install -y \
libpq-dev \
gcc \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt .

RUN pip install -r requirements.txt
Expand Down
530 changes: 530 additions & 0 deletions examples/fastapi_server_docker/files/1810.04805v2.md

Large diffs are not rendered by default.

89 changes: 73 additions & 16 deletions examples/fastapi_server_docker/main.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,82 @@
import cocoindex
import uvicorn

from fastapi import FastAPI
from dotenv import load_dotenv
from fastapi import FastAPI, Query
from psycopg_pool import ConnectionPool
import os

@cocoindex.transform_flow()
def text_to_embedding(text: cocoindex.DataSlice[str]) -> cocoindex.DataSlice[list[float]]:
"""
Embed the text using a SentenceTransformer model.
This is a shared logic between indexing and querying.
"""
return text.transform(
cocoindex.functions.SentenceTransformerEmbed(
model="sentence-transformers/all-MiniLM-L6-v2"))

@cocoindex.flow_def(name="MarkdownEmbeddingFastApiExample")
def markdown_embedding_flow(flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope):
"""
Define an example flow that embeds markdown files into a vector database.
"""
data_scope["documents"] = flow_builder.add_source(
cocoindex.sources.LocalFile(path="files"))
doc_embeddings = data_scope.add_collector()

with data_scope["documents"].row() as doc:
doc["chunks"] = doc["content"].transform(
cocoindex.functions.SplitRecursively(),
language="markdown", chunk_size=2000, chunk_overlap=500)

with doc["chunks"].row() as chunk:
chunk["embedding"] = text_to_embedding(chunk["text"])
doc_embeddings.collect(
filename=doc["filename"],
location=chunk["location"],
text=chunk["text"],
embedding=chunk["embedding"]
)

doc_embeddings.export(
"doc_embeddings",
cocoindex.storages.Postgres(),
primary_key_fields=["filename", "location"],
vector_indexes=[
cocoindex.VectorIndexDef(
field_name="embedding",
metric=cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY)])

from src.cocoindex_funs import code_embedding_flow, code_to_embedding
def search(pool: ConnectionPool, query: str, top_k: int = 5):
# Get the table name, for the export target in the text_embedding_flow above.
table_name = cocoindex.utils.get_target_storage_default_name(markdown_embedding_flow, "doc_embeddings")
# Evaluate the transform flow defined above with the input query, to get the embedding.
query_vector = text_to_embedding.eval(query)
# Run the query and get the results.
with pool.connection() as conn:
with conn.cursor() as cur:
cur.execute(f"""
SELECT filename, text, embedding <=> %s::vector AS distance
FROM {table_name} ORDER BY distance LIMIT %s
""", (query_vector, top_k))
return [
{"filename": row[0], "text": row[1], "score": 1.0 - row[2]}
for row in cur.fetchall()
]

fastapi_app = FastAPI()

query_handler = cocoindex.query.SimpleSemanticsQueryHandler(
name="SemanticsSearch",
flow=code_embedding_flow,
target_name="code_embeddings",
query_transform_flow=code_to_embedding,
default_similarity_metric=cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY
)

@fastapi_app.get("/query")
def query_endpoint(string: str):
results, _ = query_handler.search(string, 10)
return results

@fastapi_app.on_event("startup")
def startup_event():
load_dotenv()
cocoindex.init()
# Initialize database connection pool
fastapi_app.state.pool = ConnectionPool(os.getenv("COCOINDEX_DATABASE_URL"))

@fastapi_app.get("/search")
def search_endpoint(q: str = Query(..., description="Search query"), limit: int = Query(5, description="Number of results")):
results = search(fastapi_app.state.pool, q, limit)
return {"results": results}

if __name__ == "__main__":
load_dotenv()
Expand Down
4 changes: 3 additions & 1 deletion examples/fastapi_server_docker/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ cocoindex>=0.1.42
python-dotenv>=1.0.1
fastapi==0.115.12
fastapi-cli==0.0.7
uvicorn==0.34.2
uvicorn==0.34.2
psycopg==3.2.6
psycopg_pool==3.2.6
113 changes: 0 additions & 113 deletions examples/fastapi_server_docker/sample_code/main.py

This file was deleted.

45 changes: 0 additions & 45 deletions examples/fastapi_server_docker/src/cocoindex_funs.py

This file was deleted.