o
    .iC                     @   s   d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ zdd	lZdd
lmZ W n eyA   d	 ZZY nw dZeddZeeZG dd deZd	S )z"AWS DynamoDB result store backend.    )
namedtuple)sleeptime)
_parse_url)ImproperlyConfigured)
get_logger   )KeyValueStoreBackendN)ClientError)DynamoDBBackendDynamoDBAttributename	data_typec                       s  e Zd ZdZdZdZdZdZdZdZ	dZ
edddZed	d
dZedddZedddZdZd3 fdd	Zd3ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zd4d!d"Zd#d$ Zd%d& Zd'd( Zed)d* Zd+d, Z d-d. Z!d/d0 Z"d1d2 Z#  Z$S )5r   zAWS DynamoDB result backend.

    Raises:
        celery.exceptions.ImproperlyConfigured:
            if module :pypi:`boto3` is not available.
    celeryr   NTidSr   resultB	timestampNttlc              
      s  t  j|i | || _|p| j| _tstdd}d }d }|d urt|\}}	}
}}}}|}|}|d u}|d u}||krAtd|}|	dkrZd|
 | _d| _t	
d| j n|	| _| jjj}|d}|rk|| _t|d	| j| _t|d
| j| _|d| j}|rzt|| _W n ty } zt	jd| d|d |d }~ww |p| j| _| j| j| jf| _d | _|r| j||d d S d S )NzBYou need to install the boto3 library to use the DynamoDB backend.Fz6You need to specify both the Access Key ID and Secret.	localhostzhttp://localhost:z	us-east-1z*Using local-only DynamoDB endpoint URL: {}dynamodb_endpoint_urlreadwritettl_secondszTTL must be a number; got "")exc_info)access_key_idsecret_access_key)super__init__url
table_nameboto3r   	parse_urlendpoint_url
aws_regionloggerwarningformatappconfgetintread_capacity_unitswrite_capacity_unitstime_to_live_seconds
ValueErrorerror
_key_field_value_field_timestamp_field_available_fields_client_get_client)selfr#   r$   argskwargsaws_credentials_givenaws_access_key_idaws_secret_access_keyschemeregionportusernamepasswordtablequeryaccess_key_givensecret_key_given_getconfig_endpoint_urlr   e	__class__ S/var/www/html/philips/venv/lib/python3.10/site-packages/celery/backends/dynamodb.pyr"   >   s   


zDynamoDBBackend.__init__c                 C   s~   | j du r<d| ji}|dur|||d | jdur | j|d< tj	di || _ |   |  dur<|   | 	  | j S )zGet client connection.Nregion_name)r?   r@   r'   dynamodb)rR   )
r9   r(   updater'   r%   client_get_or_create_table_has_ttl_validate_ttl_methods_set_table_ttl)r;   r   r    client_parametersrO   rO   rP   r:      s(   


zDynamoDBBackend._get_clientc                 C   s6   | j j| j jdg| j| j jddg| j| jddS )z=Get the boto3 structure describing the DynamoDB table schema.)AttributeNameAttributeTypeHASH)rZ   KeyType)ReadCapacityUnitsWriteCapacityUnits)AttributeDefinitions	TableName	KeySchemaProvisionedThroughput)r5   r   r   r$   r0   r1   r;   rO   rO   rP   _get_table_schema   s   z!DynamoDBBackend._get_table_schemac              
   C   s   |   }z	| jj| jdW S  tyP } z7|jd dd}|dkrJ| jjd
i |}t	d
| j | d t	d
| j |W  Y d	}~S |d	}~ww )z=Create table if not exists, otherwise return the description.ra   ErrorCodeUnknownResourceNotFoundExceptionz*DynamoDB Table {} did not exist, creating.ACTIVEz#DynamoDB Table {} is now available.NrO   )re   r9   describe_tabler$   r
   responser.   create_tabler)   infor+   _wait_for_table_status)r;   table_schemarL   
error_codetable_descriptionrO   rO   rP   rU      s,   
z$DynamoDBBackend._get_or_create_tablec                 C   s   | j du rdS | j dkS )zReturn the desired Time to Live config.

        - True:  Enable TTL on the table; use expiry.
        - False: Disable TTL on the table; don't use expiry.
        - None:  Ignore TTL on the table; don't use expiry.
        Nr   )r2   rd   rO   rO   rP   rV      s   zDynamoDBBackend._has_ttlc                 C   sb   d}g }t |D ]}t| j|s|| q|r/tdjd|d tdjd|ddS )z:Verify boto support for the DynamoDB Time to Live methods.)update_time_to_livedescribe_time_to_livezdboto3 method(s) {methods} not found; ensure that boto3>=1.9.178 and botocore>=1.12.178 are installed,)methodsz#boto3 method(s) {methods} not foundN)	listhasattrr9   appendr)   r4   r+   joinAttributeError)r;   required_methodsmissing_methodsmethodrO   rO   rP   rW      s&   
z%DynamoDBBackend._validate_ttl_methodsc                 C   s   | j |  |ddS )zBGet the boto3 structure describing the DynamoDB TTL specification.)EnabledrZ   )ra   TimeToLiveSpecification)r$   rV   )r;   ttl_attr_namerO   rO   rP   _get_ttl_specification	  s
   z&DynamoDBBackend._get_ttl_specificationc              
   C   sp   z| j j| jd}W |S  ty7 } z |jd dd}|jd dd}tdj| j||d |d }~ww )Nrf   rg   rh   ri   MessagezJError describing Time to Live on DynamoDB table {table}: {code}: {message})rF   codemessage)	r9   ru   r$   r
   rm   r.   r)   r4   r+   )r;   descriptionrL   rr   error_messagerO   rO   rP   _get_table_ttl_description  s$   z*DynamoDBBackend._get_table_ttl_descriptionc           	      C   sn  |   }|d d }|dv r2|d d }|  r1|| jjkr1tdj|dkr(dnd| jd	 |S n'|d
v rN|  sMtdj|dkrDdnd| jd	 |S ntdj|| jd |dkr_|n| jj}z | j	j
di | j|d}tdj| j|  | jjd |W S  ty } z'|jd dd}|jd dd}tdj|  rdnd| j||d |d}~ww )z,Enable or disable Time to Live on the table.TimeToLiveDescriptionTimeToLiveStatus)ENABLEDENABLINGrZ   z5DynamoDB Time to Live is {situation} on table {table}r   zalready enabledzcurrently being enabled)	situationrF   )DISABLED	DISABLINGr   zalready disabledzcurrently being disabledzWUnknown DynamoDB Time to Live status {status} on table {table}. Attempting to continue.)statusrF   )r   zUDynamoDB table Time to Live updated: table={table} enabled={enabled} attribute={attr})rF   enabledattrrg   rh   ri   r   zHError {action} Time to Live on DynamoDB table {table}: {code}: {message}enabling	disabling)actionrF   r   r   NrO   )r   rV   
_ttl_fieldr   r)   debugr+   r$   r*   r9   rt   r   ro   r
   rm   r.   r4   )	r;   r   r   cur_attr_name	attr_namespecificationrL   rr   r   rO   rO   rP   rX   (  s   
		&

	zDynamoDBBackend._set_table_ttlrk   c                 C   sT   d}|s(| j j| jd}td| j| |d d }||k}td |rdS dS )z#Poll for the expected table status.Frf   z+Waiting for DynamoDB table {} to become {}.TableTableStatusr   N)rT   rl   r$   r)   r   r+   r   )r;   expectedachieved_staters   current_statusrO   rO   rP   rp     s   z&DynamoDBBackend._wait_for_table_statusc                 C   s   | j | jj| jj|iidS )z0Construct the item retrieval request parameters.)ra   Key)r$   r5   r   r   )r;   keyrO   rO   rP   _prepare_get_request  s   z$DynamoDBBackend._prepare_get_requestc              	   C   s~   t  }| j| jj| jj|i| jj| jj|i| jj| jjt|iid}|  r=|d 	| j
j| j
jtt|| j ii |S )z/Construct the item creation request parameters.)ra   Itemr   )r   r$   r5   r   r   r6   r7   strrV   rS   r   r/   r2   )r;   r   valuer   put_requestrO   rO   rP   _prepare_put_request  s*   z$DynamoDBBackend._prepare_put_requestc                    s    d vri S  fdd| j D S )z1Convert get_item() response to field-value pairs.r   c                    s$   i | ]}|j  d  |j  |j qS )r   r   ).0fieldraw_responserO   rP   
<dictcomp>  s    z1DynamoDBBackend._item_to_dict.<locals>.<dictcomp>)r8   )r;   r   rO   r   rP   _item_to_dict  s
   
zDynamoDBBackend._item_to_dictc                 C   s   |   S )N)r:   rd   rO   rO   rP   rT     s   zDynamoDBBackend.clientc                 C   s<   t |}| |}| jjdi |}| |}|| jjS NrO   )r   r   rT   get_itemr   r.   r6   r   )r;   r   request_parametersitem_responseitemrO   rO   rP   r.     s
   

zDynamoDBBackend.getc                 C   s*   t |}| ||}| jjdi | d S r   )r   r   rT   put_item)r;   r   r   r   rO   rO   rP   set  s   zDynamoDBBackend.setc                    s    fdd|D S )Nc                    s   g | ]}  |qS rO   )r.   )r   r   rd   rO   rP   
<listcomp>  s    z(DynamoDBBackend.mget.<locals>.<listcomp>rO   )r;   keysrO   rd   rP   mget  s   zDynamoDBBackend.mgetc                 C   s(   t |}| |}| jjdi | d S r   )r   r   rT   delete_item)r;   r   r   rO   rO   rP   delete  s   
zDynamoDBBackend.delete)NN)rk   )%__name__
__module____qualname____doc__r$   r0   r1   r(   r'   r2   supports_autoexpirer   r5   r6   r7   r   r8   r"   r:   re   rU   rV   rW   r   r   rX   rp   r   r   r   propertyrT   r.   r   r   r   __classcell__rO   rO   rM   rP   r      sB    
Y


p	
r   )r   collectionsr   r   r   kombu.utils.urlr   r&   celery.exceptionsr   celery.utils.logr   baser	   r%   botocore.exceptionsr
   ImportError__all__r   r   r)   r   rO   rO   rO   rP   <module>   s"    
