Package: azure-containerregistry
Azure Container Registry client library for PythonAzure Container Registry allows you to store and manage container images and artifacts in a private registry for all types of container deployments.Use the client library for Azure Container Registry to:List images or artifacts in a registryObtain metadata for images and artifacts, repositories and tagsSet read/write/delete properties on registry itemsDelete images and artifacts, repositories and tagsSource code|Package (Pypi)|Package (Conda)|API reference documentation|REST API documentation|Product documentationDisclaimerAzure SDK Python packages support for Python 2.7 has ended 01 January 2022. For more information and questions, please refer tohttps://github.com/Azure/azure-sdk-for-python/issues/20691Python 3.7 or later is required to use this package. For more details, please refer toAzure SDK for Python version support policy.Getting startedInstall the packageInstall the Azure Container Registry client library for Python withpip:pipinstall--preazure-containerregistryPrerequisitesPython 3.7 or later is required to use this package.You need anAzure subscriptionand aContainer Registry accountto use this package.To create a new Container Registry, you can use theAzure Portal,Azure PowerShell, or theAzure CLI.
Here's an example using the Azure CLI:azacrcreate--nameMyContainerRegistry--resource-groupMyResourceGroup--locationwestus--skuBasicAuthenticate the clientTheAzure Identity libraryprovides easy Azure Active Directory support for authentication. TheDefaultAzureCredentialassumes theAZURE_CLIENT_ID,AZURE_TENANT_ID, andAZURE_CLIENT_SECRETenvironment variables are set, for more information refer to theAzure Identity environment variables section# Create a ContainerRegistryClient that will authenticate through Active Directoryfromazure.containerregistryimportContainerRegistryClientfromazure.identityimportDefaultAzureCredentialendpoint="https://mycontainerregistry.azurecr.io"audience="https://management.azure.com"client=ContainerRegistryClient(endpoint,DefaultAzureCredential(),audience=audience)Key conceptsAregistrystores Docker images andOCI Artifacts.  An image or artifact consists of amanifestandlayers.  An image's manifest describes the layers that make up the image, and is uniquely identified by itsdigest.  An image can also be "tagged" to give it a human-readable alias.  An image or artifact can have zero or moretagsassociated with it, and each tag uniquely identifies the image.  A collection of images that share the same name but have different tags, is referred to as arepository.For more information please seeContainer Registry Concepts.ExamplesThe following sections provide several code snippets covering some of the most common ACR Service tasks, including:Registry operations:List repositoriesList tags with anonymous accessSet artifact propertiesDelete imagesBlob and manifest operations:Upload imagesDownload imagesDelete manifestDelete blobPlease note that each sample assumes there is aCONTAINERREGISTRY_ENDPOINTenvironment variable set to a string containing thehttps://prefix and the name of the login server, for example "https://myregistry.azurecr.io". Anonymous access samples are getting endpoint value from environment variableCONTAINERREGISTRY_ANONREGISTRY_ENDPOINT.List repositoriesIterate through the collection of repositories in the registry.withContainerRegistryClient(self.endpoint,self.credential)asclient:# Iterate through all the repositoriesforrepository_nameinclient.list_repository_names():print(repository_name)List tags with anonymous accessIterate through the collection of tags in the repository with anonymous access.withContainerRegistryClient(endpoint)asanon_client:manifest=anon_client.get_manifest_properties("library/hello-world","latest")print(f"Tags of{manifest.repository_name}: ")# Iterate through all the tagsfortaginmanifest.tags:print(tag)Set artifact propertiesSet properties of an artifact.withContainerRegistryClient(self.endpoint,self.credential)asclient:# Set permissions on image "library/hello-world:v1"client.update_manifest_properties("library/hello-world","v1",can_write=False,can_delete=False)Delete imagesDelete images older than the first three in the repository.withContainerRegistryClient(self.endpoint,self.credential)asclient:forrepositoryinclient.list_repository_names():# Keep the three most recent images, delete everything elsemanifest_count=0formanifestinclient.list_manifest_properties(repository,order_by=ArtifactManifestOrder.LAST_UPDATED_ON_DESCENDING):manifest_count+=1ifmanifest_count>3:# Make sure will have the permission to delete the manifest laterclient.update_manifest_properties(repository,manifest.digest,can_write=True,can_delete=True)print(f"Deleting{repository}:{manifest.digest}")client.delete_manifest(repository,manifest.digest)Upload imagesTo upload a full image, we need to upload individual layers and configuration. After that we can upload a manifest which describes an image or artifact and assign it a tag.self.repository_name="sample-oci-image"layer=BytesIO(b"Sample layer")config=BytesIO(json.dumps({"sample config":"content",}).encode())withContainerRegistryClient(self.endpoint,self.credential)asclient:# Upload a layerlayer_digest,layer_size=client.upload_blob(self.repository_name,layer)print(f"Uploaded layer: digest -{layer_digest}, size -{layer_size}")# Upload a configconfig_digest,config_size=client.upload_blob(self.repository_name,config)print(f"Uploaded config: digest -{config_digest}, size -{config_size}")# Create an oci image with config and layer infooci_manifest={"config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":config_digest,"sizeInBytes":config_size,},"schemaVersion":2,"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar","digest":layer_digest,"size":layer_size,"annotations":{"org.opencontainers.image.ref.name":"artifact.txt",},},],}# Set the image with tag "latest"manifest_digest=client.set_manifest(self.repository_name,oci_manifest,tag="latest")print(f"Uploaded manifest: digest -{manifest_digest}")Download imagesTo download a full image, we need to download its manifest and then download individual layers and configuration.withContainerRegistryClient(self.endpoint,self.credential)asclient:# Get the imageget_manifest_result=client.get_manifest(self.repository_name,"latest")received_manifest=get_manifest_result.manifestprint(f"Got manifest:\n{received_manifest}")# Download and write out the layersforlayerinreceived_manifest["layers"]:# Remove the "sha256:" prefix from digestlayer_file_name=layer["digest"].split(":")[1]try:stream=client.download_blob(self.repository_name,layer["digest"])withopen(layer_file_name,"wb")aslayer_file:forchunkinstream:layer_file.write(chunk)exceptDigestValidationError:print(f"Downloaded layer digest value did not match. Deleting file{layer_file_name}.")os.remove(layer_file_name)print(f"Got layer:{layer_file_name}")# Download and write out the configconfig_file_name="config.json"try:stream=client.download_blob(self.repository_name,received_manifest["config"]["digest"])withopen(config_file_name,"wb")asconfig_file:forchunkinstream:config_file.write(chunk)exceptDigestValidationError:print(f"Downloaded config digest value did not match. Deleting file{config_file_name}.")os.remove(config_file_name)print(f"Got config:{config_file_name}")Delete manifestwithContainerRegistryClient(self.endpoint,self.credential)asclient:get_manifest_result=client.get_manifest(self.repository_name,"latest")# Delete the imageclient.delete_manifest(self.repository_name,get_manifest_result.digest)Delete blobwithContainerRegistryClient(self.endpoint,self.credential)asclient:get_manifest_result=client.get_manifest(self.repository_name,"latest")received_manifest=get_manifest_result.manifest# Delete the layersforlayerinreceived_manifest["layers"]:client.delete_blob(self.repository_name,layer["digest"])# Delete the configclient.delete_blob(self.repository_name,received_manifest["config"]["digest"])TroubleshootingFor infomation about troubleshooting, refer to thetroubleshooting guide.GeneralACR client library will raise exceptions defined inAzure Core.LoggingThis library uses the standardlogginglibrary for logging.Basic information about HTTP sessions (URLs, headers, etc.) is logged atINFOlevel.DetailedDEBUGlevel logging, including request/response bodies andunredactedheaders, can be enabled on the client or per-operation with thelogging_enablekeyword argument.See full SDK logging documentation with exampleshere.Optional ConfigurationOptional keyword arguments can be passed in at the client and per-operation level.
The azure-corereference documentationdescribes available configurations for retries, logging, transport protocols, and more.Next stepsGo further with azure.containerregistry and oursamples.Watch ademo or deep dive video.Read more about theAzure Container Registry service.ContributingThis project welcomes contributions and suggestions.  Most contributions require
you to agree to a Contributor License Agreement (CLA) declaring that you have
the right to, and actually do, grant us the rights to use your contribution. For
details, visitcla.microsoft.com.This project has adopted theMicrosoft Open Source Code of Conduct.
For more information see theCode of Conduct FAQor contactopencode@microsoft.comwith any
additional questions or comments.