o
    Nrf O                     @   sb   d dl Z d dlZddlmZmZmZ ddlmZ e e	Z
G dd dZdd Z		dd	d
ZdS )    N   )autherrorsutils)DEFAULT_DATA_CHUNK_SIZEc                   @   s.  e Zd ZedefddZeddd Zd*dd	Z		d+d
dZ			d,ddZ
		d,ddZ		d,ddZ		d,ddZ		d,ddZeddd Zededd-ddZd-ddZedd-ddZ		d.d d!Z		d/d"d#Zedd0d$d%Zd-d&d'Zedd1d(d)ZdS )2ImageApiMixinimagec                 C   s$   | j | d|dd}| ||dS )a  
        Get a tarball of an image. Similar to the ``docker save`` command.

        Args:
            image (str): Image name to get
            chunk_size (int): The number of bytes returned by each iteration
                of the generator. If ``None``, data will be streamed as it is
                received. Default: 2 MB

        Returns:
            (generator): A stream of raw archive data.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.

        Example:

            >>> image = client.api.get_image("busybox:latest")
            >>> f = open('/tmp/busybox-latest.tar', 'wb')
            >>> for chunk in image:
            >>>   f.write(chunk)
            >>> f.close()
        z/images/{0}/getT)streamF)_get_urlZ_stream_raw_result)selfr   
chunk_sizeres r   Y/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/docker/api/image.py	get_image   s   zImageApiMixin.get_imagec                 C   s   |  | d|}| |dS )a$  
        Show the history of an image.

        Args:
            image (str): The image to show history for

        Returns:
            (list): The history of the image

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        z/images/{0}/historyT)r
   r   _result)r   r   r   r   r   r   history)   s   zImageApiMixin.historyNFc                 C   s   |rdnd|r	dndd}|r&t | jdr||d< n|r"||d< nd|i}|r/t ||d< | | j| d|d	d
}|rFdd |D S |S )a  
        List images. Similar to the ``docker images`` command.

        Args:
            name (str): Only show images belonging to the repository ``name``
            quiet (bool): Only return numeric IDs as a list.
            all (bool): Show intermediate image layers. By default, these are
                filtered out.
            filters (dict): Filters to be processed on the image list.
                Available filters:
                - ``dangling`` (bool)
                - `label` (str|list): format either ``"key"``, ``"key=value"``
                    or a list of such.

        Returns:
            (dict or list): A list if ``quiet=True``, otherwise a dict.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
           r   )Zonly_idsall1.25filter	referencefiltersz/images/jsonparamsTc                 S   s   g | ]}|d  qS )ZIdr   ).0xr   r   r   
<listcomp>c   s    z(ImageApiMixin.images.<locals>.<listcomp>)r   
version_lt_versionconvert_filtersr   r
   r   )r   namequietr   r   r   r   r   r   r   images;   s"   



zImageApiMixin.imagesc              
   C   s   |s	|s	t d| d}t|||t|tr|nd|d}ddi}	|s+|ddkr6| | j|d|d	S t|tr_t	|d
}
| | j||
||	ddW  d   S 1 sXw   Y  dS |red|	d< | | j||||	dS )ad  
        Import an image. Similar to the ``docker import`` command.

        If ``src`` is a string or unicode string, it will first be treated as a
        path to a tarball on the local system. If there is an error reading
        from that file, ``src`` will be treated as a URL instead to fetch the
        image from. You can also pass an open file handle as ``src``, in which
        case the data will be read from that file.

        If ``src`` is unset but ``image`` is set, the ``image`` parameter will
        be taken as the name of an existing image to import from.

        Args:
            src (str or file): Path to tarfile, URL, or file-like object
            repository (str): The repository to create
            tag (str): The tag to apply
            image (str): Use another image like the ``FROM`` Dockerfile
                parameter
        z(Must specify src or image to import from/images/createNsrcchangesContent-Typeapplication/tarfromSrc-)datar   rbr-   r   headerstimeoutchunkedzTransfer-Encoding)r-   r   r0   )
r   ZDockerExceptionr   _import_image_params
isinstancestrgetr   _postopen)r   r'   
repositorytagr   r(   
stream_srcur   r0   fr   r   r   import_imagef   s8   


$zImageApiMixin.import_imagec              	   C   s<   |  d}t||d|d}ddi}| | j||||ddS )a@  
        Like :py:meth:`~docker.api.image.ImageApiMixin.import_image`, but
        allows importing in-memory bytes data.

        Args:
            data (bytes collection): Bytes collection containing valid tar data
            repository (str): The repository to create
            tag (str): The tag to apply
        r%   r,   r&   r)   r*   Nr/   )r   r3   r   r7   )r   r-   r9   r:   r(   r<   r   r0   r   r   r   import_image_from_data   s   

z$ImageApiMixin.import_image_from_datac                 C      | j ||||dS )aj  
        Like :py:meth:`~docker.api.image.ImageApiMixin.import_image`, but only
        supports importing from a tar file on disk.

        Args:
            filename (str): Full path to a tar file.
            repository (str): The repository to create
            tag (str): The tag to apply

        Raises:
            IOError: File does not exist.
        r'   r9   r:   r(   r>   )r   filenamer9   r:   r(   r   r   r   import_image_from_file   s   z$ImageApiMixin.import_image_from_filec                 C   s   | j |d|||dS )NT)r'   r;   r9   r:   r(   rB   )r   r	   r9   r:   r(   r   r   r   import_image_from_stream   s   z&ImageApiMixin.import_image_from_streamc                 C   r@   )a"  
        Like :py:meth:`~docker.api.image.ImageApiMixin.import_image`, but only
        supports importing from a URL.

        Args:
            url (str): A URL pointing to a tar file.
            repository (str): The repository to create
            tag (str): The tag to apply
        rA   rB   )r   urlr9   r:   r(   r   r   r   import_image_from_url   s   z#ImageApiMixin.import_image_from_urlc                 C   r@   )aX  
        Like :py:meth:`~docker.api.image.ImageApiMixin.import_image`, but only
        supports importing from another image, like the ``FROM`` Dockerfile
        parameter.

        Args:
            image (str): Image name to import from
            repository (str): The repository to create
            tag (str): The tag to apply
        )r   r9   r:   r(   rB   )r   r   r9   r:   r(   r   r   r   import_image_from_image   s   z%ImageApiMixin.import_image_from_imagec                 C   s   |  | | d|dS )a  
        Get detailed information about an image. Similar to the ``docker
        inspect`` command, but only for images.

        Args:
            image (str): The image to inspect

        Returns:
            (dict): Similar to the output of ``docker inspect``, but as a
        single dict

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        z/images/{0}/jsonTr   r
   r   )r   r   r   r   r   inspect_image   s   zImageApiMixin.inspect_imagez1.30c                 C   sn   t |\}}i }|du rt | |}|r||d< ntd t ||d< | d|}| | j||ddS )a/  
        Get image digest and platform information by contacting the registry.

        Args:
            image (str): The image name to inspect
            auth_config (dict): Override the credentials that are found in the
                config for this request.  ``auth_config`` should contain the
                ``username`` and ``password`` keys to be valid.

        Returns:
            (dict): A dict containing distribution data

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        NX-Registry-AuthSending supplied auth configz/distribution/{0}/json)r0   T)	r   resolve_repository_nameget_config_headerlogdebugencode_headerr   r   r
   )r   r   auth_configregistry_r0   headerrF   r   r   r   inspect_distribution   s   
z"ImageApiMixin.inspect_distributionc                 C   sn   i }|durt | jdrtd||d< | j| d||dd}t | jdr0| j|ddS | 	| dS )	a9  
        Load an image that was previously saved using
        :py:meth:`~docker.api.image.ImageApiMixin.get_image` (or ``docker
        save``). Similar to ``docker load``.

        Args:
            data (binary): Image data to be loaded.
            quiet (boolean): Suppress progress details in response.

        Returns:
            (generator): Progress output as JSON objects. Only available for
                         API version >= 1.23

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        Nz1.23z,quiet is not supported in API version < 1.23r#   z/images/loadT)r-   r   r	   decode)
r   r   r    r   InvalidVersionr7   r   Zversion_gte_stream_helper_raise_for_status)r   r-   r#   r   r   r   r   r   
load_image#  s   zImageApiMixin.load_imager   c                 C   s:   |  d}i }|durt||d< | | j||ddS )a  
        Delete unused images

        Args:
            filters (dict): Filters to process on the prune list.
                Available filters:
                - dangling (bool):  When set to true (or 1), prune only
                unused and untagged images.

        Returns:
            (dict): A dict containing a list of deleted image IDs and
                the amount of disk space reclaimed in bytes.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        z/images/pruneNr   r   T)r   r   r!   r   r7   )r   r   rF   r   r   r   r   prune_imagesF  s
   
zImageApiMixin.prune_imagesc                 C   s   t |\}}|p|pd}|rd}t|\}	}
||d}i }|du r0t| |	}|r/||d< ntd t||d< |durPt | j	drLt
d||d< | j| d	|||dd
}| | |rk| j||dS | |S )aa  
        Pulls an image. Similar to the ``docker pull`` command.

        Args:
            repository (str): The repository to pull
            tag (str): The tag to pull. If ``tag`` is ``None`` or empty, it
                is set to ``latest``.
            stream (bool): Stream the output as a generator. Make sure to
                consume the generator, otherwise pull might get cancelled.
            auth_config (dict): Override the credentials that are found in the
                config for this request.  ``auth_config`` should contain the
                ``username`` and ``password`` keys to be valid.
            decode (bool): Decode the JSON data from the server into dicts.
                Only applies with ``stream=True``
            platform (str): Platform in the format ``os[/arch[/variant]]``
            all_tags (bool): Pull all image tags, the ``tag`` parameter is
                ignored.

        Returns:
            (generator or str): The output

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.

        Example:

            >>> resp = client.api.pull('busybox', stream=True, decode=True)
            ... for line in resp:
            ...     print(json.dumps(line, indent=4))
            {
                "status": "Pulling image (latest) from busybox",
                "progressDetail": {},
                "id": "e72ac664f4f0"
            }
            {
                "status": "Pulling image (latest) from busybox, endpoint: ...",
                "progressDetail": {},
                "id": "e72ac664f4f0"
            }

        ZlatestN)r:   	fromImagerK   rL   z1.32z0platform was only introduced in API version 1.32platformr%   )r   r0   r	   r1   rW   )r   parse_repository_tagr   rM   rN   rO   rP   rQ   r   r    r   rY   r7   r   r[   rZ   r   )r   r9   r:   r	   rR   rX   r_   Zall_tagsZ	image_tagrS   	repo_namer   r0   rU   responser   r   r   pull_  s<   ,


zImageApiMixin.pullc                 C   s   |s	t |\}}t|\}}| d|}d|i}	i }
|du r-t| |}|r,||
d< ntd t||
d< | j	|d|
||	d}| 
| |rQ| j||dS | |S )aG  
        Push an image or a repository to the registry. Similar to the ``docker
        push`` command.

        Args:
            repository (str): The repository to push to
            tag (str): An optional tag to push
            stream (bool): Stream the output as a blocking generator
            auth_config (dict): Override the credentials that are found in the
                config for this request.  ``auth_config`` should contain the
                ``username`` and ``password`` keys to be valid.
            decode (bool): Decode the JSON data from the server into dicts.
                Only applies with ``stream=True``

        Returns:
            (generator or str): The output from the server.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.

        Example:
            >>> resp = client.api.push(
            ...     'yourname/app',
            ...     stream=True,
            ...     decode=True,
            ... )
            ... for line in resp:
            ...   print(line)
            {'status': 'Pushing repository yourname/app (1 tags)'}
            {'status': 'Pushing','progressDetail': {}, 'id': '511136ea3c5a'}
            {'status': 'Image already pushed, skipping', 'progressDetail':{},
             'id': '511136ea3c5a'}
            ...

        z/images/{0}/pushr:   NrK   rL   )r0   r	   r   rW   )r   r`   r   rM   r   rN   rO   rP   rQ   Z
_post_jsonr[   rZ   r   )r   r9   r:   r	   rR   rX   rS   ra   r<   r   r0   rU   rb   r   r   r   push  s*   &



zImageApiMixin.pushc                 C   s,   ||d}| j | d||d}| |dS )z
        Remove an image. Similar to the ``docker rmi`` command.

        Args:
            image (str): The image to remove
            force (bool): Force removal of the image
            noprune (bool): Do not delete untagged parents
        )forcenoprunez/images/{0}r   T)_deleter   r   )r   r   re   rf   r   r   r   r   r   remove_image  s   

zImageApiMixin.remove_imagec                 C   s4   d|i}|dur||d< |  | j| d|ddS )a  
        Search for images on Docker Hub. Similar to the ``docker search``
        command.

        Args:
            term (str): A term to search for.
            limit (int): The maximum number of results to return.

        Returns:
            (list of dicts): The response of the search.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        termNlimitz/images/searchr   TrI   )r   ri   rj   r   r   r   r   search  s   zImageApiMixin.searchc                 C   sB   |||rdndd}|  d|}| j||d}| | |jdkS )aH  
        Tag an image into a repository. Similar to the ``docker tag`` command.

        Args:
            image (str): The image to tag
            repository (str): The repository to set for the tag
            tag (str): The tag name
            force (bool): Force

        Returns:
            (bool): ``True`` if successful

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.

        Example:

            >>> client.api.tag('ubuntu', 'localhost:5000/ubuntu', 'latest',
                           force=True)
        r   r   )r:   repore   z/images/{0}/tagr      )r   r7   r[   status_code)r   r   r9   r:   re   r   rF   r   r   r   r   r:     s   


zImageApiMixin.tag)NFFN)NNNNNFNNN)N)NFNFNF)NFNF)FFNF)__name__
__module____qualname__r   Zcheck_resourcer   r   r   r$   r>   r?   rD   rE   rG   rH   rJ   minimum_versionrV   r\   r]   rc   rd   rh   rk   r:   r   r   r   r   r   
   sV    

+
4






"#
U
B
r   c                 C   s.   zt | totj| W S  ty   Y dS w rp   )r4   r5   ospathisfile	TypeError)r'   r   r   r   is_file?  s   

ry   c                 C   sF   | |d}|r||d< n|rt |s||d< nd|d< |r!||d< |S )N)rl   r:   r^   r+   r,   r(   )ry   )rl   r:   r   r'   r(   r   r   r   r   r3   I  s   

r3   ro   )loggingru    r   r   r   	constantsr   	getLoggerrq   rO   r   ry   r3   r   r   r   r   <module>   s    
    9
