anthropic 0.73.0__py3-none-any.whl → 0.74.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anthropic/__init__.py +1 -0
- anthropic/_client.py +8 -0
- anthropic/_version.py +1 -1
- anthropic/lib/_files.py +2 -2
- anthropic/lib/foundry.md +127 -0
- anthropic/lib/foundry.py +443 -0
- anthropic/resources/beta/messages/messages.py +4 -4
- {anthropic-0.73.0.dist-info → anthropic-0.74.1.dist-info}/METADATA +1 -1
- {anthropic-0.73.0.dist-info → anthropic-0.74.1.dist-info}/RECORD +11 -9
- {anthropic-0.73.0.dist-info → anthropic-0.74.1.dist-info}/WHEEL +0 -0
- {anthropic-0.73.0.dist-info → anthropic-0.74.1.dist-info}/licenses/LICENSE +0 -0
anthropic/__init__.py
CHANGED
|
@@ -101,6 +101,7 @@ if not _t.TYPE_CHECKING:
|
|
|
101
101
|
from .lib.tools import beta_tool, beta_async_tool
|
|
102
102
|
from .lib.vertex import *
|
|
103
103
|
from .lib.bedrock import *
|
|
104
|
+
from .lib.foundry import AnthropicFoundry as AnthropicFoundry, AsyncAnthropicFoundry as AsyncAnthropicFoundry
|
|
104
105
|
from .lib.streaming import *
|
|
105
106
|
|
|
106
107
|
_setup_logging()
|
anthropic/_client.py
CHANGED
|
@@ -183,6 +183,10 @@ class Anthropic(SyncAPIClient):
|
|
|
183
183
|
|
|
184
184
|
@override
|
|
185
185
|
def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
|
|
186
|
+
if headers.get("Authorization") or headers.get("X-Api-Key"):
|
|
187
|
+
# valid
|
|
188
|
+
return
|
|
189
|
+
|
|
186
190
|
if self.api_key and headers.get("X-Api-Key"):
|
|
187
191
|
return
|
|
188
192
|
if isinstance(custom_headers.get("X-Api-Key"), Omit):
|
|
@@ -423,6 +427,10 @@ class AsyncAnthropic(AsyncAPIClient):
|
|
|
423
427
|
|
|
424
428
|
@override
|
|
425
429
|
def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
|
|
430
|
+
if headers.get("Authorization") or headers.get("X-Api-Key"):
|
|
431
|
+
# valid
|
|
432
|
+
return
|
|
433
|
+
|
|
426
434
|
if self.api_key and headers.get("X-Api-Key"):
|
|
427
435
|
return
|
|
428
436
|
if isinstance(custom_headers.get("X-Api-Key"), Omit):
|
anthropic/_version.py
CHANGED
anthropic/lib/_files.py
CHANGED
|
@@ -22,7 +22,7 @@ def _collect_files(directory: Path, relative_to: Path, files: list[FileTypes]) -
|
|
|
22
22
|
_collect_files(path, relative_to, files)
|
|
23
23
|
continue
|
|
24
24
|
|
|
25
|
-
files.append((
|
|
25
|
+
files.append((path.relative_to(relative_to).as_posix(), path.read_bytes()))
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
async def async_files_from_dir(directory: str | os.PathLike[str]) -> list[FileTypes]:
|
|
@@ -39,4 +39,4 @@ async def _async_collect_files(directory: anyio.Path, relative_to: anyio.Path, f
|
|
|
39
39
|
await _async_collect_files(path, relative_to, files)
|
|
40
40
|
continue
|
|
41
41
|
|
|
42
|
-
files.append((
|
|
42
|
+
files.append((path.relative_to(relative_to).as_posix(), await path.read_bytes()))
|
anthropic/lib/foundry.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Anthropic Foundry
|
|
2
|
+
|
|
3
|
+
To use this library with Foundry, use the `AnthropicFoundry` class instead of the `Anthropic` class.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pip install anthropic
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
### Basic Usage with API Key
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
from anthropic import AnthropicFoundry
|
|
18
|
+
|
|
19
|
+
client = AnthropicFoundry(
|
|
20
|
+
api_key="...", # defaults to ANTHROPIC_FOUNDRY_API_KEY environment variable
|
|
21
|
+
resource="my-resource", # your Foundry resource
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
message = client.messages.create(
|
|
25
|
+
model="claude-3-5-sonnet-20241022",
|
|
26
|
+
max_tokens=1024,
|
|
27
|
+
messages=[{"role": "user", "content": "Hello!"}],
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
print(message.content[0].text)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Using Azure AD Token Provider
|
|
34
|
+
|
|
35
|
+
For enhanced security, you can use Azure AD (Microsoft Entra) authentication instead of an API key:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from anthropic import AnthropicFoundry
|
|
39
|
+
from azure.identity import DefaultAzureCredential
|
|
40
|
+
from azure.identity import get_bearer_token_provider
|
|
41
|
+
|
|
42
|
+
credential = DefaultAzureCredential()
|
|
43
|
+
token_provider = get_bearer_token_provider(
|
|
44
|
+
credential,
|
|
45
|
+
"https://ai.azure.com/.default"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
client = AnthropicFoundry(
|
|
49
|
+
azure_ad_token_provider=token_provider,
|
|
50
|
+
resource="my-resource",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
message = client.messages.create(
|
|
54
|
+
model="claude-3-5-sonnet-20241022",
|
|
55
|
+
max_tokens=1024,
|
|
56
|
+
messages=[{"role": "user", "content": "Hello!"}],
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
print(message.content[0].text)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Examples
|
|
63
|
+
|
|
64
|
+
### Streaming Messages
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from anthropic import AnthropicFoundry
|
|
68
|
+
|
|
69
|
+
client = AnthropicFoundry(
|
|
70
|
+
api_key="...",
|
|
71
|
+
resource="my-resource",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
with client.messages.stream(
|
|
75
|
+
model="claude-3-5-sonnet-20241022",
|
|
76
|
+
max_tokens=1024,
|
|
77
|
+
messages=[{"role": "user", "content": "Write a haiku about programming"}],
|
|
78
|
+
) as stream:
|
|
79
|
+
for text in stream.text_stream:
|
|
80
|
+
print(text, end="", flush=True)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Async Usage
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from anthropic import AsyncAnthropicFoundry
|
|
87
|
+
|
|
88
|
+
async def main():
|
|
89
|
+
client = AsyncAnthropicFoundry(
|
|
90
|
+
api_key="...",
|
|
91
|
+
resource="my-resource",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
message = await client.messages.create(
|
|
95
|
+
model="claude-3-5-sonnet-20241022",
|
|
96
|
+
max_tokens=1024,
|
|
97
|
+
messages=[{"role": "user", "content": "Hello!"}],
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
print(message.content[0].text)
|
|
101
|
+
|
|
102
|
+
import asyncio
|
|
103
|
+
asyncio.run(main())
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Async Streaming
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from anthropic import AsyncAnthropicFoundry
|
|
110
|
+
|
|
111
|
+
async def main():
|
|
112
|
+
client = AsyncAnthropicFoundry(
|
|
113
|
+
api_key="...",
|
|
114
|
+
resource="my-resource",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
async with client.messages.stream(
|
|
118
|
+
model="claude-3-5-sonnet-20241022",
|
|
119
|
+
max_tokens=1024,
|
|
120
|
+
messages=[{"role": "user", "content": "Write a haiku about programming"}],
|
|
121
|
+
) as stream:
|
|
122
|
+
async for text in stream.text_stream:
|
|
123
|
+
print(text, end="", flush=True)
|
|
124
|
+
|
|
125
|
+
import asyncio
|
|
126
|
+
asyncio.run(main())
|
|
127
|
+
```
|
anthropic/lib/foundry.py
ADDED
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import inspect
|
|
5
|
+
from typing import Any, Union, Mapping, TypeVar, Callable, Awaitable, cast, overload
|
|
6
|
+
from functools import cached_property
|
|
7
|
+
from typing_extensions import Self, override
|
|
8
|
+
|
|
9
|
+
import httpx
|
|
10
|
+
|
|
11
|
+
from .._types import NOT_GIVEN, Omit, Timeout, NotGiven
|
|
12
|
+
from .._utils import is_given
|
|
13
|
+
from .._client import Anthropic, AsyncAnthropic
|
|
14
|
+
from .._compat import model_copy
|
|
15
|
+
from .._models import FinalRequestOptions
|
|
16
|
+
from .._streaming import Stream, AsyncStream
|
|
17
|
+
from .._exceptions import AnthropicError
|
|
18
|
+
from .._base_client import DEFAULT_MAX_RETRIES, BaseClient
|
|
19
|
+
from ..resources.beta import Beta, AsyncBeta
|
|
20
|
+
from ..resources.messages import Messages, AsyncMessages
|
|
21
|
+
from ..resources.beta.messages import Messages as BetaMessages, AsyncMessages as AsyncBetaMessages
|
|
22
|
+
|
|
23
|
+
AzureADTokenProvider = Callable[[], str]
|
|
24
|
+
AsyncAzureADTokenProvider = Callable[[], "str | Awaitable[str]"]
|
|
25
|
+
_HttpxClientT = TypeVar("_HttpxClientT", bound=Union[httpx.Client, httpx.AsyncClient])
|
|
26
|
+
_DefaultStreamT = TypeVar("_DefaultStreamT", bound=Union[Stream[Any], AsyncStream[Any]])
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class MutuallyExclusiveAuthError(AnthropicError):
|
|
30
|
+
def __init__(self) -> None:
|
|
31
|
+
super().__init__(
|
|
32
|
+
"The `api_key` and `azure_ad_token_provider` arguments are mutually exclusive; Only one can be passed at a time"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class BaseFoundryClient(BaseClient[_HttpxClientT, _DefaultStreamT]): ...
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class MessagesFoundry(Messages):
|
|
40
|
+
@cached_property
|
|
41
|
+
@override
|
|
42
|
+
def batches(self) -> None: # type: ignore[override]
|
|
43
|
+
"""Batches endpoint is not supported for Anthropic Foundry client."""
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class BetaFoundryMessages(BetaMessages):
|
|
48
|
+
@cached_property
|
|
49
|
+
@override
|
|
50
|
+
def batches(self) -> None: # type: ignore[override]
|
|
51
|
+
"""Batches endpoint is not supported for Anthropic Foundry client."""
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class BetaFoundry(Beta):
|
|
56
|
+
@cached_property
|
|
57
|
+
@override
|
|
58
|
+
def messages(self) -> BetaMessages: # type: ignore[override]
|
|
59
|
+
"""Return beta messages resource instance with excluded unsupported endpoints."""
|
|
60
|
+
return BetaFoundryMessages(self._client)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class AsyncMessagesFoundry(AsyncMessages):
|
|
64
|
+
@cached_property
|
|
65
|
+
@override
|
|
66
|
+
def batches(self) -> None: # type: ignore[override]
|
|
67
|
+
"""Batches endpoint is not supported for Anthropic Foundry client."""
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class AsyncBetaFoundryMessages(AsyncBetaMessages):
|
|
72
|
+
@cached_property
|
|
73
|
+
@override
|
|
74
|
+
def batches(self) -> None: # type: ignore[override]
|
|
75
|
+
"""Batches endpoint is not supported for Anthropic Foundry client."""
|
|
76
|
+
return None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class AsyncBetaFoundry(AsyncBeta):
|
|
80
|
+
@cached_property
|
|
81
|
+
@override
|
|
82
|
+
def messages(self) -> AsyncBetaMessages: # type: ignore[override]
|
|
83
|
+
"""Return beta messages resource instance with excluded unsupported endpoints."""
|
|
84
|
+
return AsyncBetaFoundryMessages(self._client)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# ==============================================================================
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class AnthropicFoundry(BaseFoundryClient[httpx.Client, Stream[Any]], Anthropic):
|
|
91
|
+
@overload
|
|
92
|
+
def __init__(
|
|
93
|
+
self,
|
|
94
|
+
*,
|
|
95
|
+
resource: str | None = None,
|
|
96
|
+
api_key: str | None = None,
|
|
97
|
+
azure_ad_token_provider: AzureADTokenProvider | None = None,
|
|
98
|
+
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
99
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
100
|
+
default_headers: Mapping[str, str] | None = None,
|
|
101
|
+
default_query: Mapping[str, object] | None = None,
|
|
102
|
+
http_client: httpx.Client | None = None,
|
|
103
|
+
_strict_response_validation: bool = False,
|
|
104
|
+
) -> None: ...
|
|
105
|
+
|
|
106
|
+
@overload
|
|
107
|
+
def __init__(
|
|
108
|
+
self,
|
|
109
|
+
*,
|
|
110
|
+
base_url: str,
|
|
111
|
+
api_key: str | None = None,
|
|
112
|
+
azure_ad_token_provider: AzureADTokenProvider | None = None,
|
|
113
|
+
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
114
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
115
|
+
default_headers: Mapping[str, str] | None = None,
|
|
116
|
+
default_query: Mapping[str, object] | None = None,
|
|
117
|
+
http_client: httpx.Client | None = None,
|
|
118
|
+
_strict_response_validation: bool = False,
|
|
119
|
+
) -> None: ...
|
|
120
|
+
|
|
121
|
+
def __init__(
|
|
122
|
+
self,
|
|
123
|
+
*,
|
|
124
|
+
resource: str | None = None,
|
|
125
|
+
api_key: str | None = None,
|
|
126
|
+
azure_ad_token_provider: AzureADTokenProvider | None = None,
|
|
127
|
+
base_url: str | None = None,
|
|
128
|
+
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
129
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
130
|
+
default_headers: Mapping[str, str] | None = None,
|
|
131
|
+
default_query: Mapping[str, object] | None = None,
|
|
132
|
+
http_client: httpx.Client | None = None,
|
|
133
|
+
_strict_response_validation: bool = False,
|
|
134
|
+
) -> None:
|
|
135
|
+
"""Construct a new synchronous Anthropic Foundry client instance.
|
|
136
|
+
|
|
137
|
+
This automatically infers the following arguments from their corresponding environment variables if they are not provided:
|
|
138
|
+
- `api_key` from `ANTHROPIC_FOUNDRY_API_KEY`
|
|
139
|
+
- `resource` from `ANTHROPIC_FOUNDRY_RESOURCE`
|
|
140
|
+
- `base_url` from `ANTHROPIC_FOUNDRY_BASE_URL`
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
resource: Your Foundry resource name, e.g. `example-resource` for `https://example-resource.services.ai.azure.com/anthropic/`
|
|
144
|
+
azure_ad_token_provider: A function that returns an Azure Active Directory token, will be invoked on every request.
|
|
145
|
+
"""
|
|
146
|
+
api_key = api_key if api_key is not None else os.environ.get("ANTHROPIC_FOUNDRY_API_KEY")
|
|
147
|
+
resource = resource if resource is not None else os.environ.get("ANTHROPIC_FOUNDRY_RESOURCE")
|
|
148
|
+
base_url = base_url if base_url is not None else os.environ.get("ANTHROPIC_FOUNDRY_BASE_URL")
|
|
149
|
+
|
|
150
|
+
if api_key is None and azure_ad_token_provider is None:
|
|
151
|
+
raise AnthropicError(
|
|
152
|
+
"Missing credentials. Please pass one of `api_key`, `azure_ad_token_provider`, or the `ANTHROPIC_FOUNDRY_API_KEY` environment variable."
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
if base_url is None:
|
|
156
|
+
if resource is None:
|
|
157
|
+
raise ValueError(
|
|
158
|
+
"Must provide one of the `base_url` or `resource` arguments, or the `ANTHROPIC_FOUNDRY_RESOURCE` environment variable"
|
|
159
|
+
)
|
|
160
|
+
base_url = f"https://{resource}.services.ai.azure.com/anthropic/"
|
|
161
|
+
elif resource is not None:
|
|
162
|
+
raise ValueError("base_url and resource are mutually exclusive")
|
|
163
|
+
|
|
164
|
+
super().__init__(
|
|
165
|
+
api_key=api_key,
|
|
166
|
+
base_url=base_url,
|
|
167
|
+
timeout=timeout,
|
|
168
|
+
max_retries=max_retries,
|
|
169
|
+
default_headers=default_headers,
|
|
170
|
+
default_query=default_query,
|
|
171
|
+
http_client=http_client,
|
|
172
|
+
_strict_response_validation=_strict_response_validation,
|
|
173
|
+
)
|
|
174
|
+
self._azure_ad_token_provider = azure_ad_token_provider
|
|
175
|
+
|
|
176
|
+
@cached_property
|
|
177
|
+
@override
|
|
178
|
+
def models(self) -> None: # type: ignore[override]
|
|
179
|
+
"""Models endpoint is not supported for Anthropic Foundry client."""
|
|
180
|
+
return None
|
|
181
|
+
|
|
182
|
+
@cached_property
|
|
183
|
+
@override
|
|
184
|
+
def messages(self) -> MessagesFoundry: # type: ignore[override]
|
|
185
|
+
"""Return messages resource instance with excluded unsupported endpoints."""
|
|
186
|
+
return MessagesFoundry(client=self)
|
|
187
|
+
|
|
188
|
+
@cached_property
|
|
189
|
+
@override
|
|
190
|
+
def beta(self) -> Beta: # type: ignore[override]
|
|
191
|
+
"""Return beta resource instance with excluded unsupported endpoints."""
|
|
192
|
+
return BetaFoundry(self)
|
|
193
|
+
|
|
194
|
+
@override
|
|
195
|
+
def copy(
|
|
196
|
+
self,
|
|
197
|
+
*,
|
|
198
|
+
api_key: str | None = None,
|
|
199
|
+
azure_ad_token_provider: AzureADTokenProvider | None = None,
|
|
200
|
+
auth_token: str | None = None,
|
|
201
|
+
base_url: str | httpx.URL | None = None,
|
|
202
|
+
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
203
|
+
http_client: httpx.Client | None = None,
|
|
204
|
+
max_retries: int | NotGiven = NOT_GIVEN,
|
|
205
|
+
default_headers: Mapping[str, str] | None = None,
|
|
206
|
+
set_default_headers: Mapping[str, str] | None = None,
|
|
207
|
+
default_query: Mapping[str, object] | None = None,
|
|
208
|
+
set_default_query: Mapping[str, object] | None = None,
|
|
209
|
+
_extra_kwargs: Mapping[str, Any] = {},
|
|
210
|
+
) -> Self:
|
|
211
|
+
"""
|
|
212
|
+
Create a new client instance re-using the same options given to the current client with optional overriding.
|
|
213
|
+
"""
|
|
214
|
+
return super().copy(
|
|
215
|
+
api_key=api_key,
|
|
216
|
+
auth_token=auth_token,
|
|
217
|
+
base_url=base_url,
|
|
218
|
+
timeout=timeout,
|
|
219
|
+
http_client=http_client,
|
|
220
|
+
max_retries=max_retries,
|
|
221
|
+
default_headers=default_headers,
|
|
222
|
+
set_default_headers=set_default_headers,
|
|
223
|
+
default_query=default_query,
|
|
224
|
+
set_default_query=set_default_query,
|
|
225
|
+
_extra_kwargs={
|
|
226
|
+
"azure_ad_token_provider": azure_ad_token_provider or self._azure_ad_token_provider,
|
|
227
|
+
**_extra_kwargs,
|
|
228
|
+
},
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
with_options = copy
|
|
232
|
+
|
|
233
|
+
def _get_azure_ad_token(self) -> str | None:
|
|
234
|
+
provider = self._azure_ad_token_provider
|
|
235
|
+
if provider is not None:
|
|
236
|
+
token = provider()
|
|
237
|
+
if not token or not isinstance(token, str): # pyright: ignore[reportUnnecessaryIsInstance]
|
|
238
|
+
raise ValueError(
|
|
239
|
+
f"Expected `azure_ad_token_provider` argument to return a string but it returned {token}",
|
|
240
|
+
)
|
|
241
|
+
return token
|
|
242
|
+
|
|
243
|
+
return None
|
|
244
|
+
|
|
245
|
+
@override
|
|
246
|
+
def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions:
|
|
247
|
+
headers: dict[str, str | Omit] = {**options.headers} if is_given(options.headers) else {}
|
|
248
|
+
|
|
249
|
+
options = model_copy(options)
|
|
250
|
+
options.headers = headers
|
|
251
|
+
|
|
252
|
+
azure_ad_token = self._get_azure_ad_token()
|
|
253
|
+
if azure_ad_token is not None:
|
|
254
|
+
if headers.get("Authorization") is None:
|
|
255
|
+
headers["Authorization"] = f"Bearer {azure_ad_token}"
|
|
256
|
+
elif self.api_key is not None:
|
|
257
|
+
if headers.get("api-key") is None:
|
|
258
|
+
assert self.api_key is not None
|
|
259
|
+
headers["api-key"] = self.api_key
|
|
260
|
+
else:
|
|
261
|
+
# should never be hit
|
|
262
|
+
raise ValueError("Unable to handle auth")
|
|
263
|
+
|
|
264
|
+
return options
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class AsyncAnthropicFoundry(BaseFoundryClient[httpx.AsyncClient, AsyncStream[Any]], AsyncAnthropic):
|
|
268
|
+
@overload
|
|
269
|
+
def __init__(
|
|
270
|
+
self,
|
|
271
|
+
*,
|
|
272
|
+
resource: str | None = None,
|
|
273
|
+
api_key: str | None = None,
|
|
274
|
+
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
|
|
275
|
+
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
276
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
277
|
+
default_headers: Mapping[str, str] | None = None,
|
|
278
|
+
default_query: Mapping[str, object] | None = None,
|
|
279
|
+
http_client: httpx.AsyncClient | None = None,
|
|
280
|
+
_strict_response_validation: bool = False,
|
|
281
|
+
) -> None: ...
|
|
282
|
+
|
|
283
|
+
@overload
|
|
284
|
+
def __init__(
|
|
285
|
+
self,
|
|
286
|
+
*,
|
|
287
|
+
base_url: str,
|
|
288
|
+
api_key: str | None = None,
|
|
289
|
+
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
|
|
290
|
+
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
291
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
292
|
+
default_headers: Mapping[str, str] | None = None,
|
|
293
|
+
default_query: Mapping[str, object] | None = None,
|
|
294
|
+
http_client: httpx.AsyncClient | None = None,
|
|
295
|
+
_strict_response_validation: bool = False,
|
|
296
|
+
) -> None: ...
|
|
297
|
+
|
|
298
|
+
def __init__(
|
|
299
|
+
self,
|
|
300
|
+
*,
|
|
301
|
+
resource: str | None = None,
|
|
302
|
+
api_key: str | None = None,
|
|
303
|
+
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
|
|
304
|
+
base_url: str | None = None,
|
|
305
|
+
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
306
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
307
|
+
default_headers: Mapping[str, str] | None = None,
|
|
308
|
+
default_query: Mapping[str, object] | None = None,
|
|
309
|
+
http_client: httpx.AsyncClient | None = None,
|
|
310
|
+
_strict_response_validation: bool = False,
|
|
311
|
+
) -> None:
|
|
312
|
+
"""Construct a new asynchronous Anthropic Foundry client instance.
|
|
313
|
+
|
|
314
|
+
This automatically infers the following arguments from their corresponding environment variables if they are not provided:
|
|
315
|
+
- `api_key` from `ANTHROPIC_FOUNDRY_API_KEY`
|
|
316
|
+
- `resource` from `ANTHROPIC_FOUNDRY_RESOURCE`
|
|
317
|
+
- `base_url` from `ANTHROPIC_FOUNDRY_BASE_URL`
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
resource: Your Foundry resource name, e.g. `example-resource` for `https://example-resource.services.ai.azure.com/anthropic/`
|
|
321
|
+
azure_ad_token_provider: A function that returns an Azure Active Directory token, will be invoked on every request.
|
|
322
|
+
"""
|
|
323
|
+
api_key = api_key if api_key is not None else os.environ.get("ANTHROPIC_FOUNDRY_API_KEY")
|
|
324
|
+
resource = resource if resource is not None else os.environ.get("ANTHROPIC_FOUNDRY_RESOURCE")
|
|
325
|
+
base_url = base_url if base_url is not None else os.environ.get("ANTHROPIC_FOUNDRY_BASE_URL")
|
|
326
|
+
|
|
327
|
+
if api_key is None and azure_ad_token_provider is None:
|
|
328
|
+
raise AnthropicError(
|
|
329
|
+
"Missing credentials. Please pass one of `api_key`, `azure_ad_token_provider`, or the `ANTHROPIC_FOUNDRY_API_KEY` environment variable."
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
if base_url is None:
|
|
333
|
+
if resource is None:
|
|
334
|
+
raise ValueError(
|
|
335
|
+
"Must provide one of the `base_url` or `resource` arguments, or the `ANTHROPIC_FOUNDRY_RESOURCE` environment variable"
|
|
336
|
+
)
|
|
337
|
+
base_url = f"https://{resource}.services.ai.azure.com/anthropic/"
|
|
338
|
+
elif resource is not None:
|
|
339
|
+
raise ValueError("base_url and resource are mutually exclusive")
|
|
340
|
+
|
|
341
|
+
super().__init__(
|
|
342
|
+
api_key=api_key,
|
|
343
|
+
base_url=base_url,
|
|
344
|
+
timeout=timeout,
|
|
345
|
+
max_retries=max_retries,
|
|
346
|
+
default_headers=default_headers,
|
|
347
|
+
default_query=default_query,
|
|
348
|
+
http_client=http_client,
|
|
349
|
+
_strict_response_validation=_strict_response_validation,
|
|
350
|
+
)
|
|
351
|
+
self._azure_ad_token_provider = azure_ad_token_provider
|
|
352
|
+
|
|
353
|
+
@cached_property
|
|
354
|
+
@override
|
|
355
|
+
def models(self) -> None: # type: ignore[override]
|
|
356
|
+
"""Models endpoint is not supported for Azure Anthropic client."""
|
|
357
|
+
return None
|
|
358
|
+
|
|
359
|
+
@cached_property
|
|
360
|
+
@override
|
|
361
|
+
def messages(self) -> AsyncMessagesFoundry: # type: ignore[override]
|
|
362
|
+
"""Return messages resource instance with excluded unsupported endpoints."""
|
|
363
|
+
return AsyncMessagesFoundry(client=self)
|
|
364
|
+
|
|
365
|
+
@cached_property
|
|
366
|
+
@override
|
|
367
|
+
def beta(self) -> AsyncBetaFoundry: # type: ignore[override]
|
|
368
|
+
"""Return beta resource instance with excluded unsupported endpoints."""
|
|
369
|
+
return AsyncBetaFoundry(client=self)
|
|
370
|
+
|
|
371
|
+
@override
|
|
372
|
+
def copy(
|
|
373
|
+
self,
|
|
374
|
+
*,
|
|
375
|
+
api_key: str | None = None,
|
|
376
|
+
azure_ad_token_provider: AsyncAzureADTokenProvider | None = None,
|
|
377
|
+
auth_token: str | None = None,
|
|
378
|
+
base_url: str | httpx.URL | None = None,
|
|
379
|
+
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
380
|
+
http_client: httpx.AsyncClient | None = None,
|
|
381
|
+
max_retries: int | NotGiven = NOT_GIVEN,
|
|
382
|
+
default_headers: Mapping[str, str] | None = None,
|
|
383
|
+
set_default_headers: Mapping[str, str] | None = None,
|
|
384
|
+
default_query: Mapping[str, object] | None = None,
|
|
385
|
+
set_default_query: Mapping[str, object] | None = None,
|
|
386
|
+
_extra_kwargs: Mapping[str, Any] = {},
|
|
387
|
+
) -> Self:
|
|
388
|
+
"""
|
|
389
|
+
Create a new client instance re-using the same options given to the current client with optional overriding.
|
|
390
|
+
"""
|
|
391
|
+
return super().copy(
|
|
392
|
+
api_key=api_key,
|
|
393
|
+
auth_token=auth_token,
|
|
394
|
+
base_url=base_url,
|
|
395
|
+
timeout=timeout,
|
|
396
|
+
http_client=http_client,
|
|
397
|
+
max_retries=max_retries,
|
|
398
|
+
default_headers=default_headers,
|
|
399
|
+
set_default_headers=set_default_headers,
|
|
400
|
+
default_query=default_query,
|
|
401
|
+
set_default_query=set_default_query,
|
|
402
|
+
_extra_kwargs={
|
|
403
|
+
"azure_ad_token_provider": azure_ad_token_provider or self._azure_ad_token_provider,
|
|
404
|
+
**_extra_kwargs,
|
|
405
|
+
},
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
with_options = copy
|
|
409
|
+
|
|
410
|
+
async def _get_azure_ad_token(self) -> str | None:
|
|
411
|
+
provider = self._azure_ad_token_provider
|
|
412
|
+
if provider is not None:
|
|
413
|
+
token = provider()
|
|
414
|
+
if inspect.isawaitable(token):
|
|
415
|
+
token = await token
|
|
416
|
+
if not token or not isinstance(cast(Any, token), str):
|
|
417
|
+
raise ValueError(
|
|
418
|
+
f"Expected `azure_ad_token_provider` argument to return a string but it returned {token}",
|
|
419
|
+
)
|
|
420
|
+
return str(token)
|
|
421
|
+
|
|
422
|
+
return None
|
|
423
|
+
|
|
424
|
+
@override
|
|
425
|
+
async def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions:
|
|
426
|
+
headers: dict[str, str | Omit] = {**options.headers} if is_given(options.headers) else {}
|
|
427
|
+
|
|
428
|
+
options = model_copy(options)
|
|
429
|
+
options.headers = headers
|
|
430
|
+
|
|
431
|
+
azure_ad_token = await self._get_azure_ad_token()
|
|
432
|
+
if azure_ad_token is not None:
|
|
433
|
+
if headers.get("Authorization") is None:
|
|
434
|
+
headers["Authorization"] = f"Bearer {azure_ad_token}"
|
|
435
|
+
elif self.api_key is not None:
|
|
436
|
+
assert self.api_key is not None
|
|
437
|
+
if headers.get("api-key") is None:
|
|
438
|
+
headers["api-key"] = self.api_key
|
|
439
|
+
else:
|
|
440
|
+
# should never be hit
|
|
441
|
+
raise ValueError("Unable to handle auth")
|
|
442
|
+
|
|
443
|
+
return options
|
|
@@ -1076,9 +1076,9 @@ class Messages(SyncAPIResource):
|
|
|
1076
1076
|
|
|
1077
1077
|
betas = [beta for beta in betas] if is_given(betas) else []
|
|
1078
1078
|
|
|
1079
|
-
if "structured-outputs-2025-
|
|
1079
|
+
if "structured-outputs-2025-11-13" not in betas:
|
|
1080
1080
|
# Ensure structured outputs beta is included for parse method
|
|
1081
|
-
betas.append("structured-outputs-2025-
|
|
1081
|
+
betas.append("structured-outputs-2025-11-13")
|
|
1082
1082
|
|
|
1083
1083
|
extra_headers = {
|
|
1084
1084
|
"X-Stainless-Helper": "beta.messages.parse",
|
|
@@ -2688,9 +2688,9 @@ class AsyncMessages(AsyncAPIResource):
|
|
|
2688
2688
|
)
|
|
2689
2689
|
betas = [beta for beta in betas] if is_given(betas) else []
|
|
2690
2690
|
|
|
2691
|
-
if "structured-outputs-2025-
|
|
2691
|
+
if "structured-outputs-2025-11-13" not in betas:
|
|
2692
2692
|
# Ensure structured outputs beta is included for parse method
|
|
2693
|
-
betas.append("structured-outputs-2025-
|
|
2693
|
+
betas.append("structured-outputs-2025-11-13")
|
|
2694
2694
|
|
|
2695
2695
|
extra_headers = {
|
|
2696
2696
|
"X-Stainless-Helper": "beta.messages.parse",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: anthropic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.74.1
|
|
4
4
|
Summary: The official Python library for the anthropic API
|
|
5
5
|
Project-URL: Homepage, https://github.com/anthropics/anthropic-sdk-python
|
|
6
6
|
Project-URL: Repository, https://github.com/anthropics/anthropic-sdk-python
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
anthropic/__init__.py,sha256=
|
|
1
|
+
anthropic/__init__.py,sha256=xp5IG2sv6wh0O6u-pJN8g3PJkQHfs2qIfU20muCRyj8,3167
|
|
2
2
|
anthropic/_base_client.py,sha256=Ca5ANeCg2kvkN3Ego42boLcHIhj9npORXzh3VGQs1tw,72929
|
|
3
|
-
anthropic/_client.py,sha256=
|
|
3
|
+
anthropic/_client.py,sha256=_BM__6VgtQZZCkWMGv6z58yTESUDtQVt2QWZIy_ya7U,23030
|
|
4
4
|
anthropic/_compat.py,sha256=t3bXgTygusFSjp0qoTb9D6E749djY0tFAwHMgKEE-Rw,6775
|
|
5
5
|
anthropic/_constants.py,sha256=wADeUqY3lsseF0L6jIen-PexfQ06FOtf2dVESXDM828,885
|
|
6
6
|
anthropic/_exceptions.py,sha256=bkSqVWxtRdRb31H7MIvtxfh5mo_Xf7Ib3nPTOmAOmGs,4073
|
|
@@ -12,7 +12,7 @@ anthropic/_resource.py,sha256=FYEOzfhB-XWTR2gyTmQuuFoecRiVXxe_SpjZlQQGytU,1080
|
|
|
12
12
|
anthropic/_response.py,sha256=1Y7-OrGn1lOwvZ_SmMlwT9Nb2i9A1RYw2Q4-F1cwPSU,30542
|
|
13
13
|
anthropic/_streaming.py,sha256=AVgSkkvKHZsFD4xQbkOi9Oi0vkHoEZbkccyUw5yIxmA,14072
|
|
14
14
|
anthropic/_types.py,sha256=vEab5B5Hp7xQQafVrgSCHeEPUmf74jofqIPo-n7Xljk,7338
|
|
15
|
-
anthropic/_version.py,sha256=
|
|
15
|
+
anthropic/_version.py,sha256=RYabrekg643fRS1GXAocPuIMGw1-85RFzoldGyJ7Sxs,162
|
|
16
16
|
anthropic/pagination.py,sha256=MgGFbx3GDm4XASijWas0-2eVb1iGR-DgqyPrDf5Jll8,5152
|
|
17
17
|
anthropic/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
anthropic/_decoders/jsonl.py,sha256=KDLw-Frjo7gRup5qDp_BWkXIZ-mFZU5vFDz0WBhEKcs,3510
|
|
@@ -31,7 +31,9 @@ anthropic/_utils/_typing.py,sha256=N_5PPuFNsaygbtA_npZd98SVN1LQQvFTKL6bkWPBZGU,4
|
|
|
31
31
|
anthropic/_utils/_utils.py,sha256=ugfUaneOK7I8h9b3656flwf5u_kthY0gvNuqvgOLoSU,12252
|
|
32
32
|
anthropic/lib/.keep,sha256=wuNrz-5SXo3jJaJOJgz4vFHM41YH_g20F5cRQo0vLes,224
|
|
33
33
|
anthropic/lib/__init__.py,sha256=ed3VXosCln6iXSojwutNZjzjoIVpDLIHfMiiMiSHjlU,99
|
|
34
|
-
anthropic/lib/_files.py,sha256=
|
|
34
|
+
anthropic/lib/_files.py,sha256=gVtOWR-evsIJV_HCX225tPRU6Dyj73FWXb7OPt5CVcQ,1221
|
|
35
|
+
anthropic/lib/foundry.md,sha256=jFWVnP5a8qARzQjUdtvxhF1p2pkPo2WCRfkumhvdlZw,2745
|
|
36
|
+
anthropic/lib/foundry.py,sha256=q4fZOnbBcBWFE_fVwL9EyJBFt-RFk0l78bzFxyO9Q2k,17537
|
|
35
37
|
anthropic/lib/_extras/__init__.py,sha256=a9HX69-V9nROM4Em9a4y-xZTgiLE2jdlCyC6ZKtxfyY,53
|
|
36
38
|
anthropic/lib/_extras/_common.py,sha256=IhHjAsirY2xfLJrzlt9rS_0IPsTJeWqKA2HWUuvDN14,348
|
|
37
39
|
anthropic/lib/_extras/_google_auth.py,sha256=Wukh6VOgcDRYSsFCVT9tx_oXI1ApIsmioSLEMsYvDfw,688
|
|
@@ -67,7 +69,7 @@ anthropic/resources/beta/files.py,sha256=rz2seKKOcoF0ebUMEMF86LoPWi1YqK2zp-dMQ7t
|
|
|
67
69
|
anthropic/resources/beta/models.py,sha256=1bPko6YIziXlKj9GWnAxReEoWIT_7TwBpU_oCUMhBlo,12516
|
|
68
70
|
anthropic/resources/beta/messages/__init__.py,sha256=7ZO4hB7hPBhXQja7gMzkwLXQVDlyap4JsihpA0UKZjk,849
|
|
69
71
|
anthropic/resources/beta/messages/batches.py,sha256=51m83Ijs6cIE_f4hRQNhSyNqDj5TVt0F0Bm4ryekoLw,36116
|
|
70
|
-
anthropic/resources/beta/messages/messages.py,sha256=
|
|
72
|
+
anthropic/resources/beta/messages/messages.py,sha256=tnm8ra108AC1AjQ2neWCFHbdYVQPU3_J1aKSWemjAVI,151689
|
|
71
73
|
anthropic/resources/beta/skills/__init__.py,sha256=QMC_HEzfI-k0jhfKJThUUjf9wf7Vs8HTxSXYNnvVx2o,836
|
|
72
74
|
anthropic/resources/beta/skills/skills.py,sha256=ytCR9JN7Qgn9GbWT0oBgpy-nvYXWwqoBvOzZ_iURANE,25036
|
|
73
75
|
anthropic/resources/beta/skills/versions.py,sha256=iWSrZ4iqVGm16f7r_aE79gDxeUTUaSw5dEBAyHIxRu8,25212
|
|
@@ -411,7 +413,7 @@ anthropic/types/shared/not_found_error.py,sha256=R6OsCvAmsf_SB2TwoX6E63o049qZMaA
|
|
|
411
413
|
anthropic/types/shared/overloaded_error.py,sha256=PlyhHt3wmzcnynSfkWbfP4XkLoWsPa9B39V3CyAdgx8,282
|
|
412
414
|
anthropic/types/shared/permission_error.py,sha256=nuyxtLXOiEkYEbFRXiAWjxU6XtdyjkAaXQ2NgMB3pjw,282
|
|
413
415
|
anthropic/types/shared/rate_limit_error.py,sha256=eYULATjXa6KKdqeBauest7RzuN-bhGsY5BWwH9eYv4c,280
|
|
414
|
-
anthropic-0.
|
|
415
|
-
anthropic-0.
|
|
416
|
-
anthropic-0.
|
|
417
|
-
anthropic-0.
|
|
416
|
+
anthropic-0.74.1.dist-info/METADATA,sha256=hj9E86URKPzwsGvQYSWbc106lywLRwyc6x-_TMkFtkU,28514
|
|
417
|
+
anthropic-0.74.1.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
418
|
+
anthropic-0.74.1.dist-info/licenses/LICENSE,sha256=i_lphP-Lz65-SMrnalKeiiUxe6ngKr9_08xk_flWV6Y,1056
|
|
419
|
+
anthropic-0.74.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|