Skip to content

Commit 3084754

Browse files
authored
Enhance Image Search Example - Live Update (#459)
* backend * frontend * fix settings * Update README.md * Update README.md * refactor: remove cli entry * refactor: remove cli entry * refactor: pass image bytes * merge func * refactor: remove redundant check * Enhancement: Add Live Update * use new api * update README and description
1 parent fd43562 commit 3084754

File tree

3 files changed

+10
-4
lines changed

3 files changed

+10
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ It defines an index flow like this:
137137
| [Embeddings to Qdrant](examples/text_embedding_qdrant) | Index documents in a Qdrant collection for semantic search |
138138
| [FastAPI Server with Docker](examples/fastapi_server_docker) | Run the semantic search server in a Dockerized FastAPI setup |
139139
| [Product_Taxonomy_Knowledge_Graph](examples/product_taxonomy_knowledge_graph) | Build knowledge graph for product recommendations |
140-
| [Image Search with Vision API](examples/image_search_example) | Generates detailed captions for images using a vision model, embeds them, enables semantic search via FastAPI and served on a React frontend.|
140+
| [Image Search with Vision API](examples/image_search_example) | Generates detailed captions for images using a vision model, embeds them, enables live-updating semantic search via FastAPI and served on a React frontend|
141141

142142
More coming and stay tuned 👀!
143143

examples/image_search_example/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- QDrant for Vector Storage
66
- Ollama Gemma3 (Image to Text)
77
- CLIP ViT-L/14 - Embeddings Model
8+
- Live Update
89

910
## Make sure Postgres and Qdrant are running
1011
```
@@ -42,12 +43,12 @@ pip install -r requirements.txt
4243
```
4344

4445
### Place your images in the `img` directory.
46+
- No need to update manually. CocoIndex will automatically update the index as new images are added to the directory.
4547

4648

4749
## Run Backend
4850
```
4951
python main.py cocoindex setup
50-
python main.py cocoindex update
5152
uvicorn main:app --reload --host 0.0.0.0 --port 8000
5253
```
5354

@@ -59,3 +60,4 @@ npm run dev
5960
```
6061

6162
Go to `http://localhost:5174` to search.
63+

examples/image_search_example/main.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from dotenv import load_dotenv
22
import cocoindex
3+
import datetime
34
import os
45
import requests
56
import base64
@@ -14,7 +15,7 @@
1415
OLLAMA_MODEL = "gemma3"
1516

1617
# 1. Extract caption from image using Ollama vision model
17-
@cocoindex.op.function()
18+
@cocoindex.op.function(cache=True, behavior_version=1)
1819
def get_image_caption(img_bytes: bytes) -> str:
1920
"""
2021
Use Ollama's gemma3 model to extract a detailed caption from an image.
@@ -55,7 +56,8 @@ def caption_to_embedding(caption: cocoindex.DataSlice) -> cocoindex.DataSlice:
5556
@cocoindex.flow_def(name="ImageObjectEmbedding")
5657
def image_object_embedding_flow(flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope):
5758
data_scope["images"] = flow_builder.add_source(
58-
cocoindex.sources.LocalFile(path="img", included_patterns=["*.jpg", "*.jpeg", "*.png"], binary=True)
59+
cocoindex.sources.LocalFile(path="img", included_patterns=["*.jpg", "*.jpeg", "*.png"], binary=True),
60+
refresh_interval=datetime.timedelta(minutes=1) # Poll for changes every 1 minute
5961
)
6062
img_embeddings = data_scope.add_collector()
6163
with data_scope["images"].row() as img:
@@ -101,6 +103,8 @@ def startup_event():
101103
query_transform_flow=caption_to_embedding,
102104
default_similarity_metric=cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY,
103105
)
106+
app.state.live_updater = cocoindex.FlowLiveUpdater(image_object_embedding_flow)
107+
app.state.live_updater.start()
104108

105109
@app.get("/search")
106110
def search(q: str = Query(..., description="Search query"), limit: int = Query(5, description="Number of results")):

0 commit comments

Comments
 (0)