build(auth_v2): add Authlib and scim2-models for the auth_v2 module

Pull in the OSS libraries the standards-based auth module orchestrates:
Authlib for the OIDC login flow and scim2-models for SCIM 2.0, and switch
PyJWT to the [crypto] extra so JWKS-backed RS256 verification is explicit
(cryptography was already a proxy dependency). scim2-models ships py.typed
but its generic, alias-driven models trip mypy's call-arg check though they
work at runtime, so treat the library as untyped at the boundary in both
litellm/mypy.ini (used by CI) and the root pyproject mypy config.
This commit is contained in:
Yassin Kortam 2026-06-10 17:22:20 -07:00
parent dff25fef44
commit 2bbf688613
3 changed files with 62 additions and 5 deletions

View file

@ -16,4 +16,8 @@ ignore_errors = True
[mypy-fastuuid.*]
ignore_missing_imports = True
ignore_errors = True
ignore_errors = True
[mypy-scim2_models.*]
follow_imports = skip
follow_imports_for_stubs = True

View file

@ -53,7 +53,9 @@ proxy = [
"orjson>=3.11.6,<4.0",
"apscheduler>=3.11.2,<4.0",
"fastapi-sso>=0.19.0,<1.0",
"PyJWT>=2.13.0,<3.0",
"PyJWT[crypto]>=2.13.0,<3.0",
"Authlib>=1.6.0,<2.0",
"scim2-models>=0.6.0,<1.0",
"python-multipart>=0.0.27,<1.0",
"cryptography>=46.0.7,<47.0",
"pynacl>=1.6.2,<2.0",
@ -277,6 +279,16 @@ version_files = [
[tool.mypy]
plugins = "pydantic.mypy"
# scim2-models ships py.typed, but its generic, alias-driven SCIM models report
# phantom call-arg errors under mypy though they work at runtime. Treat the
# library as untyped at the boundary; litellm/auth_v2 is its only consumer.
# CI runs mypy from litellm/ against litellm/mypy.ini, which carries the same
# override; this block keeps root-level mypy runs consistent.
[[tool.mypy.overrides]]
module = "scim2_models.*"
follow_imports = "skip"
follow_imports_for_stubs = true
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "session"

47
uv.lock generated
View file

@ -9,7 +9,7 @@ resolution-markers = [
]
[options]
exclude-newer = "2026-06-05T23:18:37.734017Z"
exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values.
exclude-newer-span = "P3D"
[manifest]
@ -423,6 +423,19 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a2/1f/aa74b23b6eea4cf9b79ace914df59123c4c8e7e4bd32dd22d09c126422d9/aurelio_sdk-0.0.19-py3-none-any.whl", hash = "sha256:390c0212b59ce99116df8722d3badced88c5ef0bb742a6222d479ceed0ed3948", size = 17322, upload-time = "2025-03-24T14:37:31.305Z" },
]
[[package]]
name = "authlib"
version = "1.7.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cryptography" },
{ name = "joserfc" },
]
sdist = { url = "https://files.pythonhosted.org/packages/36/98/7d93f30d029643c0275dbc0bd6d5a6f670661ee6c9a94d93af7ab4887600/authlib-1.7.2.tar.gz", hash = "sha256:2cea25fefcd4e7173bdf1372c0afc265c8034b23a8cd5dcb6a9164b826c64231", size = 176511, upload-time = "2026-05-06T08:10:23.116Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fb/95/adcb68e20c34162e9135f370d6e31737719c2b6f94bc953fe7ed1f10fe21/authlib-1.7.2-py2.py3-none-any.whl", hash = "sha256:3e1faedc9d87e7d56a164eca3ccb6ace0d61b94abe83e92242f8dc8bba9b4a9f", size = 259548, upload-time = "2026-05-06T08:10:21.436Z" },
]
[[package]]
name = "azure-ai-contentsafety"
version = "1.0.0"
@ -2735,6 +2748,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" },
]
[[package]]
name = "joserfc"
version = "1.7.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cryptography" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d3/c3/2f590052b55cbdd0ace470ee7ee1f685f6882051be93a9374891005623e2/joserfc-1.7.0.tar.gz", hash = "sha256:4aced6ab0c47846f0a531402aec2419a874b91e918df9c4c9da8a82fb559d6c4", size = 232967, upload-time = "2026-06-02T09:59:34.506Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5b/83/b6b62a66a06ce872d9429a5eb5ee20b2002fd9c331b953c94381c1f7c9f9/joserfc-1.7.0-py3-none-any.whl", hash = "sha256:17e5d7a5a35e65442b05efc435a3d5d46696ffa2c8a2ed0eea6f63fc268e3224", size = 70387, upload-time = "2026-06-02T09:59:33.264Z" },
]
[[package]]
name = "jsonlines"
version = "4.0.0"
@ -3323,6 +3348,7 @@ mlflow = [
]
proxy = [
{ name = "apscheduler" },
{ name = "authlib" },
{ name = "azure-identity" },
{ name = "azure-storage-blob" },
{ name = "backoff" },
@ -3338,7 +3364,7 @@ proxy = [
{ name = "orjson" },
{ name = "polars" },
{ name = "pydantic-settings" },
{ name = "pyjwt" },
{ name = "pyjwt", extra = ["crypto"] },
{ name = "pynacl" },
{ name = "pyroscope-io", marker = "sys_platform != 'win32'" },
{ name = "python-multipart" },
@ -3346,6 +3372,7 @@ proxy = [
{ name = "restrictedpython" },
{ name = "rich" },
{ name = "rq" },
{ name = "scim2-models" },
{ name = "soundfile" },
{ name = "starlette" },
{ name = "uvicorn" },
@ -3477,6 +3504,7 @@ requires-dist = [
{ name = "apscheduler", marker = "extra == 'proxy'", specifier = ">=3.11.2,<4.0" },
{ name = "audioread", marker = "extra == 'stt-nvidia-riva'", specifier = ">=3.0.1" },
{ name = "aurelio-sdk", marker = "python_full_version < '3.14' and extra == 'semantic-router'", specifier = ">=0.0.19,<1.0" },
{ name = "authlib", marker = "extra == 'proxy'", specifier = ">=1.6.0,<2.0" },
{ name = "azure-ai-contentsafety", marker = "extra == 'proxy-runtime'", specifier = ">=1.0.0,<2.0" },
{ name = "azure-identity", marker = "extra == 'extra-proxy'", specifier = ">=1.25.2,<2.0" },
{ name = "azure-identity", marker = "extra == 'proxy'", specifier = ">=1.25.2,<2.0" },
@ -3527,7 +3555,7 @@ requires-dist = [
{ name = "prometheus-client", marker = "extra == 'proxy-runtime'", specifier = ">=0.20.0,<1.0" },
{ name = "pydantic", specifier = ">=2.10.0,<3.0.0" },
{ name = "pydantic-settings", marker = "extra == 'proxy'", specifier = ">=2.14.1,<3.0" },
{ name = "pyjwt", marker = "extra == 'proxy'", specifier = ">=2.13.0,<3.0" },
{ name = "pyjwt", extras = ["crypto"], marker = "extra == 'proxy'", specifier = ">=2.13.0,<3.0" },
{ name = "pynacl", marker = "extra == 'proxy'", specifier = ">=1.6.2,<2.0" },
{ name = "pypdf", marker = "python_full_version < '3.14' and extra == 'proxy-runtime'", specifier = ">=6.10.2,<7.0" },
{ name = "pyroscope-io", marker = "sys_platform != 'win32' and extra == 'proxy'", specifier = ">=0.8.16,<1.0" },
@ -3542,6 +3570,7 @@ requires-dist = [
{ name = "rich", marker = "extra == 'cli'", specifier = ">=13.9.4,<14.0" },
{ name = "rich", marker = "extra == 'proxy'", specifier = ">=13.9.4,<14.0" },
{ name = "rq", marker = "extra == 'proxy'", specifier = ">=2.7.0,<3.0" },
{ name = "scim2-models", marker = "extra == 'proxy'", specifier = ">=0.6.0,<1.0" },
{ name = "semantic-router", marker = "python_full_version < '3.14' and extra == 'semantic-router'", specifier = ">=0.1.15,<1.0" },
{ name = "sentry-sdk", marker = "extra == 'proxy-runtime'", specifier = ">=2.21.0,<3.0" },
{ name = "soundfile", marker = "extra == 'proxy'", specifier = ">=0.12.1,<1.0" },
@ -6894,6 +6923,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/5e/37/e192ea709551799379958b4c4771ec507347027bb7c942662c7fbeba31cb/scikit_learn-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde", size = 7869518, upload-time = "2025-12-10T07:08:25.71Z" },
]
[[package]]
name = "scim2-models"
version = "0.6.12"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pydantic", extra = ["email"] },
]
sdist = { url = "https://files.pythonhosted.org/packages/ad/67/121a60b8433839fb19a9986e8d9f5416941e42ea6827bd7e520783477cca/scim2_models-0.6.12.tar.gz", hash = "sha256:3a57c5ec10dc1007e5f4391d3bddeaca974be8d55e9ede4a1de20019ad3a920b", size = 48631, upload-time = "2026-04-13T12:37:11.888Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3e/b0/04d4b4e10ce59e813a3000d3ccb97537e88ab0341aacebc51abee50ed637/scim2_models-0.6.12-py3-none-any.whl", hash = "sha256:8ccc8139c61f84a29a1c54d8eda3f8fd121534cdd292166be1e8289d6f05902a", size = 61012, upload-time = "2026-04-13T12:37:10.322Z" },
]
[[package]]
name = "scipy"
version = "1.15.3"