
    4Rj}                       U d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
mZmZmZ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mZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z, dd	l-m.Z.  ej^                  e0      Z1d
e2d<   e
rddl3m4Z4 g dZ5ddZ6dZ7dZ8dZ9dZ:dZ;ddZ< G d d      Z= G d d      Z> G d d      Z? G d d      Z@ G d de?      ZAy)     )annotationsN)TYPE_CHECKINGAnyDictUnionOptionalcast)override   )AccessTokenIdentityTokenProvider)	ENV_SCOPEENV_PROFILEENV_BASE_URLENV_AUTH_TOKENENV_CONFIG_DIRTOKEN_ENDPOINTDEFAULT_BASE_URLENV_WORKSPACE_IDENV_ORGANIZATION_IDOAUTH_API_BETA_HEADERENV_FEDERATION_RULE_IDENV_SERVICE_ACCOUNT_IDTOKEN_EXCHANGE_TIMEOUTENV_IDENTITY_TOKEN_FILEGRANT_TYPE_REFRESH_TOKENMANDATORY_REFRESH_SECONDS_user_agent_require_https_active_profile_config_file_path_credentials_file_pathresolve_identity_token_path   )AnthropicErrorzlogging.Loggerlog)WorkloadIdentityCredentials)StaticTokenEnvTokenCredentialsFileInMemoryConfigIdentityTokenFilec                    | y	 t        |       S # t        t        f$ r }|d| nd}t        | d| d      |d}~ww xY w)z@Parse a credentials-file ``expires_at`` field into Unix seconds.Nzcredentials file at credentialsz has invalid 'expires_at' u   ; expected an integer Unix timestamp in seconds. The SDK does not parse ISO8601 — convert with int(datetime.timestamp()) before writing the file.)int	TypeError
ValueErrorr%   )valuesourceerrwheres       l/var/www/html/meridian/meridian-ai/venv/lib/python3.12/site-packages/anthropic/lib/credentials/_providers.py_coerce_expires_atr7   2   sl    }5zz" 393E&vh/=g/y 9F G
 		s   
 ?:?oauth_tokenz1.0oidc_federation
user_oauthc                   dd} || dt                 || dt                || dt               |j                  d      }|t        k(  rk ||dt
                ||dt                ||dt               |j                  d	      s/t        j                  j                  t              }|r	d
|d|d	<   yyy|t        k(  r ||dt               yy)u   Fill empty profile fields from corresponding ANTHROPIC_* env vars.

    The profile file is authoritative — this only fills fields the file left
    unset. Empty-string env values are treated as unset.
    c                v    | j                  |      s(t        j                  j                  |      }|r|| |<   y y y N)getosenviron)targetkeyenv_varvs       r6   fillz$_fill_missing_from_env.<locals>.fillU   s5    zz#

w'As      base_urlorganization_idworkspace_idtypefederation_rule_idservice_account_idscopeidentity_tokenfile)r3   pathN)rA   Dict[str, Any]rB   strrC   rR   returnNone)r   r   r   r>   AUTH_TYPE_OIDC_FEDERATIONr   r   r   r?   r@   r   AUTH_TYPE_USER_OAUTH)configauthrE   	auth_typerD   s        r6   _fill_missing_from_envrZ   N   s      	\*"$78!12 I--T')?@T')?@T7I&xx()

67A4:A)F%&  * 
*	*T7I& 
+rF   c                  &    e Zd ZdZddZddddZy)	r(   zQAn :class:`AccessTokenProvider` that always returns a fixed token with no expiry.c                    || _         y r=   )_token)selftokens     r6   __init__zStaticToken.__init__p   s	    rF   Fforce_refreshc               2    ~t        | j                  d       S )Nr_   
expires_at)r   r]   )r^   rb   s     r6   __call__zStaticToken.__call__s   s    >>rF   N)r_   rR   rS   rT   rb   boolrS   r   )__name__
__module____qualname____doc__r`   rf    rF   r6   r(   r(   m   s    [ 16 ?rF   r(   c                  *    e Zd ZdZefddZddddZy)	r)   zQAn :class:`AccessTokenProvider` that reads ``ANTHROPIC_AUTH_TOKEN`` at call time.c                    || _         y r=   )_env_var)r^   rC   s     r6   r`   zEnvToken.__init__{   s	    rF   Fra   c                   ~t         j                  j                  | j                        }|t	        d| j                   d      t        |d       S )NzEnvironment variable zN is not set. Set it or pass an explicit `credentials=` provider to the client.rd   )r?   r@   r>   rp   r%   r   )r^   rb   r2   s      r6   rf   zEnvToken.__call__~   sS    

t}}-= ' 7T U  488rF   N)rC   rR   rS   rT   rg   )ri   rj   rk   rl   r   r`   rf   rm   rF   r6   r)   r)   x   s    [&4   16 9rF   r)   c                      e Zd ZdZ	 ddd	 	 	 	 	 ddZedd       Zedd       Zedd       ZddZ	dd	Z
d d
Zd!dZd!dZd"dZd#dZd#dZd$dZd!dZddd%dZddd&dZd'dZddd&dZd(dZy))r*   u  An :class:`AccessTokenProvider` backed by a named profile.

    A profile is a pair of files under the config directory
    (``~/.config/anthropic/`` by default; override with ``ANTHROPIC_CONFIG_DIR``):

    * ``configs/<profile>.json`` — non-secret. Holds the nested
      ``"authentication"`` object (discriminated by its ``"type"`` field), plus
      top-level ``organization_id``, ``workspace_id``, and ``base_url``.
      The ``authentication`` object may contain a ``credentials_path`` field
      overriding the credentials file location.
    * ``credentials/<profile>.json`` — secret (0600). Holds ``access_token``,
      ``expires_at``, and (for ``user_oauth`` with a ``client_id``)
      ``refresh_token``.

    The split keeps secret material out of files that may need to be readable
    by config-only consumers, and lets the SDK enforce 0600 on the credentials
    file without locking out config readers.

    Dispatches on the ``authentication.type`` discriminator:

    ``"oidc_federation"``
        OIDC workload identity federation. Lazily constructs a
        :class:`WorkloadIdentityCredentials` delegate from the nested auth
        fields plus the top-level ``organization_id`` and calls it to perform
        the jwt-bearer exchange.

    ``"user_oauth"``
        Output of an interactive PKCE login. If the auth block has a
        ``client_id``, performs ``refresh_token`` grants on expiry and
        writes the new tokens back to the credentials file (atomic replace,
        refresh-token rotation supported). Without a ``client_id``, the
        credentials file is treated as externally rotated — the SDK re-reads
        it on every invocation and returns whatever ``access_token`` is
        there, no refresh grant attempted. This is the pattern for a
        sidecar/daemon that mints the access token out-of-band.

    Args:
        profile: Profile name. ``None`` resolves via ``ANTHROPIC_PROFILE`` env
            → ``<config_dir>/active_config`` pointer file → ``"default"``.
    N)http_clientc                   ||n	t               | _        t        | j                        | _        d | _        || _        d | _        d | _        d | _        t        | _
        d | _        y r=   )r    _profiler!   _config_path_bound_base_url_http_client_owned_http_client_config_credentials_pathr   	_base_url_workload_delegate)r^   profilers   s      r6   r`   zCredentialsFile.__init__   s^     $+#6O<M-dmm<.2':> 269=.IMrF   c                    | j                   S r=   )ru   r^   s    r6   r~   zCredentialsFile.profile   s    }}rF   c                    | j                   S r=   )rv   r   s    r6   config_pathzCredentialsFile.config_path   s       rF   c                    | j                         }|j                  d      }|rt        |      j                  d      S dS )u  The ``base_url`` declared in the profile config file, if any.

        Returns ``None`` when the config has no top-level ``base_url`` key —
        callers should fall back to their own default rather than the
        provider's bound/default value, so a profile that *doesn't* pin a
        host never overrides an explicit client setting. Loads the config
        on first access.
        rG   /N)_load_configr>   rR   rstrip)r^   rW   raws      r6   resolved_base_urlz!CredentialsFile.resolved_base_url   s:     ""$jj$'*s3xs#44rF   c                
   |j                  d      }t        || j                   d       || _        | j                  E| j                  | j                        | _        t        | j                  | j                   d       yy)a  Adopt the owning client's ``base_url`` as a fallback for the token
        exchange. Slots between the config file's own ``base_url`` field and
        the hard-coded default; a ``base_url`` in the config file still wins.

        The owning client binds exactly once at construction; sharing one
        instance across clients with different ``base_url`` values is
        unsupported and silently picks the last bind when the config file
        doesn't pin a host.
        r   
: base_urlfieldN)r   r   rv   rw   rz   _resolve_base_urlr|   )r^   rG   bounds      r6   bind_base_urlzCredentialsFile.bind_base_url   su     $ 	ut'8'8&9$DE$<<#!33DLLADN4>>D4E4E3Fj1QR $rF   c                    |j                  d      rt        |d         j                  d      S | j                  | j                  S t        S )u+  base_url precedence: top-level config field → bound (the owning
        client's base_url, via :meth:`bind_base_url`) → default. Validated
        against the scheme/TLS rules so a malicious config with
        ``base_url="http://evil/"`` can't exfiltrate the assertion or refresh
        token.rG   r   )r>   rR   r   rw   r   r^   rW   s     r6   r   z!CredentialsFile._resolve_base_url   sI     ::j!vj)*11#66+'''rF   c                    | j                         }i }| j                         j                  d      t        k7  r!|j                  d      }|rt	        |      |d<   |S )zReturn headers derived from the config file (e.g. ``workspace_id``).

        Eagerly reads the config if not yet loaded. The returned dict is
        suitable for merging into the client's default headers.
        rJ   rI   zanthropic-workspace-id)r   _auth_blockr>   rU   rR   )r^   rW   headersrI   s       r6   extra_headerszCredentialsFile.extra_headers   s\     ""$"$ !!&)-FF!::n5L474E01rF   c                   | j                   | j                   S 	 | j                  j                  d      }	 t        j                  |      }t        |t              s/t	        d	| j                   dt        |      j                    d      t#        d|      }|j%                  d      }t        |t              s't	        d	| j                   dt&         dt(         d      t#        d|      }t+        ||       | j-                  |      | _        t1        | j.                  | j                   d       |j%                  d      }|r2t3        j4                  t7        |            j9                         | _        nt=        | j
                        | _        || _         |S # t        $ r:}t	        d| j                   d| j
                  dt         dt         d	      |d}~wt        t        f$ r!}t	        d	| j                   d
|       |d}~ww xY w# t        j                  $ r!}t	        d	| j                   d|       |d}~ww xY w)zPRead and cache the config file, resolving ``base_url`` and ``credentials_path``.Nutf-8encodingzConfig file not found at 
 (profile z). Set z' to select a different profile, or set z" to relocate the config directory.zConfig file at  could not be read:  is not valid JSON: z! must contain a JSON object, not .rQ   authenticationzV is missing the 'authentication' object. Expected shape: {"authentication": {"type": ""|"", ...}, ...}r   r   credentials_path)rz   rv   	read_textFileNotFoundErrorr%   ru   r   r   OSErrorUnicodeDecodeErrorjsonloadsJSONDecodeError
isinstancedictrJ   ri   r	   r>   rU   rV   rZ   r   r|   r   pathlibPathrR   
expanduserr{   r"   )r^   r   r4   
raw_configrW   raw_authrX   r
   s           r6   r   zCredentialsFile._load_config  sP   <<#<<		j##--w-?C	j"jjoJ *d+ !$"3"3!44UVZ[eVfVoVoUppqr  &
3::./(D) !$"3"3!4 5-.c2F1GX 
 $h/ 	vt,//7t~~0A0A/B*-MN88./%,\\#h-%@%K%K%MD"%;DMM%JD"U ! 	 +D,=,=+>jHY Z"m#J>JZ [45 	
 +, 	j ?43D3D2EEYZ]Y^!_`fii	j ## 	j ?43D3D2EEYZ]Y^!_`fii	js:   F H 	H
"5GH
)HH
I H<<Ic           	     B   | j                   J | j                   }t        j                  dk(  r	 t        j                  |d      }t        j                  |j                        rt        d| d
      t        j                  |j                        }|dz  rt        d| d|dd| d      |dz  rt        j                  d|||       	 |j                  d      }	 t        j                   |      }|j%                  d      }|M|t&        k7  rD| j(                  J | j(                  d   j%                  d      }t        d|dt&        d|      |S # t        $ r"}t        d| d| j                  d      |d}~wt        $ r}t        d| d	|       |d}~ww xY w# t        $ r"}t        d| d| j                  d      |d}~wt        t        f$ r}t        d| d|       |d}~ww xY w# t        j"                  $ r}t        d| d|       |d}~ww xY w)uj  Read the credentials file. Re-reads on every call — daemons rotate it.

        On Unix, verifies the file is not group/world-readable. World-readable
        credentials files are refused outright; group-readable files log a
        warning but are accepted. The check is skipped on Windows where POSIX
        mode bits don't carry the same meaning.
        NposixF)follow_symlinkszCredentials file not found at r   z).Credentials file at z could not be accessed: zu is a symlink; refusing to follow (move the real file into place to keep secret material on the expected filesystem).   z is world-readable (mode z#oz); run `chmod 600 z` before retrying.8   zMCredentials file at %s is group-readable (mode %#o); consider `chmod 600 %s`.r   r   r   r   rJ   r   zcredentials file has type z; expected z for authentication.type )r{   r?   namestatr   r%   ru   r   S_ISLNKst_modeS_IMODEr&   warningr   r   r   r   r   r>   CREDENTIALS_FILE_TYPErz   )	r^   rP   	file_statr4   moder   credsactualrY   s	            r6   _read_credentialsz!CredentialsFile._read_credentialsA  s    %%111%%77gjGGD%@	
 ||I--.$*4& 1j k  <<	 1 12De|$*4&0I$r S&&*V+=?  e|c		b..'.2C
	b$(JJsOE 6"&,A"A<<+++%56::6BI ,VJkBWAZ [++4-9  W % t$'EdV:VZVcVcUffh%ijpss j$';D6AYZ]Y^%_`fiij, ! 	p #A$zRVR_R_Qbbd!efloo+, 	b #7v=QRUQV!WX^aa	b ## 	b #7v=QRUQV!WX^aa	bs_   E F" G4 	FE<<FFF"	G1+GG1G,,G14HHHc                    | j                   | j                   S | j                  t        j                  t              | _        | j                  S )zFReturn an ``httpx.Client``, lazily creating (and tracking) one we own.)timeout)rx   ry   httpxClientr   r   s    r6   _get_http_clientz CredentialsFile._get_http_client{  sD    ($$$""*&+ll;Q&RD#&&&rF   c                    | j                   !| j                   j                          d| _         | j                  | j                  j                          yy)z3Close the owned ``httpx.Client`` if we created one.N)ry   closer}   r   s    r6   r   zCredentialsFile.close  sK    "".##))+&*D#"".##))+ /rF   c                     d| _         d| _        y)a  Drop the cached config so the next call re-reads it from disk.

        ``CredentialsFile`` caches the parsed config across calls to keep the
        hot path cheap; a daemon that rotates a profile in place (e.g. flips
        ``"type": "user_oauth"`` to ``"type": "oidc_federation"``) will not be
        picked up automatically. Callers that need to react to such changes
        can call ``reload()`` to force a fresh read on the next ``__call__``.
        N)rz   r}   r   s    r6   reloadzCredentialsFile.reload  s     "&rF   c                   | j                   J | j                   j                  }|j                  ddd       t        j                  |d| j                   j
                   dd      \  }}	 	 t        j                  |d       t        j                  |t        j                  |d	
      j                  d             t        j                  |       t        j                  |       t        j                  || j                          	 t        j$                  |t        j&                        }	 t        j                  |       t        j                  |       y# t        j                  |       w xY w# t        $ r' 	 t        j                   |        # t"        $ r Y  w xY ww xY w# t        j                  |       w xY w# t"        $ r Y yw xY w)z;Atomic write to the credentials file (NOT the config file).NTi  )parentsexist_okr   r   z.tmp)dirprefixsuffixi     )indentr   )r{   parentmkdirtempfilemkstempr   r?   fchmodwriter   dumpsencodefsyncr   replaceBaseExceptionunlinkr   openO_RDONLY)r^   datar   fdtmpdir_fds         r6   _atomic_write_credentialsz)CredentialsFile._atomic_write_credentials  sn   %%111''..TDu=
 ""v$:P:P:U:U9VVW6XaghC			"e$TZZQ7>>wGHJJsD223	WWVR[[1F!  !  			#   	   		sm   .A%E 5E3 	$G  .F& G  E00E3 3	F#=FF#	FF#FF#&F==G   	GGc                @    | j                         }t        d|d         S )zEReturn the cached ``authentication`` sub-object from the config file.rQ   r   )r   r	   r   s     r6   r   zCredentialsFile._auth_block  s$    ""$$f-=&>??rF   Fra   c                  | j                         }|j                  d      }|t        k(  r| j                  ||      S |t        k(  r| j                  ||      S t        d|d| j                   dt        dt        d	      )NrJ   ra   Unknown authentication.type  at . Expected  or r   )r   r>   rU   _call_oidc_federationrV   _call_user_oauthr%   rv   )r^   rb   rX   rY   s       r6   rf   zCredentialsFile.__call__  s    !HHV$	11--d--PP,,((](KK*9-tD<M<M;N O14D9M8PPQS
 	
rF   c                  ddl m}m} | j                         }|j	                  d      }|st        d| j                   d      |j	                  d      }|s2t        |j	                  d      | j                        }t        ||      S |j	                  d	      }	|	s) |d
| j                  dt        d| j                         t        |j	                  d      | j                        }|s&|$t        j                         |k  rt        ||      S t        |	|d}
	 | j                         j                  | j                   t          |
dt"        t%               d      }|j*                  dk7  r
 ||d       |j-                         }|j	                  d      }|s |d      |j	                  dd      }	 t/        |      }t/        t        j                               |z   }|j	                  d	      xs |	}t4        |d<   t6        |d<   ||d<   ||d<   ||d	<   | j9                  |       t        ||      S # t&        j(                  $ r} |d|       |d}~ww xY w# t0        t2        f$ r} |d|d      |d}~ww xY w)zInteractive-login profile. With a ``client_id`` in the auth block,
        we run the refresh_token grant on expiry; without one, we treat the
        credentials file as externally rotated and just read it fresh.
        r   )WorkloadIdentityError_raise_token_endpoint_erroraccess_tokenr   z is missing 'access_token'.	client_idre   rd   refresh_tokenzcredentials file for profile z (authentication.type z/ with client_id) must include 'refresh_token': N)
grant_typer   r   zapplication/json)zContent-Typezanthropic-betaz
User-Agent)r   r   z3user_oauth refresh failed to reach token endpoint:    zuser_oauth refresh failed)message_prefixz2user_oauth refresh response missing 'access_token'
expires_ini  z5user_oauth refresh response has invalid 'expires_in' z(; expected an integer number of seconds.versionrJ   )	_workloadr   r   r   r>   r%   r{   r7   r   ru   rV   timer   r   postr|   r   r   r   r   	HTTPErrorstatus_coder   r/   r0   r1   CREDENTIALS_FILE_VERSIONr   r   )r^   rX   rb   r   r   r   r   r   re   r   bodyrespr4   payload
new_accessraw_expires_inr   new_expires_atnew_refreshs                      r6   r   z CredentialsFile._call_user_oauth  s   
 	R&&(yy0 #78N8N7OOj!kllHH[)	 ,EIIl,CTE[E[\J\jII		/2'//@@V'**Y))*,  (		,(?AWAWX
!7DIIK*<T\jII 3*" 
	n((*//>>">"23$6
 '<"-- 0 D  s"'=XY"&))+[[0
'(\]] \48	^,J TYY[)J6kk/2Cm3i-f *n,l!,o&&u-GG9  	n'*]^a]b(cdjmm	n :& 	'GGY Z9 : 	s1   AH8 9I 8IIIJ .I;;J c                    | j                   J | j                   j                         sy	 | j                         S # t        $ r%}t	        |j
                  t              rY d}~y d}~ww xY w)u   ``_read_credentials`` variant that returns ``None`` on absence
        instead of raising — used by the federation disk-cache path where a
        missing credentials file just means "exchange now".
        N)r{   existsr   r%   r   	__cause__r   )r^   r4   s     r6   _read_credentials_if_existsz+CredentialsFile._read_credentials_if_exists+  sd    
 %%111%%,,.	))++ 	#--):;	s   ; 	A)A$#A$$A)c                  | j                   | j                  |      | _         | j                  | j                         S | j                         }|so|m|j	                  d      }|j	                  d      }	 |rH|Ft        j
                         t        |      t        z
  k  rt        t        |      t        |            S | j                         }	 | j                  i |xs i t        t        |j                   |j"                  d       |S # t        t        f$ r Y ^w xY w# t$        $ r!}t&        j)                  d|       Y d }~|S d }~ww xY w)Nr   re   rd   )r   rJ   r   re   z?federation token disk-cache write-back failed (best-effort): %s)r}   _build_workload_delegater{   r	  r>   r   floatr   r   rR   r/   r0   r1   r   r   r   r_   re   r   r&   debug)r^   rX   rb   cachedr   re   r_   r4   s           r6   r   z%CredentialsFile._call_oidc_federation:  sJ   ""*&*&C&CD&ID# !!)**,, 113!3!::n5LL1J	 ".		eJ&7:S&SS&S->3z?[[
 '')	^**|71$)KK"'"2"2 # z*   	^IIWY\]]	^s+   6A	D :D" DD"	E+EEc           
        ddl m}m} |j                  d      }| j                  J | j                  j                  d      }|r|s |dt
        d| j                         |j                  d      }|a|j                  d      }|d	k7  rt        d
|d      |j                  d      }|s+t        d| j                  d| j                   d|d      d }|rt        |      n	t               }	 ||	|||j                  d      | j                  j                  d      |j                  d      | j                               }
|
j                  | j                         |
S )Nr   r   r'   rK   rH   z%config file with authentication.type zS must include 'authentication.federation_rule_id' and top-level 'organization_id': rN   r3   rO   zidentity_token source z- is not supported; only 'file' is implementedrP   z@identity_token source 'file' requires a non-empty path; profile r   z has identity_token=r   rL   rI   rM   identity_token_providerrK   rH   rL   rI   rM   rs   )r   r   r'   r>   rz   rU   rv   r%   ru   r,   r   r   r|   )r^   rX   r   r'   rK   rH   identity_token_cfgr3   identity_token_pathproviderdelegates              r6   r  z(CredentialsFile._build_workload_delegateh  s    	R!XX&:;||''',,**+<=!'78Q7T UX$$%'  "XX&67)'++H5F$'=fZGt%uvv"4"8"8"@& %#}}/tD4E4E3FFZ[mZppqs 
 #'=P$%89VgVi
 /$,1+#xx(<=)).9((7#--/
 	t~~.rF   r=   )r~   Optional[str]rs   Optional[httpx.Client]rS   rT   rS   rR   rS   zpathlib.Path)rS   r  )rG   rR   rS   rT   )rW   rQ   rS   rR   )rS   zDict[str, str]rS   rQ   )rS   zhttpx.ClientrS   rT   )r   rQ   rS   rT   rg   )rX   rQ   rb   rh   rS   r   )rS   zOptional[Dict[str, Any]]rX   rQ   rS   r'   )ri   rj   rk   rl   r`   propertyr~   r   r   r   r   r   r   r   r   r   r   r   r   rf   r   r	  r   r  rm   rF   r6   r*   r*      s    'V "&N /3	NN ,	N
 
N&   ! ! 5 5S&
 &1f8t',
'"L@
 16 
" OT THp TY ,\3rF   r*   c                  4    e Zd ZdZdddZedd       Zd	dZy)
r,   zAn :class:`IdentityTokenProvider` that reads a JWT from a file on every call.

    Kubernetes projected service-account tokens (and similar) are rotated in place,
    so the file MUST be re-read on every invocation rather than cached.
    Nc                R    t        |      }|t        dt         d      || _        y )Nz;No identity token file path given. Pass `path=` or set the z environment variable.)r#   r%   r   _path)r^   rP   resolveds      r6   r`   zIdentityTokenFile.__init__  s<    .t4 MNeMf g( )  
rF   c                    | j                   S r=   )r!  r   s    r6   rP   zIdentityTokenFile.path  s    zzrF   c                   	 | j                   j                  d      j                         }|st	        d| j                    d      |S # t        $ r}t	        d| j                    d      |d }~wt
        $ r"}t	        d| j                    d| d      |d }~wt        $ r}t	        d| j                    d	      |d }~wt        t        f$ r!}t	        d| j                    d
|       |d }~ww xY w)Nr   r   z!Identity token file not found at r   zIdentity token file at z" is not readable by this process: z;. Check the file mode and the effective uid of the process.zIdentity token path zF is a directory, not a file. Point at the projected token file itself.r   z is empty. If this is a Kubernetes projected service-account token, check the volume mount and the serviceAccountToken projection audience.)	r!  r   stripr   r%   PermissionErrorIsADirectoryErrorr   r   )r^   contentr4   s      r6   rf   zIdentityTokenFile.__call__  s,   	kjj**G*<BBDG  )$** 6P Q 
 ) ! 	] #DTZZLPQ!RSY\\ 	 )$**5WX[W\ ]L M  ! 	 &tzzl 3< =  +, 	k #:4::,FZ[^Z_!`agjj	ks;   *A	 		C.A,,C.8BC.!B;;C.C))C.r=   )rP   z$Union[str, 'os.PathLike[str]', None]rS   rT   r  r  )ri   rj   rk   rl   r`   r  rP   rf   rm   rF   r6   r,   r,     s%      rF   r,   c                       e Zd ZdZ ej
                  d      Zddd	 	 	 	 	 	 	 d	dZed
d       Z	edd       Z
ed fd       Z xZS )r+   u  An :class:`AccessTokenProvider` driven by an in-memory config dict
    (same shape as ``configs/<profile>.json``) rather than files on disk.

    Intended for callers that want to construct an :class:`anthropic.Anthropic`
    client with a fully programmatic credentials setup — equivalent to the Go
    SDK's ``option.WithConfig`` / TypeScript SDK's ``ClientOptions.config``.

    Both ``authentication.type`` discriminator values are supported:

    ``"oidc_federation"``
        ``authentication.credentials_path`` is **optional**. If set, exchanged
        tokens are cached to / read from that file (same atomic 0600 write as
        :class:`CredentialsFile`). If omitted, every call performs a fresh
        jwt-bearer exchange with no on-disk cache.

    ``"user_oauth"``
        ``authentication.credentials_path`` is **required** — it is where the
        access/refresh tokens live. Behaviour is identical to a file-backed
        :class:`CredentialsFile` profile of the same shape.

    The implementation subclasses :class:`CredentialsFile` so the dispatch,
    refresh-grant, disk-cache and atomic-write logic are shared verbatim;
    only config loading and identity-token resolution are overridden.
    z<in-memory config>N)r  rs   c          	        |j                  d      }t        |t              st        dt         dt
         d      t        d|      }|j                  d      }|t        t
        fvrt        d|dt        d	t
        d
      |j                  d      }|t
        k(  r|st        dt
        d      d| _        | j                  | _	        d | _
        || _        d | _        d | _        || _        || _        |r,t!        j"                  t%        |            j'                         nd | _        | j+                  |      | _        t/        | j,                  d       y )Nr   zaconfig dict is missing the 'authentication' object. Expected shape: {"authentication": {"type": "r   r   rQ   rJ   r   r   r   r   r   zauthentication.type z requires 'authentication.credentials_path' (where the access/refresh tokens live). For profile-based resolution, use CredentialsFile instead.z<in-memory>zconfig: base_urlr   )r>   r   r   r%   rU   rV   r	   ru   _IN_MEMORY_PATHrv   rw   rx   ry   r}   !_identity_token_provider_overriderz   r   r   rR   r   r{   r   r|   r   )r^   rW   r  rs   r   rX   rY   r   s           r6   r`   zInMemoryConfig.__init__  sq    ::./(D) BB[A\ ])*/; 
 $h/HHV$	68LMM .ym <58=Q<TTUW 
  88$67,,5E &';&> ?M N  & 00.2':>IM1H.Uec2B.C!D!O!O!Qko//7t~~-?@rF   c                6    | j                   J | j                   S r=   )rz   r   s    r6   r   zInMemoryConfig._load_config  s    ||'''||rF   c                    d | _         y r=   )r}   r   s    r6   r   zInMemoryConfig.reload  s     #'rF   c           
        | j                   t        | 	  |      S ddlm}m} |j                  d      }| j                  J | j                  j                  d      }|r|s |dt        d       || j                   |||j                  d      | j                  j                  d      |j                  d	      | j                         
      }|j                  | j                         |S )Nr   r  rK   rH   z%config dict with authentication.type zQ must include 'authentication.federation_rule_id' and top-level 'organization_id'rL   rI   rM   r  )r,  superr  r   r   r'   r>   rz   rU   r   r   r|   )r^   rX   r   r'   rK   rH   r  	__class__s          r6   r  z'InMemoryConfig._build_workload_delegate   s    11973D99Q!XX&:;||''',,**+<=!'78Q7T UV W  /$($J$J1+#xx(<=)).9((7#--/
 	t~~.rF   )rW   rQ   r  zOptional[IdentityTokenProvider]rs   r  rS   rT   r  r  r  )ri   rj   rk   rl   r   r   r+  r`   r
   r   r   r  __classcell__)r1  s   @r6   r+   r+     s    2 #gll#78O DH.2+A+A "A	+A
 ,+A 
+AZ   ' '
  rF   r+   )r2   r   r3   zOptional[pathlib.Path]rS   zOptional[int])rW   rQ   rX   rQ   rS   rT   )B
__future__r   r?   r   r   r   loggingr   r   typingr   r   r   r   r   r	   typing_extensionsr
   r   _typesr   r   
_constantsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   _exceptionsr%   	getLoggerri   r&   __annotations__r   r'   __all__r7   r   CONFIG_FILE_VERSIONr   rU   rV   rZ   r(   r)   r*   r,   r+   rm   rF   r6   <module>r>     s    " 	       B B &  6     0 *'g''1^ 16
_" &      . # '>? ?9 9"R Rj+ +\m_ mrF   