Skip to content

Conversation

mliu-cloudera
Copy link
Collaborator

@mliu-cloudera mliu-cloudera commented Aug 22, 2025

Also helps lay groundwork for #307.

@Copilot Copilot AI review requested due to automatic review settings August 22, 2025 21:12
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the test configuration by moving the parametrization from the test class decorator to the fixture definition itself, leveraging pytest's direct fixture parametrization feature.

  • Removes the @pytest.mark.parametrize decorator from the test class
  • Adds params=ModelProvider.__subclasses__() parameter directly to the @pytest.fixture decorator

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@mliu-cloudera mliu-cloudera removed the request for review from baasitsharief August 22, 2025 21:46
@mliu-cloudera mliu-cloudera marked this pull request as draft August 22, 2025 21:46
def is_enabled(cls) -> bool:
"""Return whether this model provider is enabled, based on the presence of required env vars."""
def env_vars_are_set(cls) -> bool:
"""Return whether this model provider's env vars have set values."""
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"is enabled" is a bit ambiguous between "is available for use" and "is the active model provider", since we now have the MODEL_PROVIDER env var that the method doesn't even account for.

Comment on lines +61 to +65
@staticmethod
@abc.abstractmethod
def get_model_source() -> ModelSource:
"""Return the name of this model provider"""
raise NotImplementedError
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved here from the bottom of the class definition to group it with the other "metadata" methods (as opposed to the "get model" methods).

Comment on lines +69 to +74
def get_priority() -> int:
"""Return the priority of this model provider relative to the others.

1 is the highest priority.

"""
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I set the values for this based on the order we had in get_provider_class():

# Fallback to priority order if no specific provider is set
if AzureModelProvider.is_enabled():
    return AzureModelProvider
elif OpenAiModelProvider.is_enabled():
    return OpenAiModelProvider
elif BedrockModelProvider.is_enabled():
    return BedrockModelProvider
return CAIIModelProvider

return all(map(os.environ.get, cls.get_env_var_names()))

@staticmethod
def get_provider_class() -> type["ModelProvider"]:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to llm-service/app/services/models/providers/__init__.py since it doesn't make sense for it to be inherited.

]


def get_provider_class() -> type[_ModelProvider]:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revamped to loop through ModelProvider's subclasses rather than have them hard-coded.

Comment on lines -50 to +49
class ModelProvider(abc.ABC):
class _ModelProvider(abc.ABC):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With get_provider_class() moved out, this class should no longer need to be invoked directly except for subclassing.

)
)


@pytest.fixture()
@pytest.fixture(params=_ModelProvider.__subclasses__())
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've discovered that we can do this instead of the

@pytest.mark.parametrize(
    "EnabledModelProvider",
    ModelProvider.__subclasses__(),
    indirect=True,
)

below! which is a lot simpler and easier on a test writer.

Comment on lines +66 to -69
for name in get_all_env_var_names():
monkeypatch.delenv(name, raising=False)
for name in ModelProviderSubcls.get_env_var_names():
monkeypatch.setenv(name, "test")
for name in get_all_env_var_names() - ModelProviderSubcls.get_env_var_names():
monkeypatch.delenv(name, raising=False)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've realized this is probably simpler?

Comment on lines -56 to +63
ModelProviderType = Literal["Azure", "CAII", "OpenAI", "Bedrock"]


class ModelSource(str, Enum):
AZURE = "Azure"
OPENAI = "OpenAI"
BEDROCK = "Bedrock"
CAII = "CAII"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably isn't the best place for ModelSource (I moved it here from llm-service/app/services/models/ to avoid a circular import), but I wanted to replace and remove the redundant ModelProviderType.

@@ -136,7 +136,7 @@ class ProjectConfig(BaseModel):
chat_store_provider: ChatStoreProviderType
vector_db_provider: VectorDbProviderType
metadata_db_provider: MetadataDbProviderType
model_provider: Optional[ModelProviderType] = None
model_provider: Optional[ModelSource] = None
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still comes back as a string when the frontend calls /llm-service/amp/config 👍

@mliu-cloudera mliu-cloudera changed the title Parametrize ModelProvider fixture directly Clean up logic for determining the active model provider Aug 22, 2025
@mliu-cloudera mliu-cloudera marked this pull request as ready for review August 22, 2025 23:45
Comment on lines +84 to +85
logger.info('falling back to model provider "CAII"')
return CAIIModelProvider
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep it for backwards compatibility.

@mliu-cloudera mliu-cloudera merged commit 0a6b9ce into main Aug 27, 2025
3 checks passed
@mliu-cloudera mliu-cloudera deleted the liu/params branch August 27, 2025 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants