Skip to content

Commit 5bdf81b

Browse files
kwentclaude
andcommitted
Release v1.1.0: Regenerate client with new features
- Add Status API endpoints (get_status, list_statuses) - Add create sub-incident task type - Add OpenAI reasoning parameters (effort, summary) - Add alert field conditions support - Add schedule rotation member management - Add schedule Slack channel configuration - Add Makefile with version bump utilities - Add Dependabot configuration - Update Python dependencies (httpx, attrs, python-dateutil) - Simplify communications group models 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 9f50cbb commit 5bdf81b

94 files changed

Lines changed: 3308 additions & 1167 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.

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "pip"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
8+
- package-ecosystem: "github-actions"
9+
directory: "/"
10+
schedule:
11+
interval: "weekly"

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.1.0] - 2025-12-18
11+
12+
### Added
13+
- New Status API endpoints (`get_status`, `list_statuses`)
14+
- New task type: Create sub-incident (`CreateSubIncidentTaskParams`)
15+
- OpenAI chat completion reasoning parameters (`reasoning_effort`, `reasoning_summary`)
16+
- Alert trigger params now support alert field conditions
17+
- Schedule rotation member management with member type support
18+
- Schedule Slack channel configuration
19+
20+
### Changed
21+
- Regenerated client from latest OpenAPI specification
22+
- Simplified communications group models structure
23+
24+
### Removed
25+
- Deprecated communications group member and condition attribute models
26+
27+
### Known Issues
28+
- Escalation path endpoints not generated due to OpenAPI schema issues with union types in `rules_item`
29+
1030
## [1.0.1] - 2025-10-16
1131

1232
### Changed

Makefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
.PHONY: bump-major bump-minor bump-patch regenerate test
2+
3+
# Get current version from pyproject.toml
4+
CURRENT_VERSION := $(shell grep -E '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
5+
MAJOR := $(shell echo $(CURRENT_VERSION) | cut -d. -f1)
6+
MINOR := $(shell echo $(CURRENT_VERSION) | cut -d. -f2)
7+
PATCH := $(shell echo $(CURRENT_VERSION) | cut -d. -f3)
8+
9+
# Calculate new versions
10+
NEW_MAJOR := $(shell echo $$(($(MAJOR) + 1))).0.0
11+
NEW_MINOR := $(MAJOR).$(shell echo $$(($(MINOR) + 1))).0
12+
NEW_PATCH := $(MAJOR).$(MINOR).$(shell echo $$(($(PATCH) + 1)))
13+
14+
# Today's date
15+
TODAY := $(shell date +%Y-%m-%d)
16+
17+
bump-major:
18+
@echo "Bumping version: $(CURRENT_VERSION) -> $(NEW_MAJOR)"
19+
@sed -i '' 's/version = "$(CURRENT_VERSION)"/version = "$(NEW_MAJOR)"/' pyproject.toml
20+
@sed -i '' 's/## \[Unreleased\]/## [Unreleased]\n\n## [$(NEW_MAJOR)] - $(TODAY)/' CHANGELOG.md
21+
@echo "Version bumped to $(NEW_MAJOR)"
22+
23+
bump-minor:
24+
@echo "Bumping version: $(CURRENT_VERSION) -> $(NEW_MINOR)"
25+
@sed -i '' 's/version = "$(CURRENT_VERSION)"/version = "$(NEW_MINOR)"/' pyproject.toml
26+
@sed -i '' 's/## \[Unreleased\]/## [Unreleased]\n\n## [$(NEW_MINOR)] - $(TODAY)/' CHANGELOG.md
27+
@echo "Version bumped to $(NEW_MINOR)"
28+
29+
bump-patch:
30+
@echo "Bumping version: $(CURRENT_VERSION) -> $(NEW_PATCH)"
31+
@sed -i '' 's/version = "$(CURRENT_VERSION)"/version = "$(NEW_PATCH)"/' pyproject.toml
32+
@sed -i '' 's/## \[Unreleased\]/## [Unreleased]\n\n## [$(NEW_PATCH)] - $(TODAY)/' CHANGELOG.md
33+
@echo "Version bumped to $(NEW_PATCH)"
34+
35+
regenerate:
36+
openapi-python-client generate \
37+
--url https://rootly-heroku.s3.amazonaws.com/swagger/v1/swagger.json \
38+
--no-fail-on-warning \
39+
--output-path . \
40+
--overwrite \
41+
--config tools/config.yaml
42+
43+
test:
44+
python -c "import rootly_sdk; print('SDK imports successfully')"

README.md

Lines changed: 52 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,37 @@
1-
# Rootly Python SDK
2-
3-
A Python client library for accessing the [Rootly API v1](https://rootly.com/). This SDK provides both synchronous and asynchronous interfaces for interacting with Rootly's incident management platform.
4-
5-
[![PyPI version](https://badge.fury.io/py/rootly.svg)](https://badge.fury.io/py/rootly)
6-
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
7-
8-
## Installation
9-
10-
```bash
11-
pip install rootly
12-
```
13-
14-
## Quick Start
15-
16-
### Basic Usage
1+
# rootly
2+
A client library for accessing Rootly API v1
173

4+
## Usage
185
First, create a client:
196

207
```python
218
from rootly_sdk import Client
229

23-
client = Client(base_url="https://api.rootly.com")
10+
client = Client(base_url="https://api.example.com")
2411
```
2512

26-
### Authentication
27-
28-
For endpoints that require authentication, use `AuthenticatedClient`:
13+
If the endpoints you're going to hit require authentication, use `AuthenticatedClient` instead:
2914

3015
```python
3116
from rootly_sdk import AuthenticatedClient
3217

33-
client = AuthenticatedClient(
34-
base_url="https://api.rootly.com",
35-
token="your-api-token"
36-
)
18+
client = AuthenticatedClient(base_url="https://api.example.com", token="SuperSecretToken")
3719
```
3820

39-
### Making API Calls
21+
Now call your endpoint and use your models:
4022

4123
```python
4224
from rootly_sdk.models import MyDataModel
4325
from rootly_sdk.api.my_tag import get_my_data_model
4426
from rootly_sdk.types import Response
4527

46-
# Simple synchronous call
4728
with client as client:
4829
my_data: MyDataModel = get_my_data_model.sync(client=client)
49-
50-
# Or get detailed response (includes status_code, headers, etc.)
30+
# or if you need more info (e.g. status_code)
5131
response: Response[MyDataModel] = get_my_data_model.sync_detailed(client=client)
5232
```
5333

54-
### Async Usage
34+
Or do the same thing with an async version:
5535

5636
```python
5737
from rootly_sdk.models import MyDataModel
@@ -63,184 +43,82 @@ async with client as client:
6343
response: Response[MyDataModel] = await get_my_data_model.asyncio_detailed(client=client)
6444
```
6545

66-
## Advanced Configuration
67-
68-
### SSL Certificate Verification
69-
70-
By default, the client verifies SSL certificates. For internal APIs with custom certificates:
46+
By default, when you're calling an HTTPS API it will attempt to verify that SSL is working correctly. Using certificate verification is highly recommended most of the time, but sometimes you may need to authenticate to a server (especially an internal server) using a custom certificate bundle.
7147

7248
```python
7349
client = AuthenticatedClient(
74-
base_url="https://internal-api.example.com",
75-
token="your-api-token",
50+
base_url="https://internal_api.example.com",
51+
token="SuperSecretToken",
7652
verify_ssl="/path/to/certificate_bundle.pem",
7753
)
7854
```
7955

80-
**Warning:** Disabling SSL verification is a security risk and should only be used in development:
56+
You can also disable certificate validation altogether, but beware that **this is a security risk**.
8157

8258
```python
8359
client = AuthenticatedClient(
84-
base_url="https://internal-api.example.com",
85-
token="your-api-token",
60+
base_url="https://internal_api.example.com",
61+
token="SuperSecretToken",
8662
verify_ssl=False
8763
)
8864
```
8965

90-
### Custom HTTP Client Configuration
66+
Things to know:
67+
1. Every path/method combo becomes a Python module with four functions:
68+
1. `sync`: Blocking request that returns parsed data (if successful) or `None`
69+
1. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful.
70+
1. `asyncio`: Like `sync` but async instead of blocking
71+
1. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking
72+
73+
1. All path/query params, and bodies become method arguments.
74+
1. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above)
75+
1. Any endpoint which did not have a tag will be in `rootly_sdk.api.default`
76+
77+
## Advanced customizations
9178

92-
You can customize the underlying `httpx.Client` with event hooks and other options:
79+
There are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case):
9380

9481
```python
9582
from rootly_sdk import Client
9683

9784
def log_request(request):
98-
print(f"Request: {request.method} {request.url}")
85+
print(f"Request event hook: {request.method} {request.url} - Waiting for response")
9986

10087
def log_response(response):
101-
print(f"Response: {response.request.method} {response.request.url} - Status {response.status_code}")
88+
request = response.request
89+
print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")
10290

10391
client = Client(
104-
base_url="https://api.rootly.com",
105-
httpx_args={
106-
"event_hooks": {
107-
"request": [log_request],
108-
"response": [log_response]
109-
}
110-
},
92+
base_url="https://api.example.com",
93+
httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
11194
)
112-
```
113-
114-
Access the underlying httpx client directly:
115-
116-
```python
117-
# Synchronous client
118-
httpx_client = client.get_httpx_client()
11995

120-
# Asynchronous client
121-
async_httpx_client = client.get_async_httpx_client()
96+
# Or get the underlying httpx client to modify directly with client.get_httpx_client() or client.get_async_httpx_client()
12297
```
12398

124-
Set a custom httpx client (note: this overrides base_url and other settings):
99+
You can even set the httpx client directly, but beware that this will override any existing settings (e.g., base_url):
125100

126101
```python
127102
import httpx
128103
from rootly_sdk import Client
129104

130-
client = Client(base_url="https://api.rootly.com")
131-
client.set_httpx_client(
132-
httpx.Client(
133-
base_url="https://api.rootly.com",
134-
proxies="http://localhost:8030"
135-
)
105+
client = Client(
106+
base_url="https://api.example.com",
136107
)
108+
# Note that base_url needs to be re-set, as would any shared cookies, headers, etc.
109+
client.set_httpx_client(httpx.Client(base_url="https://api.example.com", proxies="http://localhost:8030"))
137110
```
138111

139-
## API Structure
140-
141-
The SDK is structured as follows:
142-
143-
1. **Four function variants per endpoint:**
144-
- `sync`: Blocking request returning parsed data or `None`
145-
- `sync_detailed`: Blocking request returning full `Response` object
146-
- `asyncio`: Async version of `sync`
147-
- `asyncio_detailed`: Async version of `sync_detailed`
148-
149-
2. **Module organization:**
150-
- Path/query parameters and request bodies become function arguments
151-
- Endpoints are grouped by their first OpenAPI tag (e.g., `rootly_sdk.api.incidents`)
152-
- Untagged endpoints are in `rootly_sdk.api.default`
153-
154-
## Development
155-
156-
### Requirements
157-
158-
- Python 3.9 or higher
159-
- [uv](https://github.com/astral-sh/uv) (recommended) or pip
160-
161-
### Installation for Development
162-
163-
```bash
164-
# Clone the repository
165-
git clone https://github.com/rootlyhq/rootly-python.git
166-
cd rootly-python
167-
168-
# Install in editable mode
169-
pip install -e .
170-
```
171-
172-
### Regenerating the Client
173-
174-
To regenerate the client from the latest OpenAPI specification:
175-
176-
```bash
177-
openapi-python-client generate \
178-
--url https://rootly-heroku.s3.amazonaws.com/swagger/v1/swagger.json \
179-
--no-fail-on-warning \
180-
--output-path . \
181-
--overwrite \
182-
--config tools/config.yaml
183-
```
184-
185-
### Building the Package
186-
187-
```bash
188-
# Install build tools
189-
pip install uv
190-
uv pip install build
191-
192-
# Build distribution files
193-
python -m build
194-
```
195-
196-
### Running Tests
197-
198-
```bash
199-
# Verify SDK imports successfully
200-
python -c "import rootly_sdk; print('SDK imports successfully')"
201-
```
202-
203-
## Publishing
204-
205-
### Automated Publishing via GitHub Actions (Recommended)
206-
207-
1. Update the version in `pyproject.toml`
208-
2. Update `CHANGELOG.md` with release notes
209-
3. Create and push a git tag:
210-
```bash
211-
git tag v1.0.0
212-
git push origin v1.0.0
213-
```
214-
4. GitHub Actions will automatically build and publish to PyPI
215-
216-
See [.github/PUBLISHING.md](.github/PUBLISHING.md) for detailed publishing instructions.
217-
218-
### Manual Publishing
219-
220-
If you need to publish manually:
221-
222-
```bash
223-
# Install dependencies
224-
pip install uv
225-
uv pip install build twine
226-
227-
# Build the package
228-
python -m build
229-
230-
# Publish to PyPI
231-
twine upload dist/*
232-
```
233-
234-
## Dependencies
235-
236-
- [httpx](https://www.python-httpx.org/) >= 0.20.0, < 0.29.0 - HTTP client
237-
- [attrs](https://www.attrs.org/) >= 22.2.0 - Data classes
238-
- [python-dateutil](https://dateutil.readthedocs.io/) >= 2.8.0 - Date parsing
239-
240-
## License
241-
242-
Apache 2.0
243-
244-
## Support
245-
246-
For issues, questions, or contributions, please visit the [GitHub repository](https://github.com/rootlyhq/rootly-python).
112+
## Building / publishing this package
113+
This project uses [Poetry](https://python-poetry.org/) to manage dependencies and packaging. Here are the basics:
114+
1. Update the metadata in pyproject.toml (e.g. authors, version)
115+
1. If you're using a private repository, configure it with Poetry
116+
1. `poetry config repositories.<your-repository-name> <url-to-your-repository>`
117+
1. `poetry config http-basic.<your-repository-name> <username> <password>`
118+
1. Publish the client with `poetry publish --build -r <your-repository-name>` or, if for public PyPI, just `poetry publish --build`
119+
120+
If you want to install this client into another project without publishing it (e.g. for development) then:
121+
1. If that project **is using Poetry**, you can simply do `poetry add <path-to-this-client>` from that project
122+
1. If that project is not using Poetry:
123+
1. Build a wheel with `poetry build -f wheel`
124+
1. Install that wheel from the other project `pip install <path-to-wheel>`

0 commit comments

Comments
 (0)