mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-12 23:01:41 +00:00
fix(proxy): cleandoc exception docstrings used in OpenAPI ERROR_RESPONSES
The Swagger error descriptions wired up in swagger_utils.ERROR_RESPONSES were taken straight from exception.__doc__, which preserves the leading whitespace from the Python source (4 spaces per body line for any multi-line docstring). openapi-typescript renders that into JSDoc verbatim, so when RateLimitError grew a real multi-line docstring in #27687, every regenerated schema.d.ts now has a different indentation than the file committed by #29885. CI's Check UI API Types Sync flips back and forth between rebases on any PR that doesn't touch schema.d.ts itself. Pass __doc__ through inspect.cleandoc so the description stored in the OpenAPI spec is dedented at the source. The committed schema.d.ts is exactly what gen:api now produces, so no schema regen is needed in this commit; future docstrings on litellm exceptions won't reintroduce the drift either. Inherited docstrings from openai/Exception are still ignored (we keep the existing __doc__-not-getdoc fallback to the class name) so the description of every other 4xx/5xx response stays the class name like 'AuthenticationError'. Co-authored-by: Krrish Dholakia <krrish-berri-2@users.noreply.github.com>
This commit is contained in:
parent
aaf1e2444b
commit
fef0f219c2
2 changed files with 50 additions and 2 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import inspect
|
||||
from typing import Any, Dict
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
|
@ -31,11 +32,25 @@ def get_status_code(exception):
|
|||
return 500 # Internal Server Error as default
|
||||
|
||||
|
||||
# Create error responses
|
||||
def _exception_description(exception):
|
||||
"""Return a normalized description for OpenAPI / JSDoc consumers.
|
||||
|
||||
Uses the class's own docstring (not an inherited one) so the rendered Swagger
|
||||
description matches the historical short-form (the class name) when only an
|
||||
upstream library defined a docstring. ``cleandoc`` strips the source-code
|
||||
indentation that would otherwise leak into the generated JSDoc comment in
|
||||
``ui/litellm-dashboard/src/lib/http/schema.d.ts``.
|
||||
"""
|
||||
doc = exception.__doc__
|
||||
if not doc:
|
||||
return exception.__name__
|
||||
return inspect.cleandoc(doc)
|
||||
|
||||
|
||||
ERROR_RESPONSES = {
|
||||
get_status_code(exception): {
|
||||
"model": ErrorResponse,
|
||||
"description": exception.__doc__ or exception.__name__,
|
||||
"description": _exception_description(exception),
|
||||
}
|
||||
for exception in LITELLM_EXCEPTION_TYPES
|
||||
}
|
||||
|
|
|
|||
33
tests/test_litellm/proxy/common_utils/test_swagger_utils.py
Normal file
33
tests/test_litellm/proxy/common_utils/test_swagger_utils.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import inspect
|
||||
|
||||
from litellm.exceptions import RateLimitError
|
||||
from litellm.proxy.common_utils.swagger_utils import (
|
||||
ERROR_RESPONSES,
|
||||
_exception_description,
|
||||
)
|
||||
|
||||
|
||||
class _ChildWithoutDoc(RateLimitError):
|
||||
pass
|
||||
|
||||
|
||||
def test_exception_description_dedents_multiline_docstring():
|
||||
description = _exception_description(RateLimitError)
|
||||
|
||||
assert RateLimitError.__doc__ is not None
|
||||
assert RateLimitError.__doc__.startswith("\n ")
|
||||
assert description == inspect.cleandoc(RateLimitError.__doc__)
|
||||
assert "\n " not in description
|
||||
|
||||
|
||||
def test_exception_description_falls_back_to_name_when_no_own_doc():
|
||||
assert _ChildWithoutDoc.__doc__ is None
|
||||
assert _exception_description(_ChildWithoutDoc) == "_ChildWithoutDoc"
|
||||
|
||||
|
||||
def test_rate_limit_error_response_description_is_dedented():
|
||||
rate_limit_response = ERROR_RESPONSES[429]
|
||||
|
||||
description = rate_limit_response["description"]
|
||||
assert description.startswith("Unified rate-limit error.")
|
||||
assert "\n " not in description
|
||||
Loading…
Add table
Reference in a new issue