Skip to content

build(deps): allow redisvl, pypdf, and openapi-core on Python 3.14 - #33801

Merged
yuneng-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_/bold-brahmagupta-943951
Jul 18, 2026
Merged

build(deps): allow redisvl, pypdf, and openapi-core on Python 3.14#33801
yuneng-berri merged 2 commits into
litellm_internal_stagingfrom
litellm_/bold-brahmagupta-943951

Conversation

@yuneng-berri

Copy link
Copy Markdown
Collaborator

Relevant issues

Linear ticket

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review (Greptile reviews automatically once the PR is opened; only comment @greptileai to re-request a review after pushing changes)

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

Screenshots / Proof of Fix

litellm already installs on Python 3.14; this change is about the optional dependencies that were still fenced off from it. The proof has two halves: nothing moves for the existing 3.10 through 3.13 range, and the three packages genuinely install and work on a real 3.14 interpreter. Because this is a packaging change, the realistic proof is a source install plus importing and exercising the features, not an LLM call; a plain pip install litellm on 3.14 additionally waits on the cp314 wheels that ship separately

Commits the proof was captured at: markers present at 966ff65fec, markers removed at 4b85239c70, native 3.14 re-verified on this branch tip 3d972c8f55 (after merging #33798 so the Rust bridge builds on 3.14)

1. No regression on Python 3.10 through 3.13. Regenerating the lock with the markers gone changed no package version on any Python branch. A name+version map of every locked package is identical before and after, and the lock diff contains no version, hash, or artifact-url change at all:

$ diff <(vmap uv.lock@966ff65fec) <(vmap uv.lock@4b85239c70)   # 420 packages each side
        (no output -> every package resolves to the same version)

$ git diff 966ff65fec..4b85239c70 -- uv.lock | grep -E '^[+-](version = |.*sha256|.*files.pythonhosted)'
        (no output -> only marker text and uv's rolling exclude-newer timestamp changed)

The same three feature suites run green before and after on 3.13.13, so the un-gated deps behave identically where they were already installed:

# 966ff65fec (markers present)
$ uv run --python 3.13 pytest \
    tests/test_litellm/caching/test_redis_semantic_cache.py \
    tests/test_litellm/interactions/test_openapi_compliance.py \
    tests/test_litellm/test_rag_openai_ingestion.py -q
56 passed in 12.08s

# 4b85239c70 (markers removed)
$ uv run --python 3.13 pytest <same three files> -q
56 passed in 7.63s

2. The three packages install and work on native Python 3.14. With #33798 merged in, a full extras sync builds and resolves on 3.14.6 with no forward-compatibility shim:

# 3d972c8f55, on python 3.14.6
$ uv sync --all-extras --python 3.14
Resolved 420 packages ... (exit 0)

$ uv run --python 3.14 pytest tests/test_litellm/interactions/test_openapi_compliance.py -q
13 passed in 1.25s
# this suite does `from openapi_core import OpenAPI` at module top, so collection
# itself fails if openapi-core is still gated out

$ uv run --python 3.14 python -c "import pypdf; \
    from litellm.rag.ingestion.file_parsers.pdf_parser import extract_text_from_pdf; \
    t=extract_text_from_pdf(open('tests/llm_translation/fixtures/dummy.pdf','rb').read()); \
    assert t and len(t)>0; print('pypdf', pypdf.__version__, '| chars', len(t), '|', repr(t.strip()))"
pypdf 6.13.3 | chars 13 | 'Test PDF File'
# real bytes through litellm's own parser, which returns nothing if pypdf is absent

$ uv run --python 3.14 python -c "import redisvl; \
    from redisvl.extensions.llmcache import SemanticCache; \
    from redisvl.utils.vectorize import CustomTextVectorizer; \
    import litellm.caching.redis_semantic_cache; print('redisvl', redisvl.__version__)"
redisvl 0.4.1

$ uv run --python 3.14 python -c "import redisvl, pypdf, openapi_core; \
    print(redisvl.__version__, pypdf.__version__, openapi_core.__version__)"
0.4.1 6.13.3 0.22.0

One honesty note on redisvl: its existing unit suite mocks the client through sys.modules, so it passes with or without the package installed; the real-import line above is what demonstrates the package is present on 3.14. A full semantic-cache round-trip additionally needs a live Redis with the RediSearch module, which is orthogonal to whether the dependency is installable

Type

🚄 Infrastructure

Changes

Three optional dependencies were still excluded on Python 3.14 by python_version < '3.14' environment markers, so the features that depend on them stayed unavailable there even after litellm itself became installable on 3.14. This removes that marker from redisvl (the Redis semantic cache, litellm/caching/redis_semantic_cache.py), pypdf (RAG PDF ingestion, litellm/rag/ingestion/file_parsers/pdf_parser.py), and openapi-core (the dev dependency behind the OpenAPI compliance tests). All three declare support for 3.14 within their pinned bands, and the regenerated lock confirms they resolve on 3.14 with no change anywhere else

semantic-router and aurelio-sdk keep their markers on purpose: every published semantic-router release still caps python_requires below 3.14, so the semantic guardrail cannot run there until upstream ships a compatible release

The lock regeneration is marker-only. redisvl stays at 0.4.1, pypdf at 6.13.3, and openapi-core at 0.22.0, each now also covering 3.14; no other package moved on any Python version. The single non-marker line in the lock diff is uv's rolling exclude-newer timestamp, which has no effect on resolution. make pre-commit and uv lock --check both pass locally

This is the Python-side half of enabling 3.14; it merges in #33798, which raised the Rust bridge's pyo3 to 0.29, so a source install now builds the native module on 3.14 as well. No new test file is added deliberately: the change is a dependency-marker removal held to the smallest reviewable diff, and it is covered by the existing feature suites run before and after on 3.13 and natively on 3.14 above, rather than a 3.14-only test that current CI has no lane to run yet

Final Attestation

  • The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR

Remove the python_version < '3.14' environment markers from redisvl,
pypdf, and openapi-core now that all three install and import cleanly
on 3.14. The relock is marker-only: no package version changed for any
Python branch, and the locked versions (redisvl 0.4.1, pypdf 6.13.3,
openapi-core 0.22.0) now serve 3.14 as well. semantic-router and
aurelio-sdk stay gated because every published release caps
python_requires below 3.14
@yuneng-berri
yuneng-berri requested a review from a team July 18, 2026 01:13
@greptile-apps

greptile-apps Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR removes the python_version < '3.14' environment markers from three optional dependencies — redisvl, pypdf, and openapi-core — so those features become available on Python 3.14. The lock file is regenerated to match: only marker text and uv's rolling exclude-newer timestamp changed; no package version moved on any Python branch.

  • redisvl (Redis semantic cache, extra-proxy extra), pypdf (RAG PDF ingestion, proxy-runtime extra), and openapi-core (dev/test dependency) all have their Python 3.14 exclusion markers removed; semantic-router and aurelio-sdk intentionally retain their markers because upstream still caps python_requires below 3.14.
  • The uv.lock changes are purely mechanical: dependency markers for transitive deps are updated to follow the three newly ungated roots, and ml_dtypes/redisvl correctly extend the numpy 2.4.4 marker from >= '3.12' and < '3.14' to >= '3.12'.

Confidence Score: 5/5

Safe to merge — purely a marker removal with no version or logic changes anywhere in the dependency graph.

The change is a two-file, marker-only edit. The lock diff confirms that no package version moved on any existing Python branch, and the PR description provides explicit resolution proof on Python 3.14. There is nothing here that could regress existing behavior.

No files require special attention.

Important Files Changed

Filename Overview
pyproject.toml Removes python_version < '3.14' markers from redisvl (extra-proxy), pypdf (proxy-runtime), and openapi-core (dev); semantic-router and aurelio-sdk markers are intentionally kept
uv.lock Lock file regenerated: markers dropped from all transitive deps of the three ungated packages; no package versions changed; only the rolling exclude-newer timestamp updated

Reviews (1): Last reviewed commit: "Merge remote-tracking branch 'origin/lit..." | Re-trigger Greptile

@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_/bold-brahmagupta-943951 (3d972c8) with litellm_internal_staging (f3d2015)1

Open in CodSpeed

Footnotes

  1. No successful run was found on litellm_internal_staging (c725017) during the generation of this report, so f3d2015 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@yuneng-berri
yuneng-berri merged commit 967d934 into litellm_internal_staging Jul 18, 2026
78 of 81 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_/bold-brahmagupta-943951 branch July 18, 2026 01:38
yuneng-berri added a commit that referenced this pull request Jul 18, 2026
…1.93.0 stable cut (#33847)

* fix(ci): bump pillow to 12.3.0 to resolve osv-scan CVEs (#33093)

(cherry picked from commit 20e646c)

* chore(deps): pin httplib2 and setuptools transitive floors (#33233)

Raise the constraint floors for two transitive dependencies so resolution moves them to their latest maintenance releases: httplib2 0.31.2 -> 0.32.0 and setuptools 82.0.1 -> 83.0.0. Both are pulled in only by optional integrations (Google API client, grpc tooling, lunary observability, the nvidia-riva extra), all lower-bound only, so the floors stay inside every requirer's allowed range and a default install is unaffected

(cherry picked from commit 8b32320)

* fix(anthropic/passthrough): drop incompatible temperature when downgrading adaptive thinking for pre-4.6 models (#33244)

* fix(anthropic/passthrough): drop temperature and cap thinking budget when downgrading adaptive thinking for pre-4.6 models

* test(anthropic/passthrough): use sufficient max_tokens for reasoning_effort thinking mapping

* fix(anthropic/passthrough): drop incompatible temperature when downgrading adaptive thinking for pre-4.6 models

Narrow the fix to the temperature reconciliation; the reasoning_effort
budget cap is reverted because the live translation grid relies on
budget_tokens >= max_tokens to reject unsupported effort tiers
(xhigh/max) on budget-mode models, so capping turned those 400s into
200s.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
(cherry picked from commit 71dffc1)

* build: raise requires-python cap to <3.15 so Python 3.14 installs current releases (#33438)

* build: drop requires-python upper cap so Python 3.14 resolves to current releases

The <3.14 cap made pip on Python 3.14 fall back to litellm 1.83.7, a
pre-April release whose old auth flow fails with 400s. The cap was added
in d9a4602 because deps lacked 3.14 wheels and uv could not resolve
the 3.14 split; both are fixed now via the existing python_version
markers plus a ddtrace version split (2.x has no cp314 wheels, 3.16+
does). Verified on 3.14.5: uv sync --all-extras installs, litellm and
proxy_server import (rust bridge falls back to pure python), real
provider calls succeed sync/async/streaming, and the core-utils test
suite passes.

* build: cap requires-python at <3.15 and keep ddtrace on one major per python band

Reviewer preference to bound the supported window at the newest tested
minor rather than leaving it open-ended, and Greptile flagged the
ddtrace 3.14+ range spanning two majors; every ddtrace 4.x ships cp314
wheels so the band is now >=4.0,<5.0, matching the single-major
convention of the 2.x band.

(cherry picked from commit c6d49a8)

* build(deps): update ddtrace to the 4.x line

A single ddtrace constraint now covers every supported Python version, so this collapses the version split introduced in #33438. Also aligns the build_from_pip image pin and updates the type-only Tracer import to its current module path

(cherry picked from commit edc38ea)

* fix(docker): restore litellm-proxy-extras source dir in runtime images (#33592)

* fix(docker): restore litellm-proxy-extras source dir in runtime images

#30243 narrowed the runtime stage to an allowlist COPY, which dropped
/app/litellm-proxy-extras from the published images. Downstream
migration jobs point prisma migrate deploy at that path; with the
schema gone (or a schema with no adjacent migrations dir, where prisma
exits 0 without applying anything) those jobs went green while never
migrating the database. Restore the folder in all three runtime stages
and assert in image-scan that the schema and a non-empty migrations dir
ship at the source path

* chore(ci): drop image-scan migration-assets assertion

(cherry picked from commit 111d447)

* fix(model_armor): restore reference attachments via skip_unscannable_attachments and remove the attachment count cap (#33554)

* fix(model_armor): add skip_unscannable_attachments to allow reference-only attachments through

* fix(model_armor): wire skip_unscannable_attachments through guardrail config

* fix(model_armor): make max_file_attachments configurable and scan overflow instead of dropping

* fix(model_armor): remove the per-request attachment count cap and scan all attachments

---------

Co-authored-by: yucheng <yucheng@berri.ai>
(cherry picked from commit 0d7b0f7)

* build(rust): raise pyo3 to 0.29 so the native bridge compiles on Python 3.14 (#33798)

pyo3 0.23.5 hard-caps the interpreter at Python 3.13, so building the
native bridge against a 3.14 interpreter aborts inside pyo3-ffi's build
script before anything links. This raises pyo3 and pyo3-async-runtimes
to 0.29 (currently the newest line, and the range starting at 0.26 that
supports 3.14) and migrates the three call sites whose APIs were renamed
across that range: Python::with_gil is now Python::attach and
Python::allow_threads is now Python::detach. On a GIL-enabled interpreter
those are pure renames with identical semantics, so behavior on 3.10
through 3.13 is unchanged

Verified by compiling the native module for cp313 and cp314 and driving
it directly on both interpreters: gil_stats reports exactly one GIL
release per sync OCR call and the async path completes, matching the
0.23.5 baseline. cargo fmt, clippy, and the workspace tests pass on both
3.13 and 3.14 with the lockfile locked, and the lock churn is confined to
the pyo3 crates

Part of #26343; addresses the pyo3 build failure reported in #33116

(cherry picked from commit f3d2015)

* build(deps): allow redisvl, pypdf, and openapi-core on Python 3.14 (#33801)

Remove the python_version < '3.14' environment markers from redisvl,
pypdf, and openapi-core now that all three install and import cleanly
on 3.14. The relock is marker-only: no package version changed for any
Python branch, and the locked versions (redisvl 0.4.1, pypdf 6.13.3,
openapi-core 0.22.0) now serve 3.14 as well. semantic-router and
aurelio-sdk stay gated because every published release caps
python_requires below 3.14

(cherry picked from commit 967d934)

* build(deps): bump mcp lock to 1.28.1 to clear image-scan findings (#33803)

* build(deps): bump mcp lock to 1.28.1 to clear image-scan findings

* build(deps): require mcp>=1.28.1

(cherry picked from commit 40e914c)

* fix(proxy): source /v1/models token limits from the cost map instead of Router.get_model_group_info (#33721)

* fix(proxy): source /v1/models token limits from cost map instead of Router.get_model_group_info

Resolves the per-model get_model_group_info fan-out on GET /v1/models
(and /models) that pegged the event loop on wildcard listings (#33636).
create_model_info_response now reads max_input_tokens/max_output_tokens
from litellm.get_model_info (the static cost map) rather than the router,
which aggregated and deepcopied every deployment in a group per listed
model.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(proxy): inject model-info lookup into create_model_info_response for deterministic coverage

Inject the cost-map lookup (defaulting to litellm.get_model_info) so the
except and max_output_tokens branches are exercised deterministically and
the token-limit tests no longer hardcode mutable cost-map values.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat(proxy): surface custom deployment token limits on /v1/models via cheap index lookup

Add Router.get_configured_token_limits, an O(1) model-name index lookup that
reads a concrete deployment's configured max_input_tokens/max_output_tokens
without triggering pattern matching or deep copies. create_model_info_response
layers this over the cost map so custom deployments absent from the cost map
still surface their limits, and admin-configured limits override cost-map
defaults, while wildcard-expanded names stay on the fast path.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
(cherry picked from commit 8536e3b)

---------

Co-authored-by: yucheng-berri <yucheng@berri.ai>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ryan-crabbe-berri <ryan@berri.ai>
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.

4 participants