
    $j|!                        d Z ddlZddlZddlZddlZddl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mZmZ e	rdd	lmZ dd
lmZ  ej        e          Zg dZ ee          dz   Zdeez  dz  defdZ G d d          ZdS )z3Webhook manager for delivering event notifications.    N)datetimetimezone)TYPE_CHECKINGAny   )fq_table_explicit   )WebhookConfigWebhookEventWebhookHttpConfig)DatabaseBackend)TenantExtension)   i,  i  i   iPF  valuereturnc                     | t                      S t          | t                    rt          j        |           S t          j        |           S )zMParse http_config column value (JSONB returned as text or dict) into a model.)r   
isinstancestrmodel_validate_jsonmodel_validate)r   s    f/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/hindsight_api/webhooks/manager.py_parse_http_configr      sG    } """% < 4U;;;+E222    c            	           e Zd ZdZ	 ddddee         ddfdZd	ed
edefdZ	dde
dedz  ddfdZdde
dededz  ddfdZdS )WebhookManagera#  
    Manages webhook registration and event firing.

    Supports both global webhooks (configured via env vars) and per-bank
    webhooks stored in the database. Deliveries are queued as async_operations
    tasks (operation_type='webhook_delivery') and picked up by the worker poller.
    Nbackendr   global_webhookstenant_extensionzTenantExtension | Nonec                 0    || _         || _        || _        d S N)_backend_global_webhooks_tenant_extension)selfr   r   r   s       r   __init__zWebhookManager.__init__,   s!       /!1r   secretpayload_bytesr   c                     dt          j        |                                |t          j                                                  z   S )z,Compute HMAC-SHA256 signature for a payload.zsha256=)hmacnewencodehashlibsha256	hexdigest)r$   r&   r'   s      r   _sign_payloadzWebhookManager._sign_payload6   s1    48FMMOO]GNSS]]____r   eventschemac                 <  K   t          d|          }t          d|          }t          j        t          j                  }|                                }	 | j                                        4 d{V }| j        j        	                    |||j
                   d{V }d |D             }	| j        |	z   }
d}|
D ]}|j        s
|j        j        |j        vrt!          j                    }|j        r|j        nd}t'          j        dt+          |          |j
        |j        |j        |j        j        |||j                                        d	          }| j        j                            ||||j
        ||           d{V  |dz  }	 ddd          d{V  n# 1 d{V swxY w Y   t6                              d	|j         d
|j
         d| d           dS # t:          $ r0}t6                              d|j         d|            Y d}~dS d}~ww xY w)a  
        Queue webhook deliveries for an event as async_operations tasks.

        Loads per-bank and global webhooks, inserts pending webhook_delivery tasks for
        any webhook whose event_types list matches the fired event type. The worker
        poller picks these up and calls MemoryEngine._handle_webhook_delivery().

        Args:
            event: The event to deliver.
            schema: Database schema (for multi-tenant). None = default schema.
        webhooksasync_operationsNc                     g | ]s}t          t          |d                    |d         |d         |d         |d         rt          |d                   ng |d         t          |d                             tS idbank_idurlr&   event_typesenabledhttp_config)r7   r8   r9   r&   r:   r;   r<   r
   r   listr   .0rows     r   
<listcomp>z-WebhookManager.fire_event.<locals>.<listcomp>S   s         "s4y>> #IJ"8}@CM@R$ZD]);$<$<$<XZ #I$6s=7I$J$J    r   r   webhook_delivery	typeoperation_idr8   r9   r&   
event_typepayload
webhook_idr<   r	   Fired webhook event 
 for bank : z delivery(ies) queuedz-Failed to queue webhook deliveries for event )	_fq_tabler   nowr   utcmodel_dump_jsonr!   acquireopsget_webhooks_for_dispatchr8   r"   r;   r0   r   r:   uuiduuid4r7   jsondumpsr   r9   r&   r<   
model_dumpinsert_webhook_delivery_taskloggerdebug	Exceptionerror)r$   r0   r1   webhook_table	ops_tablerN   payload_strconnrowsdb_webhooksall_webhooksmatchedwebhookrF   rI   task_payloades                    r   
fire_eventzWebhookManager.fire_event:   s'      "*f550&99	l8<((++--<	]},,.. 6! 6! 6! 6! 6! 6! 6!$!].HH!M          $    $4{B+ ! !G"? ! {(0CCC #':<<L/6z!CtJ#':$6,/,=,=',}#*;&-n*/+*;'2*4+2+>+I+I+K+K
 
$ $L -+HH!$$         qLGG?!/6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6! 6!p LLvvvu}vvX_vvvwwwww 	] 	] 	]LL[[[XY[[\\\\\\\\\	]s=   G! 5DF G!  
F**G! -F*.1G! !
H+%HHra   c                   K   t          d|          }t          d|          }t          j        t          j                  }|                                }	 | j        j                            |||j	                   d{V }d |D             }	| j
        |	z   }
d}|
D ]}|j        s
|j        j        |j        vrt          j                    }|j        r|j        nd}t%          j        dt)          |          |j	        |j        |j        |j        j        |||j                                        d	          }| j        j                            ||||j	        ||           d{V  |dz  }t4                              d	|j         d
|j	         d| d           dS # t8          $ r,}t4                              d|j         d| d            d}~ww xY w)a5  
        Queue webhook deliveries within an existing database connection/transaction.

        Identical to fire_event() but uses the provided connection instead of acquiring
        one from the pool. Use this to atomically insert delivery tasks in the same
        transaction as the primary operation (transactional outbox pattern).

        Args:
            event: The event to deliver.
            conn: Existing database connection (may be inside an active transaction).
            schema: Database schema (for multi-tenant). None = default schema.
        r3   r4   Nc                     g | ]s}t          t          |d                    |d         |d         |d         |d         rt          |d                   ng |d         t          |d                             tS r6   r=   r?   s     r   rB   z7WebhookManager.fire_event_with_conn.<locals>.<listcomp>   s         3t9~~	NE
x=<?<N VS%7 8 8 8TV	N 23}3E F F    r   r   rC   rD   r	   rJ   rK   rL   z& delivery(ies) queued (in-transaction)z>Failed to queue webhook deliveries (in-transaction) for event z]. CRITICAL: The enclosing database transaction is now aborted and will roll back all changes.)rM   r   rN   r   rO   rP   r!   rR   rS   r8   r"   r;   r0   r   r:   rT   rU   r7   rV   rW   r   r9   r&   r<   rX   rY   rZ   r[   r\   r]   )r$   r0   ra   r1   r^   r_   rN   r`   rb   rc   rd   re   rf   rF   rI   rg   rh   s                    r   fire_event_with_connz#WebhookManager.fire_event_with_conn   sv      "*f550&99	l8<((++--A	*DD       D     K  0;>LG'   ;$G,???#z||+2:?WZZ4
#z 2(+L(9(9#(=&{").&+k&7#.&0'.':'E'E'G'G
 
    m'DD M          1LL~u{~~em~~w~~~      	 	 	LLnQVQ\ n n`a n n n   	s   EF 
G''GGr    )__name__
__module____qualname____doc__r>   r
   r%   r   bytesr/   r   ri   r   rl    r   r   r   r   #   s         6:	2 2"2 m,2 3	2 2 2 2`C ` `# ` ` ` `M] M]l M]C$J M]RV M] M] M] M]^S S SC SQTW[Q[ Sgk S S S S S Sr   r   ) rp   r,   r)   rV   loggingrT   r   r   typingr   r   engine.schemar   rM   modelsr
   r   r   hindsight_api.engine.db.baser   hindsight_api.extensions.tenantr   	getLoggerrm   rZ   RETRY_DELAYSlenMAX_ATTEMPTSr   dictr   r   rr   r   r   <module>r~      s`   9 9      ' ' ' ' ' ' ' ' % % % % % % % % : : : : : : B B B B B B B B B B @<<<<<<??????		8	$	$ +**s<  1$3cDj4/ 34E 3 3 3 3y y y y y y y y y yr   