# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['moby_distribution',
 'moby_distribution.registry',
 'moby_distribution.registry.resources',
 'moby_distribution.spec']

package_data = \
{'': ['*']}

install_requires = \
['py-libtrust>=1.0.4',
 'pydantic>=1.5',
 'requests>=2.20.0',
 'www-authenticate>=0.9.2,<0.10.0']

setup_kwargs = {
    'name': 'moby-distribution',
    'version': '0.3.1',
    'description': 'Yet another moby(docker) distribution implement by python.',
    'long_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❯ pip install moby-distribution\n```\n\nOr install from GitHub for latest version.\n\n```bash\n❯ 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',
    'author': 'shabbywu',
    'author_email': 'shabbywu@qq.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/shabbywu/distribution',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6.1',
}


setup(**setup_kwargs)
