fix: keep ModelInfo import inline to break module-level cyclic import

CodeQL on PR #25413 (alert: "Module-level cyclic import" at line 57)
flagged that the previous P2 cleanup introduced a real circular import:

  litellm.types.router (re-imports model_management_endpoints) -> ...
  -> ModelInfo definition occurs *after* the cyclic re-import.

At module load time, depending on import order, the top-level
`from litellm.types.router import ModelInfo` could resolve to an
unbound name. The other names imported from `litellm.types.router`
in the same block (`Deployment`, `LiteLLMParamsTypedDict`,
`updateDeployment`) are defined before the cyclic re-import and
remain safe at module level.

Fix:
- Drop `ModelInfo` from the top-level `from litellm.types.router import (...)`
  block.
- Re-introduce inline `from litellm.types.router import ModelInfo` inside
  the two functions that instantiate it (`patch_model` and
  `_update_team_model_in_db`), matching the original safe pattern that
  existed before the P2 cleanup.
- Add a NOTE comment near the surviving import block explaining why
  ModelInfo is intentionally not hoisted.

No functional change. Restores the lazy-import pattern that
predates the P2 review fix.
This commit is contained in:
bussyjd 2026-04-11 03:30:34 +09:00
parent 27ef9a5a7a
commit baae1ed7e4

View file

@ -54,9 +54,15 @@ from litellm.types.router import (
Deployment,
DeploymentTypedDict,
LiteLLMParamsTypedDict,
ModelInfo,
updateDeployment,
)
# NOTE: `ModelInfo` is imported inline inside the two functions that use it
# (`patch_model` and `_update_team_model_in_db`) to break a module-level cyclic
# import. `litellm.types.router` re-imports this module before `ModelInfo` is
# defined, so a top-level `from litellm.types.router import ModelInfo` is
# unsafe at load time. CodeQL flagged this as a "module-level cyclic import"
# in PR #25413; the inline pattern is the original safe form.
from litellm.utils import get_utc_datetime
router = APIRouter()
@ -193,6 +199,9 @@ async def patch_model(
store_model_in_db,
)
# Inline import to avoid module-level cyclic import (CodeQL #25413).
from litellm.types.router import ModelInfo
try:
_is_db_mode = prisma_client is not None and store_model_in_db is True
@ -544,6 +553,9 @@ async def _update_team_model_in_db(
# Validate team_id if present in patch_data
from litellm.proxy.proxy_server import premium_user
# Inline import to avoid module-level cyclic import (CodeQL #25413).
from litellm.types.router import ModelInfo
await ModelManagementAuthChecks.allow_team_model_action(
model_params=patch_data,
user_api_key_dict=user_api_key_dict,