Skip to content

fix(deps): relax core runtime dependency pins from exact == to ranges - #26157

Merged
yuneng-berri merged 1 commit into
BerriAI:litellm_oss_staging_04_21_2026from
Anai-Guo:fix/relax-core-dependency-pins
Apr 22, 2026
Merged

fix(deps): relax core runtime dependency pins from exact == to ranges#26157
yuneng-berri merged 1 commit into
BerriAI:litellm_oss_staging_04_21_2026from
Anai-Guo:fix/relax-core-dependency-pins

Conversation

@Anai-Guo

Copy link
Copy Markdown
Contributor

Summary

When litellm migrated from Poetry to uv in PR #24905 (v1.83.1), a subtle semantic change broke library consumers:

  • Poetry: bare version strings like openai = "2.30.0" are implicitly caret ranges — they resolve to >=2.30.0,<3.0.0
  • PEP 621: openai==2.24.0 is an exact pin — only that exact version is allowed

The migration converted Poetry's implicit ranges to PEP 621 exact pins, which forces every downstream package that lists litellm as a dependency to downgrade 12 common runtime libraries (aiohttp, pydantic, openai, click, tokenizers, jinja2, etc.) to specific old patch versions — even if newer compatible versions are already installed.

Fixes: #26154
Overlaps with: #25231 (which fixes only python-dotenv)

Changes

Only the 12 core [project.dependencies] entries are changed — from exact == pins to lower-bounded ranges. The optional extras (proxy, proxy-runtime, etc.) keep their exact pins, since those are consumed by Docker images where reproducibility is important. The uv.lock file continues to provide exact pinning for Docker builds and CI.

Before (exact pins — broken for downstream consumers):

dependencies = [
    "fastuuid==0.14.0",
    "httpx==0.28.1",
    "openai==2.24.0",
    "python-dotenv==1.0.1",
    "tiktoken==0.12.0",
    "importlib-metadata==8.5.0",
    "tokenizers==0.22.2",
    "click==8.1.8",
    "jinja2==3.1.6",
    "aiohttp==3.13.3",
    "pydantic==2.12.5",
    "jsonschema==4.23.0",
]

After (lower-bounded ranges — compatible with downstream):

dependencies = [
    "fastuuid>=0.14.0",
    "httpx>=0.28.0",
    "openai>=2.0.0",
    "python-dotenv>=1.0.0",
    "tiktoken>=0.7.0",
    "importlib-metadata>=6.0.0",
    "tokenizers>=0.19.0",
    "click>=8.0.0",
    "jinja2>=3.1.0",
    "aiohttp>=3.10",
    "pydantic>=2.5.0,<3.0.0",
    "jsonschema>=4.0.0",
]

Why pydantic has an upper bound

pydantic>=2.5.0,<3.0.0 — pydantic v3 would be a breaking API change. All other ranges are open-ended upward since those packages follow semver and breaking changes would be a major version bump.

Testing

This is a metadata-only change to pyproject.toml. The uv.lock file and CI continue to install the same exact versions for testing and Docker builds. No runtime behavior changes.

When litellm migrated from Poetry to uv (PR BerriAI#24905, v1.83.1), the core
dependency specifications in pyproject.toml changed from Poetry bare-version
strings (e.g. openai = "2.30.0") to PEP 621 exact pins (openai==2.24.0).

Poetry bare-version strings are actually caret ranges (^X.Y.Z == >=X.Y.Z,<X+1),
but PEP 621 == is exact. This means every downstream package that installs
litellm as a library dependency is now forced to downgrade aiohttp, pydantic,
openai, click, and 8 other common packages to exact old versions.

Fix: restore range specifiers for the 12 core runtime dependencies. The
optional extras (proxy, proxy-runtime, etc.) are consumed primarily by
Docker images where exact pins are appropriate and are left unchanged.
The uv.lock file continues to provide exact reproducibility for Docker
builds and CI.

Fixes: BerriAI#26154
@greptile-apps

greptile-apps Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR relaxes 12 core runtime dependency pins in pyproject.toml from exact == versions to lower-bounded ranges, fixing a semantic regression introduced when litellm migrated from Poetry (implicit caret ranges) to PEP 621 (exact pins). The uv.lock file and optional extras retain their exact pins for reproducible Docker/CI builds.

  • P1: openai>=2.0.0 drops the floor 24 minor versions below the tested 2.24.0 — litellm almost certainly relies on APIs added after 2.0, so resolvers that pick an older 2.x release may encounter runtime errors. A tighter floor (e.g. >=2.20.0) would still relieve downstream pressure.
  • P2: importlib-metadata>=6.0.0 drops two major versions below the tested 8.5.0; a >=8.0.0 floor would be safer. httpx is pre-1.0 and could benefit from a <1.0 ceiling.

Confidence Score: 4/5

Safe to merge after addressing the openai floor — the P1 concern is low-probability in practice but could cause silent runtime failures for unlucky downstream consumers.

One P1 finding: the openai>=2.0.0 lower bound is significantly below the tested 2.24.0, which could allow installation of incompatible older openai v2 releases. The importlib-metadata floor concern is P2. All other changes are sound and the uv.lock continues to pin exact versions for CI/Docker.

pyproject.toml — specifically the openai and importlib-metadata lower bounds

Important Files Changed

Filename Overview
pyproject.toml Core runtime dependencies relaxed from exact == pins to lower-bounded ranges; openai floor (2.0.0) and importlib-metadata floor (6.0.0) are significantly below tested versions, risking silent runtime failures for downstream users who resolve older minor releases

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[litellm pyproject.toml] --> B{Install context}
    B -->|Library consumer pip install litellm| C[Uses relaxed ranges\nhttpx>=0.28.0\nopenai>=2.0.0\npydantic>=2.5.0 less than 3.0.0\netc.]
    B -->|Docker / CI via uv sync| D[Uses exact pins from uv.lock]
    B -->|Proxy extras| E[Uses exact pins\ngunicorn==23.0.0\nfastapi==0.124.4\netc.]
    C --> F{Resolver picks version}
    F -->|Picks latest compatible| G[Works as expected]
    F -->|Picks floor e.g. openai 2.0.0| H[Possible runtime error\nAPIs added after 2.0 missing]
    D --> I[Reproducible build]
    E --> J[Reproducible build]
Loading

Reviews (1): Last reviewed commit: "fix(deps): relax core runtime dependency..." | Re-trigger Greptile

Comment thread pyproject.toml
dependencies = [
"fastuuid>=0.14.0",
"httpx>=0.28.0",
"openai>=2.0.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 openai>=2.0.0 floor may be too permissive

The tested/released version was openai==2.24.0, but the floor is dropped 24 minor versions to 2.0.0. The OpenAI Python SDK has added new APIs, models, and response fields across 2.x minor releases that litellm almost certainly relies on. A downstream user whose resolver picks openai==2.1.0 could get AttributeError or ImportError at runtime with no warning at install time. Consider a tighter floor — e.g. openai>=2.20.0 — or document the actual minimum tested version to prevent silent breakage.

Comment thread pyproject.toml
"openai>=2.0.0",
"python-dotenv>=1.0.0",
"tiktoken>=0.7.0",
"importlib-metadata>=6.0.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 importlib-metadata floor drops two major versions

The tested pin was 8.5.0; the new floor is 6.0.0. importlib-metadata had several API removals between major versions (the packages_distributions() API, deprecation of requires(), etc.). Dropping the floor two majors below the tested version may silently allow installs that fail at runtime on older 6.x or 7.x releases. A more conservative floor like >=8.0.0 would still dramatically relax downstream pressure while staying within the tested major series.

Comment thread pyproject.toml
]
dependencies = [
"fastuuid>=0.14.0",
"httpx>=0.28.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 httpx has no upper bound on a pre-1.0 package

httpx is still pre-1.0 and has a history of breaking API changes across minor releases (streaming interface, timeout semantics, etc.). With httpx>=0.28.0 and no ceiling, litellm will accept future httpx 0.29, 0.30, or even 1.0 without any resolver warning. Adding an upper bound like <1.0 would guard against the inevitable 1.0 API break while still solving the downstream pinning problem.

Suggested change
"httpx>=0.28.0",
"httpx>=0.28.0,<1.0",

@krrish-berri-2
krrish-berri-2 changed the base branch from main to litellm_oss_staging_04_21_2026 April 22, 2026 03:18
@yuneng-berri
yuneng-berri merged commit baa50db into BerriAI:litellm_oss_staging_04_21_2026 Apr 22, 2026
3 checks passed
yuneng-berri added a commit that referenced this pull request May 7, 2026
The 12 core `[project.dependencies]` entries in pyproject.toml were exact
`==` pins, a side effect of the Poetry → uv migration. This forces every
downstream package that lists litellm as a dependency to downgrade common
runtime libraries (openai, pydantic, aiohttp, click, jsonschema, ...) to
the exact versions we ship. Customers have flagged this as a coexistence
blocker.

Switch to lower-bounded ranges with upper bounds where the upstream
package is pre-1.0 or has a known breaking-major-version policy.
Reproducibility for our Docker proxy and CI continues to come from
`uv.lock`, which is regenerated here as a metadata-only diff (no
resolved versions or hashes change).

Inspired by #26157 (which got stranded on `litellm_oss_staging_04_21_2026`
when the forward-merge to internal staging in #26216 was closed). Floors
in this PR are tighter than #26157's: they were validated by installing
litellm at `--resolution=lowest-direct` and importing the openai-namespace
symbols the codebase actually uses.

Floor highlights vs #26157:
- openai >= 2.20 (was 2.0) — Responses API symbols + `Omit` need a 2.x mid-range floor
- httpx >= 0.28, < 1.0 (was no upper) — pre-1.0
- importlib-metadata >= 8.0 (was 6.0) — stay in tested major
- tokenizers >= 0.20, < 1.0 (was 0.19, no upper) — pre-1.0
- aiohttp >= 3.10, < 4.0 (was no upper) — bound major
- pydantic >= 2.5, < 3.0 — kept
- All other floors: keep tested major, add upper bound

Adds a `check-dependency-floors.yml` GitHub Actions workflow that
installs litellm at `--resolution=lowest-direct` on Python 3.10 and 3.13
and import-checks every openai symbol the codebase uses, so a future
floor regression fails fast in CI rather than silently in the field.
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
The 12 core `[project.dependencies]` entries in pyproject.toml were exact
`==` pins, a side effect of the Poetry → uv migration. This forces every
downstream package that lists litellm as a dependency to downgrade common
runtime libraries (openai, pydantic, aiohttp, click, jsonschema, ...) to
the exact versions we ship. Customers have flagged this as a coexistence
blocker.

Switch to lower-bounded ranges with upper bounds where the upstream
package is pre-1.0 or has a known breaking-major-version policy.
Reproducibility for our Docker proxy and CI continues to come from
`uv.lock`, which is regenerated here as a metadata-only diff (no
resolved versions or hashes change).

Inspired by BerriAI#26157 (which got stranded on `litellm_oss_staging_04_21_2026`
when the forward-merge to internal staging in BerriAI#26216 was closed). Floors
in this PR are tighter than BerriAI#26157's: they were validated by installing
litellm at `--resolution=lowest-direct` and importing the openai-namespace
symbols the codebase actually uses.

Floor highlights vs BerriAI#26157:
- openai >= 2.20 (was 2.0) — Responses API symbols + `Omit` need a 2.x mid-range floor
- httpx >= 0.28, < 1.0 (was no upper) — pre-1.0
- importlib-metadata >= 8.0 (was 6.0) — stay in tested major
- tokenizers >= 0.20, < 1.0 (was 0.19, no upper) — pre-1.0
- aiohttp >= 3.10, < 4.0 (was no upper) — bound major
- pydantic >= 2.5, < 3.0 — kept
- All other floors: keep tested major, add upper bound

Adds a `check-dependency-floors.yml` GitHub Actions workflow that
installs litellm at `--resolution=lowest-direct` on Python 3.10 and 3.13
and import-checks every openai symbol the codebase uses, so a future
floor regression fails fast in CI rather than silently in the field.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants