Sign in Get started

Connectors

Import datasets from V7 (Darwin) and Roboflow into Pictograph. Annotations are converted to canonical Pictograph JSON automatically.

View as Markdown

Import remote datasets in two steps: validate the source API key → kick off the import. The import runs as an async job; the SDK polls until terminal status by default.

from pictograph import Client
client = Client()

Supported providers

providerSourceNotes
v7V7 DarwinPolygon paths, bboxes, polylines, keypoints, tags
roboflowRoboflowCOCO export → Pictograph JSON

validate

Verify the source API key and list available remote datasets. No quota consumed; the API key is sent only on this call.

result = client.connectors.validate(
    provider="v7",
    api_key="v7_api_token_…",
)
if result.valid:
    for ds in result.datasets:
        print(ds.id, ds.name, ds.image_count)
else:
    print("invalid:", result.error)

Returns ValidationResult — inspect .valid first; .datasets is populated only on success.

check_limits

Pre-flight tier-cap check before kicking off an import.

check = client.connectors.check_limits(
    total_images=12500,
    estimated_size_bytes=4_000_000_000,   # 4 GB
)
if not check.allowed:
    print("blocked by:", check.exceeded)   # "images" / "storage" / "both"

import_

Kick off the import. Trailing underscore avoids shadowing the Python import keyword.

job = client.connectors.import_(
    provider="v7",
    api_key="v7_api_token_…",
    datasets=[
        {"id": "ds_abc", "name": "Road signs", "slug": "road-signs"},
        # OR pass RemoteDataset instances from validate():
        # *result.datasets[:2],
    ],
    wait=True,
    poll_interval=3.0,
    timeout=3600.0,                    # 1h default
)
print(job.import_id, job.status)
for ds in job.datasets:
    print(ds.dataset_name, ds.images_imported, "/", ds.total_images)
ArgTypeDefaultNotes
providerConnectorProviderrequired"v7" / "roboflow"
api_keystrrequiredSent only to fetch source data
datasetsSequence[RemoteDataset | dict]requiredRemoteDataset instances or raw dicts
waitboolTruePoll until terminal
poll_intervalfloat3.0seconds
timeoutfloat3600.0Max poll seconds (V7 large exports take 30+ min)

Returns ImportJob.

get_import / wait_for_import / cancel_import

job = client.connectors.get_import(import_id)
job = client.connectors.wait_for_import(import_id, timeout=600.0)
job = client.connectors.cancel_import(import_id)

Annotation conversion

V7 / COCOPictograph
V7 polygon.pathspolygon.paths (passthrough)
V7 bounding_box (no polygon)bounding_box
V7 line.pathpolyline.path
V7 keypointkeypoint
V7 tag / ellipse / maskskipped (no Pictograph equivalent)
COCO segmentation (flat array)polygon.paths (paired into points)
COCO bbox (no segmentation)bounding_box
COCO keypoints tripletskeypoint (skips v=0)

Tier caps

Imports are charged against your storage + image-count tier caps. See Credits and your plan in the web app.

Common errors

StatusExceptionCause
401AuthErrorSource provider API key rejected
402PaymentRequiredErrorTier cap exceeded
404NotFoundErrorimport_id missing
408PollTimeoutErrorwait=True exceeded timeout (job keeps running)
422ValidationErrorInvalid provider, empty datasets list
Copied to clipboard