Sign in Get started

Result models

Every object the Pictograph Python SDK returns, with its fields and types, generated from the released package and linked to its source.

View as Markdown
On this page

Generated from pictograph 1.69.199, released November 9, 2026. Each definition links to its source at v1.69.199.

What each call returns

Call Returns
client.annotation_comments.create() AnnotationComment
client.annotation_comments.delete() None
client.annotation_comments.list() Sequence[AnnotationComment]
client.annotation_comments.react() AnnotationComment
client.annotation_comments.reply() AnnotationComment
client.annotation_comments.resolve() AnnotationComment
client.annotation_comments.unreact() AnnotationComment
client.annotation_comments.update() AnnotationComment
client.annotations.bulk_save() BulkSaveResult
client.annotations.delete() DeleteResult
client.annotations.delete_class() DeleteClassResult
client.annotations.get() list[Annotation]
client.annotations.import_coco() AnnotationImportReport
client.annotations.import_pascal_voc() AnnotationImportReport
client.annotations.import_yolo() AnnotationImportReport
client.annotations.merge_class() MergeClassResult
client.annotations.rename_class() RenameClassResult
client.annotations.save() SaveResult
client.api_keys.create() CreatedApiKey
client.api_keys.get() ApiKey
client.api_keys.list() list[ApiKey]
client.api_keys.revoke() None
client.api_keys.update() ApiKey
client.auto_annotate.batch() BatchJob
client.auto_annotate.box() PromptResult
client.auto_annotate.cancel_batch() BatchJob
client.auto_annotate.dataset() AnnotateReport
client.auto_annotate.get_batch() BatchJob
client.auto_annotate.point() PromptResult
client.auto_annotate.quote() BatchQuote
client.auto_annotate.quote_similar() SimilarQuote
client.auto_annotate.similar() BatchJob
client.auto_annotate.text() PromptResult
client.auto_annotate.wait_for_batch() BatchJob
client.batch.copy() BatchResult
client.batch.copy_to_dataset() CopyToDatasetResult
client.batch.delete() BatchResult
client.batch.move() BatchResult
client.batch.update() BatchResult
client.connectors.cancel_import() ImportJob
client.connectors.check_limits() LimitCheckResult
client.connectors.get_import() ImportJob
client.connectors.import_() ImportJob
client.connectors.validate() ValidationResult
client.connectors.wait_for_import() ImportJob
client.credits.balance() CreditBalance
client.credits.estimate() CreditEstimate
client.credits.history() list[CreditLedgerEntry]
client.credits.iter() OffsetPager[CreditLedgerEntry]
client.credits.usage_by_operation() UsageByOperation
client.datasets.archive() Dataset
client.datasets.as_pytorch() PictographTorchDataset
client.datasets.backfill_embeddings() EmbeddingBackfill
client.datasets.create() Dataset
client.datasets.delete() DatasetDeleteResult
client.datasets.download() DownloadReport
client.datasets.freeze() DatasetStorageTransition
client.datasets.get() Dataset
client.datasets.get_public_import() PublicDatasetImport
client.datasets.import_public() PublicDatasetImport
client.datasets.insights() DatasetInsights
client.datasets.iter() OffsetPager[Dataset]
client.datasets.list() list[Dataset]
client.datasets.near_duplicates() NearDuplicatesResult
client.datasets.restore() DatasetStorageTransition
client.datasets.storage_status() DatasetStorageStatus
client.datasets.unarchive() Dataset
client.datasets.update() Dataset
client.datasets.wait_for_public_import() PublicDatasetImport
client.datasets.wait_for_storage() DatasetStorageStatus
client.deployments.bulk_delete() BulkDeleteResult
client.deployments.bulk_pause() BulkActionResult
client.deployments.bulk_resume() BulkActionResult
client.deployments.compute_options() DeploymentComputeOptions
client.deployments.connect() DeploymentClient[Any]
client.deployments.create() CreatedDeployment
client.deployments.delete() None
client.deployments.get() Deployment
client.deployments.iter() OffsetPager[Deployment]
client.deployments.list() list[Deployment]
client.deployments.pause() Deployment
client.deployments.quote() DeploymentQuote
client.deployments.resume() Deployment
client.deployments.update() Deployment
client.deployments.wait_until_active() Deployment
client.directories.create() Directory
client.directories.delete() None
client.directories.list() Sequence[Directory]
client.directories.rename() Directory
client.directories.stats() DirectoryStats
client.directories.tree() Sequence[DirectoryTreeNode]
client.explore.dataset() PublicDataset
client.explore.datasets() list[PublicDataset]
client.explore.iter_datasets() OffsetPager[PublicDataset]
client.explore.iter_models() OffsetPager[PublicModel]
client.explore.model() PublicModelDetail
client.explore.models() list[PublicModel]
client.exports.bulk_delete() BulkDeleteResult
client.exports.create() Export
client.exports.delete() None
client.exports.download() Path
client.exports.get() Export
client.exports.iter() OffsetPager[Export]
client.exports.list() list[Export]
client.exports.wait_for_completion() Export
client.images.assign_splits() dict[str, int]
client.images.augment() AugmentReport
client.images.bulk_tag() int
client.images.bulk_upload() BulkUploadResult
client.images.delete() None
client.images.download() Path
client.images.download_bundle() Path
client.images.get() Image
client.images.iter() CursorPager[Image]
client.images.list() list[Image]
client.images.review() ImageStatus
client.images.set_split() ImageSplit | None
client.images.tile() TileReport
client.images.upload() Image
client.images.upload_from_directory() UploadReport
client.jobs.cancel() Job
client.jobs.get() Job
client.jobs.list() OffsetPager[Job]
client.jobs.wait() Job
client.model_evaluations.cancel() ModelEvaluation
client.model_evaluations.compute_options() EvaluationComputeOptions
client.model_evaluations.create() ModelEvaluation
client.model_evaluations.evaluate() ModelEvaluation
client.model_evaluations.get() ModelEvaluation
client.model_evaluations.iter() OffsetPager[ModelEvaluation]
client.model_evaluations.list() list[ModelEvaluation]
client.model_evaluations.report() dict[str, Any]
client.model_evaluations.wait_for_completion() ModelEvaluation
client.models.bulk_delete() BulkDeleteResult
client.models.delete() None
client.models.download() Path
client.models.download_file() Path
client.models.files() ModelFileManifest
client.models.fork() Model
client.models.get() Model
client.models.iter() OffsetPager[Model]
client.models.list() list[Model]
client.models.load() AnyModel
client.models.predict() ModelPredictResult
client.models.set_current_version() ModelVersionsPayload
client.models.update() Model
client.models.versions() ModelVersionsPayload
client.notifications.delete() None
client.notifications.list() list[Notification]
client.notifications.mark_all_read() int
client.notifications.mark_read() None
client.notifications.unread_count() int
client.organizations.invite() OrganizationInvite
client.organizations.list_invites() list[OrganizationInvite]
client.organizations.list_members() list[OrganizationMember]
client.organizations.me() Organization
client.organizations.remove_member() None
client.organizations.revoke_invite() None
client.organizations.update() Organization
client.organizations.update_member_role() dict[str, Any]
client.sam3.predict() Sam3Prediction
client.search.by_similarity() list[SimilarImage]
client.search.by_tag() list[TaggedImage]
client.tasks.contributions() TaskContributions
client.tasks.iter() OffsetPager[Task]
client.tasks.list() list[Task]
client.tools.describe() ToolCard
client.tools.list() list[ToolSummary]
client.training.augmentation_profiles() AugmentationProfiles
client.training.bulk_cancel() BulkActionResult
client.training.cancel() TrainingRun
client.training.create() TrainingRun
client.training.get() TrainingRun
client.training.iter() OffsetPager[TrainingRun]
client.training.list() list[TrainingRun]
client.training.quote() TrainingQuote
client.training.wait_for_completion() TrainingRun
client.video.extract_frames() VideoExtractionJob
client.video.get_extraction() VideoExtractionJob
client.video.probe() VideoMetadata
client.video.upload() VideoUploadInfo
client.video.wait_for_extraction() VideoExtractionJob
client.webhooks.create() CreatedWebhookEndpoint
client.webhooks.delete() None
client.webhooks.deliveries() Sequence[WebhookDelivery]
client.webhooks.event_types() list[str]
client.webhooks.get() WebhookEndpoint
client.webhooks.list() Sequence[WebhookEndpoint]
client.webhooks.replay() None
client.webhooks.rotate_secret() CreatedWebhookEndpoint
client.webhooks.test() dict[str, Any]
client.webhooks.update() WebhookEndpoint
client.workflows.bulk_cancel_runs() BulkActionResult
client.workflows.bulk_delete() BulkDeleteResult
client.workflows.cancel_run() None
client.workflows.compute_options() WorkflowComputeOptions
client.workflows.connect() DeploymentClient[Any]
client.workflows.create() Workflow
client.workflows.delete() None
client.workflows.deploy() Workflow
client.workflows.get() Workflow
client.workflows.get_run() WorkflowRun
client.workflows.iter_live_log() Iterator[RunLogRecord]
client.workflows.iter_run_log() Iterator[RunLogRecord]
client.workflows.iter_runs() OffsetPager[WorkflowRunSummary]
client.workflows.list() Sequence[Workflow]
client.workflows.list_runs() Sequence[WorkflowRunSummary]
client.workflows.live_log() RunLogPage
client.workflows.live_log_summary() RunLogSummary
client.workflows.nodes() WorkflowNodeCatalog
client.workflows.pause() Workflow
client.workflows.resume() Workflow
client.workflows.run() WorkflowRunCreated | WorkflowRun WorkflowRunCreated, WorkflowRun
client.workflows.run_log() RunLogPage
client.workflows.run_log_summary() RunLogSummary
client.workflows.templates() Sequence[WorkflowTemplate]
client.workflows.update() Workflow
client.workflows.update_endpoint() Workflow
client.workflows.upload_source() str
client.workflows.validate() WorkflowValidation
client.workflows.wait_for_run() WorkflowRun
client.workflows.wait_until_live() Workflow
client.workflows.watch_run() DeploymentStream[Any]

Models

AnnotateReport

class AnnotateReport(BaseModel):
    """Outcome of an AutoAnnotate.dataset call."""
    dataset_name: str
    images_attempted: int = 0
    images_processed: int = 0
    images_skipped: int = 0
    images_capped: int = 0
    annotations_added: int = 0
    failures: list[AnnotationFailure] = []
    job_id: str | None = None
    job_status: str | None = None

    @property
    def success(self) -> bool: ...

Source

Annotation

Annotation = (
    BBoxAnnotation
    | PolygonAnnotation
    | PolylineAnnotation
    | KeypointAnnotation
)

Source

AnnotationComment

class AnnotationComment(BaseModel):
    """One comment on an annotation."""
    id: str
    annotation_id: str
    body: str
    resolved: bool = False
    parent_comment_id: str | None = None
    is_edited: bool = False
    is_deleted: bool = False
    resolved_by: str | None = None
    resolved_by_name: str | None = None
    resolved_at: datetime | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None
    user_id: str | None = None
    author_name: str | None = None
    author_username: str | None = None
    author_avatar_url: str | None = None
    is_mine: bool = False
    reactions: list[AnnotationCommentReaction] = []

Source

AnnotationCommentReaction

class AnnotationCommentReaction(BaseModel):
    """A grouped reaction tally on a comment (one entry per reaction key)."""
    reaction: str
    count: int = 0
    reacted: bool = False

Source

AnnotationFailure

class AnnotationFailure(BaseModel):
    """One image that failed to auto-annotate in AutoAnnotate.dataset."""
    image_filename: str
    reason: str
    error_type: str | None = None
    code: str | None = None

Source

AnnotationImportFailure

class AnnotationImportFailure(BaseModel):
    """One image whose imported annotations could not be saved."""
    image_filename: str
    reason: str

Source

AnnotationImportReport

class AnnotationImportReport(BaseModel):
    """Outcome of an Annotations.import_coco / `import_pascal_voc` / `import_yolo` call."""
    dataset_name: str
    images_matched: int = 0
    images_saved: int = 0
    annotations_saved: int = 0
    unmatched_files: list[str] = []
    failures: list[AnnotationImportFailure] = []
    unconverted: list[str] = []

    @property
    def success(self) -> bool: ...

Source

AnyModel

AnyModel = (
    DetectionModel
    | InstanceSegmentationModel
    | SemanticSegmentationModel
    | KeypointModel
    | ClassificationModel
)

Source

ApiKey

class ApiKey(BaseModel):
    """API key metadata returned by list/get/update endpoints."""
    id: str
    organization_id: str
    name: str
    # First 12 characters (e.g., 'pk_live_abc1') - safe to log.
    key_prefix: str
    role: Literal['viewer', 'member', 'admin', 'owner']
    rate_limit: int
    is_active: bool
    last_used_at: datetime | None = None
    expires_at: datetime | None = None
    created_at: datetime

Source

AugmentFailure

class AugmentFailure(BaseModel):
    """One source image that failed to augment (kind in `reason`)."""
    image_id: str
    filename: str
    reason: str

Source

AugmentReport

class AugmentReport(BaseModel):
    """Outcome of an Images.augment run."""
    source: str
    target: str
    source_images: int = 0
    originals_copied: int = 0
    variants_created: int = 0
    annotations_written: int = 0
    skipped_empty: int = 0
    failures: list[AugmentFailure] = []

    @property
    def success(self) -> bool: ...

Source

AugmentationFrameworkSetting

class AugmentationFrameworkSetting(BaseModel):
    """One of a pipeline's own augmentation settings (`config["augmentation"]["framework"]`)."""
    key: str
    default: float
    min: float
    max: float
    label: str = ''
    step: float | None = None

Source

AugmentationProfile

class AugmentationProfile(BaseModel):
    """What one pipeline's `config["augmentation"]` takes, and what it applies by default."""
    # The ops it takes.
    available_ops: list[str] = []
    # The ops it applies when a run sends none.
    default_ops: list[dict[str, Any]] = []
    # Its own settings, with their ranges.
    framework: list[AugmentationFrameworkSetting] = []
    note: str = ''

Source

AugmentationProfiles

class AugmentationProfiles(BaseModel):
    """Every pipeline's training-time augmentation (`training.augmentation_profiles`)."""
    # By `pipeline_type`.
    profiles: dict[str, AugmentationProfile] = {}

Source

BBoxAnnotation

class BBoxAnnotation(BaseModel):
    """Bounding-box annotation - axis-aligned by default, optionally ROTATED."""
    # Unique within the image; a UUID is generated when omitted.
    id: str = ...
    # Class name, case-sensitive; use one of the dataset's classes.
    name: str
    type: Literal['bbox'] = 'bbox'
    bounding_box: BoundingBox
    # Present only on a rotated box; bounding_box is then its axis-aligned enclosure.
    # Training uses bounding_box either way.
    oriented_box: OrientedBoxGeometry | None = None
    confidence: float = 1.0
    created_by: str | None = None
    attributes: dict[str, object] | list[object] = []

Source

BatchFailure

class BatchFailure(BaseModel):
    """One image that failed within a batch operation."""
    id: str
    reason: str

Source

BatchJob

class BatchJob(BaseModel):
    """Snapshot of an auto-annotate batch job's progress."""
    job_id: str
    status: Literal['pending', 'running', 'completed', 'failed', 'cancelled']
    # 0-100. 100 only at terminal state.
    progress: int = 0
    total_images: int = 0
    processed_images: int = 0
    total_annotations_added: int = 0
    failed_images: int = 0
    error_message: str | None = None
    # Only on the response that started the job: the deposit taken, in micro-USD.
    estimated_credits: int | None = None
    completed_at: datetime | None = None

Source

BatchQuote

class BatchQuote(BaseModel):
    """What a batch job would cost: the deposit `batch()` would take."""
    total_images: int
    # The cost, in micro-USD.
    estimated_credits: int
    # Total SAHI tile passes priced.
    sahi_tiles: int = 0
    # T4 containers the job runs on.
    containers: int = 0
    # Your remaining balance (µUSD).
    remaining_credits: int = 0
    # Whether the balance covers the estimate.
    sufficient: bool = True
    # Image ceiling for a single job.
    max_images: int = 5000
    # True when this configuration is past the ceiling and must be split.
    exceeds_max_images: bool = False

Source

BatchResult

class BatchResult(BaseModel):
    """Outcome of a batch operation."""
    success: bool
    processed: int
    failed: list[BatchFailure] = []
    affected_directories: list[str] = []
    renamed: int = 0
    operation: str | None = None

Source

BoundingBox

class BoundingBox(BaseModel):
    """A bounding box: top-left corner + size, absolute pixels."""
    x: float
    y: float
    # Width in pixels (strictly positive).
    w: float
    # Height in pixels (strictly positive).
    h: float

Source

BulkActionResult

class BulkActionResult(BaseModel):
    """What a bulk change (pause, resume, cancel) did."""
    # Ids this call changed.
    succeeded: list[str] = []
    # Ids not found, or not in a state it could change.
    not_found: list[str] = []
    # How many were changed.
    count: int = 0

Source

BulkDeleteResult

class BulkDeleteResult(BaseModel):
    """What a bulk delete removed."""
    # Ids that existed and were deleted.
    succeeded: list[str] = []
    # Ids that were not found.
    not_found: list[str] = []
    # How many were deleted.
    count: int = 0

    # The same as succeeded.
    @property
    def deleted(self) -> list[str]: ...

Source

BulkSaveFailure

class BulkSaveFailure(BaseModel):
    """One image that could not be saved in a Annotations.bulk_save call."""
    image_id: str
    error: str

Source

BulkSaveResult

class BulkSaveResult(BaseModel):
    """Outcome of Annotations.bulk_save."""
    saved: list[SaveResult]
    failed: list[BulkSaveFailure]

    # Number of images successfully saved.
    @property
    def saved_count(self) -> int: ...

Source

BulkUploadFailure

class BulkUploadFailure(BaseModel):
    """One file that couldn't be registered in a Images.bulk_upload call (e.g. a filename that already exists in the target directory)."""
    filename: str
    error: str
    directory_path: str = '/'

Source

BulkUploadResult

class BulkUploadResult(BaseModel):
    """Outcome of Images.bulk_upload."""
    succeeded: list[Image]
    failed: list[BulkUploadFailure]

    # Number of files successfully uploaded + registered.
    @property
    def count(self) -> int: ...

Source

ClassAttribute

class ClassAttribute(BaseModel):
    """A class-level ONTOLOGY attribute definition."""
    name: str
    # Input control: text | number | select | checkbox.
    type: Literal['text', 'number', 'select', 'checkbox'] = 'text'
    # Allowed values for a 'select' attribute.
    values: list[str] | None = None

Source

CopyToDatasetResult

class CopyToDatasetResult(BaseModel):
    """Outcome of pictograph.resources.batch.Batch.copy_to_dataset."""
    success: bool
    processed: int
    failed: list[BatchFailure] = []
    affected_directories: list[str] = []
    renamed: int = 0
    operation: str | None = None
    target_dataset: str
    classes_added: list[str] = []

Source

CreatedApiKey

class CreatedApiKey(BaseModel):
    """Response from ApiKeys.create - includes the secret one time only."""
    # The full secret. The API returns it only here - store it securely (Settings can
    # reveal it again, once per sign-in).
    api_key: str
    key_id: str
    key_prefix: str
    name: str
    role: Literal['viewer', 'member', 'admin', 'owner']
    rate_limit: int
    expires_at: datetime | None = None
    created_at: datetime

Source

CreatedDeployment

class CreatedDeployment(BaseModel):
    """What `create` returns: the deployment and its token, shown once."""
    deployment: Deployment
    # The deployment's bearer token. The API returns it only here; a member can reveal
    # it again in the app.
    auth_token: str

Source

CreatedWebhookEndpoint

class CreatedWebhookEndpoint(BaseModel):
    """An endpoint and its signing secret (from create or a rotation)."""
    endpoint: WebhookEndpoint
    # The signing secret; the app shows it again under Settings → Webhooks.
    secret: str

Source

CreditBalance

class CreditBalance(BaseModel):
    """An organization's compute wallet, in micro-USD (µUSD)."""
    # The plan's monthly allowance.
    included_allowance_micro_usd: int = 0
    # Allowance and prepaid credit left to spend this period.
    included_remaining_micro_usd: int = 0
    # Monthly spend cap, allowance included; equals the allowance with pay-as-you-go
    # off.
    budget_micro_usd: int = 0
    # Spent this period.
    period_spend_micro_usd: int = 0
    # Spent beyond the allowance this period.
    period_overage_micro_usd: int = 0
    # Left under the spend cap this period.
    budget_remaining_micro_usd: int = 0
    # Start of the current billing period.
    period_start: datetime | None = None
    # When the monthly allowance resets next.
    credits_reset_at: datetime | None = None
    # DEPRECATED: whole-dollar remaining credit. Use included_remaining_micro_usd.
    credits_remaining: int = 0
    # DEPRECATED: whole-dollar monthly allowance. Use included_allowance_micro_usd.
    credits_monthly_allowance: int = 0
    # The last 20 ledger entries, newest first.
    recent_history: list[CreditLedgerEntry] = []

    # Monthly included allowance in USD (`included_allowance_micro_usd / 1e6`).
    @property
    def allowance_usd(self) -> float: ...

    # Remaining overage budget in USD (`budget_remaining_micro_usd / 1e6`).
    @property
    def budget_remaining_usd(self) -> float: ...

    # Overage budget cap in USD (`budget_micro_usd / 1e6`).
    @property
    def budget_usd(self) -> float: ...

    # Overage incurred this period in USD (`period_overage_micro_usd / 1e6`).
    @property
    def overage_usd(self) -> float: ...

    # Remaining included allowance in USD (`included_remaining_micro_usd / 1e6`).
    @property
    def remaining_usd(self) -> float: ...

    # Total spend this period in USD (`period_spend_micro_usd / 1e6`).
    @property
    def spend_usd(self) -> float: ...

Source

CreditEstimate

class CreditEstimate(BaseModel):
    """What a planned operation would cost, in micro-USD (µUSD), and whether the balance covers it."""
    operation: str
    # The unit priced, such as 'minute', 'image' or 'run'.
    unit: str
    quantity: int
    # Price per unit.
    micro_usd_per_unit: int = 0
    # `micro_usd_per_unit * quantity`.
    total_micro_usd: int = 0
    # What the organization could spend when this was estimated.
    remaining_micro_usd: int = 0
    # Whether the balance covers `total_micro_usd`.
    sufficient: bool = False
    # DEPRECATED: whole-dollar per-unit cost. Use micro_usd_per_unit.
    credits_per_unit: int = 0
    # DEPRECATED: whole-dollar total cost. Use total_micro_usd.
    total_credits: int = 0
    # DEPRECATED: whole-dollar floor on total. No longer used (always 0).
    minimum: int = 0
    # DEPRECATED: whole-dollar remaining balance. Use remaining_micro_usd.
    credits_remaining: int = 0

    # Per-unit cost in USD (`micro_usd_per_unit / 1e6`).
    @property
    def per_unit_usd(self) -> float: ...

    # Spendable compute credit in USD (`remaining_micro_usd / 1e6`).
    @property
    def remaining_usd(self) -> float: ...

    # Total estimated cost in USD (`total_micro_usd / 1e6`).
    @property
    def total_usd(self) -> float: ...

Source

CreditLedgerEntry

class CreditLedgerEntry(BaseModel):
    """A single entry in the organization's credit ledger."""
    id: str
    # Operation slug, such as 'training_a10g' or 'sam3_auto_annotation'.
    operation: str
    # Micro-USD: negative for a charge, positive for a top-up, reset or refund.
    amount: int
    # What could be spent right after this entry, in micro-USD.
    balance_after: int | None = None
    description: str | None = None
    metadata: dict[str, Any] | None = None
    created_at: datetime

Source

Dataset

class Dataset(BaseModel):
    """A Pictograph dataset - a group of images sharing an annotation config."""
    id: str
    # The organization that owns it.
    organization_id: str | None = None
    name: str
    # Its URL slug: pictograph.io/datasets/<organization>/<slug>.
    slug: str | None = None
    description: str | None = None
    annotation_types: list[str] = ['bbox']
    # Its classes; empty until it has any.
    classes: list[DatasetClass] = []
    # Images, archived ones excluded.
    image_count: int = 0
    # Images at the complete stage.
    completed_image_count: int = 0
    # Archived images (restorable).
    archived_image_count: int = 0
    # Bytes of its images, archived ones excluded.
    total_size: int = 0
    # Listed on Explore, readable by anyone.
    is_public: bool = False
    is_archived: bool = False
    archived_at: datetime | None = None
    # Where its images are stored: standard or coldline (cold storage).
    storage_class: str = 'standard'
    # Its license, a catalog id such as 'mit' or 'cc-by-4.0' ('custom': the terms are in
    # license_custom_text).
    license_id: str | None = None
    # A custom license's terms (on get, not on list rows).
    license_custom_text: str | None = None
    # Its dataset card, in markdown (on get, not on list rows).
    readme: str | None = None
    # Where an imported dataset came from (on get, not on list rows).
    source: DatasetSource | None = None
    # Its Hugging Face mirror (e.g. 'pictograph/a2d2') while the mirror is live (on get,
    # not on list rows).
    hf_repo: str | None = None
    # The image paths it shows on every card and page, in order; [] = automatic, the
    # best-annotated images (on get, not on list rows).
    hero_images: list[str] | None = None
    # Its images, only from `datasets.get(..., include_images=True)`.
    images: list[Image] | None = None
    created_at: datetime
    updated_at: datetime | None = None

Source

DatasetClass

class DatasetClass(BaseModel):
    """A class definition stored on the dataset's config."""
    name: str
    # The annotation type it's for: bbox, polygon, polyline, keypoint or tag.
    type: str | None = None
    # Hex color, such as '#e6194b'. Omitted on a write, one is assigned from the class
    # palette.
    color: str | None = None
    # The attributes an annotation of this class may carry.
    attributes: list[ClassAttribute] | None = None
    # A keypoint class's joint template (nodes and 0-indexed edges).
    skeleton: SkeletonTemplate | None = None

Source

DatasetDeleteResult

class DatasetDeleteResult(BaseModel):
    """What `datasets.delete` removed."""
    id: str
    name: str
    deleted: bool = True
    # Images deleted.
    images_deleted: int = 0
    # Directories deleted.
    directories_deleted: int = 0
    # Stored files deleted.
    files_deleted: int = 0
    # Stored files kept because an imported copy of the dataset still uses them.
    files_kept: int = 0

Source

DatasetImportProgress

class DatasetImportProgress(BaseModel):
    """Per-dataset progress row inside an ImportJob."""
    name: str | None = None
    dataset_id: str | None = None
    status: Optional[Literal['pending', 'processing', 'completed', 'error', 'cancelled']] = None
    imported: int = 0
    failed: int = 0

Source

DatasetInsights

class DatasetInsights(BaseModel):
    """Dataset Health / Insights - headline totals, class balance, and more."""
    total_images: int = 0
    total_annotations: int = 0
    annotated_images: int = 0
    unannotated_images: int = 0
    avg_annotations_per_image: float = 0.0
    total_bytes: int = 0
    status_counts: InsightsStatusCounts = ...
    class_annotation_counts: dict[str, int] = {}
    class_image_counts: dict[str, int] = {}
    type_counts: dict[str, int] = {}
    annotation_density: dict[str, int] = {}
    dimensions: InsightsDimensions = ...
    model_confidence: ModelConfidence | None = None

Source

DatasetRestoreEstimate

class DatasetRestoreEstimate(BaseModel):
    """Price quote (integer micro-USD) for restoring a cold dataset."""
    operation: str = 'dataset_restore'
    cold_bytes: int = 0
    cold_image_count: int = 0
    days_in_cold: float = 0.0
    min_storage_days: float = 90.0
    monthly_savings_micro_usd: int = 0
    retrieval_micro_usd: int = 0
    early_delete_micro_usd: int = 0
    operations_micro_usd: int = 0
    total_micro_usd: int = 0

Source

DatasetSource

class DatasetSource(BaseModel):
    """Where an imported dataset came from - its credit line."""
    # The source dataset's name, e.g. 'A2D2'.
    name: str | None = None
    # Where the original is published.
    url: str | None = None
    # Who made it.
    author: str | None = None

Source

DatasetStorageStatus

class DatasetStorageStatus(BaseModel):
    """Cold-storage state of a dataset (`GET /developer/datasets/{id}/storage`)."""
    storage_class: str = 'standard'
    storage_state: str = 'idle'
    cold_since: datetime | None = None
    cold_bytes: int = 0
    cold_image_count: int = 0
    storage_job_id: str | None = None
    restore_estimate: DatasetRestoreEstimate | None = None

Source

DatasetStorageTransition

class DatasetStorageTransition(BaseModel):
    """Acknowledgement that a freeze/restore background job started."""
    job_id: str
    storage_state: str
    quoted_micro_usd: int | None = None

Source

DeleteClassResult

class DeleteClassResult(BaseModel):
    """Outcome of Annotations.delete_class."""
    dataset_id: str
    name: str
    config_updated: bool
    images_updated: int
    annotations_removed: int

Source

DeleteResult

class DeleteResult(BaseModel):
    """Outcome of Annotations.delete."""
    image_id: str
    deleted_count: int

Source

Deployment

class Deployment(BaseModel):
    """A model inference deployment: provisioning, active, paused, failed or terminated."""
    id: str
    organization_id: str
    model_id: str
    version_id: str | None = None
    name: str
    readme: str | None = None
    status: Literal['draft', 'provisioning', 'active', 'paused', 'failed', 'terminated']
    region: str | None = None
    compute_type: Literal['cpu', 'gpu'] = 'gpu'
    gpu_type: str | None = None
    precision: str = 'fp32'
    min_containers: int
    max_containers: int
    scaledown_window: int
    rate_limit_rpm: int | None = None
    endpoint_url: str | None = None
    auth_token_prefix: str | None = None
    inference_config: dict[str, Any] = {}
    engine_build: EngineBuild | None = None
    error_message: str | None = None
    cost_rate_per_min: int = 0
    cost_per_hour_micro_usd: int | None = None
    max_cost_per_hour_micro_usd: int | None = None
    transfer_per_gib_micro_usd: int | None = None
    accrued_cost_micro_usd: int = 0
    uptime_seconds: int = 0
    transfer_bytes: int = 0
    transfer_cost_micro_usd: int = 0
    metrics: DeploymentMetrics | None = None
    runtime: DeploymentRuntime | None = None
    stream_limit: int = 0
    region_fallback: bool = False
    logged: bool | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None
    started_at: datetime | None = None
    paused_at: datetime | None = None

Source

DeploymentComputeOption

class DeploymentComputeOption(BaseModel):
    """A GPU tier a deployment runs on: its container and its price (one container)."""
    key: str
    label: str
    compute_type: Literal['cpu', 'gpu'] = 'gpu'
    gpu_type: str | None = None
    is_gpu: bool = True
    description: str = ''
    vram_gb: int | None = None
    cpu_cores: float | None = None
    memory_gib: float | None = None
    rate_per_min_micro_usd: int
    cost_per_hour_micro_usd: int | None = None

Source

DeploymentComputeOptions

class DeploymentComputeOptions(BaseModel):
    """What a deployment may run with: the regions (and the one these prices are for), each GPU tier (its container and price there) and each precision its engine is built at, the default first."""
    region: str | None = None
    regions: list[DeploymentRegion] = []
    options: list[DeploymentComputeOption] = []
    precisions: list[DeploymentComputePrecision] = []
    transfer_per_gib_micro_usd: int | None = None

Source

DeploymentComputePrecision

class DeploymentComputePrecision(BaseModel):
    """A precision a deployment's TensorRT engine can be built at, with its label."""
    precision: str
    label: str
    description: str = ''

Source

DeploymentMetrics

class DeploymentMetrics(BaseModel):
    """The requests a deployment has served."""
    requests: int = 0
    errors: int = 0
    avg_latency_ms: float = 0.0
    error_rate: float = 0.0
    last_request_at: datetime | None = None

Source

DeploymentQuote

class DeploymentQuote(BaseModel):
    """What a deployment costs while it is up, before creating it, in micro-USD."""
    rate_per_min_micro_usd: int
    container_cost_per_hour_micro_usd: int | None = None
    cost_per_hour_micro_usd: int
    cost_per_day_micro_usd: int
    warm_cost_per_hour_micro_usd: int | None = None
    warm_cost_per_day_micro_usd: int | None = None
    max_cost_per_hour_micro_usd: int | None = None
    transfer_per_gib_micro_usd: int | None = None
    scale_to_zero: bool
    billing_note: str

Source

DeploymentRegion

class DeploymentRegion(BaseModel):
    """A region a deployment can run in."""
    id: str
    label: str
    location: str = ''
    ping_url: str | None = None

Source

DeploymentRuntime

class DeploymentRuntime(BaseModel):
    """What an `active` deployment is doing right now, as Pictograph read it at `checked_at`."""
    state: str
    containers: int = 0
    creating: int = 0
    streams: int = 0
    fallback: int = 0
    waiting_since: datetime | None = None
    checked_at: datetime | None = None

Source

Directory

class Directory(BaseModel):
    """A single virtual directory in a dataset."""
    id: str
    dataset_id: str
    organization_id: str | None = None
    name: str
    parent_directory_id: str | None = None
    full_path: str
    image_count: int = 0
    nested_image_count: int = 0
    created_by: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None

Source

DirectoryStats

class DirectoryStats(BaseModel):
    """Aggregate image statistics for a directory (and, by default, its subdirectories)."""
    total_directories: int
    total_images: int
    total_size_bytes: int
    directories_by_status: dict[str, int] = {}

Source

DirectoryTreeNode

class DirectoryTreeNode(BaseModel):
    """A node in the hierarchical directory tree (children nested recursively)."""
    id: str
    name: str
    full_path: str
    image_count: int = 0
    nested_image_count: int = 0
    children: list[DirectoryTreeNode] = []

Source

DownloadFailure

class DownloadFailure(BaseModel):
    """Single failed download - collected and returned, not raised."""
    filename: str
    kind: Literal['image', 'annotation']
    reason: str

Source

DownloadReport

class DownloadReport(BaseModel):
    """Result of a Datasets.download invocation."""
    dataset_id: str
    images_downloaded: int = 0
    annotations_downloaded: int = 0
    failures: list[DownloadFailure] = []
    truncated: bool = False

    @property
    def success(self) -> bool: ...

    @property
    def total_attempted(self) -> int: ...

Source

DuplicateGroup

class DuplicateGroup(BaseModel):
    """A cluster of near-duplicate images - keep one, the rest are redundant."""
    members: list[DuplicateMember] = []
    size: int = 0
    max_similarity: float = 0.0

Source

DuplicateMember

class DuplicateMember(BaseModel):
    """One image in a near-duplicate cluster (the metadata a review UI needs)."""
    id: str
    filename: str = ''
    # Its directory in the dataset.
    directory_path: str = ''
    status: str = ''
    annotation_count: int = 0

    # The image's address in its dataset - pass it as `image` to any per-image call.
    @property
    def path(self) -> str: ...

Source

EmbeddingBackfill

class EmbeddingBackfill(BaseModel):
    """What pictograph.resources.datasets.Datasets.backfill_embeddings queued."""
    queued: int = 0
    missing: int = 0
    remaining: int = 0

Source

EngineBuild

class EngineBuild(BaseModel):
    """The TensorRT engines a workflow run or a deployment builds: `state` is `"building"`, then `"built"`. `None` on the run or deployment when every engine was already built."""
    state: str
    models: list[EngineBuildModel] = []

Source

EngineBuildModel

class EngineBuildModel(BaseModel):
    """One model's TensorRT engine build: which model, at what precision, and how far along."""
    model_id: str
    name: str | None = None
    precision: str
    state: str
    started_at: datetime | None = None
    estimate_s: float | None = None
    build_s: float | None = None

Source

EvalClassMetrics

class EvalClassMetrics(BaseModel):
    """Per-class metrics. Detection/instance-seg carry `ap`; semantic-seg carries pixel `iou` / `dice`."""
    class_name: str
    tp: int
    fp: int
    fn: int
    support: int
    precision: float
    recall: float
    f1: float
    ap: float = 0.0
    iou: float | None = None
    dice: float | None = None

Source

EvalConfusionMatrix

class EvalConfusionMatrix(BaseModel):
    """Confusion matrix (rows = ground truth, cols = predicted). Class-agnostic + IoU-matched for detection; per-pixel for semantic-seg; true-vs-predicted for classification."""
    iou_threshold: float | None = None
    labels: list[str] = []
    grid: list[list[int]] = []

Source

EvalImagePerformance

class EvalImagePerformance(BaseModel):
    """Per-image detection tallies used to rank the best- and worst-performing images."""
    image_id: str
    filename: str | None = None
    # Its directory in the dataset.
    directory_path: str | None = None
    tp: int
    fp: int
    fn: int
    gt_count: int
    pred_count: int
    predictions: list[dict[str, Any]] | None = None
    ground_truth: list[dict[str, Any]] | None = None
    miou: float | None = None

    # The image's address in its dataset - pass it as `image` to any per-image call.
    @property
    def path(self) -> str | None: ...

Source

EvalOverallMetrics

class EvalOverallMetrics(BaseModel):
    """Micro-averaged detection metrics pooled across all classes."""
    tp: int
    fp: int
    fn: int
    precision: float
    recall: float
    f1: float
    macro_f1: float
    map: float | None = 0.0
    accuracy: float | None = None
    miou: float | None = None
    mean_dice: float | None = None
    pixel_accuracy: float | None = None
    mean_pixel_accuracy: float | None = None
    frequency_weighted_iou: float | None = None

Source

EvaluationCompute

class EvaluationCompute(BaseModel):
    """What an evaluation runs on: a GPU and the precision of the model's TensorRT engine."""
    gpu: str = 't4'
    precision: str = 'fp32'

Source

EvaluationComputeGpu

class EvaluationComputeGpu(BaseModel):
    """A GPU an evaluation may run on, as pictograph.resources.model_evaluations.ModelEvaluations.compute_options lists it."""
    gpu: str
    label: str
    vram_gb: int | None = None
    description: str = ''
    cost_per_hour_micro_usd: int = 0

Source

EvaluationComputeOptions

class EvaluationComputeOptions(BaseModel):
    """What an evaluation may run on: each GPU with its memory and hourly price, each precision, the default."""
    gpus: list[EvaluationComputeGpu] = []
    precisions: list[EvaluationComputePrecision] = []
    default: EvaluationCompute = ...

Source

EvaluationComputePrecision

class EvaluationComputePrecision(BaseModel):
    """A precision the model's TensorRT engine can be built at, with its label."""
    precision: str
    label: str
    description: str = ''

Source

Export

class Export(BaseModel):
    """A dataset export - produced asynchronously, downloaded as a ZIP."""
    id: str
    dataset_id: str
    dataset_name: str
    name: str
    format: Literal['pictograph', 'darwin', 'coco', 'yolo', 'yolo_obb', 'yolo_pose', 'dota', 'pascal_voc', 'cvat', 'datumaro', 'labelme', 'csv']
    include_images: bool = False
    # Only these classes' annotations; None for all.
    class_filter: list[str] | None = None
    # Only images at this stage; None for all.
    status_filter: str | None = None
    status: Literal['pending', 'processing', 'completed', 'failed']
    # Why it failed.
    error_message: str | None = None
    # ZIP size in bytes.
    file_size: int | None = None
    image_count: int | None = None
    annotation_count: int | None = None
    created_at: datetime
    # After this, the ZIP may be deleted.
    expires_at: datetime | None = None
    # Signed download URL; on get and list, not on create.
    download_url: str | None = None
    organization_id: str | None = None

Source

Image

class Image(BaseModel):
    """An image within a Pictograph dataset."""
    id: str
    # Its dataset's id.
    dataset_id: str | None = None
    filename: str
    # Its labeling stage.
    status: Literal['new', 'annotate', 'review', 'complete'] = 'new'
    # train, val or test; None if unassigned.
    split: Optional[Literal['train', 'val', 'test']] = None
    annotation_count: int = 0
    # The lowest confidence among its annotations, 0 to 1 (1.0 for hand-drawn);
    # `images.list(min_confidence_lt=...)` filters by it for a review queue. None for
    # images saved before it was recorded.
    min_confidence: float | None = None
    # File size in bytes.
    file_size: int = 0
    # Width in pixels; None if unknown.
    width: int | None = None
    # Height in pixels; None if unknown.
    height: int | None = None
    # Stored MIME type, e.g. 'image/png'.
    content_type: str | None = None
    # Its directory in the dataset (`/` for the root).
    directory_path: str | None = None
    # Tags set by people (`images.bulk_tag` writes them), not auto-tags.
    tags: list[str] = []
    # True when archived; delete with `permanent=True` to remove it for good.
    is_archived: bool = False
    # URL of the full image; fetching it needs your X-API-Key (`images.download` saves
    # it to disk).
    image_url: str | None = None
    # CDN URL of a thumbnail, about 200 px.
    thumbnail_url: str | None = None
    # API URL of its annotations, as JSON.
    annotation_url: str | None = None
    created_at: datetime

    # The image's address in its dataset - pass it as `image` to any per-image call.
    @property
    def path(self) -> str: ...

Source

ImageSplit

ImageSplit = Literal['train', 'val', 'test']

Source

ImageStatus

ImageStatus = Literal['new', 'annotate', 'review', 'complete']

Source

ImportJob

class ImportJob(BaseModel):
    """Snapshot of an import operation - totals + per-dataset breakdown."""
    import_id: str
    status: Literal['processing', 'completed', 'error', 'cancelled']
    progress: float = 0.0
    total_images: int = 0
    imported_images: int = 0
    failed_images: int = 0
    current_dataset: str = ''
    datasets: list[DatasetImportProgress] = []

Source

InsightsDimensions

class InsightsDimensions(BaseModel):
    """Image-dimension insights (ranges, orientation split, size cloud)."""
    min_width: int | None = None
    max_width: int | None = None
    avg_width: int | None = None
    min_height: int | None = None
    max_height: int | None = None
    avg_height: int | None = None
    orientation: InsightsOrientation = ...
    sizes: list[InsightsSize] = []
    distinct_size_count: int = 0
    images_with_dimensions: int = 0
    images_missing_dimensions: int = 0

Source

InsightsOrientation

class InsightsOrientation(BaseModel):
    """Image counts by orientation."""
    landscape: int = 0
    portrait: int = 0
    square: int = 0

Source

InsightsSize

class InsightsSize(BaseModel):
    """One distinct image size and how many images share it."""
    w: int
    h: int
    count: int

Source

InsightsStatusCounts

class InsightsStatusCounts(BaseModel):
    """Image counts by labeling stage (new → complete)."""
    new: int = 0
    annotate: int = 0
    review: int = 0
    complete: int = 0

Source

Job

class Job(BaseModel):
    """One job, whatever kind of work it is."""
    id: str
    type: str
    status: str
    progress: float | None = None
    name: str | None = None
    dataset_id: str | None = None
    error: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None
    completed_at: datetime | None = None
    cancel_path: str | None = None
    detail: dict[str, Any] = {}

    # True while the job is queued or running.
    @property
    def active(self) -> bool: ...

    # True when Jobs.cancel can stop this job.
    @property
    def cancellable(self) -> bool: ...

Source

KeypointAnnotation

class KeypointAnnotation(BaseModel):
    """Single-point annotation (e.g., facial landmarks, joint locations)."""
    # Unique within the image; a UUID is generated when omitted.
    id: str = ...
    # Class name, case-sensitive; use one of the dataset's classes.
    name: str
    type: Literal['keypoint'] = 'keypoint'
    keypoint: Point
    confidence: float = 1.0
    created_by: str | None = None
    attributes: dict[str, object] | list[object] = []
    # Which object the point belongs to, 1-based within the image: points sharing an
    # instance_id are one object's joints, each named for its joint. None: a lone
    # landmark.
    instance_id: int | None = None

Source

LimitCheckResult

class LimitCheckResult(BaseModel):
    """Outcome of Connectors.check_limits."""
    allowed: bool
    current_images: int
    image_limit: int
    images_after_import: int
    current_storage_bytes: int
    storage_limit_bytes: int
    storage_after_import_bytes: int
    exceeded: Optional[Literal['images', 'storage', 'both']] = None

Source

MergeClassResult

class MergeClassResult(BaseModel):
    """Outcome of Annotations.merge_class."""
    dataset_id: str
    source_name: str
    target_name: str
    images_updated: int
    annotations_updated: int
    config_updated: bool

Source

Model

class Model(BaseModel):
    """A trained computer vision model."""
    id: str
    organization_id: str
    name: str
    # Its URL name, unique in the organization.
    slug: str | None = None
    description: str | None = None
    # Its model card, in Markdown.
    readme: str | None = None
    # Its license's catalog id (such as 'mit'), or 'custom' with license_custom_text.
    license_id: str | None = None
    # The license's text, when license_id is 'custom'.
    license_custom_text: str | None = None
    # How many people starred it.
    star_count: int = 0
    model_type: Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']
    # Its architecture, such as 'yolox-s' or 'rfdetr-base'.
    architecture: str | None = None
    visibility: Literal['private', 'public']
    status: Literal['training', 'ready', 'failed', 'archived']
    # Its validation scores from training (mAP, precision, recall), once ready.
    metrics: dict[str, Any] | None = None
    # Its classes in index order, as `{"classes": [name, ...]}`.
    class_mapping: dict[str, Any] | None = None
    # Its training settings, including its input `image_width` and `image_height` (local
    # inference reads them).
    training_config: dict[str, Any] | None = None
    version: str = '1.0.0'
    # When set, this model was fine-tuned from another.
    parent_model_id: str | None = None
    # When set, this model was imported from a public model.
    forked_from_model_id: str | None = None
    # Its weights' precision. 'fp16': half-precision weights with fp32 inputs and
    # outputs, about half the size and faster on a GPU.
    precision: Literal['fp32', 'fp16'] = 'fp32'
    created_at: datetime
    updated_at: datetime

Source

ModelConfidence

class ModelConfidence(BaseModel):
    """Active-learning rollup: how many images carry a low-confidence model prediction (min annotation confidence < 1.0), and how uncertain they are. Use it to size a human-review queue, then page it with `client.images.list(dataset_id, min_confidence_lt=...)`."""
    flagged: int = 0
    lowest: float | None = None
    avg_flagged: float | None = None
    buckets: ModelConfidenceBuckets = ...

Source

ModelConfidenceBuckets

class ModelConfidenceBuckets(BaseModel):
    """Image counts by model-confidence band (active-learning review buckets)."""
    lt50: int = 0
    b50_70: int = 0
    b70_90: int = 0
    b90_100: int = 0

Source

ModelEvaluation

class ModelEvaluation(BaseModel):
    """A model-evaluation run + its metric summary."""
    id: str
    organization_id: str
    model_id: str
    dataset_id: str
    export_id: str | None = None
    status: Literal['pending', 'running', 'completed', 'failed', 'cancelled']
    progress: int = 0
    iou_threshold: float = 0.5
    confidence_threshold: float = 0.5
    total_images: int = 0
    evaluated_images: int = 0
    failed_images: int = 0
    overall_metrics: EvalOverallMetrics | None = None
    per_class_metrics: list[EvalClassMetrics] | None = None
    confusion_matrix: EvalConfusionMatrix | None = None
    worst_images: list[EvalImagePerformance] | None = None
    best_images: list[EvalImagePerformance] | None = None
    seg_metrics: dict[str, Any] | None = None
    config: dict[str, Any] | None = None
    error_message: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None
    started_at: datetime | None = None
    completed_at: datetime | None = None
    precision: str = 'fp32'
    gpu_type: str = 't4'
    version_id: str | None = None
    engine_build: dict[str, Any] | None = None

Source

ModelFileEntry

class ModelFileEntry(BaseModel):
    """One downloadable artifact in a model's file manifest."""
    version_id: str
    name: str
    kind: str
    format: str
    size_bytes: int | None = None
    content_type: str | None = None
    updated_at: datetime | None = None
    runtime: str | None = None
    precision: str | None = None
    target_key: str | None = None
    toolchain_version: str | None = None
    stale: bool = False
    artifact_id: str | None = None

Source

ModelFileManifest

class ModelFileManifest(BaseModel):
    """A model's complete version + file manifest (`models.files`)."""
    versions: list[ModelVersionEntry] = []
    files: list[ModelFileEntry] = []
    pinned_version_id: str | None = None

Source

ModelPredictResult

class ModelPredictResult(BaseModel):
    """Result of a remote single-image test inference (`models.predict`)."""
    success: bool = True
    annotations: list[dict[str, Any]] = []
    tags: list[str] = []
    tag_scores: list[float] = []
    model_type: Optional[Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']] = None
    inference_seconds: float = 0.0

Source

ModelVersionEntry

class ModelVersionEntry(BaseModel):
    """One version in a model's file manifest (`models.files`)."""
    version_id: str
    version_number: int | None = None
    version_label: str | None = None
    created_at: datetime | None = None
    status: str | None = None
    is_latest: bool = False
    is_current: bool = False
    precision: str = 'fp32'
    training_run_id: str | None = None
    architecture: str | None = None
    metrics: dict[str, Any] = {}
    export_name: str | None = None
    pipeline_provenance: dict[str, Any] | None = None

Source

ModelVersionsPayload

class ModelVersionsPayload(BaseModel):
    """`models.versions`: every version, and which one serves."""
    versions: list[ModelVersionEntry] = []
    current_version_id: str | None = None
    pinned_version_id: str | None = None
    latest_version_id: str | None = None

Source

NearDuplicatesResult

class NearDuplicatesResult(BaseModel):
    """Near-duplicate clusters for a dataset + headline data-curation counts."""
    groups: list[DuplicateGroup] = []
    group_count: int = 0
    duplicate_image_count: int = 0
    redundant_count: int = 0
    analyzed: int = 0
    total_images: int = 0
    sample_limit: int = 0
    sample_capped: bool = False
    pairs_capped: bool = False
    threshold: float = 0.0
    directory_path: str | None = None

Source

Notification

class Notification(BaseModel):
    """One of your notifications: a training run that finished, an export that is ready."""
    id: str
    organization_id: str
    user_id: str | None = None
    # Event type, such as 'training_completed' or 'export_completed'.
    type: str
    title: str
    message: str | None = None
    metadata: dict[str, Any] | None = None
    read: bool = False
    created_at: datetime

Source

OperationUsage

class OperationUsage(BaseModel):
    """Aggregated compute spend for a single operation slug over a window."""
    # Operation slug, such as 'training_a10g'.
    operation: str
    # Total spend on this operation (µUSD).
    total_micro_usd: int = 0
    # Charges for this operation.
    event_count: int = 0

    # Total spend on this operation in USD (`total_micro_usd / 1e6`).
    @property
    def total_usd(self) -> float: ...

Source

Organization

class Organization(BaseModel):
    """An organization: its plan, its plan's limits, and its member and invite counts."""
    id: str
    name: str
    slug: str
    description: str | None = None
    is_public: bool | None = None
    # Its plan.
    subscription_tier: Union[Literal['free', 'core', 'pro', 'team', 'enterprise'], str]
    # DEPRECATED: whole dollars left this period. Use credits.balance().
    credits_remaining: int
    # DEPRECATED: the monthly allowance in whole dollars. Use credits.balance().
    credits_monthly_allowance: int
    credits_reset_at: datetime | None = None
    # Members its plan allows, pending invites included.
    max_users: int
    # Images its plan allows.
    max_images: int
    # Storage its plan allows, in bytes.
    max_storage_bytes: int
    member_count: int
    pending_invite_count: int
    created_at: datetime
    updated_at: datetime

Source

OrganizationInvite

class OrganizationInvite(BaseModel):
    """A pending / accepted / expired / revoked / declined invite."""
    id: str
    organization_id: str
    email: str
    role: Literal['admin', 'member', 'annotator', 'viewer']
    status: Literal['pending', 'accepted', 'expired', 'revoked', 'declined']
    invited_by: str | None = None
    expires_at: datetime
    created_at: datetime

Source

OrganizationMember

class OrganizationMember(BaseModel):
    """One member of the organization."""
    # Membership id: update_member_role and remove_member take it.
    id: str
    user_id: str
    email: str | None = None
    full_name: str | None = None
    role: Literal['owner', 'admin', 'member', 'annotator', 'viewer']
    joined_at: datetime

Source

OrientedBoxGeometry

class OrientedBoxGeometry(BaseModel):
    """A rotated rectangle: a centre, extents along the box's OWN axes, and an angle."""
    # Centre x, absolute image pixels.
    cx: float
    # Centre y, absolute image pixels.
    cy: float
    # Extent along the box's own +x axis.
    w: float
    # Extent along the box's own +y axis.
    h: float
    # Rotation in degrees, clockwise, [0, 360).
    angle: float = 0.0

Source

Point

class Point(BaseModel):
    """A 2D point in absolute pixel coordinates."""
    x: float
    y: float

Source

PolygonAnnotation

class PolygonAnnotation(BaseModel):
    """Polygon annotation, optionally with holes (multi-path)."""
    # Unique within the image; a UUID is generated when omitted.
    id: str = ...
    # Class name, case-sensitive; use one of the dataset's classes.
    name: str
    type: Literal['polygon'] = 'polygon'
    # Enclosing rectangle; computed on save when omitted.
    bounding_box: BoundingBox | None = None
    polygon: PolygonGeometry
    confidence: float = 1.0
    created_by: str | None = None
    attributes: dict[str, object] | list[object] = []

Source

PolygonGeometry

class PolygonGeometry(BaseModel):
    """Polygon geometry: one or more rings, filled by the even-odd rule."""
    # List of rings, filled by the even-odd rule: a ring within another is a hole, a
    # ring outside the others is another piece of the same object. Put the main outline
    # first. Each ring needs >= 3 points.
    paths: list[list[Point]]

Source

PolylineAnnotation

class PolylineAnnotation(BaseModel):
    """Open polyline annotation (e.g., road centerlines, lanes)."""
    # Unique within the image; a UUID is generated when omitted.
    id: str = ...
    # Class name, case-sensitive; use one of the dataset's classes.
    name: str
    type: Literal['polyline'] = 'polyline'
    # Enclosing rectangle; computed on save when omitted.
    bounding_box: BoundingBox | None = None
    polyline: PolylineGeometry
    confidence: float = 1.0
    created_by: str | None = None
    attributes: dict[str, object] | list[object] = []

Source

PolylineGeometry

class PolylineGeometry(BaseModel):
    """Open path: an ordered list of points connected by line segments."""
    # Ordered list of points (>= 2). Does not close.
    path: list[Point]

Source

PromptResult

class PromptResult(BaseModel):
    """Outcome of a single SAM3 prompt (point / box / text)."""
    status: Literal['success', 'no_detection', 'below_threshold']
    annotations: list[Annotation] = []
    # Confidence score for the primary detection (point/box only).
    score: float | None = None
    # GPU inference time, in seconds.
    inference_time: float | None = None

Source

PublicDataset

class PublicDataset(BaseModel):
    """A dataset in the public catalog, as Explore lists it."""
    id: str
    name: str
    slug: str | None = None
    description: str | None = None
    organization: PublicOrganization | None = None
    # Images in the dataset.
    image_count: int = 0
    annotation_count: int = 0
    annotation_types: list[str] = []
    # Its classes. A list row carries the first few; the detail has them all.
    classes: list[DatasetClass] = []
    class_count: int = 0
    # What its images most often show.
    top_auto_tags: list[str] = []
    # The license it was published under (e.g. 'cc-by-4.0').
    license_id: str | None = None
    star_count: int = 0
    is_fork: bool = False
    # Its Hugging Face mirror, if any.
    hf_repo: str | None = None
    # Its dataset card (detail only).
    readme: str | None = None
    published_at: datetime | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None

    # The qualified public name `"<organization>/<dataset>"` an import takes.
    @property
    def ref(self) -> str: ...

Source

PublicDatasetImport

class PublicDatasetImport(BaseModel):
    """An import of a public dataset into your organization."""
    import_id: str
    status: Union[Literal['pending', 'running', 'completed', 'failed', 'cancelled'], str]
    # The copy in your organization.
    dataset_id: str | None = None
    # The copy's name (a name your organization already used is suffixed '(imported)').
    dataset_name: str | None = None
    source: PublicImportSource | None = None
    total_images: int = 0
    # Images copied so far.
    image_count: int = 0
    # 0-100.
    progress: float = 0.0
    error: str | None = None
    created_at: datetime | None = None
    completed_at: datetime | None = None

    # It finished, one way or another.
    @property
    def done(self) -> bool: ...

Source

PublicImportSource

class PublicImportSource(BaseModel):
    """What an import copied from."""
    organization: str | None = None
    dataset: str | None = None
    dataset_id: str | None = None

Source

PublicModel

class PublicModel(BaseModel):
    """A ready model in the public catalog, as Explore lists it."""
    id: str
    name: str
    slug: str | None = None
    description: str | None = None
    organization: PublicOrganization | None = None
    model_type: str
    architecture: str | None = None
    precision: str | None = None
    # Its classes, in index order (`{'classes': [...]}`).
    class_mapping: dict[str, Any] | None = None
    # Its evaluation scores.
    metrics: dict[str, Any] = {}
    training_config: dict[str, Any] | None = None
    license_id: str | None = None
    star_count: int = 0
    weights_size_bytes: int | None = None
    is_fork: bool = False
    hf_repo: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None

    # Its class names, in index order.
    @property
    def classes(self) -> list[str]: ...

    # The qualified public name `"<organization>/<model>"` `models.fork` takes.
    @property
    def ref(self) -> str: ...

Source

PublicModelDetail

class PublicModelDetail(BaseModel):
    """One public model, as its own Explore page shows it (`explore.model`)."""
    id: str
    name: str
    slug: str | None = None
    description: str | None = None
    organization: PublicOrganization | None = None
    model_type: str
    architecture: str | None = None
    precision: str | None = None
    # Its classes, in index order (`{'classes': [...]}`).
    class_mapping: dict[str, Any] | None = None
    # Its evaluation scores.
    metrics: dict[str, Any] = {}
    training_config: dict[str, Any] | None = None
    license_id: str | None = None
    star_count: int = 0
    weights_size_bytes: int | None = None
    is_fork: bool = False
    hf_repo: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None
    # Its model card, in Markdown.
    readme: str | None = None
    # The license's text, when license_id is 'custom'.
    license_custom_text: str | None = None

Source

PublicOrganization

class PublicOrganization(BaseModel):
    """The organization that published a dataset or a model."""
    id: str | None = None
    name: str
    slug: str

Source

RemoteDataset

class RemoteDataset(BaseModel):
    """One dataset as listed by the source provider's validate call."""
    id: str
    name: str
    slug: str
    image_count: int = 0
    version: int | None = None

Source

RenameClassResult

class RenameClassResult(BaseModel):
    """Outcome of Annotations.rename_class."""
    dataset_id: str
    old_name: str
    new_name: str
    images_updated: int
    annotations_updated: int
    config_updated: bool

Source

RunLogBranchCounts

class RunLogBranchCounts(BaseModel):
    """How a Condition block split a stream's records: `passed` (true branch), `failed` (false)."""
    passed: int = 0
    failed: int = 0

Source

RunLogEventName

class RunLogEventName(BaseModel):
    """What a person reads for a log record's trigger: its event's name and kind (`WorkflowLiveEvent`'s)."""
    name: str
    kind: str

Source

RunLogPage

class RunLogPage(BaseModel):
    """One page of a run's log: its `records`, and `next_cursor` until the last page."""
    stream: Literal['frames', 'events', 'stats']
    order: Literal['asc', 'desc'] = 'asc'
    records: list[RunLogRecord] = []
    next_cursor: str | None = None
    log_frames: bool = True
    event_names: dict[str, RunLogEventName] = {}

Source

RunLogRecord

class RunLogRecord(BaseModel):
    """One record of a run's log: a frame, an event (a trigger firing, a capture and its upload) or stats."""
    ts: datetime
    engine_run: str
    seq: int
    record_index: int
    type: str | None = None
    source: str | None = None
    frame: int | None = None
    pts: float | None = None
    image: str | None = None
    image_id: str | None = None
    image_index: int | None = None
    image_width: int | None = None
    image_height: int | None = None
    annotation_count: int | None = None
    classes: list[str] = []
    track_ids: list[str] = []
    condition: bool | None = None
    min_confidence: float | None = None
    max_confidence: float | None = None
    latency_total_ms: float | None = None
    latency_engine_ms: float | None = None
    latency_inference_ms: float | None = None
    model_name: str | None = None
    model_task: str | None = None
    event_id: str | None = None
    trigger: str | None = None
    sequence: int | None = None
    capture_kind: str | None = None
    capture_ok: bool | None = None
    capture_detail: str | None = None
    capture_name: str | None = None
    capture_uri: str | None = None
    capture_bytes: int | None = None
    clock_suspect: bool | None = None
    rule_values: dict[str, Any] | None = None
    values_text: str | None = None
    sources: list[dict[str, Any]] | None = None
    pictograph: dict[str, Any] | None = None
    tag_confidences: Any = None
    measures: Any = None
    extra: dict[str, Any] | None = None
    message: dict[str, Any] | None = None

Source

RunLogStreamSummary

class RunLogStreamSummary(BaseModel):
    """One stream of a run's log: its record count, first and last record times, and with a Condition block, each branch's count (`condition`)."""
    count: int = 0
    first_ts: datetime | None = None
    last_ts: datetime | None = None
    condition: RunLogBranchCounts | None = None

Source

RunLogSummary

class RunLogSummary(BaseModel):
    """What a run logged, per stream (`frames` / `events` / `stats`), counted from the log."""
    log_frames: bool = True
    streams: dict[str, RunLogStreamSummary] = {}

Source

Sam3Prediction

class Sam3Prediction(BaseModel):
    """SAM3's answer to one prompt on an image you sent. Nothing was saved."""
    status: Literal['success', 'no_detection', 'below_threshold']
    annotations: list[Annotation] = []
    # Confidence score for the primary detection (point/box only).
    score: float | None = None
    # GPU inference time, in seconds.
    inference_time: float | None = None
    prompt: Literal['text', 'box', 'point']
    # The upright image's width in pixels.
    width: int
    # The upright image's height in pixels.
    height: int
    # SHA-256 of the image's bytes: an image is charged once, by this.
    image_sha256: str | None = None
    # The minimum score applied (the prompt's default when none was given).
    confidence_threshold: float | None = None
    # True when the image held more matches than fit in GPU memory, so only the most
    # confident came back; `confidence_threshold` says where the cut fell.
    degraded: bool = False

Source

SaveResult

class SaveResult(BaseModel):
    """Outcome of Annotations.save."""
    image_id: str
    previous_count: int
    new_count: int
    status: str

Source

SimilarImage

class SimilarImage(BaseModel):
    """One result from pictograph.resources.search.Search.by_similarity."""
    id: str
    filename: str
    # Its directory in the dataset.
    directory_path: str = '/'
    status: Literal['new', 'annotate', 'review', 'complete']
    annotation_count: int
    # Its auto-tags, by kind: objects, scenes and attributes.
    auto_tags: dict[str, Any] = {}
    similarity: float

    # The image's address in its dataset - pass it as `image` to any per-image call.
    @property
    def path(self) -> str: ...

Source

SimilarQuote

class SimilarQuote(BaseModel):
    """What an "Annotate similar" job would run and cost: the checks AutoAnnotate.similar makes (the examples, the target class, whether SAM3 can read the example image, the images in scope) and its estimate."""
    # Images the job would label (at most `max_images`).
    total_images: int
    # Other images in the scope, before the cap.
    total_in_scope: int = 0
    # True when the scope holds more than `max_images`.
    capped: bool = False
    # Image ceiling for a single job.
    max_images: int = 2000
    # The estimate, in micro-USD; the job starts only if the balance covers it.
    estimated_credits: int
    # T4 containers the job would run on.
    containers: int = 0
    # Your remaining balance (µUSD).
    remaining_credits: int = 0
    # Whether the balance covers the estimate.
    sufficient: bool = True
    # Example polygons the job would learn from.
    examples: int = 0
    # The class each match is labelled as.
    target_class: str = ''
    # polygon, bbox or obb.
    output_type: str = 'polygon'
    # directory or dataset.
    scope: str = 'directory'
    # The example image's folder.
    directory: str = '/'

Source

SkeletonJoint

class SkeletonJoint(BaseModel):
    """One joint of a keypoint class's template: the joint's own class name, and a suggested position on the unit square (where the app places it; not a constraint)."""
    name: str
    x: float = 0.5
    y: float = 0.5

Source

SkeletonTemplate

class SkeletonTemplate(BaseModel):
    """A keypoint class's joint template."""
    nodes: list[SkeletonJoint]
    edges: list[tuple[int, int]] = []

Source

TaggedImage

class TaggedImage(BaseModel):
    """One result from pictograph.resources.search.Search.by_tag."""
    id: str
    dataset_id: str
    filename: str
    # Its directory in the dataset.
    directory_path: str = '/'
    status: Literal['new', 'annotate', 'review', 'complete']
    annotation_count: int
    # Its auto-tags, by kind: objects, scenes and attributes.
    auto_tags: dict[str, Any] = {}

    # The image's address in its dataset - pass it as `image` to any per-image call.
    @property
    def path(self) -> str: ...

Source

Task

class Task(BaseModel):
    """One annotation task in the organization (list item)."""
    id: str
    # The dataset the task's images belong to.
    dataset_id: str
    # Dataset name (may be null if renamed/removed).
    dataset: str | None = None
    title: str
    # 'annotate' or 'review'.
    kind: str
    # 'open' or 'done'.
    status: str
    created_at: datetime
    # Number of images frozen into the task.
    image_count: int
    # Number of org members the task is assigned to.
    assignee_count: int

Source

TaskContribution

class TaskContribution(BaseModel):
    """One annotator's contribution to a task."""
    user_id: str
    full_name: str
    email: str | None = None
    avatar_url: str | None = None
    # Whether this person is a task assignee (vs a non-assignee contributor).
    is_assignee: bool
    # Measured active editing time on the task's images (seconds).
    active_seconds: int
    # Distinct task images this person annotated or authored.
    images_worked: int
    # Task images they last-saved that are now at 'complete'.
    images_completed: int
    # Annotations on images they most recently authored.
    annotations_added: int

    # `active_seconds` as minutes (float), for display.
    @property
    def active_minutes(self) -> float: ...

Source

TaskContributions

class TaskContributions(BaseModel):
    """Per-annotator contribution breakdown for a task, with rollup totals."""
    task_id: str
    contributors: list[TaskContribution]
    contributor_count: int
    # Total images frozen into the task.
    total_images: int
    # Task images at status 'complete' (any annotator).
    images_complete: int
    # Sum of every annotator's active editing time (seconds).
    total_active_seconds: int

    # `total_active_seconds` as minutes (float), for display.
    @property
    def total_active_minutes(self) -> float: ...

Source

TileFailure

class TileFailure(BaseModel):
    """One source image that failed to tile (kind in `reason`)."""
    image_id: str
    filename: str
    reason: str

Source

TileReport

class TileReport(BaseModel):
    """Outcome of an Images.tile run."""
    source: str
    target: str
    source_images: int = 0
    tiles_created: int = 0
    empty_tiles: int = 0
    annotations_written: int = 0
    failures: list[TileFailure] = []

    @property
    def success(self) -> bool: ...

Source

ToolCard

class ToolCard(BaseModel):
    """Everything an agent needs to call one vision tool."""
    tool: str
    kind: str
    id: str | None = None
    name: str
    task: str | None = None
    status: str | None = None
    summary: str = ''
    about: str | None = None
    classes: list[ToolClass] = []
    facts: dict[str, Any] = {}
    parameters: list[ToolParameter] = []
    output: ToolOutput | None = None
    modes: list[ToolMode] = []
    related: list[ToolRelated] = []
    notes: list[str] = []

Source

ToolClass

class ToolClass(BaseModel):
    """A class a tool predicts, and the annotation type it comes back as."""
    name: str
    type: str | None = None

Source

ToolCost

class ToolCost(BaseModel):
    """What one way of running a tool costs."""
    summary: str = ''
    micro_usd: int | None = None
    per: str | None = None
    estimate: bool = False
    options: list[dict[str, Any]] = []

    @property
    def free(self) -> bool: ...

    # `micro_usd` in dollars, or `None` when the price depends.
    @property
    def usd(self) -> float | None: ...

Source

ToolInput

class ToolInput(BaseModel):
    """Whether one way of running a tool accepts one kind of input."""
    kind: str
    supported: bool = False
    note: str | None = None

Source

ToolMode

class ToolMode(BaseModel):
    """One way of running a tool (`hosted`, `local`, `endpoint`, `file`, ...)."""
    mode: str
    title: str = ''
    description: str = ''
    inputs: list[ToolInput] = []
    limits: dict[str, Any] = {}
    requires: list[str] = []
    writes: bool | str = False
    cost: ToolCost = ...
    returns: str | None = None
    run: ToolRun = ...

Source

ToolOutput

class ToolOutput(BaseModel):
    """The shape of ONE prediction: prose, its JSON Schema, and an example."""
    type: str | None = None
    description: str = ''
    coordinates: str | None = None
    json_schema: dict[str, Any] | None = None
    example: dict[str, Any] | None = None

Source

ToolParameter

class ToolParameter(BaseModel):
    """A parameter a tool takes, with the bounds the API enforces."""
    name: str
    type: str = 'string'
    default: Any = None
    minimum: float | None = None
    maximum: float | None = None
    choices: list[str] = []
    applies_to: list[str] = []
    description: str = ''

Source

ToolRelated

class ToolRelated(BaseModel):
    """Another tool tied to this one (a model's endpoint, a workflow's models)."""
    tool: str
    relation: str = ''

Source

ToolRun

class ToolRun(BaseModel):
    """The exact call for one way of running a tool, in each interface that has one."""
    cli: str | None = None
    python: str | None = None
    http: str | None = None

Source

ToolSummary

class ToolSummary(BaseModel):
    """One row of `client.tools.list()`."""
    tool: str
    kind: str
    id: str | None = None
    name: str
    task: str | None = None
    status: str | None = None
    summary: str = ''

Source

TrainingClassSupport

class TrainingClassSupport(BaseModel):
    """How much of each class a run would train on."""
    pipeline_type: str
    # "annotations", or "images" for classification.
    unit: str
    # What this pipeline trains on, in words.
    trains_on: str
    # "assigned" (the images' own train/val/test) or "random" (the trainer makes one).
    split: str
    # The export's images that still exist.
    images: int = 0
    # The images the export names.
    export_images: int | None = None
    classes: list[TrainingClassSupportEntry] = []
    untrainable: list[str] = []
    # Classification: images with more than one selected tag (dropped).
    multi_tag_images: int = 0

Source

TrainingClassSupportEntry

class TrainingClassSupportEntry(BaseModel):
    """One class of a run, counted the way the trainer will count it in this export."""
    name: str
    # Units (`unit`) of this class across the whole export.
    support: int = 0
    # Units in the train split - only when the images' assigned split is used.
    train: int | None = None
    val: int | None = None
    test: int | None = None
    # Whether the run would train it (a class the train split does not supervise is left
    # out of the model, or refused for keypoints).
    trainable: bool
    # When not trainable: "no_training_data" or "not_in_train_split".
    reason: str | None = None

Source

TrainingQuote

class TrainingQuote(BaseModel):
    """A training run checked and priced without starting it (Training.quote)."""
    dataset_id: str
    dataset_name: str
    export_id: str
    export_name: str
    image_count: int | None = None
    annotation_count: int | None = None
    pipeline_type: Literal['yolox', 'sm_pytorch', 'classification', 'rfdetr_detection', 'rfdetr_segmentation', 'rfdetr_keypoint']
    # What was asked for, `"auto"` included.
    requested_gpu_type: str
    # The tier the run would use.
    gpu_type: str
    # Whether the config's predicted peak memory fits `gpu_type`; `None` when the
    # pipeline has no estimate.
    fits: bool | None = None
    # What `gpu_type="auto"` resolves to for this config.
    recommended_gpu_type: str | None = None
    # The auto-select decision behind `recommended_gpu_type`.
    gpu_autoselect: dict[str, Any] | None = None
    tiers: list[TrainingQuoteTier] = []
    epochs: int
    # The classes it would train.
    classes: list[str] = []
    class_support: TrainingClassSupport | None = None
    # Images the export names that were deleted since it was taken.
    deleted_images: int | None = None
    estimate: TrainingQuoteEstimate
    balance: TrainingQuoteBalance
    can_start: bool
    blocking: list[TrainingQuoteBlock] = []
    # The config the run would be stored with.
    config: dict[str, Any] = {}

Source

TrainingQuoteBalance

class TrainingQuoteBalance(BaseModel):
    """The org's spendable balance against what starting a run needs."""
    budget_remaining_micro_usd: int
    required_to_start_micro_usd: int
    covers_estimate: bool

Source

TrainingQuoteBlock

class TrainingQuoteBlock(BaseModel):
    """Something that keeps a valid run from starting."""
    # "insufficient_credits", "forbidden" or "key_without_creator".
    code: str
    message: str

Source

TrainingQuoteEstimate

class TrainingQuoteEstimate(BaseModel):
    """The run's estimated cost; the charge is the GPU time it uses."""
    minutes: int
    micro_usd_per_minute: int
    total_micro_usd: int
    note: str = ''

Source

TrainingQuoteTier

class TrainingQuoteTier(BaseModel):
    """One GPU tier a run can use, priced, and whether the config's predicted peak fits."""
    gpu_type: str
    total_mib: int
    # `None` when the pipeline has no memory estimate (YOLOX).
    fits: bool | None = None
    micro_usd_per_minute: int

Source

TrainingRun

class TrainingRun(BaseModel):
    """A single training job."""
    id: str
    organization_id: str
    name: str
    # The dataset it trained on.
    dataset_id: str | None = None
    # The export it trained on.
    export_id: str | None = None
    # The model it made, once completed.
    model_id: str | None = None
    pipeline_type: Literal['yolox', 'sm_pytorch', 'classification', 'rfdetr_detection', 'rfdetr_segmentation', 'rfdetr_keypoint']
    gpu_type: Optional[Literal['a10g', 'a100', 'h100', 'auto']] = None
    status: Literal['pending', 'queued', 'running', 'completed', 'failed', 'cancelled']
    # 0-100 percent.
    progress: int = 0
    current_epoch: int = 0
    total_epochs: int | None = None
    metrics: dict[str, Any] = {}
    config: dict[str, Any] = {}
    eta_seconds: int | None = None
    # Seconds of GPU time the run used, once it completes.
    training_time_seconds: int | None = None
    error_message: str | None = None
    # What was left out of the model and why, such as a class the train split doesn't
    # supervise; None when nothing was.
    warnings: list[TrainingRunWarning] | None = None
    started_at: datetime | None = None
    completed_at: datetime | None = None
    created_at: datetime
    created_by: str | None = None

Source

TrainingRunWarning

class TrainingRunWarning(BaseModel):
    """Something a training run's prep left out of the model, and why."""
    code: str
    # The warning, in words.
    message: str
    classes: list[dict[str, Any]] = []
    # What the per-split counts are in: "annotations", "pixels" or "images".
    unit: str | None = None

Source

UploadFailure

class UploadFailure(BaseModel):
    """One file that failed to upload in Images.upload_from_directory."""
    path: Path
    reason: str

Source

UploadReport

class UploadReport(BaseModel):
    """Outcome of an Images.upload_from_directory call."""
    dataset_name: str
    images_attempted: int = 0
    images_uploaded: int = 0
    images_skipped: int = 0
    failures: list[UploadFailure] = []

    @property
    def success(self) -> bool: ...

Source

UsageByOperation

class UsageByOperation(BaseModel):
    """Per-operation compute-spend breakdown over a rolling window."""
    # Window: 'day' | 'week' | 'month' | 'all'.
    range: str
    # ISO timestamp the window starts at.
    since: str | None = None
    operations: list[OperationUsage] = []
    # Total spend across the window (µUSD).
    total_micro_usd: int = 0
    # Charges across the window.
    total_events: int = 0

    # Total spend across the window in USD (`total_micro_usd / 1e6`).
    @property
    def total_usd(self) -> float: ...

Source

ValidationResult

class ValidationResult(BaseModel):
    """Outcome of Connectors.validate."""
    valid: bool
    workspace: str = ''
    datasets: list[RemoteDataset] = []
    error: str | None = None

Source

VideoExtractionJob

class VideoExtractionJob(BaseModel):
    """Snapshot of a frame-extraction job."""
    job_id: str
    status: Literal['processing', 'complete', 'failed']
    progress: int = 0
    frames_extracted: int = 0
    total_frames: int = 0
    error: str | None = None
    # The directory the frames went into, once it succeeds.
    directory_path: str | None = None
    # Set when the image quota cut the frames short; the job still completes.
    warning: str | None = None
    # The frames' image ids, once the job is complete.
    image_ids: list[str] | None = None

Source

VideoMetadata

class VideoMetadata(BaseModel):
    """Probe result for an uploaded video."""
    duration_seconds: float
    # The video's frame rate.
    native_fps: float
    width: int
    height: int
    # Frames at its own rate.
    frame_count: int

Source

VideoUploadInfo

class VideoUploadInfo(BaseModel):
    """An uploaded video: `video` is the handle pictograph.resources.video.Video.probe and pictograph.resources.video.Video.extract_frames take."""
    upload_url: str
    video: str

Source

WebhookDelivery

class WebhookDelivery(BaseModel):
    """One event's delivery to an endpoint, with its retries."""
    id: str
    endpoint_id: str
    organization_id: str
    event_type: str
    # Sent to your endpoint as X-Pictograph-Delivery-Id.
    delivery_id: str
    # pending (being tried), delivered, failed or dead_letter (out of retries).
    status: Literal['pending', 'delivered', 'failed', 'dead_letter']
    # Tries so far.
    attempts: int = 0
    # What the last try got back.
    last_status_code: int | None = None
    # The last try's error.
    last_error: str | None = None
    # When it's tried next.
    next_retry_at: datetime | None = None
    created_at: datetime | None = None
    # When it was delivered.
    delivered_at: datetime | None = None

Source

WebhookEndpoint

class WebhookEndpoint(BaseModel):
    """A registered outbound webhook destination."""
    id: str
    organization_id: str
    url: str
    description: str | None = None
    # The events it's sent; empty means every event.
    event_types: list[str] = []
    # Whether it's sent deliveries; turned off after many failures.
    enabled: bool = True
    # Goes up by one at each rotation.
    secret_version: int = 1
    # The secret's first characters.
    secret_prefix: str | None = None
    # Failed deliveries in a row; 0 after a success.
    consecutive_failures: int = 0
    # Why it was turned off.
    disabled_reason: str | None = None
    # The names of its custom headers (their values are never returned).
    auth_header_names: list[str] | None = None
    # When it was last sent a delivery.
    last_delivery_at: datetime | None = None
    created_at: datetime | None = None

Source

Workflow

class Workflow(BaseModel):
    """A saved node-graph workflow."""
    id: str
    organization_id: str
    name: str
    description: str | None = None
    readme: str | None = None
    graph: dict[str, Any] = {}
    template_key: str | None = None
    status: Literal['draft', 'ready', 'archived'] = 'draft'
    compute: WorkflowCompute = WorkflowCompute(gpu='t4')
    last_run_id: str | None = None
    validation: list[WorkflowIssue] = []
    endpoint: WorkflowEndpoint | None = None
    endpoint_token: str | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None

Source

WorkflowCompute

class WorkflowCompute(BaseModel):
    """What a workflow's runs run on: its GPU."""
    gpu: str = 't4'

Source

WorkflowComputeGpu

class WorkflowComputeGpu(BaseModel):
    """A GPU a workflow may run on, as pictograph.resources.workflows.Workflows.compute_options lists it."""
    gpu: str
    label: str
    vram_gb: int | None = None
    description: str = ''
    rate_per_min_micro_usd: int = 0
    cost_per_hour_micro_usd: int = 0

Source

WorkflowComputeOptions

class WorkflowComputeOptions(BaseModel):
    """A workflow's compute choices, priced in one region: each GPU with its memory and price, each precision a Model block may take, the default, and every region."""
    gpus: list[WorkflowComputeGpu] = []
    precisions: list[WorkflowComputePrecision] = []
    default: WorkflowCompute = WorkflowCompute(gpu='t4')
    region: str | None = None
    regions: list[DeploymentRegion] = []
    transfer_per_gib_micro_usd: int | None = None

Source

WorkflowComputePrecision

class WorkflowComputePrecision(BaseModel):
    """A precision a Model block may take (its config's `precision`)."""
    precision: str
    label: str
    description: str = ''

Source

WorkflowEndpoint

class WorkflowEndpoint(BaseModel):
    """A workflow's endpoint: where its file and dataset runs and its live streams run, in its region."""
    id: str
    status: Literal['draft', 'provisioning', 'active', 'paused', 'failed', 'terminated']
    region: str | None = None
    gpu_type: str | None = None
    min_containers: int = 0
    max_containers: int = 1
    scaledown_window: int = 60
    endpoint_url: str | None = None
    auth_token_prefix: str | None = None
    error_message: str | None = None
    engine_build: EngineBuild | None = None
    stream_limit: int = 0
    run_limit: int = 0
    region_fallback: bool = False
    streams: bool = True
    deployed: bool = False
    logged: bool | None = None
    live: WorkflowLive = ...
    live_outputs: WorkflowLiveOutputs | None = None
    runtime: DeploymentRuntime | None = None
    cost_per_hour_micro_usd: int = 0
    max_cost_per_hour_micro_usd: int = 0
    transfer_per_gib_micro_usd: int | None = None
    accrued_cost_micro_usd: int = 0
    uptime_seconds: int = 0
    transfer_bytes: int = 0
    transfer_cost_micro_usd: int = 0
    created_at: datetime | None = None
    started_at: datetime | None = None
    paused_at: datetime | None = None
    updated_at: datetime | None = None

Source

WorkflowIssue

class WorkflowIssue(BaseModel):
    """One issue with a graph: `severity` `"error"` (a run would be refused) or `"warning"`, its `code` and `message`, and its block (`node_id`; None for the whole graph)."""
    code: str
    message: str
    node_id: str | None = None
    severity: str = 'error'

Source

WorkflowLive

class WorkflowLive(BaseModel):
    """What a workflow's live stream runs and draws: its models, lines and zones, classes (each with its drawing colour and annotation type) and the events it offers (`events`)."""
    models: list[WorkflowLiveModel] = []
    measures: list[WorkflowLiveMeasure] = []
    classes: list[str] = []
    class_colors: dict[str, str] = {}
    class_types: dict[str, str] = {}
    events: list[WorkflowLiveEvent] = []

Source

WorkflowLiveEvent

class WorkflowLiveEvent(BaseModel):
    """An event a workflow offers: Event capture and a webhook pick it by `key`, and its log names it by `trigger`. Passive capture is one too (kind `"passive"`)."""
    trigger: str
    key: str
    kind: str
    name: str

Source

WorkflowLiveMeasure

class WorkflowLiveMeasure(BaseModel):
    """A line or zone of a workflow's live stream, as each frame's `measures` names it (by `id`)."""
    id: str
    name: str
    kind: str
    measure: str
    label: str
    color: str | None = None

Source

WorkflowLiveModel

class WorkflowLiveModel(BaseModel):
    """A model a workflow's live stream runs: one per Model block's model at its precision."""
    model_id: str
    name: str
    precision: str = 'fp32'
    model_type: str | None = None

Source

WorkflowLiveOutputs

class WorkflowLiveOutputs(BaseModel):
    """What a workflow endpoint's live outputs did, every outcome counted."""
    events: int = 0
    deliveries: int = 0
    saved: int = 0
    not_saved: int = 0
    skipped: int = 0
    since: datetime | None = None
    last_not_saved_reason: str | None = None
    last_not_saved_at: datetime | None = None

Source

WorkflowNodeCard

class WorkflowNodeCard(BaseModel):
    """One block type: the port it takes (`inputs`) and emits (`output`; None for a sink), a new block's config (`new_block`), its settings (`fields`) and its validation `rules`."""
    type: str
    label: str
    summary: str
    inputs: list[str] = []
    output: str | None = None
    new_block: dict[str, Any] = {}
    fields: list[WorkflowNodeField] = []
    rules: list[str] = []

Source

WorkflowNodeCatalog

class WorkflowNodeCatalog(BaseModel):
    """Every block type (`nodes`, in the editor's order) and how a graph is written (`graph`)."""
    graph: dict[str, Any] = {}
    nodes: list[WorkflowNodeCard] = []

Source

WorkflowNodeField

class WorkflowNodeField(BaseModel):
    """One setting of a block's config: its `key`, JSON `type`, whether a run needs it (`True`, or when, in words), its `default`, allowed `values`, a `note` and nested `fields`."""
    key: str
    type: str
    required: bool | str = False
    default: Any = None
    values: list[Any] | None = None
    note: str = ''
    fields: list[WorkflowNodeField] | None = None

Source

WorkflowRun

class WorkflowRun(BaseModel):
    """One execution of a workflow over a source."""
    id: str
    organization_id: str
    workflow_id: str
    status: Literal['queued', 'processing', 'completed', 'error', 'cancelled']
    progress: float = 0.0
    frames_total: int | None = None
    frames_done: int = 0
    sample_fps: float | None = None
    step_results: dict[str, Any] = {}
    condition_results: dict[str, Any] = {}
    artifacts: list[dict[str, Any]] = []
    warnings: list[str] = []
    final_micro_usd: int | None = None
    error: str | None = None
    dispatch_note: str | None = None
    endpoint_id: str | None = None
    has_log: bool = False
    compute: WorkflowRunCompute = ...
    engine_build: EngineBuild | None = None
    source: WorkflowRunSource | None = None
    stream_session: str | None = None
    outputs: WorkflowRunWrites | None = None
    live_view: WorkflowRunLiveView | None = None
    recording: WorkflowRunRecording | None = None
    result: dict[str, Any] | None = None
    created_at: datetime | None = None
    completed_at: datetime | None = None

Source

WorkflowRunCompute

class WorkflowRunCompute(BaseModel):
    """What a run ran with: its GPU and the precision its model ran at."""
    gpu: str = 't4'
    precision: str = 'fp32'

Source

WorkflowRunCreated

class WorkflowRunCreated(BaseModel):
    """What `run` returns at once: the new run's id. The run is billed as its endpoint's uptime; its share lands on `final_micro_usd` when it ends."""
    run_id: str
    status_url: str | None = None

Source

WorkflowRunLiveView

class WorkflowRunLiveView(BaseModel):
    """A video, dataset or export run's live view: `stream` and `overlay` as the run started (`watch_run`'s stream switches them), and `session` once the run is dispatched."""
    stream: bool = False
    overlay: bool = True
    session: str | None = None

Source

WorkflowRunRecording

class WorkflowRunRecording(BaseModel):
    """A stream run's annotated video: `state` is `"saved"` (whole), `"partial"` (up to where it stopped) or `"none"`, with `detail` saying why; `bytes`, `parts` and `at` (when it was made)."""
    state: Literal['saved', 'partial', 'none']
    bytes: int | None = None
    parts: int | None = None
    at: datetime | None = None
    detail: str | None = None

Source

WorkflowRunSource

class WorkflowRunSource(BaseModel):
    """What a run ran over: `kind` is `"video"`, `"image"`, `"dataset"`, `"export"` or `"stream"`, and a stream's `via` is `"whip"` (video sent to it, such as a browser's camera), `"rtsp"` or `"whep"` (a camera it pulled). Strings, so a kind added later reads as itself."""
    kind: str
    via: str | None = None
    name: str | None = None
    input: dict[str, Any] | None = None

Source

WorkflowRunSummary

class WorkflowRunSummary(BaseModel):
    """A run as `client.workflows.list_runs` lists it."""
    id: str
    status: Literal['queued', 'processing', 'completed', 'error', 'cancelled']
    created_at: datetime | None = None
    completed_at: datetime | None = None
    runtime_seconds: float | None = None
    cost_micro_usd: int = 0
    cost_settled: bool = False
    frames_done: int = 0
    frames_total: int | None = None
    progress: float = 0.0
    artifact_count: int = 0
    has_log: bool = False
    compute: WorkflowRunCompute = ...
    engine_build: EngineBuild | None = None
    source: WorkflowRunSource | None = None
    stream_session: str | None = None
    outputs: WorkflowRunWrites | None = None
    live_view: WorkflowRunLiveView | None = None
    recording: WorkflowRunRecording | None = None
    error: str | None = None

Source

WorkflowRunWrites

class WorkflowRunWrites(BaseModel):
    """What a run writes beside its log, as resolved when it started."""
    annotated_video: bool = False
    annotations: WorkflowWrittenAnnotations | None = None
    passive_capture: WorkflowWrittenPassiveCapture | None = None
    event_capture: WorkflowWrittenEventCapture | None = None
    webhook: WorkflowWrittenWebhook | None = None

Source

WorkflowTemplate

class WorkflowTemplate(BaseModel):
    """A template from the app's "New workflow" list, with its graph; `client.workflows.create(name, template_key=key)` starts from it."""
    key: str
    title: str
    description: str
    graph: dict[str, Any] = {}

Source

WorkflowValidation

class WorkflowValidation(BaseModel):
    """Whether a run of a graph would start: `valid` when no issue is an error, and every issue."""
    valid: bool
    issues: list[WorkflowIssue] = []

    # The issues that stop a run.
    @property
    def errors(self) -> list[WorkflowIssue]: ...

Source

WorkflowWrittenAnnotations

class WorkflowWrittenAnnotations(BaseModel):
    """Where a run writes annotations, and which frames."""
    dataset: str
    dataset_name: str = ''
    directory: str = '/'
    new_folder_each_run: bool = False
    folder: str = '/'
    only_with_detections: bool = True
    min_interval_s: float | None = None

Source

WorkflowWrittenEventCapture

class WorkflowWrittenEventCapture(BaseModel):
    """Where a run writes event captures: its events and the capture interval."""
    dataset: str
    dataset_name: str = ''
    directory: str = '/'
    new_folder_each_run: bool = False
    folder: str = '/'
    events: list[str] = []
    min_interval_s: float = 1.0

Source

WorkflowWrittenPassiveCapture

class WorkflowWrittenPassiveCapture(BaseModel):
    """Where a run writes passive captures, and how often."""
    dataset: str
    dataset_name: str = ''
    directory: str = '/'
    new_folder_each_run: bool = False
    folder: str = '/'
    every_s: float = 10.0

Source

WorkflowWrittenWebhook

class WorkflowWrittenWebhook(BaseModel):
    """The webhook endpoint a run sends to, and the events it sends."""
    endpoint: str
    events: list[str] = []

Source

Copied to clipboard