Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
38084c4
image captions usign blip.
gsaluja9 Sep 15, 2025
2dfb0b8
Adding devcontainers. (#208)
gsaluja9 Sep 17, 2025
e3b5994
stray file.
gsaluja9 Sep 18, 2025
4a3651f
Some review feedback
gsaluja9 Sep 19, 2025
5516ccd
Merge branch 'main' into image_captions
gsaluja9 Sep 19, 2025
c1baf46
Address review comments for image captions
ad-claw000 May 24, 2026
324e1be
merge: resolve conflicts with main
ad-claw000 May 24, 2026
b1d39a4
Address review comments for caption-image
ad-claw000 May 24, 2026
6d62459
Address review comments for PR 204
ad-claw000 May 24, 2026
7725c94
Fix pagination logic to use a stable identifier (unique IDs) instead …
ad-claw000 May 25, 2026
cb6e39d
Address review comments for caption-image
ad-claw000 May 25, 2026
2c6be7a
Fix pagination logic to use a stable identifier (unique IDs) to avoid…
ad-claw000 May 25, 2026
8ef4078
Address review comments for caption-image app
ad-claw000 May 25, 2026
e066fcf
fix: restore --extra-index-url and raise on query failure
ad-claw000 May 25, 2026
6ca5bdc
fix: address review comments on requirements and unused import
ad-claw000 May 25, 2026
a9596b0
fix: remove opinionated black formatter from devcontainer configs
ad-claw000 May 25, 2026
05dcb4a
chore: address review comments on postinstall and compose env
ad-claw000 May 25, 2026
b23a40e
fix: address review comments on pagination and batch size defaults
ad-claw000 May 25, 2026
f67e5bd
Address review comments for PR 204
ad-claw000 May 25, 2026
2c48bcc
fix: restore pagination and batch size logic
ad-claw000 May 25, 2026
416c36b
fix: restore proper Typer app execution, server-side batching and def…
ad-claw000 May 25, 2026
61ed5c5
fix: restore stable identifier for pagination to prevent skipping
ad-claw000 May 25, 2026
3c735e9
fix(caption-image): use server-side batching and handle failed images
ad-claw000 May 25, 2026
1139fe5
fix(caption-image): restore stable identifier for pagination to preve…
ad-claw000 May 25, 2026
b1133c1
Address review comments on PR 204
ad-claw000 May 26, 2026
f749633
fix(caption-image): use stable identifier for pagination to prevent s…
ad-claw000 May 26, 2026
2549a6d
Address review comments on image batching and CI preload
ad-claw000 May 26, 2026
1cc7e44
fix(caption-image): use stable identifier for pagination to prevent s…
ad-claw000 May 27, 2026
b9c3831
Address review comments on PR #204
ad-claw000 May 27, 2026
e7c73be
fix(caption-image): use stable identifier for pagination to prevent s…
ad-claw000 May 27, 2026
95d40fe
fix: address review comments for caption-image
ad-claw000 May 27, 2026
559a4f5
fix(caption-image): use stable identifier for pagination to prevent s…
ad-claw000 May 28, 2026
fda5545
Address review comments: optimize queries, fix batch processing, shar…
ad-claw000 May 28, 2026
c70dc30
fix(caption-image): use stable identifier for pagination to prevent s…
ad-claw000 May 28, 2026
eaea553
Address review comments on PR 204
ad-claw000 May 28, 2026
fa1f7eb
fix(caption-image): use stable identifier for pagination to prevent s…
ad-claw000 May 29, 2026
72801e2
fix(caption-image): address review comments
ad-claw000 May 29, 2026
9b6b44f
test(mcp-server): wait for aperturedb to be healthy before seeding
ad-claw000 May 29, 2026
a238452
Merge remote-tracking branch 'origin/main' into image_captions
ad-claw000 May 29, 2026
0b42e0f
fix(caption-image): address review comments on loop behaviour and err…
ad-claw000 May 29, 2026
6f871d3
fix(caption-image): use stable identifier for pagination to prevent s…
ad-claw000 May 29, 2026
cc0afc4
fix(caption-image): handle return status from query_fail execution
ad-claw000 May 30, 2026
f828c65
fix: use server-side batching and remove trailing whitespace
Jun 1, 2026
14bc6e6
fix(caption-image): use stable identifier for pagination to prevent s…
Jun 1, 2026
8159fdd
fix(caption-image): use ApertureDB count and batching for pagination
Jun 2, 2026
f374c67
test(mcp-server): increase client timeout to 300s to allow embedding …
Jun 2, 2026
0111156
fix(devcontainer): use correct relative paths for shared aperturedb v…
Jun 3, 2026
25cfa65
fix(devcontainer): add healthcheck for aperturedb and depend on it
Jun 4, 2026
4674c3b
fix: address review comments for caption-image
Jun 4, 2026
ce044c8
fix(ingest-croissant): use local mock dataset instead of hitting hugg…
Jun 5, 2026
91112eb
fix: address review comments
Jun 5, 2026
4514bdf
fix(ingest-croissant): fix test data to not require external network
Jun 6, 2026
3a64828
fix(ingest-croissant): add description to dummy_records in test data
Jun 6, 2026
480998d
Address review comments on PR 204
Jun 7, 2026
e227b0a
fix: pass correct options in test.sh and postinstall.sh
Jun 7, 2026
95fd128
fix(caption-image): pagination logic, hardcoded batch size, and lazy …
Jun 8, 2026
0f0c54e
refactor: use count query and server-side batch pagination for images
Jun 8, 2026
dd6bf76
fix(docker): add lenz healthcheck to fix test flakiness
Jun 9, 2026
75cf2ab
fix: address review comments for relative paths and documentation
Jun 9, 2026
f795910
fix(caption-image): restore stable identifiers for robust pagination
Jun 10, 2026
23e5832
fix(caption-image): address latest review comments
Jun 11, 2026
54f40e5
fix(caption-image): use batch_id 0 to avoid skipping images while pag…
Jun 13, 2026
cce666d
fix(caption-image): use idx for batch_id in pagination
Jun 15, 2026
7401c91
fix(caption-image): restore stable identifiers for robust pagination
Jun 27, 2026
de07d26
fix(caption-image): address PR review comments
Jul 1, 2026
d98c83f
fix(caption-image): remove devcontainers and restore stable identifie…
Jul 2, 2026
4807ef7
Merge remote-tracking branch 'origin/main' into image_captions
Jul 2, 2026
59ac20e
fix(caption-image): address PR review comments
Jul 2, 2026
59acb41
Address review comments: README fix, requirements version, and test h…
Jul 2, 2026
5055fc4
fix: surface parsing error and remove unused import
Jul 2, 2026
c5fdae8
fix(caption-image): use _uniqueid list for stable pagination
Jul 2, 2026
a8faa53
Address review comments regarding image batching and test Dockerfile …
Jul 2, 2026
fd6b916
fix(caption-image): restore stable identifier for pagination
Jul 2, 2026
2217068
Address review comments on seed retry and FindImage query batching
Jul 2, 2026
272414b
fix(caption-image): use stable identifier with limit for pagination t…
Jul 2, 2026
4baf502
Address review comments regarding batching and healthcheck port
Jul 2, 2026
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
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ jobs:
sql-server,
label-studio,
ocr-extraction,
caption-image,
Comment thread
ad-claw000 marked this conversation as resolved.
dataset-ingestion-movies
Comment thread
ad-claw000 marked this conversation as resolved.
]
Comment thread
ad-claw000 marked this conversation as resolved.
runs-on: ubuntu-latest
Expand Down
15 changes: 15 additions & 0 deletions apps/caption-image/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Pull base image.
ARG VERSION=latest
FROM aperturedata/workflows-base:${VERSION}

ENV APP_NAME=workflows-caption-image

COPY requirements.txt /
RUN pip install -U pip
RUN pip install --no-cache-dir -r /requirements.txt

COPY warmup_validate.py /warmup_validate.py
ARG PRELOAD_MODEL=false
RUN if [ "$PRELOAD_MODEL" = "true" ]; then python /warmup_validate.py; fi && rm /warmup_validate.py

COPY app /app/
66 changes: 66 additions & 0 deletions apps/caption-image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Caption Image App

This workflow retrieves all images from ApertureDB that have not been
analyzed before, and runs them through a
[BLIP (Bootstrapping Language-Image Pre-training)](https://github.com/salesforce/BLIP)
model to generate a caption for each image.

The workflow runs continuously by default, periodically checking for and processing new uncaptioned images. To run it only once, set `RUN_ONCE=true`.

## Database details

```mermaid
sequenceDiagram
participant W as Caption Image
participant A as ApertureDB instance

W->>A: FindImage
A-->>W: count
Comment thread
ad-claw000 marked this conversation as resolved.
loop Until done
W->>A: FindImage
Comment thread
ad-claw000 marked this conversation as resolved.
A-->>W: images
W->>A: UpdateImage
end
Comment thread
ad-claw000 marked this conversation as resolved.
```

Each image is updated with a caption property (`wf_caption_image`) containing the generated caption text. The BLIP model processes each image to generate descriptive text that describes the visual content of the image.

## Running in Docker

```
docker run \
-e RUN_NAME=my_testing_run \
-e DB_HOST=workflowstesting.gcp.cloud.aperturedata.dev \
-e DB_PASS="password" \
-e NUM_WORKERS=4 \
-e BATCH_SIZE=32 \
-e WF_LOG_LEVEL=INFO \
aperturedata/workflows-caption-image
```

Parameters:
* **`NUM_WORKERS`**: Specifies the number of worker threads that will be running simultaneously,
retrieving and processing images in parallel. Default is `1`. Note that the BLIP model inference is serialized with a lock to prevent PyTorch intra-op threading conflicts on CPU, so increasing `NUM_WORKERS` only parallelizes image fetching and preprocessing, not inference itself.
* **`BATCH_SIZE`**: Specifies the batch size for processing images. Default is `1`.
* **`WF_LOG_LEVEL`**: Set log level for workflow code. Available options: DEBUG, INFO, WARNING, ERROR. Default is `WARNING`. `LOG_LEVEL` is also supported as a legacy alias.

Comment thread
ad-claw000 marked this conversation as resolved.
See [Common Parameters](../../README.md#common-parameters) for common parameters.

## Cleaning up

To clean all captions generated by this workflow, simply run the following query:

```
q = [
{
"UpdateImage": {
"constraints": {
"wf_caption_image": ["!=", None]
},
"remove_props": ["wf_caption_image", "wf_caption_image_done", "wf_caption_image_failed", "wf_caption_image_error"]
}
}
]
```

or manually remove the `wf_caption_image`, `wf_caption_image_done`, `wf_caption_image_failed`, and `wf_caption_image_error` properties from images that have been processed.
17 changes: 17 additions & 0 deletions apps/caption-image/app/app.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
set -e

SLEEPING_TIME=$(/app/wf_argparse.py --type non_negative_int --envar SLEEPING_TIME --default 30)
RUN_ONCE=$(/app/wf_argparse.py --type bool --envar RUN_ONCE --default false)

python3 status_tools.py --completed 0 --phases processing --phases sleeping --phase processing
while true; do
python3 status_tools.py --completed 0 --phase processing
python3 log_processor.py "python3 caption_images.py"

if [ "$RUN_ONCE" = "true" ]; then
break
fi
python3 status_tools.py --completed 0 --phase sleeping
sleep $SLEEPING_TIME
done
42 changes: 42 additions & 0 deletions apps/caption-image/app/caption_images.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import logging

import typer

from images import FindImageQueryGenerator
from aperturedb import ParallelQuery
from connection_pool import ConnectionPool

CAPTION_IMAGE_PROPERTY = 'wf_caption_image'

def caption_images(
num_workers: int = typer.Option(1, envvar="NUM_WORKERS", help="Number of concurrent workers"),
batch_size: int = typer.Option(1, envvar="BATCH_SIZE", help="Batch size for fetching images"),
log_level: str = typer.Option("WARNING", envvar=["WF_LOG_LEVEL", "LOG_LEVEL"], help="Logging level")
):
num_workers = int(num_workers)
if num_workers <= 0:
raise ValueError("num_workers must be > 0")

batch_size = int(batch_size)
if batch_size <= 0:
raise ValueError("batch_size must be > 0")

logging.basicConfig(level=log_level.upper(), force=True)
logger = logging.getLogger(__name__)
pool = ConnectionPool()
data = FindImageQueryGenerator(
pool,
batch_size=batch_size,
caption_image_property=CAPTION_IMAGE_PROPERTY)

logger.info("Running Caption Image...")
with pool.get_connection() as db:
querier = ParallelQuery.ParallelQuery(db)
querier.query(data, batchsize=1, numthreads=num_workers, stats=True)


def main():
typer.run(caption_images)

if __name__ == "__main__":
main()
Loading
Loading