
    h|L                         d Z ddlmZ ddlmZ ddlmZ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 	 ddlZddlmZ dZ edd      Z ee      Z G d de      Zy# e$ r dxZZY *w xY w)z"AWS DynamoDB result store backend.    )
namedtuple)
ip_address)sleeptime)AnyDict)
_parse_url)ImproperlyConfigured)
get_logger   )KeyValueStoreBackendN)ClientError)DynamoDBBackendDynamoDBAttributename	data_typec                   ~    e Zd ZdZdZdZdZdZdZdZ	dZ
 edd      Z ed	d
      Z edd      Z edd      Z edd      ZdZdZd( fd	Zed        Zd(dZd Zd Zd Zd Zd Zd Zd Zd)dZd Zd Z de!de"e!e#f   fdZ$de!de"e!e#f   fdZ%d  Z&e'd!        Z(d" Z)d# Z*d$ Z+d% Z,de-de.fd&Z/ fd'Z0 xZ1S )*r   zAWS DynamoDB result backend.

    Raises:
        celery.exceptions.ImproperlyConfigured:
            if module :pypi:`boto3` is not available.
    celeryr   NTidSr   resultBchord_countN	timestampttlc                 2   t        |   |i | || _        |xs | j                  | _        t        st        d      d}d }d }|^t        |      \  }}	}
}}}}|}|}|d u}|d u}||k7  rt        d      |}|	dk(  st        j                  |	      rCd|	 d|
 | _	        d| _
        t        j                  dj                  | j                               n|	| _
        | j                  j                  j                   } |d	      }|r|| _	        t#        |j!                  d
| j$                              | _        t#        |j!                  d| j&                              | _        |j!                  d| j(                        }|r	 t#        |      | _        |xs | j                  | _        | j.                  | j0                  | j2                  f| _        d | _        |r| j9                  ||       y y # t*        $ r"}t        j-                  d| d|       |d }~ww xY w)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://: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_urlr   _is_valid_ip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                        T/var/www/Befach/backend/env/lib/python3.12/site-packages/celery/backends/dynamodb.pyr*   zDynamoDBBackend.__init__D   sW   $)&)$7&$% % !&  $?# CFFD(HeU !)$,!0<4D@#33*"# # %5!$(D(DV(L&-fXQtf$=!"-@GG)) #) 88==$$D"&'>"?"$7!'*		,,(D$ ),		--)D% ))M4+D+DEC03CD- $6tDO OO!!"
  /"7   !! " LL5cU!<!" !  Gs    G+ +	H4HHc                 :    	 t        |        y# t        $ r Y yw xY w)NTF)r   r<   )ips    rW   r/   zDynamoDBBackend._is_valid_ip   s#    	rN 		s    	c                 f   | j                   d| j                  i}||j                  ||d       | j                  | j                  |d<   t	        j
                  	 di || _         | j                          | j                          | j                          | j                          | j                   S )zGet client connection.region_name)rH   rI   r0   )dynamodb)
rB   r1   updater0   r-   client_get_or_create_table_has_ttl_validate_ttl_methods_set_table_ttl)rD   r'   r(   client_parameterss       rW   rC   zDynamoDBBackend._get_client   s    <<t! (!(()6->* 
   ,484E4E!.1 <<#DL %%'}}***,##%||    c                     | 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)rf   KeyType)ReadCapacityUnitsWriteCapacityUnits)AttributeDefinitions	TableName	KeySchemaProvisionedThroughput)r>   r   r   r,   r9   r:   rD   s    rW   _get_table_schemaz!DynamoDBBackend._get_table_schema   sp    
 &*__%9%9%)__%>%>%  &*__%9%9% &*%=%=&*&?&?&
 	
rd   c                    | j                         }	 | j                  j                  | j                        S # t        $ r}|j
                  d   j                  dd      }|dk(  r | j                  j                  d
i |}t        j                  dj                  | j                               | j                  d       t        j                  dj                  | j                               |cY d	}~S |d	}~ww xY w)z=Create table if not exists, otherwise return the description.rm   ErrorCodeUnknownResourceNotFoundExceptionz*DynamoDB Table {} did not exist, creating.ACTIVEz#DynamoDB Table {} is now available.N )rq   rB   describe_tabler,   r   responser7   create_tabler2   infor4   _wait_for_table_status)rD   table_schemarU   
error_codetable_descriptions        rW   r_   z$DynamoDBBackend._get_or_create_table   s    --/	<<...II 	G,00CJ88$=DLL$=$=$M$M!@GG ++H59@@
 )('	s"   %8 	C<B.C7/C<5C77C<c                 <    | j                   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   )r;   rp   s    rW   r`   zDynamoDBBackend._has_ttl   s*     008t 	0**a/	0rd   c                 <   d}g }t        |      D ]*  }t        | j                  |      r|j                  |       , |r^t        j                  dj                  dj                  |                   t        dj                  dj                  |                  y)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hasattrrB   appendr2   r=   r4   joinAttributeError)rD   required_methodsmissing_methodsmethods       rW   ra   z%DynamoDBBackend._validate_ttl_methods   s    
 +,F4<<0&&v. - LLJ&HH_5  	 !5<<HH_5 =   rd   c                 B    | j                   | j                         |ddS )zBGet the boto3 structure describing the DynamoDB TTL specification.)Enabledrf   )rm   TimeToLiveSpecification)r,   r`   )rD   ttl_attr_names     rW   _get_ttl_specificationz&DynamoDBBackend._get_ttl_specification  s&     ==?!.(
 	
rd   c                 X   	 | j                   j                  | j                        }|S # t        $ rv}|j                  d   j                  dd      }|j                  d   j                  dd      }t        j                  dj                  | j                  ||             |d }~ww xY w)Nrs   rt   ru   rv   MessagezJError describing Time to Live on DynamoDB table {table}: {code}: {message})rO   codemessage)	rB   r   r,   r   r{   r7   r2   r=   r4   )rD   descriptionrU   r   error_messages        rW   _get_table_ttl_descriptionz*DynamoDBBackend._get_table_ttl_description!  s    	,,<<// = K    	G,00CJJJw/33IyIMLL$foo%   G	s   &* 	B)A1B$$B)c           	      p   | j                         }|d   d   }|dv rj|d   d   }| j                         r|| j                  j                  k(  rt        j                  dj                  |dk(  rdnd| j                  	             |S |d
v rI| j                         sit        j                  dj                  |dk(  rdnd| j                  	             |S t        j                  dj                  || j                               |dk(  rn| j                  j                  }	  | j                  j                  di | j                  |      }t        j                  dj                  | j                  | j                         | j                  j                               |S # t        $ r}|j                  d   j                  dd      }|j                  d   j                  dd      }t        j!                  dj                  | j                         rdnd| j                  ||             |d}~ww xY w)z,Enable or disable Time to Live on the table.TimeToLiveDescriptionTimeToLiveStatus)ENABLEDENABLINGrf   z5DynamoDB Time to Live is {situation} on table {table}r   zalready enabledzcurrently being enabled)	situationrO   )DISABLED	DISABLINGr   zalready disabledzcurrently being disabledzWUnknown DynamoDB Time to Live status {status} on table {table}. Attempting to continue.)statusrO   )r   zUDynamoDB table Time to Live updated: table={table} enabled={enabled} attribute={attr})rO   enabledattrrt   ru   rv   r   zHError {action} Time to Live on DynamoDB table {table}: {code}: {message}enabling	disabling)actionrO   r   r   Nry   )r   r`   
_ttl_fieldr   r2   debugr4   r,   r3   rB   r   r   r}   r   r{   r7   r=   )	rD   r   r   cur_attr_name	attr_namespecificationrU   r   r   s	            rW   rb   zDynamoDBBackend._set_table_ttl6  s=    557456HI,,34_E }} DOO$8$88 LL+f!Y. #46"oo	   '&00==? '&+ 13//	   #" NN<foo  L $y0Mdoo6J6J 		<DLL<< --"+ . M
 KKG&// MMO--  		 !  	G,00CJJJw/33IyIMLL$f%)]]_z+oo%	   G	s   "B F# #	H5,BH00H5c                     d}|sq| j                   j                  | j                        }t        j	                  dj                  | j                  |             |d   d   }||k(  }t        d       |spyy)z#Poll for the expected table status.Frs   z+Waiting for DynamoDB table {} to become {}.TableTableStatusr   N)r^   rz   r,   r2   r   r4   r   )rD   expectedachieved_stater   current_statuss        rW   r~   z&DynamoDBBackend._wait_for_table_status  sx      $ : :// !; ! LL=DDOO /w7FN+x7N!H !rd   c                 x    | j                   | j                  j                  | j                  j                  |iidS )z0Construct the item retrieval request parameters.)rm   Key)r,   r>   r   r   rD   keys     rW   _prepare_get_requestz$DynamoDBBackend._prepare_get_request  s;     $$OO--s'
 	
rd   c           
      0   t               }| j                  | j                  j                  | j                  j                  |i| j
                  j                  | j
                  j                  |i| j                  j                  | j                  j                  t        |      iid}| j                         r_|d   j                  | j                  j                  | j                  j                  t        t        || j                  z               ii       |S )z/Construct the item creation request parameters.rm   Itemr   )r   r,   r>   r   r   r?   r@   strr`   r]   r   r8   r;   )rD   r   valuer   put_requests        rW   _prepare_put_requestz$DynamoDBBackend._prepare_put_request  s    F	$$OO--s' !!&&%%//) %%**))33S^-

 ==?&&$$OO--C	D,E,E EFG'(  rd   r   returnc           
      N   t               }| j                  | j                  j                  | j                  j                  |i| j
                  j                  | j
                  j                  di| j                  j                  | j                  j                  t        |      iidS )z7Construct the counter initialization request parameters0r   )r   r,   r>   r   r   _count_filedr@   r   )rD   r   r   s      rW   _prepare_init_count_requestz+DynamoDBBackend._prepare_init_count_request  s    F	$$OO--s' !!&&%%//) %%**))33S^-

 	
rd   c                     | j                   | j                  j                  | j                  j                  |iid| j                  j                   d| j                  j                   ddddiiddS )	z2Construct the counter increment request parameterszset z = z + :numz:numr   1UPDATED_NEW)rm   r   UpdateExpressionExpressionAttributeValuesReturnValues)r,   r>   r   r   r   r   s     rW   _prepare_inc_count_requestz*DynamoDBBackend._prepare_inc_count_request  s}     $$OO--s'
 #'t'8'8'='=&>c$BSBSBXBXAYY` ac
* *
 	
rd   c                     d|vri S | j                   D ci c],  }|j                  |d   |j                     |j                     . c}S c c}w )z1Convert get_item() response to field-value pairs.r   )rA   r   r   )rD   raw_responsefields      rW   _item_to_dictzDynamoDBBackend._item_to_dict  sW    %I //
 JJV,UZZ8II
 	
 
s   1A	c                 "    | j                         S N)rC   rp   s    rW   r^   zDynamoDBBackend.client  s    !!rd   c                     t        |      }| j                  |      } | j                  j                  di |}| j	                  |      }|j                  | j                  j                        S Nry   )r   r   r^   get_itemr   r7   r?   r   )rD   r   request_parametersitem_responseitems        rW   r7   zDynamoDBBackend.get  sa    #h!66s;,,,B/AB!!-0xx))..//rd   c                 v    t        |      }| j                  ||      } | j                  j                  di | y r   )r   r   r^   put_item)rD   r   r   r   s       rW   setzDynamoDBBackend.set  s6    #h!66sEB212rd   c                 J    |D cg c]  }| j                  |       c}S c c}w r   )r7   )rD   keysr   s      rW   mgetzDynamoDBBackend.mget  s    )-.#...s    c                 t    t        |      }| j                  |      } | j                  j                  di | y r   )r   r   r^   delete_item)rD   r   r   s      rW   deletezDynamoDBBackend.delete  s4    #h!66s;5"45rd   c                     t        |      }| j                  |      } | j                  j                  di |}|d   | j                  j
                     | j                  j                     }t        |      S )z<Atomically increase the chord_count and return the new count
Attributesry   )r   r   r^   update_itemr   r   r   r8   )rD   r   r   r   	new_counts        rW   incrzDynamoDBBackend.incr  sl    #h!<<SA///E2DE&|4T5F5F5K5KLTM^M^MhMhi	9~rd   c                     | j                  |d         }| j                  t        |            } | j                  j                  di | t        |   ||fi |S )Nr   ry   )get_key_for_chordr   r   r^   r   r)   _apply_chord_incr)rD   header_result_argsbodyrF   	chord_keyinit_count_requestrV   s         rW   r   z!DynamoDBBackend._apply_chord_incr'  se    **+=a+@A	!==c)nM212w(0(.0 	0rd   )NN)rx   )2__name__
__module____qualname____doc__r,   r9   r:   r1   r0   r;   supports_autoexpirer   r>   r?   r   r@   r   rA   implements_incrr*   staticmethodr/   rC   rq   r_   r`   ra   r   r   rb   r~   r   r   r   r   r   r   r   r   propertyr^   r7   r   r   r   bytesr8   r   r   __classcell__)rV   s   @rW   r   r      sY    J   J L   "<J$(cBL$-3GL(kSI"=JOWr  6
,40:
*n`"	
4
s 
tCH~ 
$
c 
d38n 
 
 " "03
/6
 # 0 0rd   r   )r   collectionsr   	ipaddressr   r   r   typingr   r   kombu.utils.urlr	   r.   celery.exceptionsr
   celery.utils.logr   baser   r-   botocore.exceptionsr   ImportError__all__r   r   r2   r   ry   rd   rW   <module>r     sw    ( "     3 2 ' &/  24IJ 	H	O0* O0  EKs   
A! !	A-,A-