Skip to main content
Image groups can consist of images with different dimensions. In contrast, image sequences are images that all have the same dimensions. When images of varying dimensions are grouped together, multiple image sequences are created, each containing files that share the same dimensions.

Create Image Groups

From Existing Files

from pathlib import Path
from uuid import UUID

from encord import EncordUserClient

# --- Configuration ---
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt"
FOLDER_ID = "00000000-0000-0000-0000-000000000000"

# --- Connect to Encord ---
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    # For US platform users use "https://api.us.encord.com"
    domain="https://api.encord.com",
)

folder = user_client.get_storage_folder(FOLDER_ID)

group_uuid: UUID = folder.create_image_group(
    file_paths=[
        Path("/path/to/front.jpg"),
        Path("/path/to/side.jpg"),
        Path("/path/to/rear.jpg"),
    ],
    title="vehicle-inspection-001",
)

print(f"Created image group with UUID: {group_uuid}")

from pathlib import Path
from uuid import UUID

from encord import EncordUserClient

# --- Configuration ---
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt"
FOLDER_ID = "00000000-0000-0000-0000-000000000000"

# --- Connect to Encord ---
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    domain="https://api.encord.com",
)

folder = user_client.get_storage_folder(FOLDER_ID)

image_groups = [
    {
        "title": "vehicle-inspection-001",
        "file_paths": [
            Path("./images/vehicle-001/front.jpg"),
            Path("./images/vehicle-001/side.jpg"),
            Path("./images/vehicle-001/rear.jpg"),
        ],
        "client_metadata": {
            "inspection_id": "001",
            "vehicle_type": "car",
        },
    },
    {
        "title": "vehicle-inspection-002",
        "file_paths": [
            Path("./images/vehicle-002/front.jpg"),
            Path("./images/vehicle-002/side.jpg"),
            Path("./images/vehicle-002/rear.jpg"),
        ],
        "client_metadata": {
            "inspection_id": "002",
            "vehicle_type": "truck",
        },
    },
]

for image_group in image_groups:
    group_uuid: UUID = folder.create_image_group(
        file_paths=image_group["file_paths"],
        title=image_group["title"],
        client_metadata=image_group["client_metadata"],
    )

    print(
        f"Created image group '{image_group['title']}' "
        f"with UUID: {group_uuid}"
    )
From Local Files

from encord import EncordUserClient
from encord.orm.dataset import LongPollingStatus
from encord.orm.storage import DataUploadImageGroupFromItems
from encord.storage import DataUploadItems

user_client = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path="<private_key_path>"
)

storage_folder = user_client.get_storage_folder("<folder_hash>")

image_group = DataUploadImageGroupFromItems(
    image_items=[
        "11111111-1111-1111-1111-111111111111",
        "22222222-2222-2222-2222-222222222222",
        "33333333-3333-3333-3333-333333333333",
    ],
    title="My Image Group",
)

upload_job_id = storage_folder.add_private_data_to_folder_start(
    integration_id="<integration_id>",
    private_files=DataUploadItems(
        image_groups_from_items=[image_group]
    ),
)

result = storage_folder.add_private_data_to_folder_get_result(upload_job_id)

if result.status == LongPollingStatus.DONE:
    print("Image group created successfully!")

from encord import EncordUserClient
from encord.orm.dataset import LongPollingStatus
from encord.orm.storage import DataUploadImageGroupFromItems
from encord.storage import DataUploadItems

# --- Configuration ---
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt"  # Replace with your SSH private key path
FOLDER_ID = "00000000-0000-0000-0000-000000000000"  # Replace with the Folder ID
INTEGRATION_ID = "00000000-0000-0000-0000-000000000000"  # Replace with the Integration ID

# --- Connect to Encord ---
user_client = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    # For US platform users use "https://api.us.encord.com"
    domain="https://api.encord.com",
)

storage_folder = user_client.get_storage_folder(FOLDER_ID)

image_groups = [
    DataUploadImageGroupFromItems(
        image_items=[
            "11111111-1111-1111-1111-111111111111",
            "22222222-2222-2222-2222-222222222222",
            "33333333-3333-3333-3333-333333333333",
        ],
        title="vehicle-inspection-001",
        client_metadata={
            "inspection_id": "001",
            "vehicle_type": "car",
        },
    ),
    DataUploadImageGroupFromItems(
        image_items=[
            "44444444-4444-4444-4444-444444444444",
            "55555555-5555-5555-5555-555555555555",
            "66666666-6666-6666-6666-666666666666",
        ],
        title="vehicle-inspection-002",
        client_metadata={
            "inspection_id": "002",
            "vehicle_type": "truck",
        },
    ),
]

upload_job_id = storage_folder.add_private_data_to_folder_start(
    integration_id=INTEGRATION_ID,
    private_files=DataUploadItems(
        image_groups_from_items=image_groups,
    ),
)

result = storage_folder.add_private_data_to_folder_get_result(upload_job_id)

if result.status == LongPollingStatus.DONE:
    print(f"Successfully created {len(image_groups)} image groups.")

Create Image Sequences

From Existing Files

from pathlib import Path
from uuid import UUID

from encord import EncordUserClient

# --- Configuration ---
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt"
FOLDER_ID = "00000000-0000-0000-0000-000000000000"

# --- Connect to Encord ---
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    # For US platform users use "https://api.us.encord.com"
    domain="https://api.encord.com",
)

folder = user_client.get_storage_folder(FOLDER_ID)

sequence_uuid: UUID = folder.create_image_sequence(
    file_paths=[
        Path("/path/to/frame001.jpg"),
        Path("/path/to/frame002.jpg"),
        Path("/path/to/frame003.jpg"),
    ],
    title="drive-sequence-001",
)

print(f"Created image sequence with UUID: {sequence_uuid}")

from pathlib import Path
from uuid import UUID

from encord import EncordUserClient

# --- Configuration ---
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt"  # Replace with the file path to your SSH private key
FOLDER_ID = "00000000-0000-0000-0000-000000000000"  # Replace with the Folder ID

# --- Connect to Encord ---
user_client: EncordUserClient = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    # For US platform users use "https://api.us.encord.com"
    domain="https://api.encord.com",
)

folder = user_client.get_storage_folder(FOLDER_ID)

image_sequences = [
    {
        "title": "drive-sequence-001",
        "file_paths": [
            Path("/path/to/frame001.jpg"),
            Path("/path/to/frame002.jpg"),
            Path("/path/to/frame003.jpg"),
        ],
        "client_metadata": {
            "sequence_id": "001",
            "scenario": "urban",
        },
    },
    {
        "title": "drive-sequence-002",
        "file_paths": [
            Path("/path/to/frame004.jpg"),
            Path("/path/to/frame005.jpg"),
            Path("/path/to/frame006.jpg"),
        ],
        "client_metadata": {
            "sequence_id": "002",
            "scenario": "highway",
        },
    },
]

for image_sequence in image_sequences:
    sequence_uuid: UUID = folder.create_image_sequence(
        file_paths=image_sequence["file_paths"],
        title=image_sequence["title"],
        client_metadata=image_sequence["client_metadata"],
    )

    print(
        f"Created image sequence '{image_sequence['title']}' "
        f"with UUID: {sequence_uuid}"
    )
From Local Files

from encord import EncordUserClient
from encord.orm.dataset import LongPollingStatus
from encord.orm.storage import DataUploadImageGroupFromItems
from encord.storage import DataUploadItems

# --- Configuration ---
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt"  # Replace with your SSH private key path
FOLDER_ID = "00000000-0000-0000-0000-000000000000"  # Replace with the Folder ID
INTEGRATION_ID = "00000000-0000-0000-0000-000000000000"  # Replace with the Integration ID

# --- Connect to Encord ---
user_client = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    domain="https://api.encord.com",
)

storage_folder = user_client.get_storage_folder(FOLDER_ID)

image_sequence = DataUploadImageGroupFromItems(
    image_items=[
        "11111111-1111-1111-1111-111111111111",
        "22222222-2222-2222-2222-222222222222",
        "33333333-3333-3333-3333-333333333333",
    ],
    title="drive-sequence-001",
    create_video=True,
)

upload_job_id = storage_folder.add_private_data_to_folder_start(
    integration_id=INTEGRATION_ID,
    private_files=DataUploadItems(
        image_groups_from_items=[image_sequence],
    ),
)

result = storage_folder.add_private_data_to_folder_get_result(upload_job_id)

if result.status == LongPollingStatus.DONE:
    print("Image sequence created successfully.")

from encord import EncordUserClient
from encord.orm.dataset import LongPollingStatus
from encord.orm.storage import DataUploadImageGroupFromItems
from encord.storage import DataUploadItems

# --- Configuration ---
SSH_PATH = "/Users/chris-encord/ssh-private-key.txt"  # Replace with your SSH private key path
FOLDER_ID = "00000000-0000-0000-0000-000000000000"  # Replace with the Folder ID
INTEGRATION_ID = "00000000-0000-0000-0000-000000000000"  # Replace with the Integration ID

# --- Connect to Encord ---
user_client = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    domain="https://api.encord.com",
)

storage_folder = user_client.get_storage_folder(FOLDER_ID)

image_sequences = [
    DataUploadImageGroupFromItems(
        image_items=[
            "11111111-1111-1111-1111-111111111111",
            "22222222-2222-2222-2222-222222222222",
            "33333333-3333-3333-3333-333333333333",
        ],
        title="drive-sequence-001",
        create_video=True,
        client_metadata={
            "sequence_id": "001",
            "scenario": "urban",
        },
    ),
    DataUploadImageGroupFromItems(
        image_items=[
            "44444444-4444-4444-4444-444444444444",
            "55555555-5555-5555-5555-555555555555",
            "66666666-6666-6666-6666-666666666666",
        ],
        title="drive-sequence-002",
        create_video=True,
        client_metadata={
            "sequence_id": "002",
            "scenario": "highway",
        },
    ),
]

upload_job_id = storage_folder.add_private_data_to_folder_start(
    integration_id=INTEGRATION_ID,
    private_files=DataUploadItems(
        image_groups_from_items=image_sequences,
    ),
)

result = storage_folder.add_private_data_to_folder_get_result(upload_job_id)

if result.status == LongPollingStatus.DONE:
    print(f"Successfully created {len(image_sequences)} image sequences.")

Create at Scale

For large-scale imports, create image groups and image sequences from a JSON manifest. This is the recommended approach when importing hundreds or thousands of grouped images because it avoids making one SDK request per group.

Image Groups


from pathlib import Path

from encord import EncordUserClient
from encord.orm.dataset import LongPollingStatus
from encord.storage import DataUploadItems

SSH_PATH = "/path/to/ssh-private-key.txt"
FOLDER_ID = "00000000-0000-0000-0000-000000000000"
JSON_FILE = Path("./image-groups.json")

user_client = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    # For US platform users use "https://api.us.encord.com"
    domain="https://api.encord.com",
)

folder = user_client.get_storage_folder(FOLDER_ID)

upload_job_id = folder.add_private_data_to_folder_start(
    DataUploadItems(file_path=JSON_FILE)
)

result = folder.add_private_data_to_folder_get_result(
    upload_job_id,
    timeout_seconds=600,
)

if result.status == LongPollingStatus.DONE:
    print("Upload complete.")
    print(result)
else:
    print("Upload did not complete within the timeout.")
    print(result)
{
  "image_groups": [
    {
      "title": "vehicle-inspection-001",
      "createVideo": false,
      "objectUrl_0": "s3://my-bucket/vehicle-001/front.jpg",
      "objectUrl_1": "s3://my-bucket/vehicle-001/side.jpg",
      "objectUrl_2": "s3://my-bucket/vehicle-001/rear.jpg",
      "clientMetadata": {
        "inspection_id": "001",
        "vehicle_type": "car"
      }
    },
    {
      "title": "vehicle-inspection-002",
      "createVideo": false,
      "objectUrl_0": "s3://my-bucket/vehicle-002/front.jpg",
      "objectUrl_1": "s3://my-bucket/vehicle-002/side.jpg",
      "objectUrl_2": "s3://my-bucket/vehicle-002/rear.jpg",
      "clientMetadata": {
        "inspection_id": "002",
        "vehicle_type": "truck"
      }
    },
    {
      "title": "vehicle-inspection-003",
      "createVideo": false,
      "objectUrl_0": "s3://my-bucket/vehicle-003/front.jpg",
      "objectUrl_1": "s3://my-bucket/vehicle-003/side.jpg",
      "objectUrl_2": "s3://my-bucket/vehicle-003/rear.jpg",
      "clientMetadata": {
        "inspection_id": "003",
        "vehicle_type": "van"
      }
    }
  ],
  "skip_duplicate_urls": true
}

Image Sequences

from pathlib import Path

from encord import EncordUserClient
from encord.orm.dataset import LongPollingStatus
from encord.storage import DataUploadItems

SSH_PATH = "/path/to/ssh-private-key.txt"
FOLDER_ID = "00000000-0000-0000-0000-000000000000"
JSON_FILE = Path("./image-sequences.json")

user_client = EncordUserClient.create_with_ssh_private_key(
    ssh_private_key_path=SSH_PATH,
    # For US platform users use "https://api.us.encord.com"
    domain="https://api.encord.com",
)

folder = user_client.get_storage_folder(FOLDER_ID)

upload_job_id = folder.add_private_data_to_folder_start(
    DataUploadItems(file_path=JSON_FILE)
)

result = folder.add_private_data_to_folder_get_result(
    upload_job_id,
    timeout_seconds=600,
)

if result.status == LongPollingStatus.DONE:
    print("Upload complete.")
    print(result)
else:
    print("Upload did not complete within the timeout.")
    print(result)

{
  "image_groups": [
    {
      "title": "drive-sequence-001",
      "createVideo": true,
      "objectUrl_0": "s3://my-bucket/drive-001/frame_0001.jpg",
      "objectUrl_1": "s3://my-bucket/drive-001/frame_0002.jpg",
      "objectUrl_2": "s3://my-bucket/drive-001/frame_0003.jpg",
      "clientMetadata": {
        "sequence_id": "001",
        "scenario": "urban"
      }
    },
    {
      "title": "drive-sequence-002",
      "createVideo": true,
      "objectUrl_0": "s3://my-bucket/drive-001/frame_0001.jpg",
      "objectUrl_1": "s3://my-bucket/drive-001/frame_0002.jpg",
      "objectUrl_2": "s3://my-bucket/drive-001/frame_0003.jpg",
      "clientMetadata": {
        "sequence_id": "002",
        "scenario": "urban"
      }
    },
    {
      "title": "drive-sequence-003",
      "createVideo": true,
      "objectUrl_0": "s3://my-bucket/drive-001/frame_0001.jpg",
      "objectUrl_1": "s3://my-bucket/drive-001/frame_0002.jpg",
      "objectUrl_2": "s3://my-bucket/drive-001/frame_0003.jpg",
      "clientMetadata": {
        "sequence_id": "003",
        "scenario": "urban"
      }
    }
  ],
  "skip_duplicate_urls": true
}