Coverage for .venv/lib/python3.13/site-packages/litellm/proxy/decisions_endpoints/endpoints.py: 75%

53 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 12:01 +0000

1from collections.abc import Mapping 

2from typing import Annotated, Final 

3 

4from fastapi import APIRouter, Depends, Request, Response 

5from fastapi.responses import ORJSONResponse # pyright: ignore[reportDeprecated] # required endpoint contract 

6from pydantic import TypeAdapter, ValidationError 

7 

8from litellm.exceptions import BadRequestError 

9from litellm.proxy.auth.user_api_key_auth import UserAPIKeyAuth, user_api_key_auth 

10from litellm.proxy.common_request_processing import ProxyBaseLLMRequestProcessing 

11from litellm.types.decisions import DecisionsRequestBody, OpenAIDecisionRequestBody 

12 

13router: Final = APIRouter() 

14_REQUEST_DATA_ADAPTER: Final[TypeAdapter[dict[str, object]]] = TypeAdapter(dict[str, object]) 

15_DECISIONS_REQUEST_BODY_ADAPTER: Final[TypeAdapter[DecisionsRequestBody]] = TypeAdapter(DecisionsRequestBody) 

16_OPENAI_DECISION_REQUEST_BODY_ADAPTER: Final[TypeAdapter[OpenAIDecisionRequestBody]] = TypeAdapter( 

17 OpenAIDecisionRequestBody 

18) 

19_GENERAL_SETTINGS_ADAPTER: Final[TypeAdapter[dict[str, object]]] = TypeAdapter(dict[str, object]) 

20_OPTIONAL_STRING_ADAPTER: Final[TypeAdapter[str | None]] = TypeAdapter(str | None) 

21_OPTIONAL_FLOAT_ADAPTER: Final[TypeAdapter[float | None]] = TypeAdapter(float | None) 

22 

23 

24async def _invalid_request( 

25 raw_data: Mapping[str, object], error: ValidationError, user_api_key_dict: UserAPIKeyAuth 

26) -> Exception: 

27 from litellm.proxy.proxy_server import proxy_logging_obj, version 

28 

29 return await ProxyBaseLLMRequestProcessing(data=dict(raw_data))._handle_llm_api_exception( 

30 e=BadRequestError( 

31 message=f"Invalid Decisions request: {error}", 

32 model=str(raw_data.get("model", "")), 

33 llm_provider="", 

34 ), 

35 user_api_key_dict=user_api_key_dict, 

36 proxy_logging_obj=proxy_logging_obj, 

37 version=version, 

38 ) 

39 

40 

41async def _request_data(request: Request, user_api_key_dict: UserAPIKeyAuth) -> dict[str, object]: 

42 body: Final = await request.body() 

43 try: 

44 return _REQUEST_DATA_ADAPTER.validate_json(body) 

45 except ValidationError as error: 

46 raise await _invalid_request(raw_data={}, error=error, user_api_key_dict=user_api_key_dict) 

47 

48 

49async def _process_decisions( 

50 request: Request, 

51 fastapi_response: Response, 

52 user_api_key_dict: UserAPIKeyAuth, 

53 body_adapter: TypeAdapter[DecisionsRequestBody] | TypeAdapter[OpenAIDecisionRequestBody], 

54) -> object: 

55 from litellm.proxy.proxy_server import ( 

56 general_settings as proxy_general_settings, 

57 ) 

58 from litellm.proxy.proxy_server import ( 

59 llm_router, 

60 proxy_config, 

61 proxy_logging_obj, 

62 user_max_tokens, 

63 user_request_timeout, 

64 version, 

65 ) 

66 from litellm.proxy.proxy_server import ( 

67 user_api_base as proxy_user_api_base, 

68 ) 

69 from litellm.proxy.proxy_server import ( 

70 user_model as proxy_user_model, 

71 ) 

72 from litellm.proxy.proxy_server import ( 

73 user_temperature as proxy_user_temperature, 

74 ) 

75 

76 data: Final = await _request_data(request, user_api_key_dict) 

77 try: 

78 body_adapter.validate_python(data) 

79 except ValidationError as error: 

80 raise await _invalid_request(raw_data=data, error=error, user_api_key_dict=user_api_key_dict) 

81 general_settings: Final = _GENERAL_SETTINGS_ADAPTER.validate_python(proxy_general_settings) 

82 user_api_base: Final = _OPTIONAL_STRING_ADAPTER.validate_python(proxy_user_api_base) 

83 user_model: Final = _OPTIONAL_STRING_ADAPTER.validate_python(proxy_user_model) 

84 user_temperature: Final = _OPTIONAL_FLOAT_ADAPTER.validate_python(proxy_user_temperature) 

85 processor: Final = ProxyBaseLLMRequestProcessing(data=data) 

86 try: 

87 return await processor.base_process_llm_request( 

88 request=request, 

89 fastapi_response=fastapi_response, 

90 user_api_key_dict=user_api_key_dict, 

91 route_type="adecisions", 

92 proxy_logging_obj=proxy_logging_obj, 

93 llm_router=llm_router, 

94 general_settings=general_settings, 

95 proxy_config=proxy_config, 

96 select_data_generator=None, 

97 model=None, 

98 user_model=user_model, 

99 user_temperature=user_temperature, 

100 user_request_timeout=user_request_timeout, 

101 user_max_tokens=user_max_tokens, 

102 user_api_base=user_api_base, 

103 version=version, 

104 ) 

105 except Exception as error: 

106 raise await processor._handle_llm_api_exception( 

107 e=error, 

108 user_api_key_dict=user_api_key_dict, 

109 proxy_logging_obj=proxy_logging_obj, 

110 version=version, 

111 ) 

112 

113 

114@router.post( 

115 "/v1/systemone", 

116 dependencies=[Depends(user_api_key_auth)], 

117 response_class=ORJSONResponse, # pyright: ignore[reportDeprecated] # required endpoint contract 

118 tags=["decisions"], 

119) 

120@router.post( 

121 "/systemone", 

122 dependencies=[Depends(user_api_key_auth)], 

123 response_class=ORJSONResponse, # pyright: ignore[reportDeprecated] # required endpoint contract 

124 tags=["decisions"], 

125) 

126async def systemone( 

127 request: Request, 

128 fastapi_response: Response, 

129 user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)], 

130): 

131 return await _process_decisions( 

132 request=request, 

133 fastapi_response=fastapi_response, 

134 user_api_key_dict=user_api_key_dict, 

135 body_adapter=_DECISIONS_REQUEST_BODY_ADAPTER, 

136 ) 

137 

138 

139@router.post( 

140 "/v1/decisions", 

141 dependencies=[Depends(user_api_key_auth)], 

142 response_class=ORJSONResponse, # pyright: ignore[reportDeprecated] # required endpoint contract 

143 tags=["decisions"], 

144) 

145@router.post( 

146 "/decisions", 

147 dependencies=[Depends(user_api_key_auth)], 

148 response_class=ORJSONResponse, # pyright: ignore[reportDeprecated] # required endpoint contract 

149 tags=["decisions"], 

150) 

151async def decisions( 

152 request: Request, 

153 fastapi_response: Response, 

154 user_api_key_dict: Annotated[UserAPIKeyAuth, Depends(user_api_key_auth)], 

155): 

156 return await _process_decisions( 

157 request=request, 

158 fastapi_response=fastapi_response, 

159 user_api_key_dict=user_api_key_dict, 

160 body_adapter=_OPENAI_DECISION_REQUEST_BODY_ADAPTER, 

161 )