o
    i6                     @  s  d dl m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
mZ d dlmZ d dlmZmZ d dlmZ d dlZd d	lmZm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# ddl$m%Z% ddl&m'Z'm(Z(m)Z) ddl*m+Z+m,Z, ddl-m.Z.m/Z/ zd dl0m1Z1 d dl2m3Z3 ddl4m5Z5 W n e6y   e7dw dBddZ8d ddd d d!dCd/d0Z9ed1d2 Z:G d3d4 d4Z;dDd9d:Z<G d;d< d<e=Z>d=Z?dEd@dAZ@dS )F    )annotationsN)	AwaitableIterable)AbstractContextManagercontextmanager)datetimetimezone)	lru_cache)AnyCallable)WeakKeyDictionary)BackgroundTasksFastAPI)APIRouteAPIWebSocketRouteMount)SecurityScopes)Span)Request)Response)	WebSocket   )ONE_SECOND_IN_NANOSECONDS)LogfireNoopSpanset_user_attributes_on_raw_span)	StackInfoget_code_object_info)handle_internal_errorsmaybe_capture_server_headers)ServerRequestHook)FastAPIInstrumentor   ) tweak_asgi_spans_tracer_providerzThe `logfire.instrument_fastapi()` method requires the `opentelemetry-instrumentation-fastapi` package.
You can install this with:
    pip install 'logfire[fastapi]'appr   returnlist[FastAPI]c                 C  sD   g }| j D ]}t|tr|j}t|tr|| |t|7 }q|S )zGFetch all sub-apps mounted to a FastAPI app, including nested sub-apps.)routes
isinstancer   r$   r   appendfind_mounted_apps)r$   mounted_appsroute_app r.   l/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/logfire/_internal/integrations/fastapi.pyr*   '   s   



r*   F)capture_headersrequest_attributes_mapperexcluded_urlsrecord_send_receiveextra_spanslogfire_instancer   r0   boolr1   MCallable[[Request | WebSocket, dict[str, Any]], dict[str, Any] | None] | Noner2   str | Iterable[str] | Noner3   r4   opentelemetry_kwargsr
   AbstractContextManager[None]c          
        s   t |ttdfsd|}t| t| || j d|}tj	|f|t
|ddd| t |v r<tdt|  |  D ]}t| |pNt|d|< qGt fdd	}	|	 S )
zInstrument a FastAPI app so that spans and logs are automatically created for each request.

    See `Logfire.instrument_fastapi` for more details.
    N,)tracer_providermeter_providerserver_request_hook)r2   r>   z'This app has already been instrumented.)r4   c               
   3  sF    zd V  W  D ]
} | = t |  qd S  D ]
} | = t |  qw N)r!   uninstrument_app)r-   r+   registryr.   r/   uninstrument_contexti   s   z0instrument_fastapi.<locals>.uninstrument_context)r(   strtypejoinr   r#   configget_meter_providerr!   instrument_app_server_request_hookpoppatch_fastapi
ValueErrorr*   r)   FastAPIInstrumentation"_default_request_attributes_mapperr   )
r5   r$   r0   r1   r2   r3   r4   r9   r-   rC   r.   rA   r/   instrument_fastapi3   s<   

rP   c                    sJ   t  dfdd} tjj| tj_d fdd}tjj |tj_S )zlGlobally monkeypatch fastapi functions and return a dictionary for recording instrumentation config per app.requestRequest | WebSocketkwargsr
   r%   c                   s@    dd| i|} | j }r|| |I d H S |I d H S )NrQ   r.   )getr$   solve_dependencies)rQ   rS   originalinstrumentation)original_solve_dependenciesrB   r.   r/   patched_solve_dependencies}   s
   
z1patch_fastapi.<locals>.patched_solve_dependencies	dependantvaluesdict[str, Any]c                   sZ   t |tr |j}|j }r |j || |fi |I d H S  d| |d|I d H S )NrZ   r[   r.   )r(   _InstrumentedValuesrQ   rT   r$   run_endpoint_function)rZ   r[   rS   rQ   rW   )original_run_endpoint_functionrB   r.   r/   patched_run_endpoint_function   s   
z4patch_fastapi.<locals>.patched_run_endpoint_functionN)rQ   rR   rS   r
   r%   r
   )rZ   r
   r[   r\   rS   r
   r%   r
   )r   fastapiroutingrU   r_   )rY   ra   r.   )r`   rX   rB   r/   rL   x   s   	rL   c                   @  s8   e Zd Zd ddZed!ddZd"ddZd#ddZdS )$rN   r5   r   r1   FCallable[[Request | WebSocket, dict[str, Any]], dict[str, Any] | None]r4   r6   c                 C  s,   |j dd| _| jjjj| _|| _|| _d S )Nrb   )custom_scope_suffix)with_settingsr5   rG   advancedns_timestamp_generatortimestamp_generatorr1   r4   )selfr5   r1   r4   r.   r.   r/   __init__   s   
zFastAPIInstrumentation.__init__	namespacerD   	root_spanr   c              
   #  sl    d fdd}|d zzdV  W |d W dS |d w  t y5 } z
j|dd	id
  d}~ww )zJRecord start and end timestamps in the root span, and possibly exceptions.attribute_namerD   c                   s>   t j t tjd}|d}d  d|  | d S )N)tzz%Y-%m-%dT%H:%M:%S.%fZzfastapi..)r   fromtimestampri   r   r   utcstrftimeset_attribute)rn   dtvaluerl   rm   rj   r.   r/   set_timestamp   s   
z9FastAPIInstrumentation.pseudo_span.<locals>.set_timestampstart_timestampNend_timestamprecorded_by_logfire_fastapiT)
attributes)rn   rD   )	Exceptionrecord_exception)rj   rl   rm   rx   excr.   rw   r/   pseudo_span   s   z"FastAPIInstrumentation.pseudo_spanrQ   rR   rV   Awaitable[Any]r%   r
   c              	     sf  |j t}|r| s|I d H S | jr| jdnt 	}t< t	|t
r/|d|j |j d}|rW|d|j d|ji}t	|trM|j|d< t|| || W d    n1 saw   Y  | d| |I d H  W d    n1 s|w   Y  t t	 tr d } d	 }d fdd}	n j} j}d fdd}	dd | D | d}
t	|t
rt|}||_|	| | ||
}
|
s|d  W  d    W  d    S |
dr|d ||
 dD ]}||
v r|
||
d| < qt||
 W d    n1 sw   Y  W d     S W d     S 1 s,w   Y   S )NzFastAPI argumentszhttp.methodr,   
http.routezfastapi.route.namezfastapi.route.operation_id	argumentsr   r"   
new_valuesr\   r%   r
   c                   s   | g dd  R S )Nr"   r.   r   resultr.   r/   solved_with_new_values   s   zIFastAPIInstrumentation.solve_dependencies.<locals>.solved_with_new_valuesc                   s   t j | dS )N)r[   )dataclassesreplacer   r   r.   r/   r      s   c              	   S  s*   i | ]\}}t |tttttfs||qS r.   )r(   r   r   r   r   r   ).0kvr.   r.   r/   
<dictcomp>   s    z=FastAPIInstrumentation.solve_dependencies.<locals>.<dictcomp>)r[   errorsdebugr   warnzfastapi.arguments.)r   r\   r%   r
   )scoperT   LOGFIRE_SPAN_SCOPE_KEYis_recordingr4   r5   spanr   r   r(   r   rt   methodpathnamer   operation_idr   set_attributesr   tupler[   r   itemscopyr^   rQ   r1   	set_levelrK   )rj   rQ   rV   rm   r   r,   fastapi_route_attributessolved_valuessolved_errorsr   r|   instrumented_valueskeyr.   r   r/   rU      sx   










=


 
G
GGz)FastAPIInstrumentation.solve_dependenciesr`   r   rZ   r[   r\   rS   c              	     s  |d||d|}|j t}|r| s|I d H S | jrIt|j}t|dd }	|	r1t	|	ni }
| j
j	d	d|jid|j d ji|
}nt }|+ | d| |I d H W  d    W  d    S 1 slw   Y  W d    d S 1 s|w   Y  d S )
Nr]   __code__'{method} {http.route} ({code.function})r   r   r,   endpoint_functionr.   )r   )r   rT   r   r   r4   inspectunwrapcallgetattrr   r5   r   r   r   r   r   )rj   r`   rQ   rZ   r[   rS   rV   rm   callbackcode
stack_info
extra_spanr.   r.   r/   r_     s,   

Rz,FastAPIInstrumentation.run_endpoint_functionN)r5   r   r1   rd   r4   r6   )rl   rD   rm   r   )rQ   rR   rV   r   r%   r
   )r`   r
   rQ   r   rZ   r
   r[   r\   rS   r
   r%   r
   )__name__
__module____qualname__rk   r   r   rU   r_   r.   r.   r.   r/   rN      s    

NrN   _requestrR   r|   r\   c                 C  s   |S r?   r.   )r   r|   r.   r.   r/   rO   0  s   rO   c                   @  s   e Zd ZU ded< dS )r^   r   rQ   N)r   r   r   __annotations__r.   r.   r.   r/   r^   7  s   
 r^   zlogfire.span	user_hookServerRequestHook | Nonec                   s   d fdd}|S )Nr   r   r   r\   c                   s   | |t <  r | | d S d S r?   )r   )r   r   r   r.   r/   hookA  s   z"_server_request_hook.<locals>.hook)r   r   r   r\   r.   )r   r   r.   r   r/   rJ   >  s   rJ   )r$   r   r%   r&   )r5   r   r$   r   r0   r6   r1   r7   r2   r8   r3   r6   r4   r6   r9   r
   r%   r:   )r   rR   r|   r\   )r   r   )A
__future__r   r   r   collections.abcr   r   
contextlibr   r   r   r   	functoolsr	   typingr
   r   weakrefr   fastapi.routingrb   r   r   r   r   r   fastapi.securityr   opentelemetry.tracer   starlette.requestsr   starlette.responsesr   starlette.websocketsr   	constantsr   mainr   r   r   r   r   r   utilsr   r   "opentelemetry.instrumentation.asgir    %opentelemetry.instrumentation.fastapir!   asgir#   ImportErrorRuntimeErrorr*   rP   rL   rN   rO   dictr^   r   rJ   r.   r.   r.   r/   <module>   sZ    
E
! 
