
    D6iK                         d 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)sleeptime)AnyDict)
_parse_url)ImproperlyConfigured)
get_logger   )KeyValueStoreBackendN)ClientError)DynamoDBBackendDynamoDBAttributename	data_typec                   n    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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&Z. xZ/S ))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                    t        |   |i | || _        |xs | j                  | _        t        st        d      d}d }d }|Ft        |      \  }}	}
}}}}|}|}|d u}|d u}||k7  rt        d      |}|	dk(  r@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*                  | j,                  | j.                  f| _        d | _        |r| j5                  ||       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://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                        [/home/azureuser/techstart-app/venv/lib/python3.12/site-packages/celery/backends/dynamodb.pyr(   zDynamoDBBackend.__init__C   sD   $)&)$7&$% % !&  $?# CFFD(HeU !)$,!0<4D@#33*"# # %5!$&7v$>!"-@GG)) #) 88==$$D"&'>"?"$7!'*		,,(D$ ),		--)D% ))M4+D+DEC03CD- $6tDO OO!!"
  /"7   !! " LL5cU!<!" !  Gs   (G 	G>G99G>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)rE   rF   r-   )dynamodb)
r?   r.   updater-   r+   client_get_or_create_table_has_ttl_validate_ttl_methods_set_table_ttl)rA   r%   r&   client_parameterss       rT   r@   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)ra   KeyType)ReadCapacityUnitsWriteCapacityUnits)AttributeDefinitions	TableName	KeySchemaProvisionedThroughput)r;   r   r   r*   r6   r7   rA   s    rT   _get_table_schemaz!DynamoDBBackend._get_table_schema   sp    
 &*__%9%9%)__%>%>%  &*__%9%9% &*%=%=&*&?&?&
 	
r_   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.rh   ErrorCodeUnknownResourceNotFoundExceptionz*DynamoDB Table {} did not exist, creating.ACTIVEz#DynamoDB Table {} is now available.N )rl   r?   describe_tabler*   r   responser4   create_tabler/   infor1   _wait_for_table_status)rA   table_schemarR   
error_codetable_descriptions        rT   rZ   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   )r8   rk   s    rT   r[   zDynamoDBBackend._has_ttl   s*     008t 	0**a/	0r_   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hasattrr?   appendr/   r:   r1   joinAttributeError)rA   required_methodsmissing_methodsmethods       rT   r\   z%DynamoDBBackend._validate_ttl_methods   s    
 +, 	/F4<<0&&v.	/ LLJ&HH_5  	 !5<<HH_5 =   r_   c                 B    | j                   | j                         |ddS )zBGet the boto3 structure describing the DynamoDB TTL specification.)Enabledra   )rh   TimeToLiveSpecification)r*   r[   )rA   ttl_attr_names     rT   _get_ttl_specificationz&DynamoDBBackend._get_ttl_specification  s&     ==?!.(
 	
r_   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)Nrn   ro   rp   rq   MessagezJError describing Time to Live on DynamoDB table {table}: {code}: {message})rL   codemessage)	r?   r   r*   r   rv   r4   r/   r:   r1   )rA   descriptionrR   r{   error_messages        rT   _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ENABLINGra   z5DynamoDB Time to Live is {situation} on table {table}r   zalready enabledzcurrently being enabled)	situationrL   )DISABLED	DISABLINGr   zalready disabledzcurrently being disabledzWUnknown DynamoDB Time to Live status {status} on table {table}. Attempting to continue.)statusrL   )r   zUDynamoDB table Time to Live updated: table={table} enabled={enabled} attribute={attr})rL   enabledattrro   rp   rq   r   zHError {action} Time to Live on DynamoDB table {table}: {code}: {message}enabling	disabling)actionrL   r   r   Nrt   )r   r[   
_ttl_fieldr   r/   debugr1   r*   r0   r?   r   r   rx   r   rv   r4   r:   )	rA   r   r   cur_attr_name	attr_namespecificationrR   r{   r   s	            rT   r]   zDynamoDBBackend._set_table_ttl-  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.Frn   z+Waiting for DynamoDB table {} to become {}.TableTableStatusr   N)rY   ru   r*   r/   r   r1   r   )rA   expectedachieved_stater|   current_statuss        rT   ry   z&DynamoDBBackend._wait_for_table_status  sx      $ : :// !; ! LL=DDOO /w7FN+x7N!H !r_   c                 x    | j                   | j                  j                  | j                  j                  |iidS )z0Construct the item retrieval request parameters.)rh   Key)r*   r;   r   r   rA   keys     rT   _prepare_get_requestz$DynamoDBBackend._prepare_get_request  s;     $$OO--s'
 	
r_   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.rh   Itemr   )r   r*   r;   r   r   r<   r=   strr[   rX   r   r5   r8   )rA   r   valuer   put_requests        rT   _prepare_put_requestz$DynamoDBBackend._prepare_put_request  s    F	$$OO--s' !!&&%%//) %%**))33S^-

 ==?&&$$OO--C	D,E,E EFG'(  r_   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   )rA   r   r   s      rT   _prepare_init_count_requestz+DynamoDBBackend._prepare_init_count_request  s    F	$$OO--s' !!&&%%//) %%**))33S^-

 	
r_   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)rh   r   UpdateExpressionExpressionAttributeValuesReturnValues)r*   r;   r   r   r   r   s     rT   _prepare_inc_count_requestz*DynamoDBBackend._prepare_inc_count_request  s}     $$OO--s'
 #'t'8'8'='=&>c$BSBSBXBXAYY` ac
* +
 	
r_   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   )r>   r   r   )rA   raw_responsefields      rT   _item_to_dictzDynamoDBBackend._item_to_dict  sW    %I //
 JJV,UZZ8II
 	
 
s   1A	c                 "    | j                         S N)r@   rk   s    rT   rY   zDynamoDBBackend.client  s    !!r_   c                     t        |      }| j                  |      } | j                  j                  di |}| j	                  |      }|j                  | j                  j                        S Nrt   )r   r   rY   get_itemr   r4   r<   r   )rA   r   request_parametersitem_responseitems        rT   r4   zDynamoDBBackend.get  sa    #h!66s;,,,B/AB!!-0xx))..//r_   c                 v    t        |      }| j                  ||      } | j                  j                  di | y r   )r   r   rY   put_item)rA   r   r   r   s       rT   setzDynamoDBBackend.set	  s6    #h!66sEB212r_   c                 J    |D cg c]  }| j                  |       c}S c c}w r   )r4   )rA   keysr   s      rT   mgetzDynamoDBBackend.mget  s    )-.#...s    c                 t    t        |      }| j                  |      } | j                  j                  di | y r   )r   r   rY   delete_item)rA   r   r   s      rT   deletezDynamoDBBackend.delete  s4    #h!66s;5"45r_   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
Attributesrt   )r   r   rY   update_itemr   r   r   r5   )rA   r   r   r   	new_counts        rT   incrzDynamoDBBackend.incr  sl    #h!<<SA///E2DE&|4T5F5F5K5KLTM^M^MhMhi	9~r_   c                     | j                  |d         }| j                  t        |            } | j                  j                  di | t        |   ||fi |S )Nr   rt   )get_key_for_chordr   r   rY   r   r'   _apply_chord_incr)rA   header_result_argsbodyrC   	chord_keyinit_count_requestrS   s         rT   r   z!DynamoDBBackend._apply_chord_incr  se    **+=a+@A	!==c)nM212w(0(.0 	0r_   )NN)rs   )0__name__
__module____qualname____doc__r*   r6   r7   r.   r-   r8   supports_autoexpirer   r;   r<   r   r=   r   r>   implements_incrr(   r@   rl   rZ   r[   r\   r   r   r]   ry   r   r   r   r   r   r   r   r   propertyrY   r4   r   r   r   bytesr5   r   r   __classcell__)rS   s   @rT   r   r      sE    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 0r_   r   )r   collectionsr   r   r   typingr   r   kombu.utils.urlr   r,   celery.exceptionsr	   celery.utils.logr
   baser   r+   botocore.exceptionsr   ImportError__all__r   r   r/   r   rt   r_   rT   <module>r      st    ( "   3 2 ' &/  24IJ 	H	G0* G0  EKs   
A 	A'&A'