o
    i                     @  s   d 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 ddlmZmZmZ ddlmZ dd	lZdd
lmZ eeef ZdZd ddZedd	dd!ddZe	G dd deZG dd deZe	G dd deZd	S )"a  This module provides a thin wrapper around the OpenTelemetry propagate API to allow
the OpenTelemetry contexts (and therefore Logfire contexts) to be transferred between
different code running in different threads, processes or even services.

In general, you should not need to use this module since Logfire will automatically
patch [`ThreadPoolExecutor`][concurrent.futures.ThreadPoolExecutor] and
[`ProcessPoolExecutor`][concurrent.futures.ProcessPoolExecutor] to carry over the context.
And existing plugins exist to propagate the context with
[requests](https://pypi.org/project/opentelemetry-instrumentation-requests/) and
[httpx](https://pypi.org/project/opentelemetry-instrumentation-httpx/).
    )annotations)IteratorMapping)contextmanager)	dataclass)Any)context	propagatetrace)TextMapPropagatorN)warn_at_user_stacklevel)get_contextattach_contextContextCarrierreturnr   c                  C  s   i } t |  | S )a<  Create a new empty carrier dict and inject context into it.

    Returns:
        A new dict with the context injected into it.

    Usage:

    ```py
    import logfire

    logfire_context = logfire.get_context()

    ...

    # later on in another thread, process or service
    with logfire.attach_context(logfire_context):
        ...
    ```

    You could also inject context into an existing mapping like headers with:

    ```py
    import logfire

    existing_headers = {'X-Foobar': 'baz'}
    existing_headers.update(logfire.get_context())
    ...
    ```
    )r	   injectcarrier r   W/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/logfire/propagate.pyr       s   
r   F)third_party
propagatorr   r   boolr   TextMapPropagator | NoneIterator[None]c             	   c  s    t  }|du r t }|s t|ttfr |j}t|ttfs|s$J |j| d}zt 	| dV  W t 	| dS t 	| w )a  Attach a context as generated by [`get_context`][logfire.propagate.get_context] to the current execution context.

    Since `attach_context` is a context manager, it restores the previous context when exiting.

    Set `third_party` to `True` if using this inside a library intended to be used by others.
    This will respect the [`distributed_tracing` argument of `logfire.configure()`][logfire.configure(distributed_tracing)],
    so users will be warned about unintentional distributed tracing by default and they can suppress it.
    See [Unintentional Distributed Tracing](https://logfire.pydantic.dev/docs/how-to-guides/distributed-tracing/#unintentional-distributed-tracing) for more information.
    Nr   )
otel_contextget_currentr	   get_global_textmap
isinstance#WarnOnExtractTraceContextPropagatorNoExtractTraceContextPropagatorwrappedextractattach)r   r   r   old_contextnew_contextr   r   r   r   C   s   
r   c                   @  s:   e Zd ZU dZded< dd	d
ZdddZedd ZdS )WrapperPropagatorz-Helper base class to wrap another propagator.r   r!   argsr   kwargsr   otel_context.Contextc                 O     | j j|i |S N)r!   r"   selfr'   r(   r   r   r   r"   i      zWrapperPropagator.extractc                 O  r*   r+   )r!   r   r,   r   r   r   r   l   r.   zWrapperPropagator.injectc                 C  s   | j jS r+   )r!   fields)r-   r   r   r   r/   o   s   zWrapperPropagator.fieldsN)r'   r   r(   r   r   r)   )r'   r   r(   r   )	__name__
__module____qualname____doc____annotations__r"   r   propertyr/   r   r   r   r   r&   c   s   
 

r&   c                      s&   e Zd ZdZ	dd fddZ  ZS )r    zA propagator that ignores any trace context that was extracted by the wrapped propagator.

    Used when `logfire.configure(distributed_tracing=False)` is called.
    Nr   r   r   otel_context.Context | Noner'   r(   r   r)   c                   s:   t  j||g|R i |}||kr|S tt||S r+   )superr"   r
   set_span_in_contextget_current_span)r-   r   r   r'   r(   result	__class__r   r   r"   z   s   z'NoExtractTraceContextPropagator.extractr+   
r   r   r   r6   r'   r   r(   r   r   r)   )r0   r1   r2   r3   r"   __classcell__r   r   r;   r   r    t   s    r    c                      s4   e Zd ZU dZdZded< 	dd fddZ  ZS )r   zA propagator that warns the first time that trace context is extracted by the wrapped propagator.

    Used when `logfire.configure(distributed_tracing=None)` is called. This is the default behavior.
    Fr   warnedNr   r   r   r6   r'   r(   r   r)   c                   s`   t  j||g|R i |}| js.||kr.t|t|kr.d| _d}t|t t| |S )NTzFound propagated trace context. See https://logfire.pydantic.dev/docs/how-to-guides/distributed-tracing/#unintentional-distributed-tracing.)	r7   r"   r?   r
   r9   r   RuntimeWarninglogfirewarn)r-   r   r   r'   r(   r:   messager;   r   r   r"      s   "

z+WarnOnExtractTraceContextPropagator.extractr+   r=   )r0   r1   r2   r3   r?   r4   r"   r>   r   r   r;   r   r      s
   
 r   )r   r   )r   r   r   r   r   r   r   r   )r3   
__future__r   collections.abcr   r   
contextlibr   dataclassesr   typingr   opentelemetryr   r   r	   r
   !opentelemetry.propagators.textmapr   rA   logfire._internal.stack_infor   strr   __all__r   r   r&   r    r   r   r   r   r   <module>   s,    
#