Skip to main content

API Description

ApertureDB uses one JSON command API for metadata, graph relationships, media, and vectors. Python and C++ clients send commands with a separate ordered list of binary blobs. Together, the command array and blob list form a query. For connection setup, see the client setup guide.

The Basics​

The API represents data as objects and connections, and operates on them through commands:

  • Objects: Each object is a node in the graph. Objects are of one of the following types:

    • Entity

    • Image

    • Video

    • Blob

    • DescriptorSet

    • Descriptor

    • BoundingBox

    • Polygon

    • Clip

    • Frame

  • Connections: represent relationships between objects.

  • Commands: perform specific actions on objects (Add/Find/Update/Delete) and the database (GetStatus/GetSchema/GetApiSchema).

Queries​

Clients send queries through an ApertureDB connector. Each query contains:

  • a JSON array of one or more commands, serialized as a string; and

  • an optional array of blobs for binary input.

The array of blobs carries binary data separately from the JSON. Each blob can contain:

  • An encoded Image (either a complete image, or a frame of a video)

  • An encoded Video

  • A feature vector (which is in itself an array of floating point values)

  • A user-defined blob

ApertureDB processes the commands and returns a response with two parts:

  • JSON command results (normally an array aligned with the query; errors can use other envelopes described in Responses), and

  • an optional array of blobs containing binary results.

Graph metadata operations in a query execute in one transaction. Response construction follows that transaction and can perform other work, including access-control changes and media retrieval. A response or delivery failure can therefore occur after writes have committed. See Responses for error phases and retry guidance; an error does not by itself prove that nothing changed.

Each command that consumes binary input takes the next blob in command order. Commands using an object URL instead of an uploaded blob do not consume that blob. For example, two AddImage commands without URLs require two encoded image blobs in the same order. Returned blobs_start and _blob_index fields refer to the separate response blob list.

The following Python example requires the aperturedb package, an existing database user with object-create permission, and a local luis_profile_photo.jpg file. Set APERTUREDB_HOST, APERTUREDB_USER, and APERTUREDB_PASSWORD in the environment. The second example uses the same connection settings and retrieves the image created by the first.

This query creates a person and an image, with a graph connection between them:

import os
from aperturedb import Connector

db = Connector.Connector(os.environ["APERTUREDB_HOST"],
user=os.environ["APERTUREDB_USER"],
password=os.environ["APERTUREDB_PASSWORD"])

query = [{
"AddEntity": {
"class": "Person",
"properties": {
"name": "Luis",
"email": "luis@aperturedata.io",
"id": 30
}
}
},{
"AddImage": {
"properties": {
"description": "profile photo",
"year_captured": 1990
}
}
}]

# Because we are inserting an image, a blob is expected
# in the blob_array

with open("luis_profile_photo.jpg", "rb") as fd:
image = fd.read()

blobs_array = [image]

# Execute the transaction
response, blobs = db.query(query, blobs_array)

# response is parsed JSON; use a helper function to
# print the JSON array nicely.
print(db.get_last_response_str())
print(f"Blobs returned: {len(blobs)}")

Output:

[{
"AddEntity": {
"status": 0
}
}, {
"AddImage": {
"status": 0
}
}]

In this example, no blob is returned as a result of the query, and the “blobs” variable will be an empty array.

Here is another example where the opposite happens: no blob is sent as part of the query, but blobs are returned as part of the response:

import os
from aperturedb import Connector

db = Connector.Connector(os.environ["APERTUREDB_HOST"],
user=os.environ["APERTUREDB_USER"],
password=os.environ["APERTUREDB_PASSWORD"])

query = [{
"FindImage": {
"constraints": ["$year_captured", "==", 1990],
"blobs": True,
"results": {
"list": ["year_captured", "description"]
}
}
}]

# Execute the transaction
response, blobs = db.query(query)

# response is parsed JSON; use a helper function to
# print the JSON array nicely.
print(db.get_last_response_str())

# Check the number of returned images:
print(f"Number of returned images: {len(blobs)}")

Output:

[{
"FindImage": {
"status": 0,
"blobs_start": 0,
"entities": [{
"_blob_index": 0,
"year_captured": 1990,
"description": "profile photo"
}],
"returned": 1
}
}]

In this case, the array of blobs (“blobs” variable) will have 1 elements, each of which is an encoded image.

Using the API​

The Python connector accepts Python lists and dictionaries and returns parsed response data plus a list of binary blobs. Native clients encode the command array as JSON. See Responses for response fields and error handling, and _ref and ref for references between commands.