Skip to content

Adding email channel api support to python SDK - #709

Open
mawasthy-lgtm wants to merge 12 commits into
linode:devfrom
mawasthy-lgtm:feat/add-create-alert-channel
Open

mawasthy-lgtm wants to merge 12 commits into
linode:devfrom
mawasthy-lgtm:feat/add-create-alert-channel

Conversation

@mawasthy-lgtm

@mawasthy-lgtm mawasthy-lgtm commented Jun 18, 2026 •

Copy link
Copy Markdown
Contributor

📝 Description

Updating python sdk to include email channel management api

What does this PR do and why is this change necessary?

Adds full SDK support for Creating a new channel (post request) used by tests and examples.
Ensures create channel fields are parsed and exposed as per the latest API response.

This change is necessary because:

The SDK did not have channel management api added.

✔️ How to Test
Clone the repository
Prepare environment (zsh / macOS)

✔️create & activate venv (recommended)
python3 -m venv .venv
source .venv/bin/activate

install deps
python -m pip install --upgrade pip

Install runtime dependencies:
pip3 install requests polling deprecated

Install dev/test extras
pip3 install -e '.[dev,test]'

test deps
pip3 install pytest mock httpretty pytest-rerunfailures

✔️How do I run the relevant unit tests?
cd <PROJECT_DIRECTORY>/linode_api4-python
Unit tests: python -m pytest test/unit -q

Unit test for all monitor: python3 -m pytest test/unit/objects/monitor_test.py -q -s
python3 -m pytest test/unit/groups/monitor_api_test.py -q -s -v

Single unit: python3 -m pytest test/unit/objects/monitor_test.py::MonitorTest -q -s
python3 -m pytest test/unit/groups/monitor_api_test.py::MonitorAlertDefinitionsTest::test_create_channel -q -s -v

What are the steps to reproduce the issue or verify the changes?
End to end integration testing should suffice

✔️How do I run the relevant integration tests?
Integration tests (E2E):
Note:
#if you have PAT token with write access only to Monitor and read for rest of the services for integration
export SKIP_E2E_FIREWALL=1 # optional: skip firewall autouse fixture
export LINODE_TOKEN="YOUR_REAL_TOKEN" # required for integration
export SKIP_E2E_FIREWALL=1 # optional: skip firewall autouse fixture

python3 -m pytest test/integration/models/monitor/test_monitor.py::test_integration_create_get_delete_alert_channel -q -s

Comment thread linode_api4/groups/monitor.py Outdated
Comment thread linode_api4/groups/monitor.py Outdated
Comment thread linode_api4/groups/monitor.py Outdated
Comment thread linode_api4/objects/monitor.py Outdated
Comment thread linode_api4/objects/monitor.py
Comment thread test/integration/models/monitor/test_monitor.py Outdated
Comment thread test/integration/models/monitor/test_monitor.py Outdated
Comment thread linode_api4/groups/monitor.py Outdated
Comment thread linode_api4/groups/monitor.py Outdated
Comment thread linode_api4/groups/monitor.py Outdated
Comment thread linode_api4/groups/monitor.py Outdated
@mawasthy-lgtm
mawasthy-lgtm requested a review from shkaruna July 22, 2026 10:58
@mawasthy-lgtm
mawasthy-lgtm marked this pull request as ready for review July 28, 2026 07:05
@mawasthy-lgtm
mawasthy-lgtm requested review from a team as code owners July 28, 2026 07:05
@mawasthy-lgtm
mawasthy-lgtm requested review from jriddle-linode and mawilk90 and removed request for a team and shkaruna July 28, 2026 07:05
@mawilk90
mawilk90 requested a review from zliang-akamai July 31, 2026 06:36
Comment thread linode_api4/objects/monitor.py Outdated
"label": Property(),
"type": Property(),
"label": Property(mutable=True),
"type": Property(AlertChannelType),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Property class doesn't support passing another class in as the first positional argument of its constructor.

Comment thread linode_api4/groups/monitor.py Outdated
Comment on lines +522 to +530
return PaginatedList(
self.client,
endpoint[1:],
page=result,
max_pages=response_json.get("pages", 1),
total_items=response_json.get("results", len(result)),
parent_id=None,
filters=parsed_filters,
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't seem to be the right way of creating a PaginatedList instance. Does make_paginated_list or make_list work for your case?

@mawasthy-lgtm mawasthy-lgtm changed the title Adding create channel api changes to python SDK Adding email channel api support to python SDK Sep 29, 2026
@zliang-akamai
zliang-akamai requested review from zliang-akamai and removed request for shkaruna October 27, 2026 17:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Alert references are incorrectly treated as fully populated definitions and retain a mutable discriminator that save() can send, while the channel CRUD test suppresses deletion failures.

2 open issues
What changed in this PR

Adds email alert-channel management to the Monitor SDK, extending existing read support with creation, updates, deletion, and retrieval of associated alerts.

Changes:

  • Adds channel creation and paginated alert lookup, preserving each alert’s service context.
  • Makes channel labels and details editable and introduces an alert-channel type enum.
  • Adds unit and integration coverage, channel fixtures, and % unit values in database-monitoring fixtures.
File Description
test/​unit/​objects/​monitor_test.py Tests channel lifecycle operations and updates the metric-unit assertion.
test/​unit/​groups/​monitor_api_test.py Tests channel operations, associated alerts, and service context across pages.
test/​integration/​models/​monitor/​test_monitor.py Adds live channel tests and creates channels for alert-definition tests.
test/​fixtures/​monitor_services_dbaas_metric-definitions.json Changes the CPU metric unit to %.
test/​fixtures/​monitor_services_dbaas_alert-definitions.json Updates the alert-list fixture’s CPU unit.
test/​fixtures/​monitor_services_dbaas_alert-definitions_12345.json Updates the individual alert fixture’s CPU unit.
test/​fixtures/​monitor_alert-channels_123.json Adds an individual email-channel response fixture.
test/​fixtures/​monitor_alert-channels_123_alerts.json Adds a paginated channel-alert reference fixture.
linode_api4/​objects/​monitor.py Adds channel type values and enables label and details updates.
linode_api4/​groups/​monitor.py Adds channel creation and service-aware associated-alert retrieval.

Review effort: Balanced

Comment on lines +40 to +45
return super().make_instance(
id,
client,
parent_id=parent_id,
json=json,
)
Comment on lines +425 to +432
# Clean up: delete the created channel
try:
created_channel.delete()
except Exception as e:
# Log but don't fail if cleanup fails
print(
f"Warning: Failed to delete channel {created_channel.id}: {e}"
)
Comment on lines +33 to +45
class _AlertChannelAlertDefinition(AlertDefinition):
"""Build channel alerts with each response item's service parent."""

@classmethod
def make_instance(cls, id, client, parent_id=None, json=None):
if parent_id is None and json:
parent_id = json.get(cls.parent_id_name)
return super().make_instance(
id,
client,
parent_id=parent_id,
json=json,
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a derived class of AlertDefinition rather than putting the method into AlertDefinition directly? Was there any blocker?

Comment on lines +507 to +510
return self.client._get_and_filter(
_AlertChannelAlertDefinition,
*filters,
endpoint=f"/monitor/alert-channels/{channel_id}/alerts",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_AlertChannelAlertDefinition is a derived class of AlertDefinition, which doesn't match the schema of the API.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants