diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9bc339ea..150875e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,5 +48,5 @@ jobs: - name: Install package run: uv pip install --system . - - name: Test SDK imports - run: python -c "import rootly_sdk; print('SDK imports successfully')" + - name: Test SDK + run: make test diff --git a/CHANGELOG.md b/CHANGELOG.md index c5719583..57675cdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.0.1] - 2026-08-31 + +### Fixed +- Allow incident responses with no assigned severity to deserialize successfully ([#18](https://github.com/rootlyhq/rootly-python/issues/18)) + ## [2.0.0] - 2026-08-14 ### Added diff --git a/Makefile b/Makefile index b35a8635..9cbc5d5a 100644 --- a/Makefile +++ b/Makefile @@ -48,4 +48,5 @@ regenerate: @uvx --from ruff==$(RUFF_VERSION) ruff format . test: + python -m unittest discover -s tests python -c "import rootly_sdk; print('SDK imports successfully')" diff --git a/pyproject.toml b/pyproject.toml index dfda158f..c8dbe4f9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "rootly" -version = "2.0.0" +version = "2.0.1" description = "A client library for accessing Rootly API v1" authors = [] readme = "README.md" diff --git a/rootly_sdk/models/incident.py b/rootly_sdk/models/incident.py index ee5817ae..aaac3646 100644 --- a/rootly_sdk/models/incident.py +++ b/rootly_sdk/models/incident.py @@ -54,7 +54,7 @@ class Incident: short_url (Union[None, Unset, str]): The short url to the incident public_title (Union[None, Unset, str]): The public title of the incident user (Union['IncidentUserType0', None, Unset]): The user who created the incident - severity (Union[Unset, SeverityResponse]): + severity (Union[None, Unset, SeverityResponse]): environments (Union[None, Unset, list['EnvironmentResponse']]): The Environments of the incident incident_types (Union[None, Unset, list['IncidentTypeResponse']]): The Incident Types of the incident services (Union[None, Unset, list['ServiceResponse']]): The Services of the incident @@ -195,7 +195,7 @@ class Incident: short_url: None | Unset | str = UNSET public_title: None | Unset | str = UNSET user: Union["IncidentUserType0", None, Unset] = UNSET - severity: Union[Unset, "SeverityResponse"] = UNSET + severity: Union[None, Unset, "SeverityResponse"] = UNSET environments: None | Unset | list["EnvironmentResponse"] = UNSET incident_types: None | Unset | list["IncidentTypeResponse"] = UNSET services: None | Unset | list["ServiceResponse"] = UNSET @@ -324,6 +324,7 @@ def to_dict(self) -> dict[str, Any]: from ..models.incident_resolved_by_type_0 import IncidentResolvedByType0 from ..models.incident_started_by_type_0 import IncidentStartedByType0 from ..models.incident_user_type_0 import IncidentUserType0 + from ..models.severity_response import SeverityResponse title = self.title @@ -397,9 +398,13 @@ def to_dict(self) -> dict[str, Any]: else: user = self.user - severity: Unset | dict[str, Any] = UNSET - if not isinstance(self.severity, Unset): + severity: None | Unset | dict[str, Any] + if isinstance(self.severity, Unset): + severity = UNSET + elif isinstance(self.severity, SeverityResponse): severity = self.severity.to_dict() + else: + severity = self.severity environments: None | Unset | list[dict[str, Any]] if isinstance(self.environments, Unset): @@ -1558,12 +1563,16 @@ def _parse_user(data: object) -> Union["IncidentUserType0", None, Unset]: user = _parse_user(d.pop("user", UNSET)) - _severity = d.pop("severity", UNSET) - severity: Unset | SeverityResponse - if isinstance(_severity, Unset): - severity = UNSET - else: - severity = SeverityResponse.from_dict(_severity) + def _parse_severity(data: object) -> None | Unset | SeverityResponse: + if data is None: + return data + if isinstance(data, Unset): + return data + if not isinstance(data, dict): + raise TypeError() + return SeverityResponse.from_dict(data) + + severity = _parse_severity(d.pop("severity", UNSET)) def _parse_environments(data: object) -> None | Unset | list["EnvironmentResponse"]: if data is None: diff --git a/tests/test_incident_response.py b/tests/test_incident_response.py new file mode 100644 index 00000000..636c320f --- /dev/null +++ b/tests/test_incident_response.py @@ -0,0 +1,28 @@ +import unittest + +from rootly_sdk.models.incident_response import IncidentResponse + + +class TestIncidentResponse(unittest.TestCase): + def test_deserializes_and_serializes_null_severity(self) -> None: + payload = { + "data": { + "id": "incident-id", + "type": "incidents", + "attributes": { + "title": "Scheduled maintenance", + "created_at": "2026-08-31T12:00:00Z", + "updated_at": "2026-08-31T12:00:00Z", + "severity": None, + }, + } + } + + response = IncidentResponse.from_dict(payload) + + self.assertIsNone(response.data.attributes.severity) + self.assertIsNone(response.to_dict()["data"]["attributes"]["severity"]) + + +if __name__ == "__main__": + unittest.main()