Current File : //usr/lib/python3/dist-packages/s3transfer/__pycache__/processpool.cpython-312.pyc
�

�<�e����~�dZddlZddlZddlZddlZddlZddlZddlmZddl	Z
ddlmZddl
mZmZddlmZmZmZddlmZmZddlmZmZdd	lmZmZmZmZmZej@e!�Z"d
Z#ejHdgd��Z%ejHd
gd��Z&ejNd��Z(d�Z)Gd�d�Z*Gd�d�Z+Gd�de�Z,Gd�de�Z-Gd�d�Z.Gd�d�Z/Gd�d�Z0Gd�d e�Z1e1jede/�Gd!�d"ejf�Z4Gd#�d$e4�Z5Gd%�d&e4�Z6y)'aCSpeeds up S3 throughput by using processes

Getting Started
===============

The :class:`ProcessPoolDownloader` can be used to download a single file by
calling :meth:`ProcessPoolDownloader.download_file`:

.. code:: python

     from s3transfer.processpool import ProcessPoolDownloader

     with ProcessPoolDownloader() as downloader:
          downloader.download_file('mybucket', 'mykey', 'myfile')


This snippet downloads the S3 object located in the bucket ``mybucket`` at the
key ``mykey`` to the local file ``myfile``. Any errors encountered during the
transfer are not propagated. To determine if a transfer succeeded or
failed, use the `Futures`_ interface.


The :class:`ProcessPoolDownloader` can be used to download multiple files as
well:

.. code:: python

     from s3transfer.processpool import ProcessPoolDownloader

     with ProcessPoolDownloader() as downloader:
          downloader.download_file('mybucket', 'mykey', 'myfile')
          downloader.download_file('mybucket', 'myotherkey', 'myotherfile')


When running this snippet, the downloading of ``mykey`` and ``myotherkey``
happen in parallel. The first ``download_file`` call does not block the
second ``download_file`` call. The snippet blocks when exiting
the context manager and blocks until both downloads are complete.

Alternatively, the ``ProcessPoolDownloader`` can be instantiated
and explicitly be shutdown using :meth:`ProcessPoolDownloader.shutdown`:

.. code:: python

     from s3transfer.processpool import ProcessPoolDownloader

     downloader = ProcessPoolDownloader()
     downloader.download_file('mybucket', 'mykey', 'myfile')
     downloader.download_file('mybucket', 'myotherkey', 'myotherfile')
     downloader.shutdown()


For this code snippet, the call to ``shutdown`` blocks until both
downloads are complete.


Additional Parameters
=====================

Additional parameters can be provided to the ``download_file`` method:

* ``extra_args``: A dictionary containing any additional client arguments
  to include in the
  `GetObject <https://botocore.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.get_object>`_
  API request. For example:

  .. code:: python

     from s3transfer.processpool import ProcessPoolDownloader

     with ProcessPoolDownloader() as downloader:
          downloader.download_file(
               'mybucket', 'mykey', 'myfile',
               extra_args={'VersionId': 'myversion'})


* ``expected_size``: By default, the downloader will make a HeadObject
  call to determine the size of the object. To opt-out of this additional
  API call, you can provide the size of the object in bytes:

  .. code:: python

     from s3transfer.processpool import ProcessPoolDownloader

     MB = 1024 * 1024
     with ProcessPoolDownloader() as downloader:
          downloader.download_file(
               'mybucket', 'mykey', 'myfile', expected_size=2 * MB)


Futures
=======

When ``download_file`` is called, it immediately returns a
:class:`ProcessPoolTransferFuture`. The future can be used to poll the state
of a particular transfer. To get the result of the download,
call :meth:`ProcessPoolTransferFuture.result`. The method blocks
until the transfer completes, whether it succeeds or fails. For example:

.. code:: python

     from s3transfer.processpool import ProcessPoolDownloader

     with ProcessPoolDownloader() as downloader:
          future = downloader.download_file('mybucket', 'mykey', 'myfile')
          print(future.result())


If the download succeeds, the future returns ``None``:

.. code:: python

     None


If the download fails, the exception causing the failure is raised. For
example, if ``mykey`` did not exist, the following error would be raised


.. code:: python

     botocore.exceptions.ClientError: An error occurred (404) when calling the HeadObject operation: Not Found


.. note::

    :meth:`ProcessPoolTransferFuture.result` can only be called while the
    ``ProcessPoolDownloader`` is running (e.g. before calling ``shutdown`` or
    inside the context manager).


Process Pool Configuration
==========================

By default, the downloader has the following configuration options:

* ``multipart_threshold``: The threshold size for performing ranged downloads
  in bytes. By default, ranged downloads happen for S3 objects that are
  greater than or equal to 8 MB in size.

* ``multipart_chunksize``: The size of each ranged download in bytes. By
  default, the size of each ranged download is 8 MB.

* ``max_request_processes``: The maximum number of processes used to download
  S3 objects. By default, the maximum is 10 processes.


To change the default configuration, use the :class:`ProcessTransferConfig`:

.. code:: python

     from s3transfer.processpool import ProcessPoolDownloader
     from s3transfer.processpool import ProcessTransferConfig

     config = ProcessTransferConfig(
          multipart_threshold=64 * 1024 * 1024,  # 64 MB
          max_request_processes=50
     )
     downloader = ProcessPoolDownloader(config=config)


Client Configuration
====================

The process pool downloader creates ``botocore`` clients on your behalf. In
order to affect how the client is created, pass the keyword arguments
that would have been used in the :meth:`botocore.Session.create_client` call:

.. code:: python


     from s3transfer.processpool import ProcessPoolDownloader
     from s3transfer.processpool import ProcessTransferConfig

     downloader = ProcessPoolDownloader(
          client_kwargs={'region_name': 'us-west-2'})


This snippet ensures that all clients created by the ``ProcessPoolDownloader``
are using ``us-west-2`` as their region.

�N)�deepcopy)�Config)�MAXINT�BaseManager)�ALLOWED_DOWNLOAD_ARGS�MB�PROCESS_USER_AGENT)�CancelledError�RetriesExceededError)�BaseTransferFuture�BaseTransferMeta)�S3_RETRYABLE_DOWNLOAD_ERRORS�CallArgs�OSUtils�calculate_num_parts�calculate_range_parameter�SHUTDOWN�DownloadFileRequest��transfer_id�bucket�key�filename�
extra_args�
expected_size�GetObjectJob)rrr�
temp_filenamer�offsetrc#�pK�t�}d��tjtj|�y�w�N)�"_add_ignore_handler_for_interrupts�signal�SIGINT)�original_handlers �8/usr/lib/python3/dist-packages/s3transfer/processpool.py�
ignore_ctrl_cr&s%����9�;��	�
�M�M�&�-�-�!1�2�s�46c�f�tjtjtj�Sr )r"r#�SIG_IGN��r%r!r!s���=�=�������7�7r*c�&�eZdZdezdezdfd�Zy)�ProcessTransferConfig��
c�.�||_||_||_y)auConfiguration for the ProcessPoolDownloader

        :param multipart_threshold: The threshold for which ranged downloads
            occur.

        :param multipart_chunksize: The chunk size of each ranged download.

        :param max_request_processes: The maximum number of processes that
            will be making S3 API transfer-related requests at a time.
        N)�multipart_threshold�multipart_chunksize�max_request_processes)�selfr0r1r2s    r%�__init__zProcessTransferConfig.__init__s�� $7�� �#6�� �%:��"r*N)�__name__�
__module__�__qualname__rr4r)r*r%r,r,
s����F���F� �	;r*r,c�x�eZdZdd�Z	dd�Zd�Zd�Zd�Zd�Zd�Z	d	�Z
d
�Zd�Zd�Z
d
�Zd�Zd�Zd�Zd�Zd�Zy)�ProcessPoolDownloaderNc�Z�|�i}t|�|_||_|�t�|_t	j
d�|_t	j
d�|_t�|_	d|_
tj�|_
d|_d|_d|_g|_y)a�Downloads S3 objects using process pools

        :type client_kwargs: dict
        :param client_kwargs: The keyword arguments to provide when
            instantiating S3 clients. The arguments must match the keyword
            arguments provided to the
            `botocore.session.Session.create_client()` method.

        :type config: ProcessTransferConfig
        :param config: Configuration for the downloader
        Ni�F)�
ClientFactory�_client_factory�_transfer_configr,�multiprocessing�Queue�_download_request_queue�
_worker_queuer�_osutil�_started�	threading�Lock�_start_lock�_manager�_transfer_monitor�
_submitter�_workers)r3�
client_kwargs�configs   r%r4zProcessPoolDownloader.__init__$s���� ��M�,�]�;��� &����>�$9�$;�D�!�'6�'<�'<�T�'B��$�,�2�2�4�8����y�����
�$�>�>�+�����
�!%��������
r*c�L�|j�|�i}|j|�|jj�}t	||||||��}t
j
d|�|jj|�t|||||��}|j||�}	|	S)asDownloads the object's contents to a file

        :type bucket: str
        :param bucket: The name of the bucket to download from

        :type key: str
        :param key: The name of the key to download from

        :type filename: str
        :param filename: The name of a file to download to.

        :type extra_args: dict
        :param extra_args: Extra arguments that may be passed to the
            client operation

        :type expected_size: int
        :param expected_size: The expected size in bytes of the download. If
            provided, the downloader will not call HeadObject to determine the
            object's size and use the provided value instead. The size is
            needed to determine whether to do a multipart download.

        :rtype: s3transfer.futures.TransferFuture
        :returns: Transfer future representing the download
        rz%Submitting download file request: %s.)rrrrr)�_start_if_needed�_validate_all_known_argsrH�notify_new_transferr�logger�debugr@�putr�_get_transfer_future)
r3rrrrrr�download_file_request�	call_args�futures
          r%�
download_filez#ProcessPoolDownloader.download_fileEs���6	
�������J��%�%�j�1��,�,�@�@�B�� 3�#����!�'�
!
��	���3�5J�	
�	
�$�$�(�(�)>�?�����!�'�
�	��*�*�;�	�B���
r*c�$�|j�y)zhShutdown the downloader

        It will wait till all downloads are complete before returning.
        N)�_shutdown_if_needed�r3s r%�shutdownzProcessPoolDownloader.shutdown{s��
	
� � �"r*c��|Sr r)r[s r%�	__enter__zProcessPoolDownloader.__enter__�s���r*c��t|t�r&|j�|jj�|j	�yr )�
isinstance�KeyboardInterruptrH�notify_cancel_all_in_progressr\)r3�exc_type�	exc_value�argss    r%�__exit__zProcessPoolDownloader.__exit__�s4���i�!2�3��%�%�1��&�&�D�D�F��
�
�r*c�~�|j5|js|j�ddd�y#1swYyxYwr )rFrC�_startr[s r%rNz&ProcessPoolDownloader._start_if_needed�s0��
�
�
�	��=�=����
�	�	�	���3�<c�r�|j�|j�|j�d|_y)NT)�_start_transfer_monitor_manager�_start_submitter�_start_get_object_workersrCr[s r%rhzProcessPoolDownloader._start�s-���,�,�.������&�&�(���
r*c�n�|D]0}|tvs�djt�}td|�d|����y)Nz, zInvalid extra_args key 'z', must be one of: )r�join�
ValueError)r3�provided�kwarg�
download_argss    r%rOz.ProcessPoolDownloader._validate_all_known_args�sL���	�E��1�1� $�	�	�*?� @�
� �.�u�g�6'�'4�o�7���	r*c�N�t||��}t|j|��}|S)N)rVr)�monitor�meta)�ProcessPoolTransferMeta�ProcessPoolTransferFuturerH)r3rrVrvrWs     r%rTz*ProcessPoolDownloader._get_transfer_future�s/��&��[�
��+��*�*��
���
r*c���tjd�t�|_|jj	t
�|jj
�|_y)Nz$Starting the TransferMonitorManager.)rQrR�TransferMonitorManagerrG�startr!�TransferMonitorrHr[s r%rkz5ProcessPoolDownloader._start_transfer_monitor_manager�sC�����;�<�.�0��
�
	
�
�
���>�?�!%���!>�!>�!@��r*c��tjd�t|j|j|j
|j|j|j��|_	|jj�y)Nz Starting the GetObjectSubmitter.)�transfer_config�client_factory�transfer_monitor�osutil�download_request_queue�worker_queue)rQrR�GetObjectSubmitterr=r<rHrBr@rArIr{r[s r%rlz&ProcessPoolDownloader._start_submitter�sa�����7�8�,� �1�1��/�/�!�3�3��<�<�#'�#?�#?��+�+�

���	
�����r*c�d�tjd|jj�t	|jj�D]d}t|j|j|j|j��}|j�|jj|��fy)NzStarting %s GetObjectWorkers.)�queuerr�r�)
rQrRr=r2�range�GetObjectWorkerrAr<rHrBr{rJ�append�r3�_�workers   r%rmz/ProcessPoolDownloader._start_get_object_workers�s������+��!�!�7�7�	
��t�,�,�B�B�C�	)�A�$��(�(�#�3�3�!%�!7�!7��|�|�	�F�
�L�L�N��M�M� � ��(�	)r*c�~�|j5|jr|j�ddd�y#1swYyxYwr )rFrC�	_shutdownr[s r%rZz)ProcessPoolDownloader._shutdown_if_needed�s1��
�
�
�	!��}�}���� �	!�	!�	!�ric�r�|j�|j�|j�d|_y)NF)�_shutdown_submitter�_shutdown_get_object_workers�"_shutdown_transfer_monitor_managerrCr[s r%r�zProcessPoolDownloader._shutdown�s-��� � �"��)�)�+��/�/�1���
r*c�b�tjd�|jj�y)Nz)Shutting down the TransferMonitorManager.)rQrRrGr\r[s r%r�z8ProcessPoolDownloader._shutdown_transfer_monitor_manager�s�����@�A��
�
��� r*c��tjd�|jjt�|j
j
�y)Nz%Shutting down the GetObjectSubmitter.)rQrRr@rS�SHUTDOWN_SIGNALrIror[s r%r�z)ProcessPoolDownloader._shutdown_submitter�s3�����<�=��$�$�(�(��9������r*c���tjd�|jD]!}|jj	t
��#|jD]}|j
��y)Nz#Shutting down the GetObjectWorkers.)rQrRrJrArSr�ror�s   r%r�z2ProcessPoolDownloader._shutdown_get_object_workers�sR�����:�;����	4�A����"�"�?�3�	4��m�m�	�F��K�K�M�	r*)NN)r5r6r7r4rXr\r^rfrNrhrOrTrkrlrmrZr�r�r�r�r)r*r%r9r9#sa���DEI�4�l#����
���A�
 �
)�!�
�!��
r*r9c�4�eZdZd�Zed��Zd�Zd�Zd�Zy)rxc� �||_||_y)a`The future associated to a submitted process pool transfer request

        :type monitor: TransferMonitor
        :param monitor: The monitor associated to the process pool downloader

        :type meta: ProcessPoolTransferMeta
        :param meta: The metadata associated to the request. This object
            is visible to the requester.
        N)�_monitor�_meta)r3rurvs   r%r4z"ProcessPoolTransferFuture.__init__�s�� ��
���
r*c��|jSr )r�r[s r%rvzProcessPoolTransferFuture.meta�s���z�z�r*c�`�|jj|jj�Sr )r��is_doner�rr[s r%�donezProcessPoolTransferFuture.done�s!���}�}�$�$�T�Z�Z�%;�%;�<�<r*c���	|jj|jj�S#t$r,|jj�|j
��wxYwr )r��poll_for_resultr�rra�_connect�cancelr[s r%�resultz ProcessPoolTransferFuture.result�sS��	��=�=�0�0����1G�1G�H�H�� �	�
�M�M�"�"�$��K�K�M��!	�s	�.1�5A&c�t�|jj|jjt	��yr )r��notify_exceptionr�rr
r[s r%r�z ProcessPoolTransferFuture.cancels&���
�
�&�&��J�J�"�"�N�$4�	
r*N)	r5r6r7r4�propertyrvr�r�r�r)r*r%rxrx�s*�������=��*
r*rxc�F�eZdZdZd�Zed��Zed��Zed��Zy)rwz2Holds metadata about the ProcessPoolTransferFuturec�.�||_||_i|_yr )�_transfer_id�
_call_args�
_user_context)r3rrVs   r%r4z ProcessPoolTransferMeta.__init__s��'���#�����r*c��|jSr )r�r[s r%rVz!ProcessPoolTransferMeta.call_args!������r*c��|jSr )r�r[s r%rz#ProcessPoolTransferMeta.transfer_id%s��� � � r*c��|jSr )r�r[s r%�user_contextz$ProcessPoolTransferMeta.user_context)s���!�!�!r*N)	r5r6r7�__doc__r4r�rVrr�r)r*r%rwrwsF��<� �
�����!��!��"��"r*rwc��eZdZdd�Zd�Zy)r;Nc��||_|j�i|_t|jjdt���}|jst
|_n|xjdt
zz
c_||jd<y)z�Creates S3 clients for processes

        Botocore sessions and clients are not pickleable so they cannot be
        inherited across Process boundaries. Instead, they must be instantiated
        once a process is running.
        NrL� )�_client_kwargsr�getr�user_agent_extrar	)r3rK�
client_configs   r%r4zClientFactory.__init__/sw��,������&�"$�D�� ��!4�!4�!8�!8��6�8�!L�M�
��-�-�-?�M�*��*�*�c�4F�.F�F�*�(5����H�%r*c�r�tjj�j	di|j��S)zCreate a botocore S3 client)�s3)�botocore�session�Session�
create_clientr�r[s r%r�zClientFactory.create_clientAs5�����'�'�)�7�7��
��'�'�
�	
r*r )r5r6r7r4r�r)r*r%r;r;.s��6�$
r*r;c�H�eZdZd�Zd�Zd�Zd�Zd�Zd�Zd�Z	d�Z
d	�Zd
�Zy)r|c�R�i|_d|_tj�|_y)a@Monitors transfers for cross-process communication

        Notifications can be sent to the monitor and information can be
        retrieved from the monitor for a particular transfer. This abstraction
        is ran in a ``multiprocessing.managers.BaseManager`` in order to be
        shared across processes.
        rN)�_transfer_states�	_id_countrDrE�
_init_lockr[s r%r4zTransferMonitor.__init__Is!��!#������#�.�.�*��r*c��|j5|j}t�|j|<|xjdz
c_|cddd�S#1swYyxYw�N�)r�r��
TransferStater��r3rs  r%rPz#TransferMonitor.notify_new_transferYsJ��
�_�_�	��.�.�K�1>��D�!�!�+�.��N�N�a��N��		�	�	�s�:A�Ac�4�|j|jS)z�Determine a particular transfer is complete

        :param transfer_id: Unique identifier for the transfer
        :return: True, if done. False, otherwise.
        )r�r�r�s  r%r�zTransferMonitor.is_done`s���$�$�[�1�6�6�6r*c�>�|j|j�y)zqNotify a particular transfer is complete

        :param transfer_id: Unique identifier for the transfer
        N)r��set_doner�s  r%�notify_donezTransferMonitor.notify_donehs��
	
���k�*�3�3�5r*c�x�|j|j�|j|j}|r|�y)aPoll for the result of a transfer

        :param transfer_id: Unique identifier for the transfer
        :return: If the transfer succeeded, it will return the result. If the
            transfer failed, it will raise the exception associated to the
            failure.
        N)r��wait_till_done�	exception�r3rr�s   r%r�zTransferMonitor.poll_for_resultos<��	
���k�*�9�9�;��)�)�+�6�@�@�	���O�r*c�,�||j|_y)z�Notify an exception was encountered for a transfer

        :param transfer_id: Unique identifier for the transfer
        :param exception: The exception encountered for that transfer
        N�r�r�r�s   r%r�z TransferMonitor.notify_exception}s��8A����k�*�4r*c�z�|jj�D]}|jr�t�|_� yr )r��valuesr�r
r�)r3�transfer_states  r%rbz-TransferMonitor.notify_cancel_all_in_progress�s4��"�3�3�:�:�<�	<�N�!�&�&�+9�+;��(�	<r*c�4�|j|jS)z�Retrieve the exception encountered for the transfer

        :param transfer_id: Unique identifier for the transfer
        :return: The exception encountered for that transfer. Otherwise
            if there were no exceptions, returns None.
        r�r�s  r%�
get_exceptionzTransferMonitor.get_exception�s���$�$�[�1�;�;�;r*c�,�||j|_y)z�Notify the amount of jobs expected for a transfer

        :param transfer_id: Unique identifier for the transfer
        :param num_jobs: The number of jobs to complete the transfer
        N)r��jobs_to_complete)r3r�num_jobss   r%� notify_expected_jobs_to_completez0TransferMonitor.notify_expected_jobs_to_complete�s��?G����k�*�;r*c�<�|j|j�S)z�Notify that a single job is completed for a transfer

        :param transfer_id: Unique identifier for the transfer
        :return: The number of jobs remaining to complete the transfer
        )r��decrement_jobs_to_completer�s  r%�notify_job_completez#TransferMonitor.notify_job_complete�s���$�$�[�1�L�L�N�Nr*N)
r5r6r7r4rPr�r�r�r�rbr�r�r�r)r*r%r|r|Hs7��+� �7�6��
A�<�
<�G�Or*r|c��eZdZdZd�Zed��Zd�Zd�Zed��Z	e	jd��Z	ed��Zejd	��Zd
�Zy)r�z6Represents the current state of an individual transferc��d|_tj�|_tj�|_d|_y)Nr)�
_exceptionrD�Event�_done_eventrE�	_job_lock�_jobs_to_completer[s r%r4zTransferState.__init__�s.�����$�?�?�,���"���)���!"��r*c�6�|jj�Sr )r��is_setr[s r%r�zTransferState.done�s�����&�&�(�(r*c�8�|jj�yr )r��setr[s r%r�zTransferState.set_done�s�������r*c�B�|jjt�yr )r��waitrr[s r%r�zTransferState.wait_till_done�s�������f�%r*c��|jSr �r�r[s r%r�zTransferState.exception�r�r*c��||_yr r��r3�vals  r%r�zTransferState.exception�s	����r*c��|jSr �r�r[s r%r�zTransferState.jobs_to_complete�s���%�%�%r*c��||_yr r�r�s  r%r�zTransferState.jobs_to_complete�s
��!$��r*c��|j5|xjdzc_|jcddd�S#1swYyxYwr�)r�r�r[s r%r�z(TransferState.decrement_jobs_to_complete�s8��
�^�^�	*��"�"�a�'�"��)�)�	*�	*�	*�s	�!8�AN)
r5r6r7r�r4r�r�r�r�r��setterr�r�r)r*r%r�r��s���@�#��)��)��&������������&��&����%��%�*r*r�c��eZdZy)rzN)r5r6r7r)r*r%rzrz�s��r*rzc�*��eZdZ�fd�Zd�Zd�Z�xZS)�BaseS3TransferProcessc�>��t�|��||_d|_yr )�superr4r<�_client)r3r�	__class__s  �r%r4zBaseS3TransferProcess.__init__�s���
����-�����r*c��|jj�|_t�5|j	�ddd�y#1swYyxYwr )r<r�r�r&�_do_runr[s r%�runzBaseS3TransferProcess.run�s?���+�+�9�9�;���
�_�
	�
�L�L�N�
	�
	�
	�s�A�A
c��td��)Nz	_do_run())�NotImplementedErrorr[s r%r�zBaseS3TransferProcess._do_run�s
��!�+�.�.r*)r5r6r7r4r�r��
__classcell__�r�s@r%r�r��s����
�"/r*r�c�N��eZdZ�fd�Zd�Zd�Zd�Zd�Zd�Zd�Z	d�Z
d	�Z�xZS)
r�c�j��t�|�|�||_||_||_||_||_y)aTSubmit GetObjectJobs to fulfill a download file request

        :param transfer_config: Configuration for transfers.
        :param client_factory: ClientFactory for creating S3 clients.
        :param transfer_monitor: Monitor for notifying and retrieving state
            of transfer.
        :param osutil: OSUtils object to use for os-related behavior when
            performing the transfer.
        :param download_request_queue: Queue to retrieve download file
            requests.
        :param worker_queue: Queue to submit GetObjectJobs for workers
            to perform.
        N)r�r4r=rHrBr@rA)r3r~rr�r�r�r�r�s       �r%r4zGetObjectSubmitter.__init__�s9���,	����(� /���!1������'=��$�)��r*c��	|jj�}|tk(rtj	d�y	|j|��L#t$rn}tj	d||d��|jj|j|�|jj|j�Yd}~�sd}~wwxYw)NTz#Submitter shutdown signal received.zFException caught when submitting jobs for download file request %s: %s��exc_info)r@r�r�rQrR�_submit_get_object_jobs�	ExceptionrHr�rr�)r3rU�es   r%r�zGetObjectSubmitter._do_runs����$(�$@�$@�$D�$D�$F�!�$��7����B�C��
��,�,�-B�C�
���

����3�)��!����&�&�7�7�)�5�5�q���&�&�2�2�)�5�5����

�s�A�	C�A$C�Cc���|j|�}|j||�}||jjkr|j	||�y|j|||�yr )�	_get_size�_allocate_temp_filer=r0�_submit_single_get_object_job�_submit_ranged_get_object_jobs�r3rU�sizers    r%r	z*GetObjectSubmitter._submit_get_object_jobs/sb���~�~�3�4���0�0�1F��M�
��$�'�'�;�;�;��.�.�%�}�
�
�/�/�%�}�d�
r*c��|j}|�@|jjd|j|jd�|j
��d}|S)N��Bucket�Key�
ContentLengthr))rr��head_objectrrr)r3rUrs   r%r
zGetObjectSubmitter._get_size;sb��-�;�;�
�� �4�D�L�L�4�4��,�3�3�)�-�-��(�2�2���	�M�
�r*c��|jj|j�}|jj||�|Sr )rB�get_temp_filenamer�allocaters    r%rz&GetObjectSubmitter._allocate_temp_fileEs;�����6�6�!�*�*�
�
�	
�����m�T�2��r*c	���|j|jd�|j|j|j|j|d|j
|j��y)Nr�r�rrrrrrr)�_notify_jobs_to_completer�_submit_get_object_jobrrrr)r3rUrs   r%rz0GetObjectSubmitter._submit_single_get_object_jobLsa��	
�%�%�&;�&G�&G��K��#�#�-�9�9�(�/�/�%�)�)�'��,�7�7�*�3�3�	$�	
r*c
��|jj}t||�}|j|j|�t|�D]s}||z}t
|||�}d|i}	|	j|j�|j|j|j|j|||	|j���uy)N�Ranger)
r=r1rrrr�r�updaterrrrr)
r3rUrr�	part_size�	num_parts�ir�range_parameter�get_object_kwargss
          r%rz1GetObjectSubmitter._submit_ranged_get_object_jobsZs����)�)�=�=�	�'��i�8�	��%�%�!�-�-�y�	
��y�!�	�A���]�F�7��1�i��O�")�/� :���$�$�%:�%E�%E�F��'�'�1�=�=�,�3�3�)�-�-�+��,�.�7�7�
(�
�	r*c�L�|jjtdi|���y)Nr))rArSr)r3�get_object_job_kwargss  r%rz)GetObjectSubmitter._submit_get_object_jobss�������|�D�.C�D�Er*c�j�tjd||�|jj||�y)Nz3Notifying %s job(s) to complete for transfer_id %s.)rQrRrHr�)r3rr�s   r%rz+GetObjectSubmitter._notify_jobs_to_completevs3�����A���	
�
	
���?�?��)�	
r*)
r5r6r7r4r�r	r
rrrrrrrs@r%r�r��s1���*�:�.
���
��2F�
r*r�c�P��eZdZdZdezZ�fd�Zd�Zd�Zd�Z	d�Z
d�Zd	�Z�xZ
S)
r���c�\��t�|�|�||_||_||_||_y)a�Fulfills GetObjectJobs

        Downloads the S3 object, writes it to the specified file, and
        renames the file to its final location if it completes the final
        job for a particular transfer.

        :param queue: Queue for retrieving GetObjectJob's
        :param client_factory: ClientFactory for creating S3 clients
        :param transfer_monitor: Monitor for notifying
        :param osutil: OSUtils object to use for os-related behavior when
            performing the transfer.
        N)r�r4�_queuer<rHrB)r3r�rr�r�r�s     �r%r4zGetObjectWorker.__init__�s0���	����(����-���!1�����r*c��	|jj�}|tk(rtj	d�y|j
j
|j�s|j|�ntj	d|�|j
j|j�}tj	d||j�|s1|j|j|j|j���)Nz Worker shutdown signal received.zBSkipping get object job %s because there was a previous exception.z%%s jobs remaining for transfer_id %s.)
r/r�r�rQrRrHr�r�_run_get_object_jobr��_finalize_downloadrr)r3�job�	remainings   r%r�zGetObjectWorker._do_run�s�����+�+�/�/�#�C��o�%����?�@���)�)�7�7����H��(�(��-����!���
�.�.�B�B�����I�
�L�L�7�����
�
��'�'��O�O�S�%6�%6�����-r*c�@�	|j|j|j|j|j|j
��y#t$rI}tjd||d��|jj|j|�Yd}~yd}~wwxYw)N)rrrrrzBException caught when downloading object for get object job %s: %sTr)�_do_get_objectrrrrrr
rQrRrHr�r)r3r3rs   r%r1z#GetObjectWorker._run_get_object_job�s���	H�����z�z��G�G�!�/�/��>�>��z�z�
 �
���	H��L�L�(����
�
�
�"�"�3�3�C�O�O�Q�G�G��	H�s�AA�	B�?B�Bc	�<�d}t|j�D]9}	|jjd||d�|��}|j	|||d�yt|��#t
$r3}	tjd|	|dz|jd��|	}Yd}	~	�~d}	~	wwxYw)Nr�BodyzCRetrying exception caught (%s), retrying request, (attempt %s / %s)r�Trr))	r��
_MAX_ATTEMPTSr��
get_object�_write_to_filerrQrRr)
r3rrrrr�last_exceptionr%�responsers
          r%r6zGetObjectWorker._do_get_object�s������t�)�)�*�	#�A�
#�2�4�<�<�2�2��!�s��.8����#�#�M�6�8�F�;K�L��
	#�"#�>�2�2��0�	
#����:����E��&�&�!�
��"#���	
#�s�5A�	B�()B�Bc����t|d�5}|j|�t��fd�d�}|D]}|j|��	ddd�y#1swYyxYw)Nzrb+c�:���j�j�Sr )�read�
_IO_CHUNKSIZE)�bodyr3s��r%�<lambda>z0GetObjectWorker._write_to_file.<locals>.<lambda>�s���$�)�)�D�,>�,>�"?�r*r*)�open�seek�iter�write)r3rrrB�f�chunks�chunks`  `   r%r;zGetObjectWorker._write_to_file�sV���
�(�E�
"�	�a�
�F�F�6�N��?��E�F��
�������
�	�	�	�s�:A�Ac���|jj|�r|jj|�n|j	|||�|jj|�yr )rHr�rB�remove_file�_do_file_renamer�)r3rrrs    r%r2z"GetObjectWorker._finalize_download�sN���!�!�/�/��<��L�L�$�$�]�3�� � ��m�X�F����*�*�;�7r*c���	|jj||�y#t$rA}|jj	||�|jj|�Yd}~yd}~wwxYwr )rB�rename_filer
rHr�rL)r3rrrrs     r%rMzGetObjectWorker._do_file_rename�sV��	4��L�L�$�$�]�H�=���	4��"�"�3�3�K��C��L�L�$�$�]�3�3��	4�s��	A)�7A$�$A))r5r6r7r9rrAr4r�r1r6r;r2rMrrs@r%r�r��s7����M���F�M��&�6H�&3�*�8�4r*r�)7r��collections�
contextlib�loggingr>r"rD�copyr�botocore.sessionr��botocore.configr�s3transfer.compatrr�s3transfer.constantsrrr	�s3transfer.exceptionsr
r�s3transfer.futuresrr
�s3transfer.utilsrrrrr�	getLoggerr5rQr��
namedtuplerr�contextmanagerr&r!r,r9rxrwr;r|r�rz�register�Processr�r�r�r)r*r%�<module>r`sY��u�l����
����"�1�N�N�F�C���
��	�	�8�	$����
-�k�,�,���
��&�{�%�%�����"���3��3�8�;�;�,C�C�L-
� 2�-
�`"�.�"�*
�
�4]O�]O�@-*�-*�`	�[�	���� 1�?�C�/�O�3�3�/�6D
�.�D
�No4�+�o4r*
¿Qué es la limpieza dental de perros? - Clínica veterinaria


Es la eliminación del sarro y la placa adherida a la superficie de los dientes mediante un equipo de ultrasonidos que garantiza la integridad de las piezas dentales a la vez que elimina en profundidad cualquier resto de suciedad.

A continuación se procede al pulido de los dientes mediante una fresa especial que elimina la placa bacteriana y devuelve a los dientes el aspecto sano que deben tener.

Una vez terminado todo el proceso, se mantiene al perro en observación hasta que se despierta de la anestesia, bajo la atenta supervisión de un veterinario.

¿Cada cuánto tiempo tengo que hacerle una limpieza dental a mi perro?

A partir de cierta edad, los perros pueden necesitar una limpieza dental anual o bianual. Depende de cada caso. En líneas generales, puede decirse que los perros de razas pequeñas suelen acumular más sarro y suelen necesitar una atención mayor en cuanto a higiene dental.


Riesgos de una mala higiene


Los riesgos más evidentes de una mala higiene dental en los perros son los siguientes:

  • Cuando la acumulación de sarro no se trata, se puede producir una inflamación y retracción de las encías que puede descalzar el diente y provocar caídas.
  • Mal aliento (halitosis).
  • Sarro perros
  • Puede ir a más
  • Las bacterias de la placa pueden trasladarse a través del torrente circulatorio a órganos vitales como el corazón ocasionando problemas de endocarditis en las válvulas. Las bacterias pueden incluso acantonarse en huesos (La osteomielitis es la infección ósea, tanto cortical como medular) provocando mucho dolor y una artritis séptica).

¿Cómo se forma el sarro?

El sarro es la calcificación de la placa dental. Los restos de alimentos, junto con las bacterias presentes en la boca, van a formar la placa bacteriana o placa dental. Si la placa no se retira, al mezclarse con la saliva y los minerales presentes en ella, reaccionará formando una costra. La placa se calcifica y se forma el sarro.

El sarro, cuando se forma, es de color blanquecino pero a medida que pasa el tiempo se va poniendo amarillo y luego marrón.

Síntomas de una pobre higiene dental
La señal más obvia de una mala salud dental canina es el mal aliento.

Sin embargo, a veces no es tan fácil de detectar
Y hay perros que no se dejan abrir la boca por su dueño. Por ejemplo…

Recientemente nos trajeron a la clínica a un perro que parpadeaba de un ojo y decía su dueño que le picaba un lado de la cara. Tenía molestias y dificultad para comer, lo que había llevado a sus dueños a comprarle comida blanda (que suele ser un poco más cara y llevar más contenido en grasa) durante medio año. Después de una exploración oftalmológica, nos dimos cuenta de que el ojo tenía una úlcera en la córnea probablemente de rascarse . Además, el canto lateral del ojo estaba inflamado. Tenía lo que en humanos llamamos flemón pero como era un perro de pelo largo, no se le notaba a simple vista. Al abrirle la boca nos llamó la atención el ver una muela llena de sarro. Le realizamos una radiografía y encontramos una fístula que llegaba hasta la parte inferior del ojo.

Le tuvimos que extraer la muela. Tras esto, el ojo se curó completamente con unos colirios y una lentilla protectora de úlcera. Afortunadamente, la úlcera no profundizó y no perforó el ojo. Ahora el perro come perfectamente a pesar de haber perdido una muela.

¿Cómo mantener la higiene dental de tu perro?
Hay varias maneras de prevenir problemas derivados de la salud dental de tu perro.

Limpiezas de dientes en casa
Es recomendable limpiar los dientes de tu perro semanal o diariamente si se puede. Existe una gran variedad de productos que se pueden utilizar:

Pastas de dientes.
Cepillos de dientes o dedales para el dedo índice, que hacen más fácil la limpieza.
Colutorios para echar en agua de bebida o directamente sobre el diente en líquido o en spray.

En la Clínica Tus Veterinarios enseñamos a nuestros clientes a tomar el hábito de limpiar los dientes de sus perros desde que son cachorros. Esto responde a nuestro compromiso con la prevención de enfermedades caninas.

Hoy en día tenemos muchos clientes que limpian los dientes todos los días a su mascota, y como resultado, se ahorran el dinero de hacer limpiezas dentales profesionales y consiguen una mejor salud de su perro.


Limpiezas dentales profesionales de perros y gatos

Recomendamos hacer una limpieza dental especializada anualmente. La realizamos con un aparato de ultrasonidos que utiliza agua para quitar el sarro. Después, procedemos a pulir los dientes con un cepillo de alta velocidad y una pasta especial. Hacemos esto para proteger el esmalte.

La frecuencia de limpiezas dentales necesaria varía mucho entre razas. En general, las razas grandes tienen buena calidad de esmalte, por lo que no necesitan hacerlo tan a menudo e incluso pueden pasarse la vida sin requerir una limpieza. Sin embargo, razas pequeñas como el Yorkshire o el Maltés, deben hacérselas todos los años desde cachorros si se quiere conservar sus piezas dentales.

Otro factor fundamental es la calidad del pienso. Algunas marcas han diseñado croquetas que limpian la superficie del diente y de la muela al masticarse.

Ultrasonido para perros

¿Se necesita anestesia para las limpiezas dentales de perros y gatos?

La limpieza dental en perros no es una técnica que pueda practicarse sin anestesia general , aunque hay veces que los propietarios no quieren anestesiar y si tiene poco sarro y el perro es muy bueno se puede intentar…… , pero no se va a poder pulir ni acceder a todas la zona de la boca …. Además los limpiadores dentales van a irrigar agua y hay riesgo de aspiración a vías respiratorias si no se realiza una anestesia correcta con intubación traqueal . En resumen , sin anestesia no se va hacer una correcta limpieza dental.

Tampoco sirve la sedación ya que necesitamos que el animal esté totalmente quieto, y el veterinario tenga un acceso completo a todas sus piezas dentales y encías.

Alimentos para la limpieza dental

Hay que tener cierto cuidado a la hora de comprar determinados alimentos porque no todos son saludables. Algunos tienen demasiado contenido graso, que en exceso puede causar problemas cardiovasculares y obesidad.

Los mejores alimentos para los dientes son aquellos que están elaborados por empresas farmacéuticas y llevan componentes químicos con tratamientos específicos para el diente del perro. Esto implica no solo limpieza a través de la acción mecánica de morder sino también un tratamiento antibacteriano para prevenir el sarro.

Conclusión

Si eres como la mayoría de dueños, por falta de tiempo , es probable que no estés prestando la suficiente atención a la limpieza dental de tu perro. Por eso te animamos a que comiences a limpiar los dientes de tu perro y consideres atender a su higiene bucal con frecuencia.

Estas simples medidas pueden conllevar a que tu perro tenga una vida más larga y mucho más saludable.

Si te resulta imposible introducir un cepillo de dientes a tu perro en la boca, pásate con él por clínica Tus Veterinarios y te explicamos cómo hacerlo.

Necesitas hacer una limpieza dental profesional a tu mascota?
Llámanos al 622575274 o contacta con nosotros

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

¡Hola!