anthropics / anthropic-sdk-python

MIT License
1.51k stars 181 forks source link

`pip install anthropic` currently fails on Python 3.13 #718

Closed simonw closed 2 weeks ago

simonw commented 3 weeks ago

One of the anthropic dependencies is not yet available for Python 3.13 - tokenizers needs pyo3-ffi and that's not on Python 3.13 yet:

This means nothing that runs Python 3.13 can pip install anthropic right now.

Is the tokenizers dependency really necessary? I think it's only there for a VERY old count tokens feature which isn't actually that useful because it still uses the Claude 2 tokenizer:

https://github.com/anthropics/anthropic-sdk-python/blob/cd80d46f7a223a5493565d155da31b898a4c6ee5/src/anthropic/_client.py#L270-L286

simonw commented 3 weeks ago

One option could be to make the tokenizers dependency optional and tell people who are using that count_tokens() method that they'll need to install it for that method to work.

simonw commented 3 weeks ago

... oh, it looks like it's not just tokenizers - the jiter library used by Pydantic also relies on PyO3: https://github.com/pydantic/jiter

From this comment:

It looks like that project is waiting on this fix too:

wizardofozzie commented 3 weeks ago

3.12 failing also

RobertCraigie commented 3 weeks ago

@wizardofozzie can you open a separate issue for 3.12? That should already be supported

simonw commented 3 weeks ago

... oh, it looks like it's not just tokenizers - the jiter library used by Pydantic also relies on PyO3: https://github.com/pydantic/jiter

Correction: it looks like that library has available Python 3.13 wheels already: https://pypi.org/project/jiter/0.6.1/#files

simonw commented 3 weeks ago

So actually I think the underlying problem is this:

I think dropping tokenizers or making it optional is a good idea - it's a pretty heavy dependency for a library that's mainly just an HTTP API client.

simonw commented 3 weeks ago

I did some digging around and it turns out tokenizers is an optional dependency already - it only gets imported if you call the client.count_tokens() method.

Here's what happens in an environment without that module installed:

>>> import anthropic
>>> client = anthropic.Anthropic()
>>> client.count_tokens("hi")
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    client.count_tokens("hi")
    ~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/Users/simon/Dropbox/Development/anthropic-sdk-python/src/anthropic/_client.py", line 281, in count_tokens
    tokenizer = self.get_tokenizer()
  File "/Users/simon/Dropbox/Development/anthropic-sdk-python/src/anthropic/_client.py", line 286, in get_tokenizer
    return sync_get_tokenizer()
  File "/Users/simon/Dropbox/Development/anthropic-sdk-python/src/anthropic/_tokenizers.py", line 41, in sync_get_tokenizer
    return _load_tokenizer(text)
  File "/Users/simon/Dropbox/Development/anthropic-sdk-python/src/anthropic/_tokenizers.py", line 29, in _load_tokenizer
    from tokenizers import Tokenizer
ModuleNotFoundError: No module named 'tokenizers'
simonw commented 3 weeks ago

I ended up making these changes and now the test suite passes for Python 3.13 on my laptop:

diff --git a/.python-version b/.python-version
index 43077b2..3a4f41e 100644
--- a/.python-version
+++ b/.python-version
@@ -1 +1 @@
-3.9.18
+3.13
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 1ccb9a4..924b866 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -14,11 +14,9 @@ dependencies = [
     "anyio>=3.5.0, <5",
     "distro>=1.7.0, <2",
     "sniffio",
-    "cached-property; python_version < '3.8'",
-    "tokenizers >= 0.13.0",
     "jiter>=0.4.0, <1",
 ]
-requires-python = ">= 3.7"
+requires-python = ">= 3.9"
 classifiers = [
   "Typing :: Typed",
   "Intended Audience :: Developers",

I had to bump the requires-python up because there was a dependency conflict without it:

% uv sync
  × No solution found when resolving dependencies:
  ╰─▶ Because the requested Python version (>=3.7) does not satisfy Python>=3.9 and the requested Python version (>=3.7) does not satisfy
      Python>=3.8,<3.9, we can conclude that Python>=3.8 is incompatible.
      And because jiter>=0.4.0 depends on Python>=3.8 and only the following versions of jiter are available:
          jiter<=0.4.0
          jiter==0.4.1
          jiter==0.4.2
          jiter==0.5.0
          jiter==0.6.0
          jiter==0.6.1
      we can conclude that jiter>=0.4.0 cannot be used.
      And because your project depends on jiter>=0.4.0 and your project requires anthropic[vertex], we can conclude that your projects's
      requirements are unsatisfiable.

      hint: The `requires-python` value (>=3.7) includes Python versions that are not supported by your dependencies (e.g., jiter>=0.4.0 only
      supports >=3.8). Consider using a more restrictive `requires-python` value (like >=3.8).
simonw commented 3 weeks ago

If anyone needs a workaround for this in order to run software on Python 3.13 that depends on this library you can install my branch like this:

python -m pip install https://github.com/simonw/anthropic-sdk-python/archive/9c13bb441ee4eb88a100ed363fc431ec8fd30c43.zip
RobertCraigie commented 2 weeks ago

This should be fixed in the latest release!

$ uv run python -c 'import sys; print(sys.version)'
3.13.0 (main, Oct  7 2024, 05:02:14) [Clang 15.0.0 (clang-1500.3.9.4)]

$ uv run python -c 'import anthropic; anthropic.Anthropic()'