+
    QV-j—=  ã                   ó„  a € R t"0 t R t^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RI	H
t
HtHt ^RIHtHtHt ]
'       d   ^ RIt^ RIHt ]! 4       '       d   ^ RIHtHt ^ RIHt MR;t;ttRs] ^ k ]P2                  P5                  R	4      RJ t] ! R
 R4      4       t]RR R ll4       tR R ltR R ltR R lt R R lt!R# )zSContains `WebhooksServer` and `webhook_endpoint` to create a webhook server easily.N©ÚCallable)Úwraps)ÚTYPE_CHECKINGÚAnyÚOptional)ÚexperimentalÚis_fastapi_availableÚis_gradio_available©ÚRequest)ÚFastAPIr   )ÚJSONResponseÚSPACE_IDc                   ó–   a a€ ] tR t^*t oRtV3R lV 3R lltRV3R lR lltRV3R lR lltRV3R lR	 lltV3R
 lR lt	Rt
VtV ;t# )ÚWebhooksServera•  
The [`WebhooksServer`] class lets you create an instance of a Gradio app that can receive Huggingface webhooks.
These webhooks can be registered using the [`~WebhooksServer.add_webhook`] decorator. Webhook endpoints are added to
the app as a POST endpoint to the FastAPI router. Once all the webhooks are registered, the `launch` method has to be
called to start the app.

It is recommended to accept [`WebhookPayload`] as the first argument of the webhook function. It is a Pydantic
model that contains all the information about the webhook event. The data will be parsed automatically for you.

Check out the [webhooks guide](../guides/webhooks_server) for a step-by-step tutorial on how to set up your
WebhooksServer and deploy it on a Space.

> [!WARNING]
> `WebhooksServer` is experimental. Its API is subject to change in the future.

> [!WARNING]
> You must have `gradio` installed to use `WebhooksServer` (`pip install --upgrade gradio`).

Args:
    ui (`gradio.Blocks`, optional):
        A Gradio UI instance to be used as the Space landing page. If `None`, a UI displaying instructions
        about the configured webhooks is created.
    webhook_secret (`str`, optional):
        A secret key to verify incoming webhook requests. You can set this value to any secret you want as long as
        you also configure it in your [webhooks settings panel](https://huggingface.co/settings/webhooks). You
        can also set this value as the `WEBHOOK_SECRET` environment variable. If no secret is provided, the
        webhook endpoints are opened without any security.

Example:

    ```python
    import gradio as gr
    from huggingface_hub import WebhooksServer, WebhookPayload

    with gr.Blocks() as ui:
        ...

    app = WebhooksServer(ui=ui, webhook_secret="my_secret_key")

    @app.add_webhook("/say_hello")
    async def hello(payload: WebhookPayload):
        return {"message": "hello"}

    app.launch()
    ```
c                ó   <€ V ^8„  d   QhRR/# )é   Úreturnr   © )ÚformatÚ__classdict__s   "€Úq/Volumes/fast/ai/experiments/ui-tars-smoke/.venv/lib/python3.14/site-packages/huggingface_hub/_webhooks_server.pyÚ__annotate__ÚWebhooksServer.__annotate__[   s   ø€ ÷ $ñ $Ð)9ñ $ó    c                óŽ   <€ \        4       '       g   \        R 4      h\        4       '       g   \        R4      h\        SV `  V 4      # )zjYou must have `gradio` installed to use `WebhooksServer`. Please run `pip install --upgrade gradio` first.zlYou must have `fastapi` installed to use `WebhooksServer`. Please run `pip install --upgrade fastapi` first.)r
   ÚImportErrorr	   ÚsuperÚ__new__)ÚclsÚargsÚkwargsÚ	__class__s   &*,€r   r   ÚWebhooksServer.__new__[   sL   ø€ Ü"×$Ò$Üðóð ô $×%Ò%Üðóð ô ‰w‰˜sÓ#Ð#r   c                óF   <€ V ^8„  d   QhRS[ R,          RS[R,          RR/# )r   Úuiú	gr.BlocksÚwebhook_secretNr   )r   Ústr)r   r   s   "€r   r   r   h   s2   ø€ ÷ 	3ñ 	3á�[Õ!ð	3ñ ˜d�
ð	3ð 
ñ		3r   c                ó”   € Wn         T;'       g    \        P                  ! R 4      V n        / V n        \        V P                  4       R# )ÚWEBHOOK_SECRETN)Ú_uiÚosÚgetenvr(   Úregistered_webhooksÚ_warn_on_empty_secret)Úselfr&   r(   s   &&&r   Ú__init__ÚWebhooksServer.__init__h   s9   € ð
 Œà,×KÐK´·	²	Ð:JÓ0KˆÔØ8:ˆÔ Ü˜d×1Ñ1Ö2r   c                ó4   <€ V ^8„  d   QhRS[ R,          RS[/# ©r   ÚpathNr   ©r)   r   )r   r   s   "€r   r   r   s   s   ø€ ÷ )ñ )¡ d¥
ð )±hñ )r   c                óž   a a€ \        S4      '       d   S P                  4       ! S4      # \        \        P                  4      VV 3R l4       pV# )aà  
Decorator to add a webhook to the [`WebhooksServer`] server.

Args:
    path (`str`, optional):
        The URL path to register the webhook function. If not provided, the function name will be used as the
        path. In any case, all webhooks are registered under `/webhooks`.

Raises:
    ValueError: If the provided path is already registered as a webhook.

Example:
    ```python
    from huggingface_hub import WebhooksServer, WebhookPayload

    app = WebhooksServer()

    @app.add_webhook
    async def trigger_training(payload: WebhookPayload):
        if payload.repo.type == "dataset" and payload.event.action == "update":
            # Trigger a training job if a dataset is updated
            ...

    app.launch()
```
c                  óÈ   <€ V ^ ,          pRS;'       g    VP                   P                  R4       2pVSP                  9   d   \        RV R24      hVSP                  V&   R# )é    z
/webhooks/Ú/zWebhook z already exists.N)Ú__name__Ústripr/   Ú
ValueError)r!   r"   ÚfuncÚabs_pathr6   r1   s   *,  €€r   Ú_inner_postÚ/WebhooksServer.add_webhook.<locals>._inner_post”   sc   ø€ à˜•7ˆDØ# T×%:Ð%:¨T¯]©]×$AÑ$AÀ#Ó$FÐ#GÐHˆHØ˜4×3Ñ3Ô3Ü  8¨H¨:Ð5EÐ!FÓGÐGØ15ˆD×$Ñ$ XÓ.r   )ÚcallableÚadd_webhookr   r   Úpost)r1   r6   rA   s   ff r   rD   ÚWebhooksServer.add_webhooks   sG   ù€ ô8 �D�>Š>à×#Ñ#Ô% dÓ+Ð+ô 
Œw�|‰|Ó	õ	6ó 
ð	6ð Ðr   c                ó*   <€ V ^8„  d   QhRS[ RS[RR/# )r   Úprevent_thread_lockÚlaunch_kwargsr   N)Úboolr   )r   r   s   "€r   r   r   ž   s#   ø€ ÷ "ñ "©$ð "Éð "ÐQUñ "r   c                ó$  a	€ V P                   ;'       g    V P                  4       pVP                  R\        4       VP                  ! RRR/VB w  V n         pV P                  P                  4        FJ  w  rVV P                  e   \        W`P                  R7      pV P
                  P                  V4      ! V4       KL  	  \        P                  P                  R4      pVe
   RV,           MVP                  ;'       g    VP                  o	S	f   \!        R4      hS	P#                  R	4      o	R
pVRRP%                  V	3R lV P                   4       4      ,           ,          pVR,          p\'        V4       V'       g   VP)                  4        R# R# )z�Launch the Gradio app and register webhooks to the underlying FastAPI server.

Input parameters are forwarded to Gradio when launching the app.
ÚsharerH   TN©r(   Ú
SPACE_HOSTzhttps://zWCannot find the URL of the app. Please provide a valid `ui` or update `gradio` version.r;   z/
Webhooks are correctly setup and ready to use:Ú
c              3   ó2   <"  € T F  pR S V 2x € K  	  R# 5i)z	  - POST Nr   )Ú.0ÚwebhookÚurls   & €r   Ú	<genexpr>Ú(WebhooksServer.launch.<locals>.<genexpr>»   s   øé € Ð#gÑNfÀ7 i°¨u°W°IÕ$>ÓNfùs   ƒzG
Go to https://huggingface.co/settings/webhooks to setup your webhooks.r   )r,   Ú_get_default_uiÚ
setdefaultÚ	_is_localÚlaunchÚfastapi_appr/   Úitemsr(   Ú_wrap_webhook_to_check_secretrE   r-   ÚenvironÚgetÚ	share_urlÚ	local_urlr>   r=   ÚjoinÚprintÚblock_thread)
r1   rH   rI   r&   Ú_r6   r?   Ú
space_hostÚmessagerS   s
   &&,      @r   rY   ÚWebhooksServer.launchž   sH  ø€ ð
 �X‰X×/Ð/˜×-Ñ-Ó/ˆð
 	× Ñ  ¬)Ô4Ø!#§¢Ñ!U¸tÐ!UÀ}Ñ!UÑˆÔ˜!˜Qð ×2Ñ2×8Ñ8Ö:‰JˆDà×"Ñ"Ò.Ü4°T×J]ÑJ]Ô^�ð ×Ñ×!Ñ! $Ô'¨Ö-ñ ;ô —Z‘Z—^‘^ LÓ1ˆ
Ø)3Ò)?ˆj˜:Ö%ÀbÇlÁl×FbÐFbÐVX×VbÑVbˆØŠ;ÜÐvÓwÐwØ�i‰i˜‹nˆØDˆØ�4˜$Ÿ)™)Ô#gÈd×NfÒNfÓ#gÓgÕgÕgˆØÐ]Õ]ˆÜˆgŒç"Ø�O‰OÖñ #r   c                ó   <€ V ^8„  d   QhRR/# )r   r   r'   r   )r   r   s   "€r   r   r   Â   s   ø€ ÷ ñ  ñ r   c           
     óÊ  € ^ RI pVP                  ! 4       ;_uu_ 4       pVP                  ! R4       VP                  ! R4       VP                  ! \        V P                  4       R2R,           RP                  R V P                  P                  4        4       4      ,           4       VP                  ! \        '       d   R	MR4       RRR4       V#   + '       g   i     X# ; i)
zLDefault UI if not provided (lists webhooks and provides basic instructions).Nu)   # This is an app to process ðŸ¤— WebhooksaT  Webhooks are a foundation for MLOps-related features. They allow you to listen for new changes on specific repos or to all repos belonging to particular set of users/organizations (not just your repos, but any repo). Check out this [guide](https://huggingface.co/docs/hub/webhooks) to get to know more about webhooks on the Huggingface Hub.z webhook(s) are registered:z

z
 c              3   ó`   "  € T F$  w  rR V R\        VP                  V4       R2x € K&  	  R# 5i)z- [z](Ú)N)Ú_get_webhook_doc_urlr<   )rQ   Úwebhook_pathrR   s   &  r   rT   Ú1WebhooksServer._get_default_ui.<locals>.<genexpr>Ñ   s:   é € ð á1QÑ-˜ð ˜,˜ rÔ*>¸w×?OÑ?OÐQ]Ó*^Ð)_Ð_`ÕaÛ1Qùs   ‚,.z¶
This app is running on a Space. You can find the corresponding URL in the options menu (top-right) > 'Embed the Space'. The URL looks like 'https://{username}-{repo_name}.hf.space'.z¡Go to https://huggingface.co/settings/webhooks to setup your webhooks.
You app is running locally. Please look at the logs to check the full URL you need to set.)ÚgradioÚBlocksÚMarkdownÚlenr/   ra   r[   rX   )r1   Úgrr&   s   &  r   rV   ÚWebhooksServer._get_default_uiÂ   sÇ   € ãà�YŠY�[Œ[˜BØ�KŠKÐCÔDØ�KŠKðDôð �KŠKÜ�t×/Ñ/Ó0Ð1Ð1LÐMØõà—*‘*ñ à15×1IÑ1I×1OÑ1OÔ1Qóó õôð �KŠK÷ “9ñqðvô÷! ð2 ˆ	÷3 Ž[ð2 ˆ	ús   žB)CÃC"	)r,   rZ   r/   r(   )NN©N)F)r<   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r2   rD   rY   rV   Ú__static_attributes__Ú__classdictcell__Ú__classcell__)r#   r   s   @@r   r   r   *   sD   ù‡ € ñ-÷^$ó $÷	3ò 	3÷)ò )÷V"ò "÷H÷ ð r   r   c                ó>   € V ^8„  d   QhR\         R,          R\        /# r5   r7   )r   s   "r   r   r   ã   s"   € ÷ Jñ Jœ3 �:ð J´ñ Jr   c                ó”   a € \        S 4      '       d   \        4       ! S 4      # \        \        P                  4      R V 3R ll4       pV# )a  Decorator to start a [`WebhooksServer`] and register the decorated function as a webhook endpoint.

This is a helper to get started quickly. If you need more flexibility (custom landing page or webhook secret),
you can use [`WebhooksServer`] directly. You can register multiple webhook endpoints (to the same server) by using
this decorator multiple times.

Check out the [webhooks guide](../guides/webhooks_server) for a step-by-step tutorial on how to set up your
server and deploy it on a Space.

> [!WARNING]
> `webhook_endpoint` is experimental. Its API is subject to change in the future.

> [!WARNING]
> You must have `gradio` installed to use `webhook_endpoint` (`pip install --upgrade gradio`).

Args:
    path (`str`, optional):
        The URL path to register the webhook function. If not provided, the function name will be used as the path.
        In any case, all webhooks are registered under `/webhooks`.

Examples:
    The default usage is to register a function as a webhook endpoint. The function name will be used as the path.
    The server will be started automatically at exit (i.e. at the end of the script).

    ```python
    from huggingface_hub import webhook_endpoint, WebhookPayload

    @webhook_endpoint
    async def trigger_training(payload: WebhookPayload):
        if payload.repo.type == "dataset" and payload.event.action == "update":
            # Trigger a training job if a dataset is updated
            ...

    # Server is automatically started at the end of the script.
    ```

    Advanced usage: register a function as a webhook endpoint and start the server manually. This is useful if you
    are running it in a notebook.

    ```python
    from huggingface_hub import webhook_endpoint, WebhookPayload

    @webhook_endpoint
    async def trigger_training(payload: WebhookPayload):
        if payload.repo.type == "dataset" and payload.event.action == "update":
            # Trigger a training job if a dataset is updated
            ...

    # Start the server manually
    trigger_training.launch()
    ```
c                ó0   € V ^8„  d   QhR\         R\         /# )r   r?   r   r   )r   s   "r   r   Ú&webhook_endpoint.<locals>.__annotate__  s   € ÷ ñ ”Xð ¤(ñ r   c                 ó  <a€ \        4       oSP                  S4      ! V 4       \        SP                  4      ^8X  d!   \        P
                  ! SP                  4       \        SP                  4      V3R l4       pWn        V # )é   c                  óh   <€ \         P                  ! S P                  4       S P                  4        R # ru   )ÚatexitÚ
unregisterrY   )Úapps   €r   Ú_launch_nowÚ5webhook_endpoint.<locals>._inner.<locals>._launch_now$  s    ø€ ô ×Ò˜cŸj™jÔ)Ø�J‰JŽLr   )Ú_get_global_apprD   rr   r/   r„   ÚregisterrY   r   )r?   r‡   r†   r6   s   & @€r   Ú_innerÚ webhook_endpoint.<locals>._inner  sf   ù€ äÓˆØ�‰˜Ô˜dÔ#Üˆs×&Ñ&Ó'¨1Ô,ä�OŠO˜CŸJ™JÔ'ä	ˆs�z‰zÓ	ô	ó 
ð	ð
 "ŒØˆr   )rC   Úwebhook_endpointr   r   rD   )r6   r‹   s   f r   r�   r�   â   sA   ø€ ôl �‡~‚~äÔ! $Ó'Ð'ä
Œ>×%Ñ%Ó&÷ó 'ðð  €Mr   c                ó$   € V ^8„  d   QhR\         /# )r   r   )r   )r   s   "r   r   r   0  s   € ÷ ñ œñ r   c                  ó2   € \         f   \        4       s \         # ru   )Ú_global_appr   r   r   r   r‰   r‰   0  s   € äÒÜ$Ó&ˆÜÐr   c                ó6   € V ^8„  d   QhR\         R,          RR/# )r   r(   Nr   ©r)   )r   s   "r   r   r   7  s   € ÷ 6ñ 6¬#°­*ð 6¸ñ 6r   c                 ój   € V f$   \        R4       \        R4       \        R4       R # \        R4       R # )NzZWebhook secret is not defined. This means your webhook endpoints will be open to everyone.z•To add a secret, set `WEBHOOK_SECRET` as environment variable or pass it at initialization: 
	`app = WebhooksServer(webhook_secret='my_secret', ...)`zpFor more details about webhook secrets, please refer to https://huggingface.co/docs/hub/webhooks#webhook-secret.z$Webhook secret is correctly defined.)rb   rM   s   &r   r0   r0   7  s:   € ØÒÜÐjÔkÜðJô	
ô 	ðHö	
ô
 	Ð4Ö5r   c                ó<   € V ^8„  d   QhR\         R\         R\         /# )r   Úwebhook_namerm   r   r’   )r   s   "r   r   r   F  s&   € ÷ Wñ W¤sð W¼#ð WÄ#ñ Wr   c                óP   € RV ,           VP                  RR4      ,           R,           # )z@Returns the anchor to a given webhook in the docs (experimental)z/docs#/default/r;   rd   Ú_post)Úreplace)r•   rm   s   &&r   rl   rl   F  s$   € à˜|Õ+¨l×.BÑ.BÀ3ÈÓ.LÕLÈwÕVÐVr   c                ó<   € V ^8„  d   QhR\         R\        R\         /# )r   r?   r(   r   )r   r)   )r   s   "r   r   r   K  s!   € ÷ -ñ -¬ð -Ä#ð -Ì(ñ -r   c                ór  a aa€ \         P                  ! S 4      o\        S 4      R V VV3R ll4       pRSP                  9  dt   SP	                  \         P
                  ! R\         P
                  P                  \        R7      3\        SP                  P                  4       4      ,           R7      Vn
        V# )aŠ  Wraps a webhook function to check the webhook secret before calling the function.

This is a hacky way to add the `request` parameter to the function signature. Since FastAPI based itself on route
parameters to inject the values to the function, we need to hack the function signature to retrieve the `Request`
object (and hence the headers). A far cleaner solution would be to use a middleware. However, since
`fastapi==0.90.1`, a middleware cannot be added once the app has started. And since the FastAPI app is started by
Gradio internals (and not by us), we cannot add a middleware.

This method is called only when a secret has been defined by the user. If a request is sent without the
"x-webhook-secret", the function will return a 401 error (unauthorized). If the header is sent but is incorrect,
the function will return a 403 error (forbidden).

Inspired by https://stackoverflow.com/a/33112180.
c                ó$   € V ^8„  d   QhR\         /# )r   Úrequestr   )r   s   "r   r   Ú3_wrap_webhook_to_check_secret.<locals>.__annotate__]  s   € ÷ "ñ "¤wñ "r   c              ›   ó*  <"  € V P                   P                  R 4      pVf   \        RR/RR7      # VS8w  d   \        RR/RR7      # RSP                  9   d   WR&   \        P
                  ! S4      '       d   S! R	/ VB G Rj  x€L
 # S! R	/ VB #  L5i)
zx-webhook-secretNÚerrorz x-webhook-secret header not set.i‘  )Ústatus_codezInvalid webhook secret.i“  rœ   r   )Úheadersr^   r   Ú
parametersÚinspectÚiscoroutinefunction)rœ   r"   Úrequest_secretr?   Úinitial_sigr(   s   &, €€€r   Ú_protected_funcÚ6_wrap_webhook_to_check_secret.<locals>._protected_func\  sœ   øé € à Ÿ™×,Ñ,Ð-?Ó@ˆØÒ!Ü Ð*LÐ MÐ[^Ô_Ð_Ø˜^Ô+Ü Ð*CÐ DÐRUÔVÐVð ˜×.Ñ.Ô.Ø '�9Ñô ×&Ò& t×,Ò,Ù™ ™×'Ð'á‘>˜&‘>Ð!ñ (ùs   ƒA5BÁ9BÂBÂBrœ   )ÚnameÚkindÚ
annotation)r¢   )r£   Ú	signaturer   r¢   r˜   Ú	ParameterÚPOSITIONAL_OR_KEYWORDr   ÚtupleÚvaluesÚ__signature__)r?   r(   r§   r¦   s   ff @r   r\   r\   K  s¢   ú€ ô ×#Ò# DÓ)€Kä
ˆ4ƒ[÷"ñ "ó ð"ð$ ˜×.Ñ.Ô.Ø(3×(;Ñ(;ä×!Ò! y´w×7HÑ7H×7^Ñ7^ÔkrÔsðô �K×*Ñ*×1Ñ1Ó3Ó4õ5ð )<ó )
ˆÔ%ð Ðr   c                óN   € V ^8„  d   Qh/ ^ \         9   d   \        R,          ;R&   # )r   r   r�   )Ú__conditional_annotations__r   )r   s   "r   r   r      s!   € × YÑ Y÷0 /Ò .ŒXÐ&Õ'Ñ .ò1 Zr   ru   )#r³   ry   r„   r£   r-   Úcollections.abcr   Ú	functoolsr   Útypingr   r   r   Úutilsr   r	   r
   ro   rs   Úfastapir   r   Úfastapi.responsesr   r�   r]   r^   rX   r   r�   r‰   r0   rl   r\   r   )r³   s   @r   Ú<module>rº      s¼   øðö Zã Û Û 	Ý $Ý ß /Ñ /ç JÑ J÷ ÛÝá×Òß(Þ.ð (,Ð+€GÐ+ˆg˜ð +/€Ó .Ø�J‰J�N‰N˜:Ó&¨$Ð.€	ð ÷tð tó ðtðn öJó ðJõZõ6õW÷
-r   