Skip to content

Commit 83bbb01

Browse files
kwentclaude
andcommitted
Fix escalation path generation with OpenAPI spec patching
The real issue was not anyOf vs oneOf — openapi-python-client cannot handle inline oneOf variants (objects with properties/required but no $ref). Additionally, the upstream spec has urgency_ids arrays missing items definitions. Added tools/fix_openapi_escalation_paths.py that: - Extracts inline rule variants into named component schemas - Fixes arrays missing items definitions - Replaces inline definitions with $ref pointers Escalation path endpoints now fully generate with typed rule models: alert_urgency, working_hour, json_path, field, service, deferral_window. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 0d3de39 commit 83bbb01

86 files changed

Lines changed: 2604 additions & 2640 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
## [1.3.0] - 2026-04-21
1111

1212
### Added
13+
- New Escalation Paths endpoints (create, read, update, delete, list) with typed rule models (alert urgency, working hour, JSON path, field, service, deferral window)
1314
- New API Keys endpoints (create, read, update, delete, list, rotate)
1415
- New SLA endpoints (create, read, update, delete, list)
1516
- New On-Call endpoints (list on-call users)
@@ -39,10 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3940
- Some escalation policy path rule type models (consolidated in upstream spec)
4041

4142
### Fixed
42-
- Applied nullable enum fix to 1,350 model files via `tools/fix_nullable_enums.py`
43-
44-
### Known Issues
45-
- Escalation path endpoints not generated due to OpenAPI schema issues with union types in `rules_item`
43+
- Applied nullable enum fix to 1,348 model files via `tools/fix_nullable_enums.py`
44+
- Escalation path endpoints now fully generated — added `tools/fix_openapi_escalation_paths.py` to patch inline `oneOf` variants into named `$ref` schemas and fix missing array `items` definitions
4645

4746
## [1.2.1] - 2025-03-02
4847

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
from http import HTTPStatus
2+
from typing import Any
3+
from urllib.parse import quote
4+
5+
import httpx
6+
7+
from ... import errors
8+
from ...client import AuthenticatedClient, Client
9+
from ...models.errors_list import ErrorsList
10+
from ...models.escalation_policy_path_response import EscalationPolicyPathResponse
11+
from ...models.new_escalation_policy_path import NewEscalationPolicyPath
12+
from ...types import Response
13+
14+
15+
def _get_kwargs(
16+
escalation_policy_id: str,
17+
*,
18+
body: NewEscalationPolicyPath,
19+
) -> dict[str, Any]:
20+
headers: dict[str, Any] = {}
21+
22+
_kwargs: dict[str, Any] = {
23+
"method": "post",
24+
"url": "/v1/escalation_policies/{escalation_policy_id}/escalation_paths".format(
25+
escalation_policy_id=quote(str(escalation_policy_id), safe=""),
26+
),
27+
}
28+
29+
_kwargs["json"] = body.to_dict()
30+
31+
headers["Content-Type"] = "application/vnd.api+json"
32+
33+
_kwargs["headers"] = headers
34+
return _kwargs
35+
36+
37+
def _parse_response(
38+
*, client: AuthenticatedClient | Client, response: httpx.Response
39+
) -> ErrorsList | EscalationPolicyPathResponse | None:
40+
if response.status_code == 201:
41+
response_201 = EscalationPolicyPathResponse.from_dict(response.json())
42+
43+
return response_201
44+
45+
if response.status_code == 401:
46+
response_401 = ErrorsList.from_dict(response.json())
47+
48+
return response_401
49+
50+
if response.status_code == 422:
51+
response_422 = ErrorsList.from_dict(response.json())
52+
53+
return response_422
54+
55+
if client.raise_on_unexpected_status:
56+
raise errors.UnexpectedStatus(response.status_code, response.content)
57+
else:
58+
return None
59+
60+
61+
def _build_response(
62+
*, client: AuthenticatedClient | Client, response: httpx.Response
63+
) -> Response[ErrorsList | EscalationPolicyPathResponse]:
64+
return Response(
65+
status_code=HTTPStatus(response.status_code),
66+
content=response.content,
67+
headers=response.headers,
68+
parsed=_parse_response(client=client, response=response),
69+
)
70+
71+
72+
def sync_detailed(
73+
escalation_policy_id: str,
74+
*,
75+
client: AuthenticatedClient,
76+
body: NewEscalationPolicyPath,
77+
) -> Response[ErrorsList | EscalationPolicyPathResponse]:
78+
"""Creates an escalation path
79+
80+
Creates a new escalation path from provided data
81+
82+
Args:
83+
escalation_policy_id (str):
84+
body (NewEscalationPolicyPath):
85+
86+
Raises:
87+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
88+
httpx.TimeoutException: If the request takes longer than Client.timeout.
89+
90+
Returns:
91+
Response[ErrorsList | EscalationPolicyPathResponse]
92+
"""
93+
94+
kwargs = _get_kwargs(
95+
escalation_policy_id=escalation_policy_id,
96+
body=body,
97+
)
98+
99+
response = client.get_httpx_client().request(
100+
**kwargs,
101+
)
102+
103+
return _build_response(client=client, response=response)
104+
105+
106+
def sync(
107+
escalation_policy_id: str,
108+
*,
109+
client: AuthenticatedClient,
110+
body: NewEscalationPolicyPath,
111+
) -> ErrorsList | EscalationPolicyPathResponse | None:
112+
"""Creates an escalation path
113+
114+
Creates a new escalation path from provided data
115+
116+
Args:
117+
escalation_policy_id (str):
118+
body (NewEscalationPolicyPath):
119+
120+
Raises:
121+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
122+
httpx.TimeoutException: If the request takes longer than Client.timeout.
123+
124+
Returns:
125+
ErrorsList | EscalationPolicyPathResponse
126+
"""
127+
128+
return sync_detailed(
129+
escalation_policy_id=escalation_policy_id,
130+
client=client,
131+
body=body,
132+
).parsed
133+
134+
135+
async def asyncio_detailed(
136+
escalation_policy_id: str,
137+
*,
138+
client: AuthenticatedClient,
139+
body: NewEscalationPolicyPath,
140+
) -> Response[ErrorsList | EscalationPolicyPathResponse]:
141+
"""Creates an escalation path
142+
143+
Creates a new escalation path from provided data
144+
145+
Args:
146+
escalation_policy_id (str):
147+
body (NewEscalationPolicyPath):
148+
149+
Raises:
150+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
151+
httpx.TimeoutException: If the request takes longer than Client.timeout.
152+
153+
Returns:
154+
Response[ErrorsList | EscalationPolicyPathResponse]
155+
"""
156+
157+
kwargs = _get_kwargs(
158+
escalation_policy_id=escalation_policy_id,
159+
body=body,
160+
)
161+
162+
response = await client.get_async_httpx_client().request(**kwargs)
163+
164+
return _build_response(client=client, response=response)
165+
166+
167+
async def asyncio(
168+
escalation_policy_id: str,
169+
*,
170+
client: AuthenticatedClient,
171+
body: NewEscalationPolicyPath,
172+
) -> ErrorsList | EscalationPolicyPathResponse | None:
173+
"""Creates an escalation path
174+
175+
Creates a new escalation path from provided data
176+
177+
Args:
178+
escalation_policy_id (str):
179+
body (NewEscalationPolicyPath):
180+
181+
Raises:
182+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
183+
httpx.TimeoutException: If the request takes longer than Client.timeout.
184+
185+
Returns:
186+
ErrorsList | EscalationPolicyPathResponse
187+
"""
188+
189+
return (
190+
await asyncio_detailed(
191+
escalation_policy_id=escalation_policy_id,
192+
client=client,
193+
body=body,
194+
)
195+
).parsed

0 commit comments

Comments
 (0)