diff --git a/docs/contents/specification/models.md b/docs/contents/specification/models.md index 2f7376a..9cec305 100644 --- a/docs/contents/specification/models.md +++ b/docs/contents/specification/models.md @@ -20,10 +20,6 @@ Key points: Returns a config instance of the same subclass type, with `fleet` filtered down to exactly the requested robot. -### Deprecated: `log_level` - -`ConnectorConfig.log_level` is deprecated in favor of `ConnectorConfig.logging.log_level`. - (spec-models-robotconfig)= ## `RobotConfig` diff --git a/inorbit_connector/models.py b/inorbit_connector/models.py index db74924..64875d1 100644 --- a/inorbit_connector/models.py +++ b/inorbit_connector/models.py @@ -8,7 +8,6 @@ # Standard import os import re -import warnings from pathlib import Path from typing import List, Optional @@ -18,21 +17,18 @@ from inorbit_edge.robot import INORBIT_CLOUD_SDK_ROBOT_CONFIG_URL from pydantic import ( BaseModel, - field_validator, - HttpUrl, - FilePath, + ConfigDict, DirectoryPath, Field, - model_validator, + FilePath, + HttpUrl, + field_validator, ) # InOrbit -from inorbit_connector.utils import DEFAULT_TIMEZONE, DEFAULT_LOGGING_CONFIG +from inorbit_connector.utils import DEFAULT_LOGGING_CONFIG, DEFAULT_TIMEZONE from inorbit_connector.logging.logger import LogLevels -# Ensure deprecation warnings are shown -warnings.filterwarnings("always", category=DeprecationWarning) - class MapConfigBase(BaseModel): """Base class for map configuration with common metadata fields. @@ -245,6 +241,8 @@ class ConnectorConfig(BaseModel): fleet (list[RobotConfig]): The list of robot configurations. """ + model_config = ConfigDict(extra="forbid") + api_key: str | None = os.getenv("INORBIT_API_KEY") # default_factory + explicit HttpUrl construction: handing a bare # string default to a `HttpUrl`-typed field stores it as `str` (the @@ -267,9 +265,6 @@ class ConnectorConfig(BaseModel): maps: dict[str, MapConfig] = {} env_vars: dict[str, str] = {} metrics: MetricsConfig = MetricsConfig() - # Kept for backwards compatibility. Deprecated in version 1.1.0 - # Use logging.log_level instead - log_level: LogLevels | None = Field(default=None, exclude=True) fleet: list[RobotConfig] def to_singular_config(self, robot_id: str) -> "ConnectorConfig": @@ -299,24 +294,6 @@ def to_singular_config(self, robot_id: str) -> "ConnectorConfig": ) return config - @model_validator(mode="after") - def warn_log_level_deprecated(self) -> "ConnectorConfig": - """Warn if log_level is set as it is deprecated. - - Returns: - ConnectorConfig: The model instance - """ - if self.log_level is not None: - warnings.warn( - "The 'log_level' field is deprecated. " - "Please use 'logging.log_level' instead.", - DeprecationWarning, - stacklevel=2, - ) - if self.logging.log_level is None: - self.logging.log_level = self.log_level - return self - @field_validator("fleet") def must_contain_at_least_one_robot( cls, fleet: list[RobotConfig] diff --git a/tests/test_models.py b/tests/test_models.py index 854b461..ea145db 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -156,6 +156,12 @@ def test_use_websockets_preserved_in_to_singular_config(self, base_model): singular = model.to_singular_config("robot1") assert singular.use_websockets is True + def test_extra_fields_are_forbidden(self, base_model): + init_input = base_model.copy() + init_input["log_level"] = "INFO" + with pytest.raises(ValidationError, match="Extra inputs are not permitted"): + ConnectorConfig(**init_input) + @mock.patch.dict(os.environ, {"INORBIT_API_KEY": "env_valid_key"}) def test_reads_api_key_from_environment_variable(self, base_model): importlib.reload(sys.modules["inorbit_connector.models"])