U n^vs@sddlZddlmZddlmZmZddlmZddlm Z ddlm Z ddlm Z ddlm Z dd l mZdd l mZdd l mZmZGd d d eZGdddeZGdddeZGdddeZGdddeZGdddeZGddde ZGddde ZGddde ZdS)N)six)seekablereadable)IN_MEMORY_UPLOAD_TAG)Task)SubmissionTask)CreateMultipartUploadTask)CompleteMultipartUploadTask) get_callbacks)get_filtered_dict)DeferredOpenFileChunksizeAdjusterc@s.eZdZd ddZddZddZdd Zd S) AggregatedProgressCallbackcCs||_||_d|_dS)aAggregates progress updates for every provided progress callback :type callbacks: A list of functions that accepts bytes_transferred as a single argument :param callbacks: The callbacks to invoke when threshold is reached :type threshold: int :param threshold: The progress threshold in which to take the aggregated progress and invoke the progress callback with that aggregated progress total rN) _callbacks _threshold _bytes_seen)self callbacks thresholdrm/private/var/folders/sd/whlwsn6x1_qgglc0mjv25_695qk2gl/T/pip-install-4zq3fp6i/s3transfer/s3transfer/upload.py__init__s z#AggregatedProgressCallback.__init__cCs&|j|7_|j|jkr"|dSN)rr_trigger_callbacks)rbytes_transferredrrr__call__-s z#AggregatedProgressCallback.__call__cCs|jdkr|dS)z@Flushes out any progress that has not been sent to its callbacksrN)rrrrrrflush2s z AggregatedProgressCallback.flushcCs"|jD]}||jdqd|_dS)N)rr)rr)rcallbackrrrr7s z-AggregatedProgressCallback._trigger_callbacksN)r)__name__ __module__ __qualname__rrrrrrrrrs rc@sJeZdZdZddZdddZddZd d Zd d Zd dZ ddZ dS)InterruptReaderaWrapper that can interrupt reading using an error It uses a transfer coordinator to propagate an error if it notices that a read is being made while the file is being read from. :type fileobj: file-like obj :param fileobj: The file-like object to read from :type transfer_coordinator: s3transfer.futures.TransferCoordinator :param transfer_coordinator: The transfer coordinator to use if the reader needs to be interrupted. cCs||_||_dSr)_fileobj_transfer_coordinator)rfileobjtransfer_coordinatorrrrrJszInterruptReader.__init__NcCs|jjr|jj|j|Sr)r% exceptionr$read)ramountrrrr)NszInterruptReader.readcCs|j|dSr)r$seek)rwhererrrr+XszInterruptReader.seekcCs |jSr)r$tellrrrrr-[szInterruptReader.tellcCs|jdSr)r$closerrrrr.^szInterruptReader.closecCs|Srrrrrr __enter__aszInterruptReader.__enter__cOs |dSr)r.)rargskwargsrrr__exit__dszInterruptReader.__exit__)N) r r!r"__doc__rr)r+r-r.r/r2rrrrr#=s  r#c@sfeZdZdZdddZeddZddZd d Zd d Z d dZ ddZ ddZ ddZ ddZdS)UploadInputManageraJBase manager class for handling various types of files for uploads This class is typically used for the UploadSubmissionTask class to help determine the following: * How to determine the size of the file * How to determine if a multipart upload is required * How to retrieve the body for a PutObject * How to retrieve the bodies for a set of UploadParts The answers/implementations differ for the various types of file inputs that may be accepted. All implementations must subclass and override public methods from this class. NcCs||_||_||_dSr)_osutilr%_bandwidth_limiterrosutilr'bandwidth_limiterrrrrwszUploadInputManager.__init__cCs tddS)aDetermines if the source for the upload is compatible with manager :param upload_source: The source for which the upload will pull data from. :returns: True if the manager can handle the type of source specified otherwise returns False. zmust implement _is_compatible()NNotImplementedErrorclsZ upload_sourcerrr is_compatible|s z UploadInputManager.is_compatiblecCs tddS)aWhether the body it provides are stored in-memory :type operation_name: str :param operation_name: The name of the client operation that the body is being used for. Valid operation_names are ``put_object`` and ``upload_part``. :rtype: boolean :returns: True if the body returned by the manager will be stored in memory. False if the manager will not directly store the body in memory. z%must implement store_body_in_memory()N)NotImplementedroperation_namerrrstores_body_in_memorys z(UploadInputManager.stores_body_in_memorycCs tddS)zProvides the transfer size of an upload :type transfer_future: s3transfer.futures.TransferFuture :param transfer_future: The future associated with upload request z&must implement provide_transfer_size()Nr:rtransfer_futurerrrprovide_transfer_sizesz(UploadInputManager.provide_transfer_sizecCs tddS)aDetermines where a multipart upload is required :type transfer_future: s3transfer.futures.TransferFuture :param transfer_future: The future associated with upload request :type config: s3transfer.manager.TransferConfig :param config: The config associated to the transfer manager :rtype: boolean :returns: True, if the upload should be multipart based on configuartion and size. False, otherwise. z*must implement requires_multipart_upload()Nr:rrDconfigrrrrequires_multipart_uploads z,UploadInputManager.requires_multipart_uploadcCs tddS)aReturns the body to use for PutObject :type transfer_future: s3transfer.futures.TransferFuture :param transfer_future: The future associated with upload request :type config: s3transfer.manager.TransferConfig :param config: The config associated to the transfer manager :rtype: s3transfer.utils.ReadFileChunk :returns: A ReadFileChunk including all progress callbacks associated with the transfer future. z$must implement get_put_object_body()Nr:rCrrrget_put_object_bodys z&UploadInputManager.get_put_object_bodycCs tddS)aYields the part number and body to use for each UploadPart :type transfer_future: s3transfer.futures.TransferFuture :param transfer_future: The future associated with upload request :type chunksize: int :param chunksize: The chunksize to use for this upload. :rtype: int, s3transfer.utils.ReadFileChunk :returns: Yields the part number and the ReadFileChunk including all progress callbacks associated with the transfer future for that specific yielded part. z)must implement yield_upload_part_bodies()Nr:)rrD chunksizerrryield_upload_part_bodiessz+UploadInputManager.yield_upload_part_bodiescCs*t||j}|jr&|jj||jdd}|S)NF)Zenabled)r#r%r6Zget_bandwith_limited_stream)rr&rrr _wrap_fileobjs z UploadInputManager._wrap_fileobjcCst|d}|rt|gSgS)Nprogress)r r)rrDrrrr_get_progress_callbackss  z*UploadInputManager._get_progress_callbackscCsdd|DS)NcSsg|] }|jqSr)r).0rrrr sz;UploadInputManager._get_close_callbacks..r)rZaggregated_progress_callbacksrrr_get_close_callbackssz'UploadInputManager._get_close_callbacks)N)r r!r"r3r classmethodr>rBrErHrIrKrLrNrQrrrrr4hs   r4c@sdeZdZdZeddZddZddZdd Zd d Z d d Z ddZ ddZ ddZ ddZdS)UploadFilenameInputManagerzUpload utility for filenamescCs t|tjSr) isinstancer string_typesr<rrrr>sz(UploadFilenameInputManager.is_compatiblecCsdS)NFrr@rrrrBsz0UploadFilenameInputManager.stores_body_in_memorycCs|j|j|jjjdSr)metarEr5Z get_file_size call_argsr&rCrrrrEs z0UploadFilenameInputManager.provide_transfer_sizecCs|jj|jkSr)rVsizemultipart_thresholdrFrrrrHsz4UploadFilenameInputManager.requires_multipart_uploadcCsJ||\}}||}||}||}|jj}|jj|||||dS)Nr& chunk_sizefull_file_sizerclose_callbacks)&_get_put_object_fileobj_with_full_sizerLrNrQrVrXr5#open_file_chunk_reader_from_fileobj)rrDr& full_sizerr]rXrrrrIs   z.UploadFilenameInputManager.get_put_object_bodyc cs|jj}|||}td|dD]j}||}||}||d}|j|jjj|||d\} } | | } |j j | || ||d} || fVq"dS)N) start_byte part_sizer\rZ) rVrX_get_num_partsrangerNrQ'_get_upload_part_fileobj_with_full_sizerWr&rLr5r_) rrDrJr\Z num_parts part_numberrr]rbr&r`Zread_file_chunkrrrrKs*      z3UploadFilenameInputManager.yield_upload_part_bodiescCst|||jjd}|S)N)Z open_function)r r5open)rr&rbrrr_get_deferred_open_files z2UploadFilenameInputManager._get_deferred_open_filecCs"|jjj}|jj}||d|fS)Nr)rVrWr&rXrirrDr&rXrrrr^#s zAUploadFilenameInputManager._get_put_object_fileobj_with_full_sizecKs |d}|d}||||fS)Nrbr\)ri)rr&r1rbr`rrrrf(szBUploadFilenameInputManager._get_upload_part_fileobj_with_full_sizecCstt|jjt|Sr)intmathceilrVrXfloat)rrDrcrrrrd-sz)UploadFilenameInputManager._get_num_partsN)r r!r"r3rRr>rBrErHrIrKrir^rfrdrrrrrSs rSc@s<eZdZdZeddZddZddZdd Zd d Z d S) UploadSeekableInputManagerz&Upload utility for an open file objectcCst|ot|Sr)rrr<rrrr>4sz(UploadSeekableInputManager.is_compatiblecCs|dkr dSdSdS)N put_objectFTrr@rrrrB8sz0UploadSeekableInputManager.stores_body_in_memorycCsD|jjj}|}|dd|}|||j||dS)Nr)rVrWr&r-r+rE)rrDr&Zstart_positionZ end_positionrrrrE>s   z0UploadSeekableInputManager.provide_transfer_sizecKs ||d}t|t|fS)Nrc)r)rBytesIOlen)rr&r1datarrrrfJszBUploadSeekableInputManager._get_upload_part_fileobj_with_full_sizecCs"|jjj}||jj}||fSr)rVrWr&r-rXrjrrrr^Ys zAUploadSeekableInputManager._get_put_object_fileobj_with_full_sizeN) r r!r"r3rRr>rBrErfr^rrrrro2s  rocsheZdZdZdfdd ZeddZddZd d Zd d Z d dZ ddZ dddZ ddZ ZS)UploadNonSeekableInputManagerz7Upload utility for a file-like object that cannot seek.Ncstt||||d|_dS)N)superrur _initial_datar7 __class__rrrcs  z&UploadNonSeekableInputManager.__init__cCst|Sr)rr<rrrr>hsz+UploadNonSeekableInputManager.is_compatiblecCsdS)NTrr@rrrrBlsz3UploadNonSeekableInputManager.stores_body_in_memorycCsdSrrrCrrrrEosz3UploadNonSeekableInputManager.provide_transfer_sizecCsT|jjdk r|jj|jkS|jjj}|j}|||d|_t|j|krLdSdSdS)NFT)rVrXrYrWr&_readrxrs)rrDrGr&rrrrrHts  z7UploadNonSeekableInputManager.requires_multipart_uploadcCs@||}||}|jjj}||j|||}d|_|Sr)rNrQrVrWr& _wrap_datarxr))rrDrr]r&bodyrrrrIs    z1UploadNonSeekableInputManager.get_put_object_bodyc cs^|jjj}d}||}||}|d7}|||}|srBrErHrIrKr{r| __classcell__rrryrruas   *ruc@s\eZdZdZddddgZdgZddZdd d Zd d Zd dZ ddZ ddZ ddZ dS)UploadSubmissionTaskz.Task for submitting tasks to execute an uploadZSSECustomerKeyZSSECustomerAlgorithmZSSECustomerKeyMD5Z RequestPayercCsHtttg}|jjj}|D]}||r|Sqtd|t|fdS)aoRetrieves a class for managing input for an upload based on file type :type transfer_future: s3transfer.futures.TransferFuture :param transfer_future: The transfer future for the request :rtype: class of UploadInputManager :returns: The appropriate class to use for managing a specific type of input for uploads. z&Input %s of type: %s is not supported.N) rSrorurVrWr&r> RuntimeErrortype)rrDZupload_manager_resolver_chainr&Zupload_manager_clsrrr_get_upload_input_manager_clss    z2UploadSubmissionTask._get_upload_input_manager_clsNcCsd||||j|}|jjdkr*|||||sL|||||||n|||||||dS)a :param client: The client associated with the transfer manager :type config: s3transfer.manager.TransferConfig :param config: The transfer config associated with the transfer manager :type osutil: s3transfer.utils.OSUtil :param osutil: The os utility associated to the transfer manager :type request_executor: s3transfer.futures.BoundedExecutor :param request_executor: The request executor associated with the transfer manager :type transfer_future: s3transfer.futures.TransferFuture :param transfer_future: The transfer future associated with the transfer request that tasks are being submitted for N)rr%rVrXrErH_submit_upload_request_submit_multipart_request)rclientrGr8request_executorrDr9upload_input_managerrrr_submit s:  zUploadSubmissionTask._submitc CsN|jj}||d}|jj|t|j||||j|j|j ddd|ddS)Nrp)rr&bucketkey extra_argsT)r' main_kwargsis_finaltag) rVrW_get_upload_task_tagr%submit PutObjectTaskrIrrr) rrrGr8rrDrrWZput_object_tagrrrr2s* z+UploadSubmissionTask._submit_upload_requestcCs|jj}|j|t|j||j|j|jdd}g} ||j} | |d} |jj } t } | |j | }|||}|D]B\}}| |jj|t|j|||j|j|| dd|id| dqx||j}|j|t|j||j|j|d|| dd d dS) N)rrrr)r'r upload_part)rr&rrrgr upload_id)r'rpending_main_kwargsr)rpartsT)r'rrr)rVrWr%rrrrr_extra_upload_part_argsrrXr Zadjust_chunksizeZmultipart_chunksizerKappendUploadPartTask_extra_complete_multipart_argsr )rrrGr8rrDrrWZcreate_multipart_futureZ part_futuresZextra_part_argsZupload_part_tagrXZadjusterrJZ part_iteratorrgr&Zcomplete_multipart_extra_argsrrrrLs~   z.UploadSubmissionTask._submit_multipart_requestcCs t||jSr)r UPLOAD_PART_ARGSrrrrrrsz,UploadSubmissionTask._extra_upload_part_argscCs t||jSr)r COMPLETE_MULTIPART_ARGSrrrrrsz3UploadSubmissionTask._extra_complete_multipart_argscCsd}||rt}|Sr)rBr)rrrArrrrrs z)UploadSubmissionTask._get_upload_task_tag)N) r r!r"r3rrrrrrrrrrrrrrs  'Mrc@seZdZdZddZdS)rz Task to do a nonmultipart uploadc Cs,|}|jf|||d|W5QRXdS)aP :param client: The client to use when calling PutObject :param fileobj: The file to upload. :param bucket: The name of the bucket to upload to :param key: The name of the key to upload to :param extra_args: A dictionary of any extra arguments that may be used in the upload. )BucketKeyBodyN)rp)rrr&rrrr}rrr_mains zPutObjectTask._mainNr r!r"r3rrrrrrsrc@seZdZdZddZdS)rz+Task to upload a part in a multipart uploadc Cs>|"}|jf|||||d|} W5QRX| d} | |dS)a :param client: The client to use when calling PutObject :param fileobj: The file to upload. :param bucket: The name of the bucket to upload to :param key: The name of the key to upload to :param upload_id: The id of the upload :param part_number: The number representing the part of the multipart upload :param extra_args: A dictionary of any extra arguments that may be used in the upload. :rtype: dict :returns: A dictionary representing a part:: {'Etag': etag_value, 'PartNumber': part_number} This value can be appended to a list to be used to complete the multipart upload. )rrZUploadId PartNumberrETag)rr)r) rrr&rrrrgrr}responseetagrrrrszUploadPartTask._mainNrrrrrrsr)rlZbotocore.compatrZs3transfer.compatrrZs3transfer.futuresrZs3transfer.tasksrrrr Zs3transfer.utilsr r r r objectrr#r4rSrorurrrrrrr s*        !+yQ/D