Heuristic:Cohere ai Cohere python Pydantic V1 V2 Compatibility
| Knowledge Sources | |
|---|---|
| Domains | Compatibility, SDK |
| Last Updated | 2026-02-15 14:00 GMT |
Overview
The SDK supports both Pydantic v1 (>=1.9.2) and v2 via runtime version detection and conditional imports from `pydantic.v1` compatibility layer.
Description
Since the SDK supports `pydantic >= 1.9.2`, it must handle both Pydantic v1 and v2 APIs which have fundamentally different import paths for fields, type parsing, and JSON encoding. The SDK detects the version at import time using `IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")` and conditionally imports utilities from either the native Pydantic v1 module or the `pydantic.v1` compatibility shim in Pydantic v2.
Usage
This heuristic is relevant when:
- Debugging import errors related to Pydantic in environments with pinned versions
- Extending the SDK with custom Pydantic models that need to work with both v1 and v2
- Understanding warning suppression (UserWarning from `pydantic.v1` imports is intentionally suppressed)
- Working with SSE parsing which relies on discriminated union handling that differs between v1/v2
The Insight (Rule of Thumb)
- Action: Do not pin Pydantic to a specific major version in projects using the Cohere SDK. The SDK handles both.
- Value: `IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")` at `core/pydantic_utilities.py:35`.
- Trade-off: Supporting both versions adds complexity to the codebase but maximizes compatibility. Users with Pydantic v1 projects can adopt the SDK without upgrading.
- Caveat: The `pydantic.v1` compatibility layer in Pydantic v2 emits `UserWarning`s, which the SDK suppresses with `warnings.catch_warnings()`.
Reasoning
Pydantic v2 was a major rewrite with breaking changes to `ModelField`, `parse_obj`, JSON encoders, and datetime parsing. Many production codebases are still on Pydantic v1. By using feature detection rather than version pinning, the SDK avoids forcing users into a specific Pydantic version. The `pydantic.v1` shim in Pydantic v2 provides backward-compatible interfaces but generates deprecation warnings, hence the warning suppression.
Code Evidence
Version detection and conditional imports from `core/pydantic_utilities.py:35-71`:
IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.")
if IS_PYDANTIC_V2:
import warnings
_datetime_adapter = pydantic.TypeAdapter(dt.datetime)
_date_adapter = pydantic.TypeAdapter(dt.date)
def parse_datetime(value: Any) -> dt.datetime:
if isinstance(value, dt.datetime):
return value
return _datetime_adapter.validate_python(value)
with warnings.catch_warnings():
warnings.simplefilter("ignore", UserWarning)
from pydantic.v1.fields import ModelField as ModelField
from pydantic.v1.json import ENCODERS_BY_TYPE as encoders_by_type
from pydantic.v1.typing import get_args as get_args
from pydantic.v1.typing import get_origin as get_origin
from pydantic.v1.typing import is_literal_type as is_literal_type
from pydantic.v1.typing import is_union as is_union
else:
from pydantic.datetime_parse import parse_date as parse_date
from pydantic.datetime_parse import parse_datetime as parse_datetime
from pydantic.fields import ModelField as ModelField
from pydantic.json import ENCODERS_BY_TYPE as encoders_by_type
from pydantic.typing import get_args as get_args
from pydantic.typing import get_origin as get_origin
NotRequired compatibility from `core/request_options.py:5-8`:
try:
from typing import NotRequired
except ImportError:
from typing_extensions import NotRequired