Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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')"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
29 changes: 19 additions & 10 deletions rootly_sdk/models/incident.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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:
Expand Down
28 changes: 28 additions & 0 deletions tests/test_incident_response.py
Original file line number Diff line number Diff line change
@@ -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()