Microsoft Azure Custom Vision Client Library for Python providing training and prediction clients for custom computer vision models.
npx @tessl/cli install tessl/pypi-azure-cognitiveservices-vision-customvision@3.1.0Microsoft Azure Custom Vision Client Library for Python provides powerful machine learning capabilities for training custom computer vision models without requiring deep ML expertise. This library enables developers to build domain-specific image classification and object detection models through Azure's cloud infrastructure, offering programmatic access to the complete machine learning pipeline from data upload to model deployment.
pip install azure-cognitiveservices-vision-customvisionmsrest>=0.6.21, azure-common~=1.1, azure-mgmt-core>=1.2.0,<2.0.0from azure.cognitiveservices.vision.customvision.training import CustomVisionTrainingClient
from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClientAuthentication:
from msrest.authentication import ApiKeyCredentialsfrom azure.cognitiveservices.vision.customvision.training import CustomVisionTrainingClient
from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
from msrest.authentication import ApiKeyCredentials
# Initialize training client
training_key = "your-training-key"
training_endpoint = "https://southcentralus.api.cognitive.microsoft.com"
credentials = ApiKeyCredentials(in_headers={"Training-key": training_key})
training_client = CustomVisionTrainingClient(training_endpoint, credentials)
# Create a new project
project = training_client.create_project("My Custom Vision Project")
# Initialize prediction client
prediction_key = "your-prediction-key"
prediction_endpoint = "https://southcentralus.api.cognitive.microsoft.com"
prediction_credentials = ApiKeyCredentials(in_headers={"Prediction-key": prediction_key})
prediction_client = CustomVisionPredictionClient(prediction_endpoint, prediction_credentials)
# Make predictions (after model is trained and published)
with open("test_image.jpg", "rb") as image_data:
results = prediction_client.classify_image(project.id, "published_model_name", image_data)
for prediction in results.predictions:
print(f"{prediction.tag_name}: {prediction.probability:.2%}")The Azure Custom Vision API follows a two-client architecture that separates model development from inference:
This design enables scalable workflows where models are developed using the training client and deployed for production inference through the prediction client, supporting both cloud-based and edge deployment scenarios.
Complete machine learning pipeline management including project creation, data upload and management, model training, performance evaluation, and export capabilities. Supports both image classification and object detection workflows with advanced features like custom domains, batch operations, and AI-assisted labeling.
class CustomVisionTrainingClient:
def __init__(self, endpoint: str, credentials): ...
# Project Management
def get_projects(self) -> list: ...
def create_project(self, name: str, **options) -> Project: ...
def get_project(self, project_id: str) -> Project: ...
def delete_project(self, project_id: str): ...
def update_project(self, project_id: str, updated_project: Project) -> Project: ...
def export_project(self, project_id: str) -> ProjectExport: ...
def import_project(self, token: str, name: str = None) -> Project: ...
# Domain Management
def get_domains(self) -> list: ...
def get_domain(self, domain_id: str) -> Domain: ...
# Training Operations
def train_project(self, project_id: str, **options) -> Iteration: ...
def get_iterations(self, project_id: str) -> list: ...
def get_iteration(self, project_id: str, iteration_id: str) -> Iteration: ...
def delete_iteration(self, project_id: str, iteration_id: str): ...
def update_iteration(self, project_id: str, iteration_id: str, name: str) -> Iteration: ...
# Image Management
def create_images_from_data(self, project_id: str, image_data: bytes, tag_ids: list = None) -> ImageCreateSummary: ...
def create_images_from_files(self, project_id: str, batch: ImageFileCreateBatch) -> ImageCreateSummary: ...
def create_images_from_urls(self, project_id: str, batch: ImageUrlCreateBatch) -> ImageCreateSummary: ...
def create_images_from_predictions(self, project_id: str, batch: ImageIdCreateBatch) -> ImageCreateSummary: ...
def get_images(self, project_id: str, **options) -> list: ...
def get_images_by_ids(self, project_id: str, image_ids: list, iteration_id: str = None) -> list: ...
def get_tagged_images(self, project_id: str, **options) -> list: ...
def get_untagged_images(self, project_id: str, **options) -> list: ...
def delete_images(self, project_id: str, image_ids: list = None, **options): ...
def update_image_metadata(self, project_id: str, image_ids: list, metadata: dict) -> ImageMetadataUpdateSummary: ...
def get_image_count(self, project_id: str, **options) -> int: ...
def get_tagged_image_count(self, project_id: str, **options) -> int: ...
def get_untagged_image_count(self, project_id: str, **options) -> int: ...
# Tag Management
def get_tags(self, project_id: str, iteration_id: str = None) -> list: ...
def create_tag(self, project_id: str, name: str, **options) -> Tag: ...
def get_tag(self, project_id: str, tag_id: str, iteration_id: str = None) -> Tag: ...
def delete_tag(self, project_id: str, tag_id: str): ...
def update_tag(self, project_id: str, tag_id: str, updated_tag: Tag) -> Tag: ...
# Performance Analysis
def get_iteration_performance(self, project_id: str, iteration_id: str, **options) -> IterationPerformance: ...
def get_image_performances(self, project_id: str, iteration_id: str, **options) -> list: ...
def get_image_performance_count(self, project_id: str, iteration_id: str, **options) -> int: ...
# Publishing
def publish_iteration(self, project_id: str, iteration_id: str, publish_name: str, prediction_id: str, **options) -> bool: ...
def unpublish_iteration(self, project_id: str, iteration_id: str): ...
# Export Management
def get_exports(self, project_id: str, iteration_id: str) -> list: ...
def export_iteration(self, project_id: str, iteration_id: str, platform: str, **options) -> Export: ...
# Quick Testing
def quick_test_image(self, project_id: str, image_data: bytes, **options) -> ImagePrediction: ...
def quick_test_image_url(self, project_id: str, url: str, **options) -> ImagePrediction: ...
# Additional Operations (see training.md for complete signatures)
# Image regions, tagging, predictions, suggestions, and more...Inference operations for trained custom vision models supporting both image classification and object detection. Provides multiple prediction methods with options for storing prediction results or running predictions without storage.
class CustomVisionPredictionClient:
def __init__(self, endpoint: str, credentials): ...
# Image Classification (with storage)
def classify_image(self, project_id: str, published_name: str, image_data: bytes, application: str = None) -> ImagePrediction: ...
def classify_image_url(self, project_id: str, published_name: str, url: str, application: str = None) -> ImagePrediction: ...
# Image Classification (no storage)
def classify_image_with_no_store(self, project_id: str, published_name: str, image_data: bytes, application: str = None) -> ImagePrediction: ...
def classify_image_url_with_no_store(self, project_id: str, published_name: str, url: str, application: str = None) -> ImagePrediction: ...
# Object Detection (with storage)
def detect_image(self, project_id: str, published_name: str, image_data: bytes, application: str = None) -> ImagePrediction: ...
def detect_image_url(self, project_id: str, published_name: str, url: str, application: str = None) -> ImagePrediction: ...
# Object Detection (no storage)
def detect_image_with_no_store(self, project_id: str, published_name: str, image_data: bytes, application: str = None) -> ImagePrediction: ...
def detect_image_url_with_no_store(self, project_id: str, published_name: str, url: str, application: str = None) -> ImagePrediction: ...class Project:
"""Custom Vision project with settings and metadata."""
id: str
name: str
description: str
domain_id: str
classification_type: str
target_export_platforms: list
created: datetime
last_modified: datetime
thumbnail_uri: str
drain_mode: str
image_processing_settings: dict
is_flagship: bool
status: str
class ImagePrediction:
"""Main prediction result containing predictions and metadata."""
id: str
project: str
iteration: str
created: datetime
predictions: list
class Prediction:
"""Individual prediction with tag, probability, and optional bounding box."""
probability: float
tag_id: str
tag_name: str
bounding_box: BoundingBox = None
class BoundingBox:
"""Image region coordinates for object detection."""
left: float
top: float
width: float
height: float
class Iteration:
"""Trained model iteration with performance metrics."""
id: str
name: str
created: datetime
last_modified: datetime
trained_at: datetime
status: str
is_default: bool
domain_id: str
classification_type: str
platform: str
export_model_container_uri: str
reserved_budget_in_hours: int
publish_name: str
class Tag:
"""Image classification tag."""
id: str
name: str
description: str
image_count: int
type: str
class Domain:
"""Available domain for different model types."""
id: str
name: str
type: str
exportable: bool
enabled: bool
class CustomVisionErrorException(Exception):
"""Exception raised for all API operation failures."""
error: CustomVisionError
class CustomVisionError:
"""Detailed error information."""
code: str
message: str
# Training-specific Model Classes
class ImageCreateSummary:
"""Summary of image creation operation."""
is_batch_successful: bool
images: list
duplicate_count: int
class ImageFileCreateBatch:
"""Batch for creating images from files."""
images: list
tag_ids: list
class ImageFileCreateEntry:
"""Single file entry for batch creation."""
name: str
contents: bytes
tag_ids: list
regions: list
class ImageUrlCreateBatch:
"""Batch for creating images from URLs."""
images: list
tag_ids: list
class ImageUrlCreateEntry:
"""Single URL entry for batch creation."""
url: str
tag_ids: list
regions: list
class ImageIdCreateBatch:
"""Batch for creating images from predictions."""
images: list
tag_ids: list
class ImageIdCreateEntry:
"""Single prediction entry for batch creation."""
id: str
tag_ids: list
regions: list
class Image:
"""Image information with metadata."""
id: str
created: datetime
width: int
height: int
image_uri: str
thumbnail_uri: str
metadata: dict
tags: list
regions: list
predictions: list
class ImageRegion:
"""Image region information."""
region_id: str
tag_name: str
created: datetime
tag_id: str
left: float
top: float
width: float
height: float
class ImageRegionCreateBatch:
"""Batch for creating regions."""
regions: list
class ImageRegionCreateEntry:
"""Single region entry for batch creation."""
image_id: str
tag_id: str
left: float
top: float
width: float
height: float
class ImageRegionCreateSummary:
"""Region creation summary."""
created: list
duplicated: list
exceeded: list
class ImageRegionProposal:
"""Region proposal."""
project_id: str
image_id: str
proposals: list
class ImageTag:
"""Image tag information."""
image_id: str
tag_id: str
created: datetime
class ImageTagCreateBatch:
"""Batch for creating tags."""
tags: list
class ImageTagCreateEntry:
"""Single tag entry for batch creation."""
image_id: str
tag_id: str
class ImageTagCreateSummary:
"""Tag creation summary."""
created: list
duplicated: list
exceeded: list
class ImageMetadataUpdateEntry:
"""Metadata update entry."""
image_id: str
metadata: dict
class ImageMetadataUpdateSummary:
"""Metadata update summary."""
updated: list
limit_exceeded: list
errors: list
class Export:
"""Export details."""
platform: str
status: str
download_uri: str
flavor: str
newer_version_available: bool
class ProjectExport:
"""Project export information."""
token: str
class ProjectSettings:
"""Project settings."""
domain_id: str
classification_type: str
target_export_platforms: list
use_negative_set: bool
detection_parameters: str
image_processing_settings: dict
class ImageProcessingSettings:
"""Image processing settings."""
augmentation_methods: dict
class IterationPerformance:
"""Iteration performance metrics."""
per_tag_performance: list
precision: float
precision_std_deviation: float
recall: float
recall_std_deviation: float
average_precision: float
class TagPerformance:
"""Tag performance metrics."""
id: str
name: str
precision: float
precision_std_deviation: float
recall: float
recall_std_deviation: float
average_precision: float
class ImagePerformance:
"""Image performance metrics."""
id: str
created: datetime
width: int
height: int
image_uri: str
thumbnail_uri: str
predictions: list
tags: list
class PredictionQueryResult:
"""Prediction query result."""
results: list
token: dict
class PredictionQueryToken:
"""Prediction query token."""
session: str
continuation: str
max_count: int
order_by: str
tags: list
iteration_id: str
start_time: datetime
end_time: datetime
application: str
class PredictionQueryTag:
"""Prediction query tag."""
id: str
min_threshold: float
max_threshold: float
class StoredImagePrediction:
"""Stored image prediction."""
id: str
project: str
iteration: str
created: datetime
predictions: list
image_uri: str
thumbnail_uri: str
class SuggestedTagAndRegion:
"""Tag and region suggestion."""
id: str
tag: dict
region: dict
confidence: float
class SuggestedTagAndRegionQuery:
"""Suggestion query result."""
results: list
token: dict
class SuggestedTagAndRegionQueryToken:
"""Suggestion query token."""
session: str
continuation: str
max_count: int
order_by: str
tag_ids: list
threshold: float
class StoredSuggestedTagAndRegion:
"""Stored suggestion."""
id: str
tag_id: str
region: dict
confidence: float
class TagFilter:
"""Tag filter criteria."""
tag_id: str
min_threshold: float
max_threshold: float
class ModelInformation:
"""Model information."""
model_id: str
model_name: str
created_date: datetime
domain_id: str
class CustomBaseModelInfo:
"""Custom base model information."""
name: str
version: int
class TrainingParameters:
"""Training parameters."""
training_type: str
reserved_budget_in_hours: int
force_train: bool
notification_email_address: str
selected_tags: list
custom_base_model_info: dict
class Region:
"""Region information."""
left: float
top: float
width: float
height: float
class RegionProposal:
"""Region proposal."""
confidence: float
bounding_box: dict
class ImageUrl:
"""Image URL information."""
url: str# Classification Types
class Classifier:
MULTICLASS = "Multiclass"
MULTILABEL = "Multilabel"
# Training Types
class TrainingType:
REGULAR = "Regular"
ADVANCED = "Advanced"
# Export Platforms
class ExportPlatform:
COREML = "CoreML"
TENSORFLOW = "TensorFlow"
DOCKERFILE = "DockerFile"
ONNX = "ONNX"
VAIDK = "VAIDK"
OPENVINO = "OpenVino"
# Export Status
class ExportStatus:
EXPORTING = "Exporting"
FAILED = "Failed"
DONE = "Done"
# Domain Types
class DomainType:
CLASSIFICATION = "Classification"
OBJECT_DETECTION = "ObjectDetection"
# Tag Types
class TagType:
REGULAR = "Regular"
NEGATIVE = "Negative"
GENERAL_PRODUCT = "GeneralProduct"
# Export Flavors
class ExportFlavor:
LINUX = "Linux"
WINDOWS = "Windows"
ONNX10 = "ONNX10"
ONNX12 = "ONNX12"
ARM = "ARM"
TENSOR_FLOW_NORMAL = "TensorFlowNormal"
TENSOR_FLOW_LITE = "TensorFlowLite"
# Image Creation Status
class ImageCreateStatus:
OK = "OK"
OK_DUPLICATE = "OKDuplicate"
ERROR_SOURCE = "ErrorSource"
ERROR_IMAGE_FORMAT = "ErrorImageFormat"
ERROR_IMAGE_SIZE_BYTES = "ErrorImageSizeBytes"
ERROR_STORAGE = "ErrorStorage"
ERROR_LIMIT_EXCEED = "ErrorLimitExceed"
ERROR_TAG_LIMIT_EXCEED = "ErrorTagLimitExceed"
ERROR_REGION_LIMIT_EXCEED = "ErrorRegionLimitExceed"
ERROR_UNKNOWN = "ErrorUnknown"
# Image Metadata Update Status
class ImageMetadataUpdateStatus:
OK = "OK"
ERROR_IMAGE_NOT_FOUND = "ErrorImageNotFound"
ERROR_LIMIT_EXCEED = "ErrorLimitExceed"
ERROR_UNKNOWN = "ErrorUnknown"
# Project Status
class ProjectStatus:
SUCCEEDED = "Succeeded"
IMPORTING = "Importing"
FAILED = "Failed"
# Order By Options
class OrderBy:
NEWEST = "Newest"
OLDEST = "Oldest"
SUGGESTED = "Suggested"
# Sort By Options
class SortBy:
UNCERTAINTY_ASCENDING = "UncertaintyAscending"
UNCERTAINTY_DESCENDING = "UncertaintyDescending"
# Custom Vision Error Codes (major categories)
class CustomVisionErrorCodes:
NO_ERROR = "NoError"
BAD_REQUEST = "BadRequest"
BAD_REQUEST_EXPORT_PLATFORM_NOT_SUPPORTED = "BadRequestExportPlatformNotSupported"
BAD_REQUEST_INVALID_IDS = "BadRequestInvalidIds"
BAD_REQUEST_INVALID_IMPORT_TOKEN = "BadRequestInvalidImportToken"
BAD_REQUEST_LIMITED_TRIAL_MODEL = "BadRequestLimitedTrialModel"
BAD_REQUEST_NOT_LIMITED_TRIAL = "BadRequestNotLimitedTrial"
BAD_REQUEST_PARAMETER_MISSING = "BadRequestParameterMissing"
BAD_REQUEST_PROJECT_NOT_TRAINED = "BadRequestProjectNotTrained"
BAD_REQUEST_PROJECT_TRAINED = "BadRequestProjectTrained"
BAD_REQUEST_REGION_PROPOSAL_NOT_SUPPORTED = "BadRequestRegionProposalNotSupported"
BAD_REQUEST_TRAINING_NOT_NEEDED = "BadRequestTrainingNotNeeded"
BAD_REQUEST_UNSUPPORTED_DOMAIN = "BadRequestUnsupportedDomain"
BAD_REQUEST_UNSUPPORTED_EXPORT_PLATFORM = "BadRequestUnsupportedExportPlatform"
CONFLICT = "Conflict"
FORBIDDEN = "Forbidden"
FORBIDDEN_DOMAIN_NOT_SUPPORTED_FOR_ADVANCEDTRAINING = "ForbiddenDomainNotSupportedForAdvancedTraining"
FORBIDDEN_EXPORT_VALIDATION_FAILED = "ForbiddenExportValidationFailed"
FORBIDDEN_INVALID_SUBSCRIPTION_API = "ForbiddenInvalidSubscriptionApi"
FORBIDDEN_LIMITED_TRIAL_UPGRADE_REQUIRED = "ForbiddenLimitedTrialUpgradeRequired"
FORBIDDEN_MULTI_CLASS_LABEL_LIMIT_EXCEEDED = "ForbiddenMultiClassLabelLimitExceeded"
FORBIDDEN_MULTI_LABEL_LABEL_LIMIT_EXCEEDED = "ForbiddenMultiLabelLabelLimitExceeded"
FORBIDDEN_PROJECT_EXISTS = "ForbiddenProjectExists"
FORBIDDEN_QUERY_TOO_LONG = "ForbiddenQueryTooLong"
FORBIDDEN_USER_RESOURCE_ACCESS = "ForbiddenUserResourceAccess"
INTERNAL_SERVER_ERROR = "InternalServerError"
NOT_FOUND = "NotFound"
NOT_SUPPORTED = "NotSupported"
QUOTA_EXCEEDED = "QuotaExceeded"
REQUEST_ENTITY_TOO_LARGE = "RequestEntityTooLarge"
REQUEST_TIMEOUT = "RequestTimeout"
TOO_MANY_REQUESTS = "TooManyRequests"
UNAUTHORIZED = "Unauthorized"
UNSPECIFIED = "Unspecified"
UNSUPPORTED_MEDIA_TYPE = "UnsupportedMediaType"
ERROR_INVALID = "ErrorInvalid"
# ... and 120+ additional specific error codes