Skip to content
Open
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
148 changes: 148 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ MailerSend Python SDK
- [Get a single invite](#get-a-single-invite)
- [Resend an invite](#resend-an-invite)
- [Cancel an invite](#cancel-an-invite)
- [DMARC Monitoring](#dmarc-monitoring)
- [Get a list of monitors](#get-a-list-of-monitors)
- [Create a monitor](#create-a-monitor)
- [Update a monitor](#update-a-monitor)
- [Delete a monitor](#delete-a-monitor)
- [Get aggregated reports](#get-aggregated-reports)
- [Get IP-specific reports](#get-ip-specific-reports)
- [Get report sources](#get-report-sources)
- [Mark IP as favorite](#mark-ip-as-favorite)
- [Remove IP from favorites](#remove-ip-from-favorites)
- [Other Endpoints](#other-endpoints)
- [Get API Quota](#get-api-quota)
- [Error Handling](#error-handling)
Expand Down Expand Up @@ -2681,6 +2691,143 @@ request = (UsersBuilder()
response = ms.users.cancel_invite(request)
```

## DMARC Monitoring

### Get a list of monitors

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.page(1)
.limit(25)
.build_list_request())

response = ms.dmarc_monitoring.list_monitors(request)
```

### Create a monitor

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.domain_id("your-domain-id")
.build_create_request())

response = ms.dmarc_monitoring.create_monitor(request)
```

### Update a monitor

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.wanted_dmarc_record("v=DMARC1; p=reject; rua=mailto:dmarc@example.com")
.build_update_request())

response = ms.dmarc_monitoring.update_monitor(request)
```

### Delete a monitor

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.build_delete_request())

response = ms.dmarc_monitoring.delete_monitor(request)
```

### Get aggregated reports

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.page(1)
.limit(25)
.build_report_request())

response = ms.dmarc_monitoring.get_aggregated_report(request)
```

### Get IP-specific reports

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.ip("192.168.1.1")
.page(1)
.limit(25)
.build_ip_report_request())

response = ms.dmarc_monitoring.get_ip_report(request)
```

### Get report sources

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.build_report_sources_request())

response = ms.dmarc_monitoring.get_report_sources(request)
```

### Mark IP as favorite

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.ip("192.168.1.1")
.build_mark_favorite_request())

response = ms.dmarc_monitoring.mark_ip_favorite(request)
```

### Remove IP from favorites

```python
from mailersend import MailerSendClient, DmarcMonitoringBuilder

ms = MailerSendClient()

request = (DmarcMonitoringBuilder()
.monitor_id("monitor-id")
.ip("192.168.1.1")
.build_remove_favorite_request())

response = ms.dmarc_monitoring.remove_ip_favorite(request)
```

## Other Endpoints

### Get API Quota
Expand Down Expand Up @@ -2799,6 +2946,7 @@ def test_list_sms_recipients():
| SMS Inbound Routing | `{GET, POST, PUT, DELETE} sms-inbounds` | ✅ |
| Sender Identities | `{GET, POST, PUT, DELETE} identities` | ✅ |
| API Quota | `GET api-quota` | ✅ |
| DMARC Monitoring | `{GET, POST, PUT, DELETE} dmarc-monitoring` | ✅ |

*All endpoints are available and fully tested. Refer to [official API docs](https://developers.mailersend.com/) for the most up-to-date API specifications.*

Expand Down
4 changes: 3 additions & 1 deletion mailersend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from .builders.sms_recipients import SmsRecipientsBuilder
from .builders.sms_webhooks import SmsWebhooksBuilder
from .builders.sms_inbounds import SmsInboundsBuilder
from .builders.dmarc_monitoring import DmarcMonitoringBuilder
from .resources.email import Email
from .resources.activity import Activity
from .resources.analytics import Analytics
Expand Down Expand Up @@ -91,7 +92,8 @@
"SmsRecipientsBuilder",
"SmsWebhooksBuilder",
"SmsInboundsBuilder",

"DmarcMonitoringBuilder",

# Resources
"Email",
"Activity",
Expand Down
2 changes: 2 additions & 0 deletions mailersend/builders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .sms_recipients import SmsRecipientsBuilder
from .sms_webhooks import SmsWebhooksBuilder
from .sms_inbounds import SmsInboundsBuilder
from .dmarc_monitoring import DmarcMonitoringBuilder

__all__ = [
"EmailBuilder",
Expand All @@ -50,4 +51,5 @@
"SmsRecipientsBuilder",
"SmsWebhooksBuilder",
"SmsInboundsBuilder",
"DmarcMonitoringBuilder",
]
132 changes: 132 additions & 0 deletions mailersend/builders/dmarc_monitoring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""Builder for DMARC Monitoring requests."""

from typing import Optional

from ..exceptions import ValidationError
from ..models.dmarc_monitoring import (
DmarcMonitoringListRequest,
DmarcMonitoringListQueryParams,
DmarcMonitoringCreateRequest,
DmarcMonitoringUpdateRequest,
DmarcMonitoringDeleteRequest,
DmarcMonitoringReportRequest,
DmarcMonitoringReportQueryParams,
DmarcMonitoringIpReportRequest,
DmarcMonitoringReportSourcesRequest,
DmarcMonitoringFavoriteRequest,
)


class DmarcMonitoringBuilder:
"""Builder for creating DMARC Monitoring requests using a fluent interface."""

def __init__(self):
"""Initialize a new DmarcMonitoringBuilder."""
self._reset()

def _reset(self):
"""Reset all builder state."""
self._monitor_id: Optional[str] = None
self._ip: Optional[str] = None
self._domain_id: Optional[str] = None
self._wanted_dmarc_record: Optional[str] = None
self._page: Optional[int] = None
self._limit: Optional[int] = None

def monitor_id(self, monitor_id: str) -> "DmarcMonitoringBuilder":
"""Set the monitor ID."""
self._monitor_id = monitor_id
return self

def ip(self, ip: str) -> "DmarcMonitoringBuilder":
"""Set the IP address."""
self._ip = ip
return self

def domain_id(self, domain_id: str) -> "DmarcMonitoringBuilder":
"""Set the domain ID for creating a monitor."""
self._domain_id = domain_id
return self

def wanted_dmarc_record(self, record: str) -> "DmarcMonitoringBuilder":
"""Set the wanted DMARC record for updating a monitor."""
self._wanted_dmarc_record = record
return self

def page(self, page: int) -> "DmarcMonitoringBuilder":
"""Set the page number for pagination."""
if page < 1:
raise ValidationError("Page must be greater than 0")
self._page = page
return self

def limit(self, limit: int) -> "DmarcMonitoringBuilder":
"""Set the number of items per page."""
if limit < 10 or limit > 100:
raise ValidationError("Limit must be between 10 and 100")
self._limit = limit
return self

def build_list_request(self) -> DmarcMonitoringListRequest:
"""Build a DmarcMonitoringListRequest."""
query_params = DmarcMonitoringListQueryParams(
page=self._page if self._page is not None else 1,
limit=self._limit if self._limit is not None else 25,
)
return DmarcMonitoringListRequest(query_params=query_params)

def build_create_request(self) -> DmarcMonitoringCreateRequest:
"""Build a DmarcMonitoringCreateRequest."""
return DmarcMonitoringCreateRequest(domain_id=self._domain_id)

def build_update_request(self) -> DmarcMonitoringUpdateRequest:
"""Build a DmarcMonitoringUpdateRequest."""
return DmarcMonitoringUpdateRequest(
monitor_id=self._monitor_id,
wanted_dmarc_record=self._wanted_dmarc_record,
)

def build_delete_request(self) -> DmarcMonitoringDeleteRequest:
"""Build a DmarcMonitoringDeleteRequest."""
return DmarcMonitoringDeleteRequest(monitor_id=self._monitor_id)

def build_report_request(self) -> DmarcMonitoringReportRequest:
"""Build a DmarcMonitoringReportRequest for aggregated reports."""
query_params = DmarcMonitoringReportQueryParams(
page=self._page if self._page is not None else 1,
limit=self._limit if self._limit is not None else 25,
)
return DmarcMonitoringReportRequest(
monitor_id=self._monitor_id,
query_params=query_params,
)

def build_ip_report_request(self) -> DmarcMonitoringIpReportRequest:
"""Build a DmarcMonitoringIpReportRequest for IP-specific reports."""
query_params = DmarcMonitoringReportQueryParams(
page=self._page if self._page is not None else 1,
limit=self._limit if self._limit is not None else 25,
)
return DmarcMonitoringIpReportRequest(
monitor_id=self._monitor_id,
ip=self._ip,
query_params=query_params,
)

def build_report_sources_request(self) -> DmarcMonitoringReportSourcesRequest:
"""Build a DmarcMonitoringReportSourcesRequest."""
return DmarcMonitoringReportSourcesRequest(monitor_id=self._monitor_id)

def build_mark_favorite_request(self) -> DmarcMonitoringFavoriteRequest:
"""Build a DmarcMonitoringFavoriteRequest for marking an IP as favorite."""
return DmarcMonitoringFavoriteRequest(
monitor_id=self._monitor_id,
ip=self._ip,
)

def build_remove_favorite_request(self) -> DmarcMonitoringFavoriteRequest:
"""Build a DmarcMonitoringFavoriteRequest for removing an IP from favorites."""
return DmarcMonitoringFavoriteRequest(
monitor_id=self._monitor_id,
ip=self._ip,
)
2 changes: 2 additions & 0 deletions mailersend/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from .resources.sms_sending import SmsSending
from .resources.sms_webhooks import SmsWebhooks
from .resources.other import Other
from .resources.dmarc_monitoring import DmarcMonitoring
from .logging import get_logger, RequestLogger


Expand Down Expand Up @@ -142,6 +143,7 @@ def __init__(
self.sms_recipients = SmsRecipients(self)
self.sms_webhooks = SmsWebhooks(self)
self.api_quota = Other(self)
self.dmarc_monitoring = DmarcMonitoring(self)

self.logger.info("MailerSend client initialized successfully")
if debug:
Expand Down
19 changes: 19 additions & 0 deletions mailersend/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,16 @@
SmsInboundDeleteRequest,
SmsInbound,
)
from .dmarc_monitoring import (
DmarcMonitoringListRequest,
DmarcMonitoringCreateRequest,
DmarcMonitoringUpdateRequest,
DmarcMonitoringDeleteRequest,
DmarcMonitoringReportRequest,
DmarcMonitoringIpReportRequest,
DmarcMonitoringReportSourcesRequest,
DmarcMonitoringFavoriteRequest,
)

__all__ = [
"BaseModel",
Expand Down Expand Up @@ -289,4 +299,13 @@
"SmsInboundUpdateRequest",
"SmsInboundDeleteRequest",
"SmsInbound",
# DMARC Monitoring models
"DmarcMonitoringListRequest",
"DmarcMonitoringCreateRequest",
"DmarcMonitoringUpdateRequest",
"DmarcMonitoringDeleteRequest",
"DmarcMonitoringReportRequest",
"DmarcMonitoringIpReportRequest",
"DmarcMonitoringReportSourcesRequest",
"DmarcMonitoringFavoriteRequest",
]
Loading