
    b\j                       % S SK Jr  S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SK	J
r
JrJrJrJrJr  S SKJr  S SKrSSKJrJr  SSKJrJrJrJrJrJr  SSKJrJrJ r J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(J)r)J*r*J+r+J,r,J-r-J.r.J/r/J0r0J1r1J2r2J3r3  S	S
K4J5r5  \Rl                  " \75      r8S\9S'   \
(       a  SSK:J;r;  / SQr<SS jr=Sr>Sr?Sr@SrASrBS S jrC " S S5      rD " S S5      rE " S S5      rF " S S5      rG " S S\F5      rHg)!    )annotationsN)TYPE_CHECKINGAnyDictUnionOptionalcast)override   )AccessTokenIdentityTokenProvider)	SecretStr_unwrap_secret_strip_traceback_json_dumps_secrets_wrap_secret_fields_NonObjectPayloadError)	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                    U c  g [        U 5      $ ! [        [        4 a"  nUb  SU 3OSn[        U SU < S35      UeSnAff = f)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       Z/var/www/website/venv/lib/python3.13/site-packages/anthropic/lib/credentials/_providers.py_coerce_expires_atr=   :   sl    }5zz" 393E&vh/=g/y 9F G
 		s   
 A>Aoauth_tokenz1.0oidc_federation
user_oauthc                   SS jnU" U S[         5        U" U S[        5        U" U S[        5        UR                  S5      nU[        :X  au  U" US[
        5        U" US[        5        U" US[        5        UR                  S	5      (       d4  [        R                  R                  [        5      nU(       a	  S
US.US	'   gggU[        :X  a  U" US[        5        gg)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                    U R                  U5      (       d,  [        R                  R                  U5      nU(       a  X0U'   g g g N)getosenviron)targetkeyenv_varvs       r<   fill$_fill_missing_from_env.<locals>.fill]   s5    zz#

w'As      base_urlorganization_idworkspace_idtypefederation_rule_idservice_account_idscopeidentity_tokenfile)r9   pathN)rG   Dict[str, Any]rH   strrI   rY   returnNone)r   r   r   rD   AUTH_TYPE_OIDC_FEDERATIONr   r   r   rE   rF   r!   AUTH_TYPE_USER_OAUTH)configauthrK   	auth_typerJ   s        r<   _fill_missing_from_envra   V   s      	\*"$78!12 I--T')?@T')?@T7I&xx())

67A4:A)F%&  * 
*	*T7I& 
+rM   c                  4    \ rS rSrSrS	S jrSS.S
S jjrSrg)r.   u   zQAn :class:`AccessTokenProvider` that always returns a fixed token with no expiry.c                    Xl         g rC   _token)selftokens     r<   __init__StaticToken.__init__x   s    rM   Fforce_refreshc               ,    A[        U R                  S S9$ )Nrh   
expires_at)r   rf   )rg   rl   s     r<   __call__StaticToken.__call__{   s    >>rM   re   N)rh   rY   rZ   r[   rl   boolrZ   r   )__name__
__module____qualname____firstlineno____doc__ri   rp   __static_attributes__ rM   r<   r.   r.   u   s    [ 16 ? ?rM   r.   c                  :    \ rS rSrSr\4S	S jjrSS.S
S jjrSrg)r/      zQAn :class:`AccessTokenProvider` that reads ``ANTHROPIC_AUTH_TOKEN`` at call time.c                    Xl         g rC   _env_var)rg   rI   s     r<   ri   EnvToken.__init__   s    rM   Frk   c                   A[         R                  R                  U R                  5      nUc  [	        SU R                   S35      e[        US S9$ )NzEnvironment variable zN is not set. Set it or pass an explicit `credentials=` provider to the client.rn   )rE   rF   rD   r   r+   r   )rg   rl   r8   s      r<   rp   EnvToken.__call__   sS    

t}}-= ' 7T U  488rM   r~   N)rI   rY   rZ   r[   rr   )	rt   ru   rv   rw   rx   r   ri   rp   ry   rz   rM   r<   r/   r/      s    [&4   16 9 9rM   r/   c                  $   \ rS rSrSr SSS.     SS jjjr\SS j5       r\SS j5       r\SS j5       r	S S	 jr
S!S
 jrS"S jrS#S jrS#S jrS$S jrS%S jrS%S jrS&S jrS#S jrSS.S'S jjrSS.S(S jjrS)S jrSS.S(S jjrS*S jrSrg)+r0      um  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                   Ub  UO	[        5       U l        [        U R                  5      U l        S U l        X l        S U l        S U l        S U l        [        U l
        S U l        g rC   )r&   _profiler'   _config_path_bound_base_url_http_client_owned_http_client_config_credentials_pathr   	_base_url_workload_delegate)rg   profiler   s      r<   ri   CredentialsFile.__init__   s\     $+#6O<M-dmm<.2':> 269=.IMrM   c                    U R                   $ rC   )r   rg   s    r<   r   CredentialsFile.profile   s    }}rM   c                    U R                   $ rC   )r   r   s    r<   config_pathCredentialsFile.config_path   s       rM   c                    U R                  5       nUR                  S5      nU(       a  [        U5      R                  S5      $ S$ )uY  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.
rN   /N)_load_configrD   rY   rstrip)rg   r^   raws      r<   resolved_base_url!CredentialsFile.resolved_base_url   s:     ""$jj$'*s3xs#44rM   c                    UR                  S5      n[        X R                   S3S9  X l        U R                  bB  U R                  U R                  5      U l        [        U R                  U R                   S3S9  gg)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%   r   r   r   _resolve_base_urlr   )rg   rN   bounds      r<   bind_base_urlCredentialsFile.bind_base_url   sq     $ 	u'8'8&9$DE$<<#!33DLLADN4>>D4E4E3Fj1QR $rM   c                    UR                  S5      (       a  [        US   5      R                  S5      $ U R                  b  U R                  $ [        $ )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.rN   r   )rD   rY   r   r   r   rg   r^   s     r<   r   !CredentialsFile._resolve_base_url   sL     ::j!!vj)*11#66+'''rM   c                    U R                  5       n0 nU R                  5       R                  S5      [        :w  a&  UR                  S5      nU(       a  [	        U5      US'   U$ )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.
rQ   rP   zanthropic-workspace-id)r   _auth_blockrD   r\   rY   )rg   r^   headersrP   s       r<   extra_headersCredentialsFile.extra_headers  s\     ""$"$ !!&)-FF!::n5L474E01rM   c                   U R                   b  U R                   $  U R                  R                  SS9n [        R                  " U5      n[        U[        5      (       d/  [	        S	U R                   S[        U5      R                    S35      e[#        SU5      nUR%                  S5      n[        U[        5      (       d'  [	        S	U R                   S[&         S[(         S35      e[#        SU5      n[+        XF5        U R-                  U5      U l        [1        U R.                  U R                   S3S9  UR%                  S5      nU(       a3  [2        R4                  " [7        U5      5      R9                  5       U l        O[=        U R
                  5      U l        X@l         U$ ! [         a;  n[	        SU R                   SU R
                  < S[         S[         S3	5      UeSnAf[        [        4 a!  n[	        S	U R                   S
U 35      UeSnAff = f! [        R                   a!  n[	        S	U R                   SU 35      UeSnAff = f)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: ! must contain a JSON object, not .rX   authenticationzV is missing the 'authentication' object. Expected shape: {"authentication": {"type": ""|"", ...}, ...}r   r   credentials_path)r   r   	read_textFileNotFoundErrorr+   r   r   r   OSErrorUnicodeDecodeErrorjsonloadsJSONDecodeError
isinstancedictrQ   rt   r	   rD   r\   r]   ra   r   r   r%   pathlibPathrY   
expanduserr   r(   )rg   r   r:   
raw_configr^   raw_authr_   r
   s           r<   r   CredentialsFile._load_config  sR   <<#<<		j##--w-?C	j"jjoJ *d++ !$"3"3!44UVZ[eVfVoVoUppqr  &
3::./(D)) !$"3"3!4 5-.c2F1GX 
 $h/ 	v,//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-6G##H6HHI.I

Ic           	        U R                   c   eU R                   n[        R                  S:X  a   [        R                  " USS9n[        R                  " UR                  5      (       a  [        SU S
35      e[        R                  " UR                  5      nUS-  (       a  [        SU SUS SU S35      eUS-  (       a  [        R                  SUUU5         [        [        R                  " UR!                  SS95      5      nUR-                  S5      nUbR  U[.        :w  aH  U R0                  c   eU R0                  S   R-                  S5      n[        SU< S[.        < SU< 35      eU$ ! [         a#  n[        SU SU R                  < S35      UeSnAf[         a  n[        SU S	U 35      UeSnAff = f! [         a#  n[        SU SU R                  < S35      UeSnAf[        R"                   a   n[        SU SU 35      [%        U5      eSnAf[&         a"  n[        SU SUR(                   S35      SeSnAf[        [*        4 a  n[        SU SU 35      UeSnAff = f)uI  Read the credentials file. Re-reads on every call — daemons rotate it.

Secret values in the returned dict (every string field not in
``_secrets._PLAIN_KEYS``) are :class:`SecretStr`-wrapped — unwrap
with ``_unwrap_secret`` at the point of use. Writing the dict back
through :meth:`_atomic_write_credentials` unwraps automatically.

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   ).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   r   r   rQ   r   zcredentials file has type z; expected z for authentication.type )r   rE   namestatr   r+   r   r   S_ISLNKst_modeS_IMODEr,   warningr   r   r   r   r   r   r   	type_namer   rD   CREDENTIALS_FILE_TYPEr   )rg   rW   	file_statr:   modecredsactualr`   s           r<   _read_credentials!CredentialsFile._read_credentialsI  s    %%111%%77gjGGD%@	
 ||I--..$*4& 1j k  <<	 1 12De|$*4&0I$r S&&*V+=?  e|c		b
 %8

4>>[b>Cc8d$eE" 6"&,A"A<<+++%56::6BI ,VJkBWAZ [++4-9  i % t$'EdV:VZVcVcUffh%ijpss j$';D6AYZ]Y^%_`fiij4 ! 	p #A$zRVR_R_Qbbd!efloo## 	t #7v=QRUQV!WX^nor^ss% 	 !&tf,Mcmm_\]^ +, 	b #7v=QRUQV!WX^aa	bs_   E1 ,G  1
F=;FF=&F88F= 
I.
G((I.?HI.'II.I))I.c                    U R                   b  U R                   $ U R                  c  [        R                  " [        S9U l        U R                  $ )zFReturn an ``httpx.Client``, lazily creating (and tracking) one we own.)timeout)r   r   httpxClientr    r   s    r<   _get_http_client CredentialsFile._get_http_client  sD    ($$$""*&+ll;Q&RD#&&&rM   c                    U R                   b!  U R                   R                  5         SU l         U R                  b  U R                  R                  5         gg)z3Close the owned ``httpx.Client`` if we created one.N)r   closer   r   s    r<   r   CredentialsFile.close  sK    "".##))+&*D#"".##))+ /rM   c                     SU l         SU l        g)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)r   r   r   s    r<   reloadCredentialsFile.reload  s     "&rM   c                v   U R                   c   eU R                   R                  nUR                  SSSS9  [        R                  " USU R                   R
                   S3SS9u  p4  [        R                  " US5        [        R                  " U[        US	S
95        [        R                  " U5        [        R                  " U5        [        R                  " X@R                   5         [        R                   " U[        R"                  5      n [        R                  " U5        [        R                  " U5        g! [        R                  " U5        f = f! [         a)     [        R                  " U5        e ! [         a     e f = ff = f! [        R                  " U5        f = f! [         a     gf = f)aA  Atomic write to the credentials file (NOT the config file).

``data`` may hold :class:`SecretStr` token values (see
:meth:`_read_credentials`); they are unwrapped at dump time, so the
on-disk format is unchanged and this frame's locals stay redacted if
the write fails (e.g. ENOSPC) with a crash reporter capturing them.
NTi  )parentsexist_okr   r   z.tmp)dirprefixsuffixi     )indent)r   parentmkdirtempfilemkstempr   rE   fchmodwriter   fsyncr   replaceBaseExceptionunlinkr   openO_RDONLY)rg   datar   fdtmpdir_fds         r<   _atomic_write_credentials)CredentialsFile._atomic_write_credentials  s^    %%111''..TDu=
 ""v$:P:P:U:U9VVW6Xagh			"e$0a@AJJs223	WWVR[[1F!  !  			#   	   		sm   )AD? 56E ,%F+ F (F+ ?EE 
F%E<;F<
F	FF		FF((F+ +
F87F8c                @    U R                  5       n[        SUS   5      $ )zEReturn the cached ``authentication`` sub-object from the config file.rX   r   )r   r	   r   s     r<   r   CredentialsFile._auth_block  s$    ""$$f-=&>??rM   Frk   c                  U R                  5       nUR                  S5      nU[        :X  a  U R                  X!S9$ U[        :X  a  U R                  X!S9$ [        SU< SU R                   S[        < S[        < S3	5      e)NrQ   rk   Unknown authentication.type  at . Expected  or r   )r   rD   r\   _call_oidc_federationr]   _call_user_oauthr+   r   )rg   rl   r_   r`   s       r<   rp   CredentialsFile.__call__  s    !HHV$	11--d-PP,,(((KK*9-tD<M<M;N O14D9M8PPQS
 	
rM   c                  SSK JnJnJn  U R	                  5       nUR                  S5      nU(       d  [        SU R                   S35      eUR                  S5      nU(       d8  [        UR                  S5      U R                  5      n	[        [        U5      U	S9$ UR                  S	5      n
U
(       d+  U" S
U R                  < S[        < SU R                   35      e[        UR                  S5      U R                  5      n	U(       d/  U	b,  [        R                  " 5       U	:  a  [        [        U5      U	S9$ [        U
US.n U R                  5       R!                  U R"                   [$         3['        U5      S[(        [+        5       S.S9nUR2                  S:w  a  U" USS9   [5        UR7                  5       5      nUR                  S5      nU(       d  U" S5      eUR                  SS5      n [?        U5      n[?        [        R                  " 5       5      U-   nUR                  S	5      =(       d    U
n[B        US!'   [D        US"'   XS'   UUS'   UUS	'   U RG                  U5        [        [        U5      US9$ ! [,        R.                   a  nU" SU 35      [1        U5      eSnAff = f! [8         a5  nU" SUR2                   S3UR2                  U" U5      S9[1        U5      eSnAf[:         a9  nU" SUR<                   SUR2                   S3UR2                  U" U5      S9SeSnAff = f! [@        [8        4 a  nU" SU< S 35      UeSnAff = f)#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_request_id_raise_token_endpoint_erroraccess_tokenr   z is missing 'access_token'.	client_idro   rn   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)contentr   z3user_oauth refresh failed to reach token endpoint:    zuser_oauth refresh failed)message_prefixz8user_oauth refresh returned a non-JSON response (status r   )status_code
request_idz#user_oauth refresh returned a JSON z	 (status z); expected an object.z2user_oauth refresh response missing 'access_token'
expires_ini  z5user_oauth refresh response has invalid 'expires_in' z(; expected an integer number of seconds.versionrQ   )$	_workloadr  r  r  r   rD   r+   r   r=   r   r   r   r]   timer"   r   postr   r   r   r   r$   r   	HTTPErrorr   r  r   r   r7   r   r   r5   r6   CREDENTIALS_FILE_VERSIONr   r  )rg   r_   rl   r  r  r  r   r  r  ro   r  bodyrespr:   payload
new_accessraw_expires_inr  new_expires_atnew_refreshs                       r<   r   CredentialsFile._call_user_oauth  sl   
 	_^&&(yy0 #78N8N7OOj!kllHH[)	 ,EIIl,CTE[E[\J^L%AjYY		/2'//@@V'**Y))*,  (		,(?AWAWX
!7DIIK*<T^L%AjYY 3*"2
	)((*//>>">"23 ,D1$6
 '<"-- 0 D( s"'=XY	&9$))+&FG$ [[0
'(\]] \48	^,J TYY[)J6kk/2Cm3i-f *n,l!,o 	&&u-
!;WWe  	)'EcUK#C()	)  	) (J4K[K[J\\^_ ,,&t, $C(	)
 & 	 (5cmm_IdN^N^M__uv ,,&t, 		 :& 	'GGY Z9 : 	sU   A
I= 'J. 3L1 =J+J&&J+.
L.80K((L.54L))L.1MMMc                    U R                   c   eU R                   R                  5       (       d  g U R                  5       $ ! [         a*  n[	        UR
                  [        5      (       a   SnAge SnAff = f)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   )rg   r:   s     r<   _read_credentials_if_exists+CredentialsFile._read_credentials_if_exists_  sj    
 %%111%%,,..	))++ 	#--):;;	s   A 
A5A0/A00A5c                  U R                   c  U R                  U5      U l         U R                  c  U R                  5       $ U R                  5       nU(       d~  Ub{  UR	                  S5      nUR	                  S5      n U(       aQ  UbN  [
        R
                  " 5       [        U5      [        -
  :  a%  [        [        [        U5      5      [        U5      S9$ U R                  5       n U R                  0 U=(       d    0 E[        [         [#        UR$                  5      UR&                  S.E5        U$ ! [        [        4 a     Nmf = f! [(         a!  n[*        R-                  SU5         S nAU$ S nAff = f)Nr  ro   rn   )r  rQ   r  ro   z?federation token disk-cache write-back failed (best-effort): %s)r   _build_workload_delegater   r/  rD   r   floatr#   r   rY   r   r5   r6   r7   r  r#  r   r   rh   ro   r   r,   debug)rg   r_   rl   cachedr  ro   rh   r:   s           r<   r  %CredentialsFile._call_oidc_federationn  sY   ""*&*&C&CD&ID# !!)**,, 113!3!::n5LL1J	 ".		eJ&7:S&SS&S1M-N[^_i[jkk
 '')	^**|71 %.ekk$:"'"2"2
 ' z* "  	^IIWY\]]	^s,   >AD1 'AE 1EE
E2E--E2c           
        SSK JnJn  UR                  S5      nU R                  c   eU R                  R                  S5      nU(       a  U(       d  U" S[
        < SU R                   35      eUR                  S5      nUbk  UR                  S5      nUS	:w  a  [        S
U< S35      eUR                  S5      nU(       d+  [        SU R                  < SU R                   SU< S35      eOS nU(       a  [        U5      O	[        5       n	U" U	UUUR                  S5      U R                  R                  S5      UR                  S5      U R                  5       S9n
U
R                  U R                  5        U
$ )Nr   r  r-   rR   rO   z%config file with authentication.type zS must include 'authentication.federation_rule_id' and top-level 'organization_id': rU   r9   rV   zidentity_token source z- is not supported; only 'file' is implementedrW   z@identity_token source 'file' requires a non-empty path; profile r
  z has identity_token=r   rS   rP   rT   identity_token_providerrR   rO   rS   rP   rT   r   )r  r  r-   rD   r   r\   r   r+   r   r2   r   r   r   )rg   r_   r  r-   rR   rO   identity_token_cfgr9   identity_token_pathproviderdelegates              r<   r2  (CredentialsFile._build_workload_delegate  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~~.rM   )	r   r   r   r   r   r   r   r   r   rC   )r   Optional[str]r   Optional[httpx.Client]rZ   r[   rZ   rY   rZ   zpathlib.Path)rZ   r@  )rN   rY   rZ   r[   )r^   rX   rZ   rY   )rZ   zDict[str, str]rZ   rX   )rZ   zhttpx.ClientrZ   r[   )r   rX   rZ   r[   rr   )r_   rX   rl   rs   rZ   r   )rZ   zOptional[Dict[str, Any]]r_   rX   rZ   r-   )rt   ru   rv   rw   rx   ri   propertyr   r   r   r   r   r   r   r   r   r   r   r  r   rp   r  r/  r  r2  ry   rz   rM   r<   r0   r0      s    'V "&N /3	NN ,	N
 
N&   ! ! 5 5S&
 &1fFP',
'(X@
 16 
" OT lX` TY .`3rM   r0   c                  D    \ rS rSrSrSS	S jjr\S
S j5       rSS jrSr	g)r2   i  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    [        U5      nUc  [        S[         S35      eX l        g )Nz;No identity token file path given. Pass `path=` or set the z environment variable.)r)   r+   r!   _path)rg   rW   resolveds      r<   ri   IdentityTokenFile.__init__  s:    .t4 MNeMf g( )  
rM   c                    U R                   $ rC   rJ  r   s    r<   rW   IdentityTokenFile.path  s    zzrM   c                    U R                   R                  SS9R                  5       nU(       d  [	        SU R                    S35      eU$ ! [         a  n[	        SU R                    S35      UeS nAf[
         a"  n[	        SU R                    SU S35      UeS nAf[         a  n[	        SU R                    S	35      UeS nAf[        [        4 a!  n[	        SU R                    S
U 35      UeS nAff = f)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.)	rJ  r   stripr   r+   PermissionErrorIsADirectoryErrorr   r   )rg   r  r:   s      r<   rp   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 
C4A//C4<BC4&C  C4C//C4rN  rC   )rW   z$Union[str, 'os.PathLike[str]', None]rZ   r[   rC  rB  )
rt   ru   rv   rw   rx   ri   rG  rW   rp   ry   rz   rM   r<   r2   r2     s%      rM   r2   c                     ^  \ rS rSrSr\R                  " S5      rSSS.       SS jjr\	SS j5       r
\	SS j5       r\	SU 4S	 jj5       rS
rU =r$ )r1   i  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:  r   c          	        UR                  S5      n[        U[        5      (       d  [        S[         S[
         S35      e[        SU5      nUR                  S5      nU[        [
        4;  a   [        SU< S[        < S	[
        < S
35      eUR                  S5      nU[
        :X  a  U(       d  [        S[
        < S35      eSU l        U R                  U l	        S U l
        X0l        S U l        S U l        X l        Xl        U(       a-  [         R"                  " [%        U5      5      R'                  5       OS U l        U R+                  U5      U l        [/        U R,                  SS9  g )Nr   zaconfig dict is missing the 'authentication' object. Expected shape: {"authentication": {"type": "r   r   rX   rQ   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   )rD   r   r   r+   r\   r]   r	   r   _IN_MEMORY_PATHr   r   r   r   r   !_identity_token_provider_overrider   r   r   rY   r   r   r   r   r%   )rg   r^   r:  r   r   r_   r`   r   s           r<   ri   InMemoryConfig.__init__  sn    ::./(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~~-?@rM   c                8    U R                   c   eU R                   $ rC   )r   r   s    r<   r   InMemoryConfig._load_configK  s    ||'''||rM   c                    S U l         g rC   )r   r   s    r<   r   InMemoryConfig.reloadP  s     #'rM   c           
       > U R                   c  [        TU ]	  U5      $ SSKJnJn  UR                  S5      nU R                  c   eU R                  R                  S5      nU(       a  U(       d  U" S[        < S35      eU" U R                   UUUR                  S5      U R                  R                  S5      UR                  S	5      U R                  5       S
9nUR                  U R                  5        U$ )Nr   r8  rR   rO   z%config dict with authentication.type zQ must include 'authentication.federation_rule_id' and top-level 'organization_id'rS   rP   rT   r9  )rX  superr2  r  r  r-   rD   r   r\   r   r   r   )rg   r_   r  r-   rR   rO   r>  	__class__s          r<   r2  'InMemoryConfig._build_workload_delegateV  s    11973D99Q!XX&:;||''',,**+<=!'78Q7T UV W  /$($J$J1+#xx(<=)).9((7#--/
 	t~~.rM   )
r   r   r   r   r   r   rX  r   r   r   )r^   rX   r:  zOptional[IdentityTokenProvider]r   rA  rZ   r[   rD  rE  rF  )rt   ru   rv   rw   rx   r   r   rW  ri   r
   r   r   r2  ry   __classcell__)r`  s   @r<   r1   r1     s    2 ll#78O DH.2+A+A "A	+A
 ,+A 
+AZ   ' '
  rM   r1   )r8   r   r9   zOptional[pathlib.Path]rZ   zOptional[int])r^   rX   r_   rX   rZ   r[   )I
__future__r   rE   r   r   r   loggingr   r   typingr   r   r   r   r   r	   typing_extensionsr
   r   _typesr   r   _secretsr   r   r   r   r   r   
_constantsr   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   _exceptionsr+   	getLoggerrt   r,   __annotations__r  r-   __all__r=   r   CONFIG_FILE_VERSIONr#  r\   r]   ra   r.   r/   r0   r2   r1   rz   rM   r<   <module>ro     s    " 	       B B &  6      0 *''1^ 16
_" &      . # '>? ?9 9"@	 @	F+ +\m_ mrM   