# moby-distribution - Yet another moby(docker) distribution implement by python.
moby-distribution is a library for operating Docker Image Manifest and Blobs (Layers, Config, etc.).
Works for Python 3.6+.
## Usage
### Install
You can install from PyPi.
```bash
❯ pip install moby-distribution
```
Or install from GitHub for latest version.
```bash
❯ pip install https://github.com/shabbywu/distribution/archive/main.zip
```
### Introduction
The API provides several classes: `ManifestRef`, `Blob`, `Tags`, `DockerRegistryV2Client`, `APIEndpoint`, `ImageRef`
`ManifestRef` has the following methods:
- `get(media_type)` retrieve image manifest as the provided media_type
- `get_metadata(media_type)` retrieve the manifest descriptor if the manifest exists.
- `delete(raise_not_found)` Removes the manifest specified by the provided reference.
- `put(manifest)` creates or updates the given manifest.
`Blob` has the following methods:
- `download(digest)` download the blob from registry to `local_path` or `fileobj`
- `upload()` upload the blob from `local_path` or `fileobj` to the registry by streaming
- `upload_at_one_time()` upload the monolithic blob from `local_path` or `fileobj` to the registry at one time.
- `mount_from(from_repo)` mount the blob from the given repo, if the client has read access to.
- `delete(digest)` delete the blob at the registry.
`Tags` has the following methods:
- `list()` return the list of tags in the repo
- `get(tag)` retrieve the manifest descriptor identified by the tag.
- `untag(tag)` work like `ManifestRef.delete()`
`ImageRef` has the following methods:
- `from_image(from_repo, from_reference, to_repo, to_reference)` init a `ImageRef` from `{from_repo}:{from_reference}` but will name `{to_repo, to_reference}`.
- `save(dest)` save the image to dest, as Docker Image Specification v1.2 Format.
- `push(media_type="application/vnd.docker.distribution.manifest.v2+json")` push the image to the registry.
- `push_v2()` push the image to the registry, with Manifest Schema2.
- `add_layer(layer_ref)` add a layer to this image, this is a way to build a new Image.
`DockerRegistryV2Client` has the following methods:
- `from_api_endpoint(api_endpoint, username, password)` initial a client to the `api_endpoint` with `username` and `password`
`APIEndpoint` is a dataclass, you can define APIEndpoint in the following ways:
```python
from moby_distribution import APIEndpoint
# 1. Provide scheme
APIEndpoint(url="https://registry.hub.docker.com")
# 2. No scheme provided
APIEndpoint(url="registry.hub.docker.com")
```
if the scheme is missing, we will detect whether the server provides ssl and verify the certificate.
If no ssl: use http(80).
If have ssl, but certificate is invalid:
- try to ping the registry with https(443), if success, use it
- otherwise, downgrade to http(80)
If have ssl and valid certificate: use https(443)
We provide an anonymous client connected to Docker Official Registry as default, you can find it at `moby_distribution.default_client`,
and you can override the default client by `set_default_client(client)`.
### Example
#### 1. List Tags for the Docker Official Image `library/python`
```python
from moby_distribution import Tags
Tags(repo="library/python").list()
# ['2', '2-alpine', '2-alpine3.10', '2-alpine3.11', '2-alpine3.4', '2-alpine3.6', ...]
```
#### 2. Get Manifest for the Docker Official Image `library/python:latest`
```python
from moby_distribution import ManifestRef, ManifestSchema1, ManifestSchema2
# Get Docker Image Manifest Version 2, Schema 1
# see alse: https://github.com/distribution/distribution/blob/main/docs/spec/manifest-v2-1.md
ManifestRef(repo="library/python", reference="latest").get(ManifestSchema1.content_type())
# Get Docker Image Manifest Version 2, Schema 2
# see alse: https://github.com/distribution/distribution/blob/main/docs/spec/manifest-v2-2.md
ManifestRef(repo="library/python", reference="latest").get(ManifestSchema2.content_type())
```
#### 3. Get the Config(aka Image JSON) for the Docker Official Image `library/python:latest`
```python
from io import BytesIO
from moby_distribution import ManifestRef, Blob
# Get Docker Image Manifest Version 2, Schema 2
manifest = ManifestRef(repo="library/python", reference="latest").get()
fh = BytesIO()
Blob(fileobj=fh, repo="library/python", digest=manifest.config.digest).download()
fh.seek(0)
config = fh.read()
```
> Using the `local_path` parameter, you can download to the file system instead of memory.
### 4. Push Blobs (Layers, Config, etc.) to Docker Registry
```python
from io import BytesIO
from moby_distribution import Blob, DockerRegistryV2Client, OFFICIAL_ENDPOINT
# To upload files to Docker Registry, you must login to your account
client = DockerRegistryV2Client.from_api_endpoint(OFFICIAL_ENDPOINT, username="your-username", password="your-password")
fh = BytesIO("just a demo")
assert Blob(repo="your-username/demo", fileobj=fh).upload()
```
> Using the `local_path` parameter, you can upload blobs from the file system instead of memory.
### 5. Push Image Manifest to Docker Registry
```python
from moby_distribution import ManifestSchema2, DockerRegistryV2Client, OFFICIAL_ENDPOINT, ManifestRef
# To upload files to Docker Registry, you must login to your account
client = DockerRegistryV2Client.from_api_endpoint(OFFICIAL_ENDPOINT, username="your-username", password="your-password")
# Build the ManifestSchema2 you need to upload
manifest = ManifestSchema2(
schemaVersion=2,
mediaType="application/vnd.docker.distribution.manifest.v2+json",
config={
...
},
layers=[
...
]
)
ManifestRef(repo="your-username/demo", reference="latest").put(manifest)
```
### 6. Upload the complete image to Docker Registry, Do it Yourself!
Read the process description of [the official document](https://github.com/distribution/distribution/blob/main/docs/spec/api.md#pushing-an-image)
1. Pushing the Layers as Example 4 do
2. Pushing the Config as Example 4 do
3. Pushing the Image Manifest as Example 5 do
Done, Congratulations!
**Here is another way, use the newly implemented ImageRef!**
```python
from moby_distribution import ImageRef, DockerRegistryV2Client, OFFICIAL_ENDPOINT
# To upload files to Docker Registry, you must login to your account
client = DockerRegistryV2Client.from_api_endpoint(OFFICIAL_ENDPOINT, username="your-username", password="your-password")
image_ref = ImageRef.from_image(from_repo="your-repo", from_reference="your-reference", to_reference="the-new-reference")
image_ref.push()
```
The above statement achieves the equivalent function of `docker tag {your-repo}:{your-reference} {your-repo}:{the-new-reference} && docker push {your-repo}:{the-new-reference}`
### RoadMap
- [x] implement the Distribution Client API for moby(docker)
- [x] implement the Docker Image Operator(Operator that implement Example 6)
- [ ] Command line tool for operating Image
- [ ] implement the Distribution Client API for OCI
Raw data
{
"_id": null,
"home_page": "https://github.com/shabbywu/distribution",
"name": "moby-distribution",
"maintainer": null,
"docs_url": null,
"requires_python": "<4,>=3.8",
"maintainer_email": null,
"keywords": null,
"author": "shabbywu",
"author_email": "shabbywu@qq.com",
"download_url": "https://files.pythonhosted.org/packages/86/5b/216eb4775d140a92bad5152c479fa4560afd8ccab1f1e145a7480bf0120b/moby_distribution-0.8.2.tar.gz",
"platform": null,
"description": "# moby-distribution - Yet another moby(docker) distribution implement by python.\n\nmoby-distribution is a library for operating Docker Image Manifest and Blobs (Layers, Config, etc.).\n\nWorks for Python 3.6+.\n\n## Usage\n\n### Install\nYou can install from PyPi.\n\n```bash\n\u276f pip install moby-distribution\n```\n\nOr install from GitHub for latest version.\n\n```bash\n\u276f pip install https://github.com/shabbywu/distribution/archive/main.zip\n```\n\n### Introduction\nThe API provides several classes: `ManifestRef`, `Blob`, `Tags`, `DockerRegistryV2Client`, `APIEndpoint`, `ImageRef`\n\n`ManifestRef` has the following methods:\n- `get(media_type)` retrieve image manifest as the provided media_type\n- `get_metadata(media_type)` retrieve the manifest descriptor if the manifest exists.\n- `delete(raise_not_found)` Removes the manifest specified by the provided reference.\n- `put(manifest)` creates or updates the given manifest.\n\n`Blob` has the following methods:\n- `download(digest)` download the blob from registry to `local_path` or `fileobj`\n- `upload()` upload the blob from `local_path` or `fileobj` to the registry by streaming\n- `upload_at_one_time()` upload the monolithic blob from `local_path` or `fileobj` to the registry at one time.\n- `mount_from(from_repo)` mount the blob from the given repo, if the client has read access to.\n- `delete(digest)` delete the blob at the registry.\n\n`Tags` has the following methods:\n- `list()` return the list of tags in the repo\n- `get(tag)` retrieve the manifest descriptor identified by the tag.\n- `untag(tag)` work like `ManifestRef.delete()`\n\n`ImageRef` has the following methods:\n- `from_image(from_repo, from_reference, to_repo, to_reference)` init a `ImageRef` from `{from_repo}:{from_reference}` but will name `{to_repo, to_reference}`.\n- `save(dest)` save the image to dest, as Docker Image Specification v1.2 Format.\n- `push(media_type=\"application/vnd.docker.distribution.manifest.v2+json\")` push the image to the registry.\n- `push_v2()` push the image to the registry, with Manifest Schema2.\n- `add_layer(layer_ref)` add a layer to this image, this is a way to build a new Image.\n\n`DockerRegistryV2Client` has the following methods:\n- `from_api_endpoint(api_endpoint, username, password)` initial a client to the `api_endpoint` with `username` and `password`\n\n`APIEndpoint` is a dataclass, you can define APIEndpoint in the following ways:\n```python\nfrom moby_distribution import APIEndpoint\n# 1. Provide scheme\nAPIEndpoint(url=\"https://registry.hub.docker.com\")\n\n# 2. No scheme provided\nAPIEndpoint(url=\"registry.hub.docker.com\")\n```\n\nif the scheme is missing, we will detect whether the server provides ssl and verify the certificate.\n\nIf no ssl: use http(80).\nIf have ssl, but certificate is invalid:\n - try to ping the registry with https(443), if success, use it\n - otherwise, downgrade to http(80)\nIf have ssl and valid certificate: use https(443)\n\nWe provide an anonymous client connected to Docker Official Registry as default, you can find it at `moby_distribution.default_client`,\nand you can override the default client by `set_default_client(client)`.\n\n### Example\n#### 1. List Tags for the Docker Official Image `library/python`\n```python\nfrom moby_distribution import Tags\n\nTags(repo=\"library/python\").list()\n# ['2', '2-alpine', '2-alpine3.10', '2-alpine3.11', '2-alpine3.4', '2-alpine3.6', ...]\n```\n\n#### 2. Get Manifest for the Docker Official Image `library/python:latest`\n```python\nfrom moby_distribution import ManifestRef, ManifestSchema1, ManifestSchema2\n\n# Get Docker Image Manifest Version 2, Schema 1\n# see alse: https://github.com/distribution/distribution/blob/main/docs/spec/manifest-v2-1.md\nManifestRef(repo=\"library/python\", reference=\"latest\").get(ManifestSchema1.content_type())\n\n# Get Docker Image Manifest Version 2, Schema 2\n# see alse: https://github.com/distribution/distribution/blob/main/docs/spec/manifest-v2-2.md\nManifestRef(repo=\"library/python\", reference=\"latest\").get(ManifestSchema2.content_type())\n```\n\n#### 3. Get the Config(aka Image JSON) for the Docker Official Image `library/python:latest`\n```python\nfrom io import BytesIO\nfrom moby_distribution import ManifestRef, Blob\n\n# Get Docker Image Manifest Version 2, Schema 2\nmanifest = ManifestRef(repo=\"library/python\", reference=\"latest\").get()\n\nfh = BytesIO()\nBlob(fileobj=fh, repo=\"library/python\", digest=manifest.config.digest).download()\n\nfh.seek(0)\nconfig = fh.read()\n```\n\n> Using the `local_path` parameter, you can download to the file system instead of memory.\n\n### 4. Push Blobs (Layers, Config, etc.) to Docker Registry\n\n```python\nfrom io import BytesIO\nfrom moby_distribution import Blob, DockerRegistryV2Client, OFFICIAL_ENDPOINT\n\n# To upload files to Docker Registry, you must login to your account\nclient = DockerRegistryV2Client.from_api_endpoint(OFFICIAL_ENDPOINT, username=\"your-username\", password=\"your-password\")\n\nfh = BytesIO(\"just a demo\")\n\nassert Blob(repo=\"your-username/demo\", fileobj=fh).upload()\n```\n\n> Using the `local_path` parameter, you can upload blobs from the file system instead of memory.\n\n### 5. Push Image Manifest to Docker Registry\n\n```python\nfrom moby_distribution import ManifestSchema2, DockerRegistryV2Client, OFFICIAL_ENDPOINT, ManifestRef\n\n# To upload files to Docker Registry, you must login to your account\nclient = DockerRegistryV2Client.from_api_endpoint(OFFICIAL_ENDPOINT, username=\"your-username\", password=\"your-password\")\n\n# Build the ManifestSchema2 you need to upload\nmanifest = ManifestSchema2(\n schemaVersion=2,\n mediaType=\"application/vnd.docker.distribution.manifest.v2+json\",\n config={\n ...\n },\n layers=[\n ...\n ]\n)\n\nManifestRef(repo=\"your-username/demo\", reference=\"latest\").put(manifest)\n```\n\n### 6. Upload the complete image to Docker Registry, Do it Yourself!\nRead the process description of [the official document](https://github.com/distribution/distribution/blob/main/docs/spec/api.md#pushing-an-image)\n1. Pushing the Layers as Example 4 do\n2. Pushing the Config as Example 4 do\n3. Pushing the Image Manifest as Example 5 do\n\nDone, Congratulations!\n\n**Here is another way, use the newly implemented ImageRef!**\n```python\nfrom moby_distribution import ImageRef, DockerRegistryV2Client, OFFICIAL_ENDPOINT\n\n# To upload files to Docker Registry, you must login to your account\nclient = DockerRegistryV2Client.from_api_endpoint(OFFICIAL_ENDPOINT, username=\"your-username\", password=\"your-password\")\n\nimage_ref = ImageRef.from_image(from_repo=\"your-repo\", from_reference=\"your-reference\", to_reference=\"the-new-reference\")\nimage_ref.push()\n```\nThe above statement achieves the equivalent function of `docker tag {your-repo}:{your-reference} {your-repo}:{the-new-reference} && docker push {your-repo}:{the-new-reference}`\n\n### RoadMap\n- [x] implement the Distribution Client API for moby(docker)\n- [x] implement the Docker Image Operator(Operator that implement Example 6)\n- [ ] Command line tool for operating Image\n- [ ] implement the Distribution Client API for OCI\n\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Yet another moby(docker) distribution implement by python.",
"version": "0.8.2",
"project_urls": {
"Homepage": "https://github.com/shabbywu/distribution",
"Repository": "https://github.com/shabbywu/distribution"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "26e34064b62fd736d088fabd0024ad58049759d5e95024496225d2383fbe7b7d",
"md5": "ccdf79b8888e7ec5a4529616695836bb",
"sha256": "dd063867f9fbf356702a586b1b4dd598c35cd10a7c696c2177662b297bfb2a4c"
},
"downloads": -1,
"filename": "moby_distribution-0.8.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ccdf79b8888e7ec5a4529616695836bb",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4,>=3.8",
"size": 30240,
"upload_time": "2024-04-12T04:17:41",
"upload_time_iso_8601": "2024-04-12T04:17:41.693052Z",
"url": "https://files.pythonhosted.org/packages/26/e3/4064b62fd736d088fabd0024ad58049759d5e95024496225d2383fbe7b7d/moby_distribution-0.8.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "865b216eb4775d140a92bad5152c479fa4560afd8ccab1f1e145a7480bf0120b",
"md5": "5eba254cfb7c039d8bf040e8f48b0633",
"sha256": "714669fec79f3afd801ba218a10291d1657ec848a0eeaa47f85ac11bb13ebafb"
},
"downloads": -1,
"filename": "moby_distribution-0.8.2.tar.gz",
"has_sig": false,
"md5_digest": "5eba254cfb7c039d8bf040e8f48b0633",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4,>=3.8",
"size": 25342,
"upload_time": "2024-04-12T04:17:43",
"upload_time_iso_8601": "2024-04-12T04:17:43.549137Z",
"url": "https://files.pythonhosted.org/packages/86/5b/216eb4775d140a92bad5152c479fa4560afd8ccab1f1e145a7480bf0120b/moby_distribution-0.8.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-12 04:17:43",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "shabbywu",
"github_project": "distribution",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "moby-distribution"
}