Bug in Python API? (Pydantic Dependency)

For Workes & Pages, what is the name of the domain?

example.com

What is the error message?

pydantic.errors.PydanticUndefinedAnnotation: name ‘TraceItem’ is not defined

What is the issue or error you’re encountering

New Pydantic release causes the Cloudflare Python (v3.1.0) library to break

What steps have you taken to resolve the issue?

pip install pydantic==2.9.* seems to be the latest version to work with Cloudflare Python library

What are the steps to reproduce the issue?

pip install cloudflare
example.py with minimal example to use the Cloudflare API

import os
from cloudflare import Cloudflare

client = Cloudflare(
    # This is the default and can be omitted
    api_email=os.environ.get("CLOUDFLARE_EMAIL"),
    # This is the default and can be omitted
    api_key=os.environ.get("CLOUDFLARE_API_KEY"),
)

print(client.zones.list())

python3.12 -m example.py

2 Likes

I can confirm, same here. Using the Python API causes pydantic.errors.PydanticUndefinedAnnotation: name 'TraceItem' is not defined:

$ python -m venv venv
$ source venv/bin/activate.fish
$ pip install cloudflare
# …
Successfully installed annotated-types-0.7.0 anyio-4.6.2.post1 certifi-2024.8.30 cloudflare-3.1.0 distro-1.9.0 h11-0.14.0 httpcore-1.0.7 httpx-0.27.2 idna-3.10 pydantic-2.10.1 pydantic-core-2.27.1 sniffio-1.3.1 typing-extensions-4.12.2
$ python --version
Python 3.12.7

Just importing is enough to cause this:

$ python -c 'from cloudflare import CloudFlare'
Traceback (most recent call last):
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 815, in _resolve_forward_ref
    obj = _typing_extra.eval_type_backport(obj, *self._types_namespace)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_typing_extra.py", line 534, in eval_type_backport
    return _eval_type_backport(value, globalns, localns, type_params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_typing_extra.py", line 558, in _eval_type_backport
    return _eval_type(value, globalns, localns, type_params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_typing_extra.py", line 592, in _eval_type
    return typing._eval_type(  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 415, in _eval_type
    return t._evaluate(globalns, localns, type_params, recursive_guard=recursive_guard)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 952, in _evaluate
    self.__forward_value__ = _eval_type(
                             ^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 430, in _eval_type
    ev_args = tuple(
              ^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 431, in <genexpr>
    _eval_type(
  File "/usr/lib64/python3.12/typing.py", line 415, in _eval_type
    return t._evaluate(globalns, localns, type_params, recursive_guard=recursive_guard)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 952, in _evaluate
    self.__forward_value__ = _eval_type(
                             ^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 430, in _eval_type
    ev_args = tuple(
              ^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 431, in <genexpr>
    _eval_type(
  File "/usr/lib64/python3.12/typing.py", line 415, in _eval_type
    return t._evaluate(globalns, localns, type_params, recursive_guard=recursive_guard)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/typing.py", line 947, in _evaluate
    eval(self.__forward_code__, globalns, localns),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 1, in <module>
NameError: name 'TraceItem' is not defined

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/tmp/venv/lib64/python3.12/site-packages/cloudflare/__init__.py", line 6, in <module>
    from ._client import (
  File "/tmp/venv/lib64/python3.12/site-packages/cloudflare/_client.py", line 11, in <module>
    from . import resources, _exceptions
  File "/tmp/venv/lib64/python3.12/site-packages/cloudflare/resources/__init__.py", line 555, in <module>
    from .request_tracers import (
  File "/tmp/venv/lib64/python3.12/site-packages/cloudflare/resources/request_tracers/__init__.py", line 3, in <module>
    from .traces import (
  File "/tmp/venv/lib64/python3.12/site-packages/cloudflare/resources/request_tracers/traces.py", line 24, in <module>
    from ...types.request_tracers import trace_create_params
  File "/tmp/venv/lib64/python3.12/site-packages/cloudflare/types/request_tracers/__init__.py", line 8, in <module>
    from .trace_create_response import TraceCreateResponse as TraceCreateResponse
  File "/tmp/venv/lib64/python3.12/site-packages/cloudflare/types/request_tracers/trace_create_response.py", line 23, in <module>
    TraceCreateResponse.model_rebuild()
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/main.py", line 594, in model_rebuild
    return _model_construction.complete_model_class(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_model_construction.py", line 658, in complete_model_class
    schema = cls.__get_pydantic_core_schema__(cls, handler)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/main.py", line 702, in __get_pydantic_core_schema__
    return handler(source)
           ^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_schema_generation_shared.py", line 84, in __call__
    schema = self._handler(source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 612, in generate_schema
    schema = self._generate_schema_inner(obj)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 881, in _generate_schema_inner
    return self._model_schema(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 693, in _model_schema
    {k: self._generate_md_field_schema(k, v, decorators) for k, v in fields.items()},
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 1073, in _generate_md_field_schema
    common_field = self._common_field_schema(name, field_info, decorators)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 1261, in _common_field_schema
    schema = self._apply_annotations(
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 2061, in _apply_annotations
    schema = get_inner_schema(source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_schema_generation_shared.py", line 84, in __call__
    schema = self._handler(source_type)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 2042, in inner_handler
    schema = self._generate_schema_inner(obj)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 875, in _generate_schema_inner
    return self.generate_schema(self._resolve_forward_ref(obj))
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib64/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 817, in _resolve_forward_ref
    raise PydanticUndefinedAnnotation.from_name_error(e) from e
pydantic.errors.PydanticUndefinedAnnotation: name 'TraceItem' is not defined

For further information visit https://errors.pydantic.dev/2.10/u/undefined-annotation

A downgrade of Pydantic to the latest 2.9 release seems to fix this:

# continue from the same venv as above
$ pip install 'pydantic==2.9.*'
$ python -c 'from cloudflare import Cloudflare'

Went okay.

hi that fix doesn’t work with Python 3.8.10 , could you help me please thank you ?

I’m getting this too. Seems like the Cloudflare Python SDK is not compatible with the latest pydantic 2.10.x. Downgrading to pydantic 2.9.2 solved it for me as well.

Temporary fix is to pin httpx and pydantic:

pydantic==2.9.2
httpx==0.27.2
1 Like

it doesn’t work with python 3.8.10 , please help

Unless you post what is going wrong there isn’t much to comment on.

it raises this error raise PydanticUndefinedAnnotation.from_name_error(e) from e pydantic.errors.PydanticUndefinedAnnotation: name 'TraceItem' is not defined

with : Python 3.8.10

pydantic==2.9.2
pydantic_core==2.23.4
httpcore==1.0.7
httpx==0.27.2

could you help please?

I don’t personally run Python 3.8 but my functional venv has these packages installed:

annotated-types==0.7.0
anyio==4.6.2.post1
certifi==2024.8.30
charset-normalizer==3.4.0
cloudflare==3.1.0
distro==1.9.0
exceptiongroup==1.2.2
h11==0.14.0
httpcore==1.0.7
httpx==0.27.2
idna==3.10
pydantic==2.9.2
pydantic_core==2.23.4
requests==2.32.3
sniffio==1.3.1
typing_extensions==4.12.2
urllib3==2.2.3

Your error, however, makes me think that you’re not actually running the script with those requirements. Are you using a venv properly?

yes it works with python 3.12.7 but not with 3.8.10 it raises the error

I suppose you will have to wait for Cloudflare to fix it then. Personally I would just use a newer Python version.

A deep dive of what is happening, and why on the v.3.0.0 Beta Release Discussion on Github.