From d02d1ef7abb5ef48d9ba81883ffec458d844eeab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Badenes?= Date: Tue, 19 May 2026 17:05:29 -0300 Subject: [PATCH 1/3] Remove deprecated ConnectorConfig.log_level field BREAKING CHANGE: `ConnectorConfig.log_level` (deprecated since v1.1.0) is removed. Use `ConnectorConfig.logging.log_level` instead. Co-Authored-By: Claude Opus 4.6 --- docs/contents/specification/models.md | 4 ---- inorbit_connector/models.py | 25 ------------------------- 2 files changed, 29 deletions(-) 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..682b800 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 @@ -30,9 +29,6 @@ from inorbit_connector.utils import DEFAULT_TIMEZONE, DEFAULT_LOGGING_CONFIG 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. @@ -267,9 +263,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 +292,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] From 3e3df5aec4f57df9115f63a421934ca410ef8024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Badenes?= Date: Tue, 19 May 2026 20:09:02 -0300 Subject: [PATCH 2/3] Forbid extra fields on ConnectorConfig Pydantic v2 defaults to extra="ignore", so removing the deprecated log_level field would silently drop it instead of erroring. Setting extra="forbid" ensures stale configs fail loudly. Co-Authored-By: Claude Code --- inorbit_connector/models.py | 3 +++ tests/test_models.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/inorbit_connector/models.py b/inorbit_connector/models.py index 682b800..442cdce 100644 --- a/inorbit_connector/models.py +++ b/inorbit_connector/models.py @@ -17,6 +17,7 @@ from inorbit_edge.robot import INORBIT_CLOUD_SDK_ROBOT_CONFIG_URL from pydantic import ( BaseModel, + ConfigDict, field_validator, HttpUrl, FilePath, @@ -241,6 +242,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 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"]) From 97d14760c5b85fa50f7e0a301352febab27e0941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Badenes?= Date: Wed, 20 May 2026 09:11:27 -0300 Subject: [PATCH 3/3] Update models.py --- inorbit_connector/models.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/inorbit_connector/models.py b/inorbit_connector/models.py index 442cdce..64875d1 100644 --- a/inorbit_connector/models.py +++ b/inorbit_connector/models.py @@ -18,16 +18,15 @@ from pydantic import ( BaseModel, ConfigDict, - field_validator, - HttpUrl, - FilePath, 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