U
    ^»{jž&  ã                   @  s’   d Z ddlmZ ddlZddlmZ ddlZddlmZ erhddl	Z	ddlm
Z
mZmZmZ ddlmZ e e¡ZG dd	„ d	ƒZG d
d„ dƒZdS )z?Provide a lower-level async interface to the Devtools Protocol.é    )ÚannotationsN)ÚTYPE_CHECKING)Úprotocol)ÚAnyÚCallableÚ	CoroutineÚMutableMapping)ÚBrokerc                   @  sŠ   e Zd ZU dZded< ded< ded< ddd	d
œdd„Zd ddddœdd„Zddœdddd	dœdd„Zdd	dœdd„Zdddœdd„Z	dS )!ÚSessionz8A session is a single conversation with a single target.ÚstrÚ
session_idÚintÚ
message_idz`MutableMapping[str, tuple[Callable[[protocol.BrowserResponse], Coroutine[Any, Any, Any]], bool]]Úsubscriptionsr	   ÚNone)r   ÚbrokerÚreturnc                 C  s>   t |tƒstdƒ‚|| _|| _t d|› �¡ d| _i | _dS )a,  
        Construct a session from the browser as an object.

        A session is like an open conversation with a target.
        All commands are sent on sessions.

        Args:
            broker:  a reference to the browser's broker
            session_id:  the id given by the browser

        zsession_id must be a stringzNew session: r   N)	Ú
isinstancer   Ú	TypeErrorÚ_brokerr   Ú_loggerÚdebugr   r   )Úselfr   r   © r   úd/var/www/html/bwave/python/venv/lib/python3.8/site-packages/choreographer/protocol/devtools_async.pyÚ__init__$   s    
zSession.__init__NúMutableMapping[str, Any] | Noneúprotocol.BrowserResponse©ÚcommandÚparamsr   c              	   Ã  sš   | j }|  j d7  _ t ||dœ¡}| jr4| j|d< |r@||d< t d|› d|rX| ¡ nd› d| j› d	�¡ t d
t|ƒ 	dd¡› �¡ | j
 |¡I dH S )a/  
        Send a devtools command on the session.

        https://chromedevtools.github.io/devtools-protocol/

        Args:
            command: devtools command to send
            params: the parameters to send

        Returns:
            A message key (session, message id) tuple or None

        é   )ÚidÚmethodÚ	sessionIdr    zCmd 'z', param keys 'Ú z', sessionId 'ú'zFull params: ú%z%%N)r   r   ZBrowserCommandr   r   r   ÚkeysZdebug2r   Úreplacer   Ú
write_json)r   r   r    Z
current_idZjson_commandr   r   r   Úsend_command;   s     þÿ
$ÿzSession.send_commandT©Ú	repeatingú>Callable[[protocol.BrowserResponse], Coroutine[Any, Any, Any]]Úbool©ÚstringÚcallbackr-   r   c                C  s8   t  |¡stdƒ‚|| jkr&tdƒ‚n||f| j|< dS )a6  
        Subscribe to an event on this session.

        Args:
            string: the name of the event. Can use * wildcard at the end.
            callback: the callback (which takes a message dict and returns nothing)
            repeating: default True, should the callback execute more than once

        z/Call back must be be `async def` type function.zSYou are already subscribed to this string, duplicate subscriptions are not allowed.N)ÚinspectÚiscoroutinefunctionr   r   Ú
ValueError)r   r1   r2   r-   r   r   r   Ú	subscribea   s    
ÿ
ÿzSession.subscribe©r1   r   c                 C  s   || j krdS | j |= dS ©zh
        Remove a subscription.

        Args:
            string: the subscription to remove.

        N)r   ©r   r1   r   r   r   Úunsubscribe   s    
zSession.unsubscribeúasyncio.Future[Any]c                 C  s   | j  | j|¡S )a—  
        Return a future for a browser event.

        Generally python asyncio doesn't recommend futures.

        But in this case, one must call subscribe_once and await it later,
        generally because they must subscribe and then provoke the event.

        Args:
            string: the event to subscribe to

        Returns:
            A future to be awaited later, the complete event.

        )r   Znew_subscription_futurer   r9   r   r   r   Úsubscribe_once‹   s    zSession.subscribe_once)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r   r+   r6   r:   r<   r   r   r   r   r
      s   
 ý+ûr
   c                   @  sÌ   e Zd ZU dZded< ded< dddœdd	„Zd
ddœdd„Zdddœdd„Zd
dœdd„Zd,ddddœdd„Z	d
dœdd„Z
dddœdd„Zdd œdd!d"dd#œd$d%„Zddd&œd'd(„Zdd)d&œd*d+„ZdS )-ÚTargetzLA target like a browser, tab, or others. It sends commands. It has sessions.r   Ú	target_idzMutableMapping[str, Session]Úsessionsr	   )rC   r   c                 C  s:   t |tƒstdƒ‚|| _i | _|| _t d|› d�¡ dS )zÉ
        Create a target after one ahs been created by the browser.

        Args:
            broker:  a reference to the browser's broker
            target_id:  the id given by the browser

        ztarget_id must be stringzCreated new target Ú.N)r   r   r   r   rD   rC   r   r   )r   rC   r   r   r   r   r   ¦   s    	
zTarget.__init__r
   r   )Úsessionr   c                 C  s"   t |tƒstdƒ‚|| j|j< d S )Nz$session must be a session type class)r   r
   r   rD   r   ©r   rF   r   r   r   Ú_add_session¹   s    
zTarget._add_session)r   r   c                 C  s"   t |tƒr|j}| j |d ¡}d S )N)r   r
   r   rD   Úpop)r   r   Ú_r   r   r   Ú_remove_session¾   s    
zTarget._remove_session)r   c                 C  s(   | j  ¡ stdƒ‚tt| j  ¡ ƒƒ}|S )z7Retrieve the first session of the target, if it exists.z9Cannot use this method without at least one valid session)rD   ÚvaluesÚRuntimeErrorÚnextÚiterrG   r   r   r   Úget_sessionÃ   s    
ÿzTarget.get_sessionNr   r   r   c                 Ã  s,   | j  ¡ stdƒ‚|  ¡ }| ||¡I dH S )zè
        Send a command to the first session in a target.

        https://chromedevtools.github.io/devtools-protocol/

        Args:
            command: devtools command to send
            params: the parameters to send

        z6Cannot send_command without at least one valid sessionN)rD   rL   rM   rP   r+   )r   r   r    rF   r   r   r   r+   Ì   s    
zTarget.send_commandc                 Ã  s^   | j jjd| jddœd�I dH }d|kr8tdƒt |¡‚|d d	 }t|| j ƒ}|  |¡ |S )
z$Create a new session on this target.zTarget.attachToTargetT)ZtargetIdÚflatten)r    NÚerrorzCould not create sessionÚresultr$   )	r   Ú_browserr+   rC   rM   r   ÚDevtoolsProtocolErrorr
   rH   )r   Úresponser   Znew_sessionr   r   r   Úcreate_sessionà   s     
þÿÿþ
zTarget.create_sessionc                 Ã  sd   t |tƒr|j}| jjjdd|id�I dH }|  |¡ d|krNtdƒt 	|¡‚t
 d|› d�¡ |S )	zm
        Close a session by session_id.

        Args:
            session_id: the session to close

        zTarget.detachFromTargetr$   )r   r    NrR   zCould not close sessionzThe session z has been closed.)r   r
   r   r   rT   r+   rK   rM   r   rU   r   r   )r   r   rV   r   r   r   Úclose_sessionò   s"    
þ
ÿÿþzTarget.close_sessionTr,   r.   r/   r0   c                C  s   |   ¡ }|j|||d� dS )aI  
        Subscribe to an event on the main session of this target.

        Args:
            string: the name of the event. Can use * wildcard at the end.
            callback: the callback (which takes a message dict and returns nothing)
            repeating: default True, should the callback execute more than once

        r,   N)rP   r6   )r   r1   r2   r-   rF   r   r   r   r6     s    zTarget.subscriber7   c                 C  s   |   ¡ }| |¡ dS r8   )rP   r:   ©r   r1   rF   r   r   r   r:   "  s    zTarget.unsubscriber;   c                 C  s   |   ¡ }| |¡S )a¼  
        Return a future for a browser event for the first session of this target.

        Generally python asyncio doesn't recommend futures.

        But in this case, one must call subscribe_once and await it later,
        generally because they must subscribe and then provoke the event.

        Args:
            string: the event to subscribe to

        Returns:
            A future to be awaited later, the complete event.

        )rP   r<   rY   r   r   r   r<   -  s    zTarget.subscribe_once)N)r=   r>   r?   r@   rA   r   rH   rK   rP   r+   rW   rX   r6   r:   r<   r   r   r   r   rB   ž   s   
 ý"ûrB   )r@   Ú
__future__r   r3   Útypingr   ZlogistroZchoreographerr   Zasyncior   r   r   r   Zchoreographer._brokersr	   Ú	getLoggerr=   r   r
   rB   r   r   r   r   Ú<module>   s   
 
