ORAS Python SDK
ORAS Python SDK (Open Container Initiative Registry as Storage) is a Python library that enables users to push and pull OCI Artifacts to and from OCI-conformant registries. The current version is 0.2.42, and the project maintains an active and rapid release cadence with frequent updates.
Warnings
- breaking AWS ECR authentication support (`oras[ecr]`) was moved to an optional extra. If you were previously relying on ECR authentication without explicitly installing `oras[ecr]`, your setup will break.
- breaking Python 3.7+ compatibility was fixed, specifically regarding the use of union syntax (e.g., `list | None`). If you are using Python 3.7 or older, or if your environment relied on previous (potentially broken) behavior, this might affect you.
- gotcha The authentication priority for various credential sources (AWS-native, docker login, credHelpers, credsStore) has been explicitly fixed and re-ordered. If your environment relies on a specific order of credential resolution, this change might alter how your client authenticates.
- gotcha There have been multiple fixes related to how Docker's `credsStore` and `credHelpers` binaries are located and used for authentication. Users relying on these Docker credential helpers might experience intermittent authentication failures or incorrect credential resolution.
- gotcha An open issue indicates potential data loss where `oras-py` strips paths to basename during pull operations, leading to filename collisions if multiple artifacts share the same basename. This could result in one artifact overwriting another upon pulling.
Install
-
pip install oras -
pip install oras[ecr]
Imports
- OrasClient
from oras.client import OrasClient
- ManifestConfig
from oras.oci import ManifestConfig
Quickstart
import os
from oras.client import OrasClient
# Prepare a dummy file to push
with open('artifact.txt', 'w') as f:
f.write('Hello, ORAS!')
registry_hostname = os.environ.get('ORAS_REGISTRY_HOSTNAME', 'localhost:5000')
repository_target = f"{registry_hostname}/my/artifact:v1"
username = os.environ.get('ORAS_USERNAME', '')
password = os.environ.get('ORAS_PASSWORD', '')
client = OrasClient(hostname=registry_hostname, insecure=True) # Use insecure=True for local registries without TLS
if username and password:
print(f"Attempting to login to {registry_hostname}...")
try:
client.login(username=username, password=password)
print("Login successful.")
except Exception as e:
print(f"Login failed: {e}")
# Depending on local setup, login might not be strictly necessary for insecure local registries
print(f"Pushing artifact to {repository_target}...")
try:
push_response = client.push(files=["artifact.txt"], target=repository_target)
print(f"Push successful: {push_response}")
except Exception as e:
print(f"Push failed: {e}")
print("Ensure a registry is running at and accessible from '" + registry_hostname + "'. For example: 'docker run -d -p 5000:5000 --name oras-quickstart ghcr.io/oras-project/registry:latest'")
# Clean up after push if successful
# os.remove('artifact.txt') # Uncomment to clean up
# For pulling, create a new directory to avoid conflicts if artifact.txt already exists
pull_dir = './pulled_artifacts'
os.makedirs(pull_dir, exist_ok=True)
print(f"Pulling artifact from {repository_target} into {pull_dir}...")
try:
# Pulls into the current working directory by default, unless oras.utils.workdir is used
# For this example, we'll let it pull to current dir and specify path for clarity
pulled_files = client.pull(target=repository_target, output_dir=pull_dir)
print(f"Pull successful. Files: {pulled_files}")
# Verify content if needed
# with open(os.path.join(pull_dir, 'artifact.txt'), 'r') as f:
# print(f.read())
except Exception as e:
print(f"Pull failed: {e}")
# Cleanup pulled files
# import shutil
# shutil.rmtree(pull_dir)
# os.remove('artifact.txt') # If not removed after push