[FEATURE] Allow Dictionary Inputs for Complex Types in SDK
Problem Statement The SDK currently requires users to create specific object types (like EndpointCoreConfigInput, AiGatewayConfig, RateLimit, EndpointTag) when e.g. creating a serving endpoint (sticking to this as endpoint creation/updating and gateway configuration is my current use case). This can be cumbersome and somewhat challenging to learn.
For instance, creating a serving endpoint currently looks something like:
from databricks.sdk.service.serving import (
ServedEntityInput,
EndpointCoreConfigInput,
ExternalModel,
ExternalModelProvider,
OpenAiConfig,
)
create_endpoint_config = EndpointCoreConfigInput(
name="dr-gateway-demo",
served_entities=[
ServedEntityInput(
name="<name>",
external_model=ExternalModel(
name="<model-name>",
provider=ExternalModelProvider.OPENAI,
task="llm/v1/chat",
openai_config=OpenAiConfig(
openai_api_key=f"{{{{secrets/{SECRETS_SCOPE}/{SECRETS_KEY}}}}}",
),
),
)
],
)
Even for someone experienced with the API, it takes a lot of extra time consulting docs making sure the classes are properly instantiated.
This is made more challenging by how deeply nested these types are (see above).
Proposed Solution Allow the SDK to accept both custom objects and plain dictionaries for complex type parameters, with a recursive helper function that converts dictionaries to appropriate object types while handling nested structures and type compatibility. For example, the create() method could be updated to accept either custom objects or dictionaries (resulting in the following signature):
def create(self,
name: str,
config: Union[EndpointCoreConfigInput, Dict[str, Any]],
*,
ai_gateway: Optional[Union[AiGatewayConfig, Dict[str, Any]]] = None,
rate_limits: Optional[Union[List[RateLimit], List[Dict[str, Any]]]] = None,
route_optimized: Optional[bool] = None,
tags: Optional[Union[List[EndpointTag], List[Dict[str, Any]]]] = None) -> Wait[ServingEndpointDetailed]:
# Implementation that handles both object and dictionary inputs
Additional Context
One of the use cases this enables is making it much easier to update configs—you can just .update() the corresponding dict. It would also:
- Make it more similar in usage to the MLflow deployments SDK (at least for model serving), which does let you pass configs as plain dicts
- Make objects you might send via a REST API request with the requests library more compatible with the SDK, without a tricky translation to specific object types.
Completely agree. One thing I do as a workaround is use the from_dict methods provided by the data classes (e.g. https://github.com/databricks/databricks-sdk-py/blob/79b096fb414d87ea5c8d4484687544ce63bbe266/databricks/sdk/service/jobs.py#L1545)