Skip to main content

Quick Start

Open In Colab Download View source on GitHub

In this notebook:

  • Connect to ApertureDB
  • Load the Cookbook dataset
  • Run queries — metadata filters, graph traversal, and vector search

Connect to ApertureDB

Option A: ApertureDB Cloud (recommended)
Sign up for a free 30-day trial. Get your key from Connect > Generate API Key, add it to a .env file in this directory:

APERTUREDB_KEY=your_key_here

Option B: Community Edition (local Docker)
Run this in a terminal before starting the notebook:

docker run -d --name aperturedb \\
-p 55555:55555 -e ADB_MASTER_KEY=admin -e ADB_FORCE_SSL=false \\
aperturedata/aperturedb-community
%pip install --upgrade --quiet aperturedb python-dotenv
# Option A: ApertureDB Cloud
from dotenv import load_dotenv
load_dotenv() # loads APERTUREDB_KEY from .env into the environment
True
# Option B: Community Edition (local Docker)
# !adb config create localdb --active \\
# --host localhost --port 55555 \\
# --username admin --password admin \\
# --no-use-ssl --no-interactive

Connect and Verify

Run GetStatus to confirm your connection is working.

from aperturedb.Utils import Utils
from aperturedb.CommonLibrary import create_connector

# Create the connector for ApertureDB
client = create_connector()

# Use the connector to create a Utils object and print the summary
utils = Utils(client)
utils.summary()

Load the Cookbook Dataset

The Cookbook dataset contains 20 dishes with photos, descriptions, and ingredients — built to demonstrate ApertureDB capabilities.

! wget https://github.com/aperture-data/Cookbook/raw/refs/heads/main/scripts/load_cookbook_data.sh
! bash load_cookbook_data.sh


from aperturedb.cli.ingest import from_csv, TransformerType, IngestType

from_csv(
filepath="data/dishes.adb.csv",
ingest_type=IngestType.IMAGE,
transformer=[
TransformerType.clip_pytorch_embeddings,
TransformerType.image_properties,
TransformerType.common_properties]
)

from_csv(
filepath="data/ingredients.adb.csv",
ingest_type=IngestType.ENTITY,
)

from_csv(
filepath="data/dish_ingredients.adb.csv",
ingest_type=IngestType.CONNECTION,
)
100%|███████████████████████████████████████| 335M/335M [00:06<00:00, 53.2MiB/s]
  0%|          | 0.00/107M [00:00<?, ?B/s]
sample_count 30
``````output
Progress: 100%|██████████| 30.0/30.0 [00:19<00:00, 1.58items/s]
``````output
============ ApertureDB Loader Stats ============
Total time (s): 19.024478673934937
Total queries executed: 30
Avg Query time (s): 0.270937975247701
Query time std: 0.20982933835044162
Avg Query Throughput (q/s): 3.690881645829695
Overall insertion throughput (element/s): 1.5769157470318704
Total inserted elements: 30
Total successful commands: 60
=================================================
sample_count 65
``````output
Progress: 100%|██████████| 65.0/65.0 [00:09<00:00, 7.21items/s]
``````output
============ ApertureDB Loader Stats ============
Total time (s): 9.01276445388794
Total queries executed: 65
Avg Query time (s): 0.12738604545593263
Query time std: 0.12897449230058589
Avg Query Throughput (q/s): 7.850153416890044
Overall insertion throughput (element/s): 7.2119936488476855
Total inserted elements: 65
Total successful commands: 65
=================================================
sample_count 69
``````output
Progress: 100%|██████████| 69.0/69.0 [00:09<00:00, 7.66items/s]
``````output
============ ApertureDB Loader Stats ============
Total time (s): 9.013163328170776
Total queries executed: 69
Avg Query time (s): 0.12440769223199374
Query time std: 0.12473818331751528
Avg Query Throughput (q/s): 8.038088176535048
Overall insertion throughput (element/s): 7.655469837580716
Total inserted elements: 69
Total successful commands: 207
=================================================
``````output

Run Queries

a) Find images of dishes from Scottish Cuisine

For this simple query, we are able to use an object wrapper class.

from aperturedb.Images import Images
from aperturedb.Constraints import Constraints

# Create an Images wrapper object
images = Images(client)

# Search
images.search(
constraints=Constraints().equal("cuisine", "Scottish"),
limit=3,
)

# display result
images.display()

png

png

png

b) Find images and information of dishes with butter and chicken in them

from aperturedb.CommonLibrary import create_connector, execute_query
from aperturedb.NotebookHelpers import display

query = [
{ # Find an ingredient with the name "butter"
"FindEntity": {
"with_class": "Ingredient",
"constraints": {
"name": [
"==",
"butter"
]
},
"_ref": 1, # forward reference
}
},
{ # Find an ingredient with the name "chicken"
"FindEntity": {
"with_class": "Ingredient",
"constraints": {
"name": [
"==",
"chicken"
]
},
"_ref": 2 # forward reference
}
},
{ # Find an image connected to both ingredients
"FindImage": {
"blobs": True,
"is_connected_to": {
"all": [ # Must be connected to all ingredients
{
"ref": 1, # backward reference
},
{
"ref": 2, # backward reference
}
]
},
"results": {
"limit": 5, # Maximum of five results
"all_properties": True # Return all properties
}
}
}
]
client = create_connector()
result, response, blobs = execute_query(client, query, [])

# Print the response
print(response)

# Check if the query was successful
if result == 0:
display(blobs)

[{'FindEntity': {'returned': 0, 'status': 0}}, {'FindEntity': {'returned': 0, 'status': 0}}, {'FindImage': {'blobs_start': 0, 'entities': [{'Recipe URL': 'https://www.indianhealthyrecipes.com/butter-chicken/', '_blob_index': 0, '_uniqueid': '15.3.484460', 'adb_data_source': 'IngestType.IMAGE.dishes.adb.csv', 'adb_image_height': 768, 'adb_image_id': '4', 'adb_image_sha256': 'a3b41c925f1d51003ef7dd924999eed0d04b31752a9dacf47065df1de3458a1a', 'adb_image_size': 227547, 'adb_image_width': 1024, 'caption': 'Chicken in Creamy tomato based gravy', 'contributor': 'gautam', 'cuisine': 'Indian', 'id': 4, 'location': 'NJ', 'name': 'Butter chicken', 'type': 'main dish'}, {'Recipe URL': 'https://www.tajmahal-oban.co.uk/', '_blob_index': 1, '_uniqueid': '15.7.484540', 'adb_data_source': 'IngestType.IMAGE.dishes.adb.csv', 'adb_image_height': 768, 'adb_image_id': '8', 'adb_image_sha256': '14a706e59bbbf9bd135469efb93684c69ba5c2763d94e00d8f6172537b749013', 'adb_image_size': 255347, 'adb_image_width': 1024, 'caption': 'Butter chicken, special fried rice, garlic naan, peshwari naan', 'contributor': 'gavin', 'cuisine': 'Indian', 'id': 8, 'location': 'UK', 'name': 'butter chicken with special fried rice and assorted naan breads', 'type': 'main dish'}], 'returned': 2, 'status': 0}}]

png

png

c) Find similar looking dishes to a bread

from aperturedb.CommonLibrary import create_connector, execute_query
from aperturedb.NotebookHelpers import display as nbd
from IPython.display import display
import clip
import torch

device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/16", device=device)

search_tokens = clip.tokenize([f"a photo of bread on plate"]).to(device)
search_embeddings = model.encode_text(search_tokens)

query = [{
"FindDescriptor": {
"set": "ViT-B/16", # Name of descriptor set to use
"k_neighbors": 10, # How many results to return
"distances": True, # Also return distances (as _distance property)
"blobs": False, # Don't return vectors of matching descriptors
"_ref": 1, # forward reference,
"metric": "CS",
"results": {
"list": ["_uniqueid"]
}
}
}, {
"FindImage": {
"blobs": True, # Return image binary data
"is_connected_to": {
"ref": 1 # backward reference
},
"results": {
"list": ["_uniqueid"], # Return only unique ids
"group_by_source": True
}
}
}]

if device == "cuda":
search_embeddings = search_embeddings.float()
blobs = search_embeddings[0].cpu().detach().numpy().tobytes()
else:
blobs = search_embeddings[0].detach().numpy().tobytes()

client = create_connector()
result, response, blobs = execute_query(client, query, [blobs])

# Print the response
print(response)

# Check if the query was successful
if result == 0:
# Here we reorder the images based on the distances before displaying them
# based on decreasing distance from the input vector.
descriptors = response[0]["FindDescriptor"]["entities"]
images = response[1]["FindImage"]["entities"]
for d in descriptors:
bi = images[d["_uniqueid"]][0]["_blob_index"]
display(d["_distance"], bi)
nbd([blobs[bi]])

[{'FindDescriptor': {'entities': [{'_distance': 0.29368117451667786, '_uniqueid': '3.184.484840'}, {'_distance': 0.28876030445098877, '_uniqueid': '3.187.484900'}, {'_distance': 0.26952141523361206, '_uniqueid': '3.173.484620'}, {'_distance': 0.2660259008407593, '_uniqueid': '3.167.484500'}, {'_distance': 0.25563734769821167, '_uniqueid': '3.169.484540'}, {'_distance': 0.2544242739677429, '_uniqueid': '3.177.484700'}, {'_distance': 0.2532556354999542, '_uniqueid': '3.168.484520'}, {'_distance': 0.2471557855606079, '_uniqueid': '3.178.484720'}, {'_distance': 0.2463374137878418, '_uniqueid': '3.170.484560'}, {'_distance': 0.24523672461509705, '_uniqueid': '3.164.484440'}], 'returned': 10, 'status': 0}}, {'FindImage': {'blobs_start': 0, 'entities': {'3.164.484440': [{'_blob_index': 0, '_uniqueid': '15.2.484440'}], '3.167.484500': [{'_blob_index': 1, '_uniqueid': '15.5.484500'}], '3.168.484520': [{'_blob_index': 2, '_uniqueid': '15.6.484520'}], '3.169.484540': [{'_blob_index': 3, '_uniqueid': '15.7.484540'}], '3.170.484560': [{'_blob_index': 4, '_uniqueid': '15.8.484560'}], '3.173.484620': [{'_blob_index': 5, '_uniqueid': '15.11.484620'}], '3.177.484700': [{'_blob_index': 6, '_uniqueid': '15.15.484700'}], '3.178.484720': [{'_blob_index': 7, '_uniqueid': '15.16.484720'}], '3.184.484840': [{'_blob_index': 8, '_uniqueid': '15.22.484840'}], '3.187.484900': [{'_blob_index': 9, '_uniqueid': '15.25.484900'}]}, 'group_by_source': True, 'returned': 10, 'status': 0}}]
0.29368117451667786
8
0.28876030445098877
9
0.26952141523361206
5
0.2660259008407593
1
0.25563734769821167
3
0.2544242739677429
6
0.2532556354999542
2
0.2471557855606079
7
0.2463374137878418
4
0.24523672461509705
0

png

png

png

png

png

png

png

png

png

png

What's Next?

  • Think about how to move from your current data tools to ApertureDB - learn more about the unique features and differences
  • Learn to add and work with various objects in your instance using our Cookbook dataset
  • Bulk load various data types