Ë
    tPêjÕ  ã                  ó8  — U d Z ddlmZ ddlZddlZddlmZ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mZmZ dd
lmZ ddlmZ ddlmZmZmZmZ dZded<    eddi«      Zded<    e
dd¬«       G d„ d«      «       Z dd„Z!dd„Z" G d„ d«      Z#dd„Z$d d„Z%y)!aÍ  ASGI app for `/metrics` that keeps registry rendering off the event loop.

``prometheus_client.make_asgi_app`` collects and serializes the whole registry
inline in the coroutine, so a large scrape (tens of MB on high cardinality
deployments) blocks every other request on the loop for its whole duration. This
app renders in a worker thread instead, shares one render across concurrent
scrapes that want the same output, and streams the payload back in chunks.
é    )ÚannotationsN)ÚCallableÚIteratorÚMapping)Ú	dataclass)ÚMappingProxyType)ÚFinal)ÚCollectorRegistry)Úchoose_encoderÚgzip_accepted)ÚRequest)ÚStreamingResponse)ÚASGIAppÚReceiveÚScopeÚSendi   r	   ÚRESPONSE_CHUNK_SIZE_BYTESzContent-EncodingÚgzipÚ_GZIP_HEADERST)ÚfrozenÚslotsc                  ó:   — e Zd ZU dZded<   ded<   ded<   ded	<   y
)ÚScrapeRequestz]What a scrape asks for, normalized so that header spellings sharing an output share a render.z$Callable[[CollectorRegistry], bytes]ÚencoderÚstrÚcontent_typeÚboolÚgzippedútuple[str, ...]Úmetric_namesN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__© ó    úu/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/integrations/prometheus_metrics_endpoint.pyr   r      s   … ágà1Ó1ØÓØƒMØ!Ô!r'   r   c                óN   — t        | «      \  }}t        ||t        |«      |¬«      S )N)r   r   r   r    )r   r   r   )ÚacceptÚaccept_encodingr    r   r   s        r(   Úparse_scrape_requestr,   (   s/   € Ü*¨6Ó2Ñ€Gˆ\ÜØØ!Ü˜oÓ.Ø!ô	ð r'   c                ó¸   — |j                  |j                  r| j                  |j                  «      n| «      }|j                  rt	        j
                  |«      S |S ©N)r   r    Úrestricted_registryr   r   Úcompress)ÚregistryÚrequestÚrendereds      r(   Úrender_scraper4   2   sK   € Ø—o‘oØ>E×>RÒ>Rˆ×$Ñ$ W×%9Ñ%9Ô:ÐX`ó€Hð '.§o¢oŒ4�=‰=˜Ó"ÐC¸8ÐCr'   c                  ó(   — e Zd ZdZdd„Zdd„Zdd„Zy)	ÚCoalescedScrapeRendererzjRenders the registry in a worker thread, sharing one render per distinct output across concurrent scrapes.c                ó2   — || _         t        i «      | _        y r.   )Ú	_registryr   Ú	_inflight)Úselfr1   s     r(   Ú__init__z CoalescedScrapeRenderer.__init__<   s   € Ø!ˆŒÜFVÐWYÓFZˆ�r'   c                ó’   — t        | j                  j                  «       D ��ci c]  \  }}||usŒ||“Œ c}}«      | _        y c c}}w r.   )r   r9   Úitems)r:   ÚfinishedÚkeyÚtasks       r(   Ú_forgetzCoalescedScrapeRenderer._forget@   s:   € Ü)ÀdÇnÁn×FZÑFZÓF\×*u¹¸¸dÐ`dÐltÒ`t¨3°©9Ó*uÓvˆ�ùÓ*us
   £A
°A
c              ƒ  ó¦  K  — | j                   j                  |«      }|�t        j                  |«      ƒ d {  –—† S t        j                  t        j
                  t        | j                  |«      «      }t        i | j                   ¥||i¥«      | _         |j                  | j                  «       t        j                  |«      ƒ d {  –—† S 7 Œ”7 Œ­wr.   )r9   ÚgetÚasyncioÚshieldÚcreate_taskÚ	to_threadr4   r8   r   Úadd_done_callbackrA   )r:   r2   Úinflightr@   s       r(   ÚrenderzCoalescedScrapeRenderer.renderC   s¢   è ø€ ØŸ.™.×,Ñ,¨WÓ5ˆØÐÜ Ÿ™¨Ó1×1Ð1ä×)Ñ)¬'×*;Ñ*;¼MÈ4Ï>É>Ð[bÓ*cÓdˆÜ)Ð*K¨T¯^©^Ð*K¸WÀdÑ*KÓLˆŒØ×Ñ˜tŸ|™|Ô,Ü—^‘^ DÓ)×)Ð)ð 2øð
 *ús"   ‚6C¸C¹BCÃCÃ	CÃCN)r1   r
   ÚreturnÚNone)r>   zasyncio.Task[bytes]rK   rL   )r2   r   rK   Úbytes)r!   r"   r#   r$   r;   rA   rJ   r&   r'   r(   r6   r6   9   s   „ Ùtó[ówô*r'   r6   c                óJ   ‡ — ˆ fd„t        dt        ‰ «      t        «      D «       S )Nc              3  ó6   •K  — | ]  }‰||t         z    –— Œ y ­wr.   )r   )Ú.0ÚstartÚbodys     €r(   ú	<genexpr>z_chunks.<locals>.<genexpr>O   s   øè ø€ ÒxÀˆD�˜Ô!:Ñ:Ô;Ñxùs   ƒr   )ÚrangeÚlenr   )rR   s   `r(   Ú_chunksrV   N   s   ø€ ÛxÌÈqÔRUÐVZÓR[Ô]vÓIwÔxÐxr'   c                ó*   ‡— t        | «      Šdˆfd„}|S )Nc           	   “  ó²  •K  — t        | |«      }t        |j                  j                  dd«      |j                  j                  dd«      t	        |j
                  j                  d«      «      ¬«      }‰j                  |«      ƒ d {  –—† }t        t        |«      |j                  |j                  rt        nd ¬«      } || ||«      ƒ d {  –—†  y 7 ŒJ7 Œ­w)Nr*   Ú zaccept-encodingzname[])r*   r+   r    )Ú
media_typeÚheaders)r   r,   r[   rC   ÚtupleÚquery_paramsÚgetlistrJ   r   rV   r   r   r   )ÚscopeÚreceiveÚsendr2   ÚscraperR   ÚresponseÚrenderers          €r(   Úmetrics_appz*make_metrics_asgi_app.<locals>.metrics_appU   s¶   øè ø€ Ü  ¨Ó0ˆÜ,Ø—?‘?×&Ñ& x°Ó4Ø#ŸO™O×/Ñ/Ð0AÀ2ÓFÜ˜w×3Ñ3×;Ñ;¸HÓEÓFô
ˆð
 %ŸO™O¨FÓ3×3ˆÜ+Ü�D‹MØ×*Ñ*Ø%+§^¢^•M¸ô
ˆñ
 �u˜g tÓ,×,Ñ,ð 4øð 	-ús%   ƒBCÂCÂ	ACÃCÃCÃC)r_   r   r`   r   ra   r   rK   rL   )r6   )r1   re   rd   s     @r(   Úmake_metrics_asgi_apprf   R   s   ø€ Ü-¨hÓ7€Hõ-ð Ðr'   )r*   r   r+   r   r    r   rK   r   )r1   r
   r2   r   rK   rM   )rR   rM   rK   zIterator[bytes])r1   r
   rK   r   )&r$   Ú
__future__r   rD   r   Úcollections.abcr   r   r   Údataclassesr   Útypesr   Útypingr	   Úprometheus_clientr
   Úprometheus_client.expositionr   r   Ústarlette.requestsr   Ústarlette.responsesr   Ústarlette.typesr   r   r   r   r   r%   r   r   r,   r4   r6   rV   rf   r&   r'   r(   ú<module>rq      s–   ðòõ #ã Û ß 7Ñ 7Ý !Ý "Ý å /ß FÝ &Ý 1ß 9Ó 9à#,Ð ˜5Ó ,á'Ð);¸VÐ(DÓE€ˆuÓ Eñ �$˜dÔ#÷"ð "ó $ð"óóD÷*ñ *ó*yôr'   