From 4ffbcdf1d3c8c2fbaf7152d207b24cdb0ea82ac9 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Tue, 19 Dec 2023 13:21:58 -0500
Subject: [PATCH 1/8] chore(internal): fix typos (#287)
---
src/anthropic/_base_client.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/anthropic/_base_client.py b/src/anthropic/_base_client.py
index 92189617..481171a4 100644
--- a/src/anthropic/_base_client.py
+++ b/src/anthropic/_base_client.py
@@ -107,7 +107,7 @@
class PageInfo:
- """Stores the necesary information to build the request to retrieve the next page.
+ """Stores the necessary information to build the request to retrieve the next page.
Either `url` or `params` must be set.
"""
From eec4574f1f6668804c88bda67b901db10400fbc3 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Tue, 19 Dec 2023 13:53:28 -0500
Subject: [PATCH 2/8] docs(readme): remove old migration guide (#289)
---
README.md | 64 -------------------------------------------------------
1 file changed, 64 deletions(-)
diff --git a/README.md b/README.md
index 82e8c20c..ae5c548f 100644
--- a/README.md
+++ b/README.md
@@ -8,70 +8,6 @@ and offers both synchronous and asynchronous clients powered by [httpx](https://
For the AWS Bedrock API, see [`anthropic-bedrock`](https://github.com/anthropics/anthropic-bedrock-python).
-## Migration from v0.2.x and below
-
-In `v0.3.0`, we introduced a fully rewritten SDK.
-
-The new version uses separate sync and async clients, unified streaming, typed params and structured response objects, and resource-oriented methods:
-
-**Sync before/after:**
-
-```diff
-- client = anthropic.Client(os.environ["ANTHROPIC_API_KEY"])
-+ client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
- # or, simply provide an ANTHROPIC_API_KEY environment variable:
-+ client = anthropic.Anthropic()
-
-- rsp = client.completion(**params)
-- rsp["completion"]
-+ rsp = client.completions.create(**params)
-+ rsp.completion
-```
-
-**Async before/after:**
-
-```diff
-- client = anthropic.Client(os.environ["ANTHROPIC_API_KEY"])
-+ client = anthropic.AsyncAnthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
-
-- await client.acompletion(**params)
-+ await client.completions.create(**params)
-```
-
-The `.completion_stream()` and `.acompletion_stream()` methods have been removed;
-simply pass `stream=True`to `.completions.create()`.
-
-Streaming responses are now incremental; the full text is not sent in each message,
-as v0.3 sends the `Anthropic-Version: 2023-06-01` header.
-
-
-Example streaming diff
-
-```diff py
- import anthropic
-
-- client = anthropic.Client(os.environ["ANTHROPIC_API_KEY"])
-+ client = anthropic.Anthropic()
-
- # Streams are now incremental diffs of text
- # rather than sending the whole message every time:
- text = "
-- stream = client.completion_stream(**params)
-- for data in stream:
-- diff = data["completion"].replace(text, "")
-- text = data["completion"]
-+ stream = client.completions.create(**params, stream=True)
-+ for data in stream:
-+ diff = data.completion # incremental text
-+ text += data.completion
- print(diff, end="")
-
- print("Done. Final text is:")
- print(text)
-```
-
-
-
## Documentation
The API documentation can be found [here](https://docs.anthropic.com/claude/reference/).
From 9ec5c57ba9a14a769d540e48755b05a1c190b45b Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Tue, 19 Dec 2023 14:04:35 -0500
Subject: [PATCH 3/8] chore(package): bump minimum typing-extensions to 4.7
(#290)
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index e18918f3..905f3cee 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -10,7 +10,7 @@ authors = [
dependencies = [
"httpx>=0.23.0, <1",
"pydantic>=1.9.0, <3",
- "typing-extensions>=4.5, <5",
+ "typing-extensions>=4.7, <5",
"anyio>=3.5.0, <5",
"distro>=1.7.0, <2",
"sniffio",
From d18a895d380fc0c6610443486d73247b0cd97376 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Wed, 20 Dec 2023 20:21:52 -0500
Subject: [PATCH 4/8] docs(messages): improvements to helpers reference + typos
(#291)
---
README.md | 7 ++---
examples/messages_stream_handler.py | 3 +--
helpers.md | 40 ++++++++++++++++++++++++++++-
3 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index ae5c548f..a61754bd 100644
--- a/README.md
+++ b/README.md
@@ -131,11 +131,8 @@ async def main() -> None:
print(text, end="", flush=True)
print()
- # you can still get the accumulated final message outside of
- # the context manager, as long as the entire stream was consumed
- # inside of the context manager
- accumulated = await stream.get_final_message()
- print(accumulated.model_dump_json(indent=2))
+ message = await stream.get_final_message()
+ print(message.model_dump_json(indent=2))
asyncio.run(main())
```
diff --git a/examples/messages_stream_handler.py b/examples/messages_stream_handler.py
index 41f982f7..a0175d6f 100644
--- a/examples/messages_stream_handler.py
+++ b/examples/messages_stream_handler.py
@@ -1,9 +1,8 @@
import asyncio
from typing_extensions import override
-from anthropic import AsyncAnthropic
+from anthropic import AsyncAnthropic, AsyncMessageStream
from anthropic.types.beta import MessageStreamEvent
-from anthropic.lib.streaming import AsyncMessageStream
client = AsyncAnthropic()
diff --git a/helpers.md b/helpers.md
index 821cae62..a5edcaf8 100644
--- a/helpers.md
+++ b/helpers.md
@@ -21,7 +21,7 @@ async with client.beta.messages.stream(
`client.beta.messages.stream()` returns a `MessageStreamManager`, which is a context manager that yields a `MessageStream` which is iterable, emits events and accumulates messages.
Alternatively, you can use `client.beta.messages.create(..., stream=True)` which returns an
-iteratable of the events in the stream and uses less memory (most notably, it does not accumulate a final message
+iterable of the events in the stream and uses less memory (most notably, it does not accumulate a final message
object for you).
The stream will be cancelled when the context manager exits but you can also close it prematurely by calling `stream.close()`.
@@ -45,6 +45,44 @@ print()
### Events
+You can pass an `event_handler` argument to `client.beta.messages.stream` to register callback methods that are fired when certain events happen:
+
+```py
+import asyncio
+from typing_extensions import override
+
+from anthropic import AsyncAnthropic, AsyncMessageStream
+from anthropic.types.beta import MessageStreamEvent
+
+client = AsyncAnthropic()
+
+class MyStream(AsyncMessageStream):
+ @override
+ async def on_text(self, delta: str) -> None:
+ print(text, end="", flush=True)
+
+ @override
+ async def on_stream_event(self, event: MessageStreamEvent) -> None:
+ print("on_event fired with:", event)
+
+async def main() -> None:
+ async with client.beta.messages.stream(
+ max_tokens=1024,
+ messages=[
+ {
+ "role": "user",
+ "content": "Say hello there!",
+ }
+ ],
+ model="claude-2.1",
+ event_handler=MyStream,
+ ) as stream:
+ message = await stream.get_final_message()
+ print("accumulated message: ", message.model_dump_json(indent=2))
+
+asyncio.run(main())
+```
+
#### `await on_stream_event(event: MessageStreamEvent)`
The event is fired when an event is received from the API.
From ba2953dcaa8a8fcebaa7e8891304687c95b17499 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Thu, 21 Dec 2023 07:39:09 -0500
Subject: [PATCH 5/8] chore(internal): add bin script (#292)
---
bin/check-env-state.py | 40 ++++++++++++++++++++++++++++++++++++++++
pyproject.toml | 1 +
requirements-dev.lock | 4 +++-
3 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 bin/check-env-state.py
diff --git a/bin/check-env-state.py b/bin/check-env-state.py
new file mode 100644
index 00000000..e1b8b6cb
--- /dev/null
+++ b/bin/check-env-state.py
@@ -0,0 +1,40 @@
+"""Script that exits 1 if the current environment is not
+in sync with the `requirements-dev.lock` file.
+"""
+
+from pathlib import Path
+
+import importlib_metadata
+
+
+def should_run_sync() -> bool:
+ dev_lock = Path(__file__).parent.parent.joinpath("requirements-dev.lock")
+
+ for line in dev_lock.read_text().splitlines():
+ if not line or line.startswith("#") or line.startswith("-e"):
+ continue
+
+ dep, lock_version = line.split("==")
+
+ try:
+ version = importlib_metadata.version(dep)
+
+ if lock_version != version:
+ print(f"mismatch for {dep} current={version} lock={lock_version}")
+ return True
+ except Exception:
+ print(f"could not import {dep}")
+ return True
+
+ return False
+
+
+def main() -> None:
+ if should_run_sync():
+ exit(1)
+ else:
+ exit(0)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/pyproject.toml b/pyproject.toml
index 905f3cee..2e837c62 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -58,6 +58,7 @@ dev-dependencies = [
"time-machine",
"nox",
"dirty-equals>=0.6.0",
+ "importlib-metadata>=6.7.0",
]
diff --git a/requirements-dev.lock b/requirements-dev.lock
index f1d546fc..07c2e0e5 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -21,12 +21,13 @@ distlib==0.3.7
distro==1.8.0
exceptiongroup==1.1.3
filelock==3.12.4
-fsspec==2023.12.1
+fsspec==2023.12.2
h11==0.14.0
httpcore==1.0.2
httpx==0.25.2
huggingface-hub==0.16.4
idna==3.4
+importlib-metadata==7.0.0
iniconfig==2.0.0
isort==5.10.1
mypy==1.7.1
@@ -58,5 +59,6 @@ tqdm==4.66.1
typing-extensions==4.8.0
urllib3==2.1.0
virtualenv==20.24.5
+zipp==3.17.0
# The following packages are considered to be unsafe in a requirements file:
setuptools==68.2.2
From ae6c59fab76e6736b469a44e6d6b1f884a9d77b3 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Thu, 21 Dec 2023 22:47:39 -0500
Subject: [PATCH 6/8] test: run the garbage collector less often (#293)
---
tests/test_client.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/test_client.py b/tests/test_client.py
index f474752c..2fe4afe6 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -208,8 +208,8 @@ def build_request(options: FinalRequestOptions) -> None:
ITERATIONS = 10
for _ in range(ITERATIONS):
build_request(options)
- gc.collect()
+ gc.collect()
snapshot_after = tracemalloc.take_snapshot()
tracemalloc.stop()
@@ -964,8 +964,8 @@ def build_request(options: FinalRequestOptions) -> None:
ITERATIONS = 10
for _ in range(ITERATIONS):
build_request(options)
- gc.collect()
+ gc.collect()
snapshot_after = tracemalloc.take_snapshot()
tracemalloc.stop()
From 1753887a776f41bdc2d648329cfe6f20c91125e5 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Fri, 22 Dec 2023 05:44:58 -0500
Subject: [PATCH 7/8] chore(internal): use ruff instead of black for formatting
(#294)
---
bin/{blacken-docs.py => ruffen-docs.py} | 130 ++++-------------------
pyproject.toml | 12 ++-
requirements-dev.lock | 5 +-
src/anthropic/_models.py | 2 +-
src/anthropic/_types.py | 16 +--
src/anthropic/_utils/_transform.py | 5 +-
src/anthropic/_utils/_utils.py | 4 +-
src/anthropic/lib/streaming/_messages.py | 12 +--
tests/test_transform.py | 4 +-
9 files changed, 56 insertions(+), 134 deletions(-)
rename bin/{blacken-docs.py => ruffen-docs.py} (52%)
diff --git a/bin/blacken-docs.py b/bin/ruffen-docs.py
similarity index 52%
rename from bin/blacken-docs.py
rename to bin/ruffen-docs.py
index 45d0ad12..37b3d94f 100644
--- a/bin/blacken-docs.py
+++ b/bin/ruffen-docs.py
@@ -1,16 +1,14 @@
-# fork of https://github.com/asottile/blacken-docs implementing https://github.com/asottile/blacken-docs/issues/170
+# fork of https://github.com/asottile/blacken-docs adapted for ruff
from __future__ import annotations
import re
+import sys
import argparse
import textwrap
import contextlib
+import subprocess
from typing import Match, Optional, Sequence, Generator, NamedTuple, cast
-import black
-from black.mode import TargetVersion
-from black.const import DEFAULT_LINE_LENGTH
-
MD_RE = re.compile(
r"(?P^(?P *)```\s*python\n)" r"(?P.*?)" r"(?P^(?P=indent)```\s*$)",
re.DOTALL | re.MULTILINE,
@@ -19,55 +17,12 @@
r"(?P^(?P *)```\s*pycon\n)" r"(?P.*?)" r"(?P^(?P=indent)```.*$)",
re.DOTALL | re.MULTILINE,
)
-RST_PY_LANGS = frozenset(("python", "py", "sage", "python3", "py3", "numpy"))
-BLOCK_TYPES = "(code|code-block|sourcecode|ipython)"
-DOCTEST_TYPES = "(testsetup|testcleanup|testcode)"
-RST_RE = re.compile(
- rf"(?P"
- rf"^(?P *)\.\. ("
- rf"jupyter-execute::|"
- rf"{BLOCK_TYPES}:: (?P\w+)|"
- rf"{DOCTEST_TYPES}::.*"
- rf")\n"
- rf"((?P=indent) +:.*\n)*"
- rf"\n*"
- rf")"
- rf"(?P(^((?P=indent) +.*)?\n)+)",
- re.MULTILINE,
-)
-RST_PYCON_RE = re.compile(
- r"(?P"
- r"(?P *)\.\. ((code|code-block):: pycon|doctest::.*)\n"
- r"((?P=indent) +:.*\n)*"
- r"\n*"
- r")"
- r"(?P(^((?P=indent) +.*)?(\n|$))+)",
- re.MULTILINE,
-)
PYCON_PREFIX = ">>> "
PYCON_CONTINUATION_PREFIX = "..."
PYCON_CONTINUATION_RE = re.compile(
rf"^{re.escape(PYCON_CONTINUATION_PREFIX)}( |$)",
)
-LATEX_RE = re.compile(
- r"(?P^(?P *)\\begin{minted}{python}\n)"
- r"(?P.*?)"
- r"(?P^(?P=indent)\\end{minted}\s*$)",
- re.DOTALL | re.MULTILINE,
-)
-LATEX_PYCON_RE = re.compile(
- r"(?P^(?P *)\\begin{minted}{pycon}\n)" r"(?P.*?)" r"(?P^(?P=indent)\\end{minted}\s*$)",
- re.DOTALL | re.MULTILINE,
-)
-PYTHONTEX_LANG = r"(?Ppyblock|pycode|pyconsole|pyverbatim)"
-PYTHONTEX_RE = re.compile(
- rf"(?P^(?P *)\\begin{{{PYTHONTEX_LANG}}}\n)"
- rf"(?P.*?)"
- rf"(?P^(?P=indent)\\end{{(?P=lang)}}\s*$)",
- re.DOTALL | re.MULTILINE,
-)
-INDENT_RE = re.compile("^ +(?=[^ ])", re.MULTILINE)
-TRAILING_NL_RE = re.compile(r"\n+\Z", re.MULTILINE)
+DEFAULT_LINE_LENGTH = 100
class CodeBlockError(NamedTuple):
@@ -77,7 +32,6 @@ class CodeBlockError(NamedTuple):
def format_str(
src: str,
- black_mode: black.FileMode,
) -> tuple[str, Sequence[CodeBlockError]]:
errors: list[CodeBlockError] = []
@@ -91,24 +45,10 @@ def _collect_error(match: Match[str]) -> Generator[None, None, None]:
def _md_match(match: Match[str]) -> str:
code = textwrap.dedent(match["code"])
with _collect_error(match):
- code = black.format_str(code, mode=black_mode)
+ code = format_code_block(code)
code = textwrap.indent(code, match["indent"])
return f'{match["before"]}{code}{match["after"]}'
- def _rst_match(match: Match[str]) -> str:
- lang = match["lang"]
- if lang is not None and lang not in RST_PY_LANGS:
- return match[0]
- min_indent = min(INDENT_RE.findall(match["code"]))
- trailing_ws_match = TRAILING_NL_RE.search(match["code"])
- assert trailing_ws_match
- trailing_ws = trailing_ws_match.group()
- code = textwrap.dedent(match["code"])
- with _collect_error(match):
- code = black.format_str(code, mode=black_mode)
- code = textwrap.indent(code, min_indent)
- return f'{match["before"]}{code.rstrip()}{trailing_ws}'
-
def _pycon_match(match: Match[str]) -> str:
code = ""
fragment = cast(Optional[str], None)
@@ -119,7 +59,7 @@ def finish_fragment() -> None:
if fragment is not None:
with _collect_error(match):
- fragment = black.format_str(fragment, mode=black_mode)
+ fragment = format_code_block(fragment)
fragment_lines = fragment.splitlines()
code += f"{PYCON_PREFIX}{fragment_lines[0]}\n"
for line in fragment_lines[1:]:
@@ -159,42 +99,33 @@ def _md_pycon_match(match: Match[str]) -> str:
code = textwrap.indent(code, match["indent"])
return f'{match["before"]}{code}{match["after"]}'
- def _rst_pycon_match(match: Match[str]) -> str:
- code = _pycon_match(match)
- min_indent = min(INDENT_RE.findall(match["code"]))
- code = textwrap.indent(code, min_indent)
- return f'{match["before"]}{code}'
-
- def _latex_match(match: Match[str]) -> str:
- code = textwrap.dedent(match["code"])
- with _collect_error(match):
- code = black.format_str(code, mode=black_mode)
- code = textwrap.indent(code, match["indent"])
- return f'{match["before"]}{code}{match["after"]}'
-
- def _latex_pycon_match(match: Match[str]) -> str:
- code = _pycon_match(match)
- code = textwrap.indent(code, match["indent"])
- return f'{match["before"]}{code}{match["after"]}'
-
src = MD_RE.sub(_md_match, src)
src = MD_PYCON_RE.sub(_md_pycon_match, src)
- src = RST_RE.sub(_rst_match, src)
- src = RST_PYCON_RE.sub(_rst_pycon_match, src)
- src = LATEX_RE.sub(_latex_match, src)
- src = LATEX_PYCON_RE.sub(_latex_pycon_match, src)
- src = PYTHONTEX_RE.sub(_latex_match, src)
return src, errors
+def format_code_block(code: str) -> str:
+ return subprocess.check_output(
+ [
+ sys.executable,
+ "-m",
+ "ruff",
+ "format",
+ "--stdin-filename=script.py",
+ f"--line-length={DEFAULT_LINE_LENGTH}",
+ ],
+ encoding="utf-8",
+ input=code,
+ )
+
+
def format_file(
filename: str,
- black_mode: black.FileMode,
skip_errors: bool,
) -> int:
with open(filename, encoding="UTF-8") as f:
contents = f.read()
- new_contents, errors = format_str(contents, black_mode)
+ new_contents, errors = format_str(contents)
for error in errors:
lineno = contents[: error.offset].count("\n") + 1
print(f"{filename}:{lineno}: code block parse error {error.exc}")
@@ -217,15 +148,6 @@ def main(argv: Sequence[str] | None = None) -> int:
type=int,
default=DEFAULT_LINE_LENGTH,
)
- parser.add_argument(
- "-t",
- "--target-version",
- action="append",
- type=lambda v: TargetVersion[v.upper()],
- default=[],
- help=f"choices: {[v.name.lower() for v in TargetVersion]}",
- dest="target_versions",
- )
parser.add_argument(
"-S",
"--skip-string-normalization",
@@ -235,15 +157,9 @@ def main(argv: Sequence[str] | None = None) -> int:
parser.add_argument("filenames", nargs="*")
args = parser.parse_args(argv)
- black_mode = black.FileMode(
- target_versions=set(args.target_versions),
- line_length=args.line_length,
- string_normalization=not args.skip_string_normalization,
- )
-
retv = 0
for filename in args.filenames:
- retv |= format_file(filename, black_mode, skip_errors=args.skip_errors)
+ retv |= format_file(filename, skip_errors=args.skip_errors)
return retv
diff --git a/pyproject.toml b/pyproject.toml
index 2e837c62..0993fdcc 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -49,7 +49,6 @@ managed = true
dev-dependencies = [
"pyright",
"mypy",
- "black",
"respx",
"pytest",
"pytest-asyncio",
@@ -64,17 +63,18 @@ dev-dependencies = [
[tool.rye.scripts]
format = { chain = [
- "format:black",
- "format:docs",
"format:ruff",
+ "format:docs",
+ "fix:ruff",
"format:isort",
]}
"format:black" = "black ."
-"format:docs" = "python bin/blacken-docs.py README.md api.md"
-"format:ruff" = "ruff --fix ."
+"format:docs" = "python bin/ruffen-docs.py README.md api.md"
+"format:ruff" = "ruff format"
"format:isort" = "isort ."
"check:ruff" = "ruff ."
+"fix:ruff" = "ruff --fix ."
typecheck = { chain = [
"typecheck:pyright",
@@ -160,6 +160,8 @@ unfixable = [
]
ignore-init-module-imports = true
+[tool.ruff.format]
+docstring-code-format = true
[tool.ruff.per-file-ignores]
"bin/**.py" = ["T201", "T203"]
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 07c2e0e5..59453708 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -11,10 +11,8 @@ annotated-types==0.6.0
anyio==4.1.0
argcomplete==3.1.2
attrs==23.1.0
-black==23.3.0
certifi==2023.7.22
charset-normalizer==3.3.2
-click==8.1.7
colorlog==6.7.0
dirty-equals==0.6.0
distlib==0.3.7
@@ -35,7 +33,6 @@ mypy-extensions==1.0.0
nodeenv==1.8.0
nox==2023.4.22
packaging==23.2
-pathspec==0.11.2
platformdirs==3.11.0
pluggy==1.3.0
py==1.11.0
@@ -49,7 +46,7 @@ pytz==2023.3.post1
pyyaml==6.0.1
requests==2.31.0
respx==0.20.2
-ruff==0.1.7
+ruff==0.1.9
six==1.16.0
sniffio==1.3.0
time-machine==2.9.0
diff --git a/src/anthropic/_models.py b/src/anthropic/_models.py
index 5b8c9601..330a2064 100644
--- a/src/anthropic/_models.py
+++ b/src/anthropic/_models.py
@@ -382,7 +382,7 @@ class RootModel(GenericModel, Generic[_T]):
For example:
```py
- validated = RootModel[int](__root__='5').__root__
+ validated = RootModel[int](__root__="5").__root__
# validated: 5
```
"""
diff --git a/src/anthropic/_types.py b/src/anthropic/_types.py
index 4d4ebf8a..8372db4f 100644
--- a/src/anthropic/_types.py
+++ b/src/anthropic/_types.py
@@ -278,11 +278,13 @@ class NotGiven:
For example:
```py
- def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response: ...
+ def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response:
+ ...
+
- get(timeout=1) # 1s timeout
- get(timeout=None) # No timeout
- get() # Default timeout behavior, which may not be statically known at the method definition.
+ get(timeout=1) # 1s timeout
+ get(timeout=None) # No timeout
+ get() # Default timeout behavior, which may not be statically known at the method definition.
```
"""
@@ -304,14 +306,14 @@ class Omit:
```py
# as the default `Content-Type` header is `application/json` that will be sent
- client.post('/upload/files', files={'file': b'my raw file content'})
+ client.post("/upload/files", files={"file": b"my raw file content"})
# you can't explicitly override the header as it has to be dynamically generated
# to look something like: 'multipart/form-data; boundary=0d8382fcf5f8c3be01ca2e11002d2983'
- client.post(..., headers={'Content-Type': 'multipart/form-data'})
+ client.post(..., headers={"Content-Type": "multipart/form-data"})
# instead you can remove the default `application/json` header by passing Omit
- client.post(..., headers={'Content-Type': Omit()})
+ client.post(..., headers={"Content-Type": Omit()})
```
"""
diff --git a/src/anthropic/_utils/_transform.py b/src/anthropic/_utils/_transform.py
index 91175590..342b5241 100644
--- a/src/anthropic/_utils/_transform.py
+++ b/src/anthropic/_utils/_transform.py
@@ -80,9 +80,10 @@ def transform(
```py
class Params(TypedDict, total=False):
- card_id: Required[Annotated[str, PropertyInfo(alias='cardID')]]
+ card_id: Required[Annotated[str, PropertyInfo(alias="cardID")]]
- transformed = transform({'card_id': ''}, Params)
+
+ transformed = transform({"card_id": ""}, Params)
# {'cardID': ''}
```
diff --git a/src/anthropic/_utils/_utils.py b/src/anthropic/_utils/_utils.py
index 993462a6..cc624b0c 100644
--- a/src/anthropic/_utils/_utils.py
+++ b/src/anthropic/_utils/_utils.py
@@ -211,13 +211,15 @@ def required_args(*variants: Sequence[str]) -> Callable[[CallableT], CallableT]:
def foo(*, a: str) -> str:
...
+
@overload
def foo(*, b: bool) -> str:
...
+
# This enforces the same constraints that a static type checker would
# i.e. that either a or b must be passed to the function
- @required_args(['a'], ['b'])
+ @required_args(["a"], ["b"])
def foo(*, a: str | None = None, b: bool | None = None) -> str:
...
```
diff --git a/src/anthropic/lib/streaming/_messages.py b/src/anthropic/lib/streaming/_messages.py
index 987acd16..76accf0f 100644
--- a/src/anthropic/lib/streaming/_messages.py
+++ b/src/anthropic/lib/streaming/_messages.py
@@ -105,9 +105,9 @@ def on_text(self, text: str, snapshot: str) -> None:
text, for example:
```py
- on_text('Hello', 'Hello')
- on_text(' there', 'Hello there')
- on_text('!', 'Hello there!')
+ on_text("Hello", "Hello")
+ on_text(" there", "Hello there")
+ on_text("!", "Hello there!")
```
"""
@@ -295,9 +295,9 @@ async def on_text(self, text: str, snapshot: str) -> None:
text, for example:
```
- on_text('Hello', 'Hello')
- on_text(' there', 'Hello there')
- on_text('!', 'Hello there!')
+ on_text("Hello", "Hello")
+ on_text(" there", "Hello there")
+ on_text("!", "Hello there!")
```
"""
diff --git a/tests/test_transform.py b/tests/test_transform.py
index cfcf870e..1d1fb9bc 100644
--- a/tests/test_transform.py
+++ b/tests/test_transform.py
@@ -189,7 +189,9 @@ class DateDictWithRequiredAlias(TypedDict, total=False):
def test_datetime_with_alias() -> None:
assert transform({"required_prop": None}, DateDictWithRequiredAlias) == {"prop": None} # type: ignore[comparison-overlap]
- assert transform({"required_prop": date.fromisoformat("2023-02-23")}, DateDictWithRequiredAlias) == {"prop": "2023-02-23"} # type: ignore[comparison-overlap]
+ assert transform({"required_prop": date.fromisoformat("2023-02-23")}, DateDictWithRequiredAlias) == {
+ "prop": "2023-02-23"
+ } # type: ignore[comparison-overlap]
class MyModel(BaseModel):
From 77270e3b634d931436bbdac58181858bf2055cb9 Mon Sep 17 00:00:00 2001
From: Stainless Bot <107565488+stainless-bot@users.noreply.github.com>
Date: Fri, 22 Dec 2023 05:45:20 -0500
Subject: [PATCH 8/8] release: 0.8.1
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 17 +++++++++++++++++
pyproject.toml | 2 +-
src/anthropic/_version.py | 2 +-
4 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 6538ca91..2b28d6ec 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.8.0"
+ ".": "0.8.1"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7feae44c..0b36bdd8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,22 @@
# Changelog
+## 0.8.1 (2023-12-22)
+
+Full Changelog: [v0.8.0...v0.8.1](https://github.com/anthropics/anthropic-sdk-python/compare/v0.8.0...v0.8.1)
+
+### Chores
+
+* **internal:** add bin script ([#292](https://github.com/anthropics/anthropic-sdk-python/issues/292)) ([ba2953d](https://github.com/anthropics/anthropic-sdk-python/commit/ba2953dcaa8a8fcebaa7e8891304687c95b17499))
+* **internal:** fix typos ([#287](https://github.com/anthropics/anthropic-sdk-python/issues/287)) ([4ffbcdf](https://github.com/anthropics/anthropic-sdk-python/commit/4ffbcdf1d3c8c2fbaf7152d207b24cdb0ea82ac9))
+* **internal:** use ruff instead of black for formatting ([#294](https://github.com/anthropics/anthropic-sdk-python/issues/294)) ([1753887](https://github.com/anthropics/anthropic-sdk-python/commit/1753887a776f41bdc2d648329cfe6f20c91125e5))
+* **package:** bump minimum typing-extensions to 4.7 ([#290](https://github.com/anthropics/anthropic-sdk-python/issues/290)) ([9ec5c57](https://github.com/anthropics/anthropic-sdk-python/commit/9ec5c57ba9a14a769d540e48755b05a1c190b45b))
+
+
+### Documentation
+
+* **messages:** improvements to helpers reference + typos ([#291](https://github.com/anthropics/anthropic-sdk-python/issues/291)) ([d18a895](https://github.com/anthropics/anthropic-sdk-python/commit/d18a895d380fc0c6610443486d73247b0cd97376))
+* **readme:** remove old migration guide ([#289](https://github.com/anthropics/anthropic-sdk-python/issues/289)) ([eec4574](https://github.com/anthropics/anthropic-sdk-python/commit/eec4574f1f6668804c88bda67b901db10400fbc3))
+
## 0.8.0 (2023-12-19)
Full Changelog: [v0.7.8...v0.8.0](https://github.com/anthropics/anthropic-sdk-python/compare/v0.7.8...v0.8.0)
diff --git a/pyproject.toml b/pyproject.toml
index 0993fdcc..265ac8e4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "anthropic"
-version = "0.8.0"
+version = "0.8.1"
description = "The official Python library for the anthropic API"
readme = "README.md"
license = "MIT"
diff --git a/src/anthropic/_version.py b/src/anthropic/_version.py
index 810a1124..9703c64f 100644
--- a/src/anthropic/_version.py
+++ b/src/anthropic/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless.
__title__ = "anthropic"
-__version__ = "0.8.0" # x-release-please-version
+__version__ = "0.8.1" # x-release-please-version