hooksniff-python 0.4.2__tar.gz → 0.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/PKG-INFO +4 -4
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/README.md +3 -3
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/hooksniff/__init__.py +1 -1
- hooksniff_python-0.4.3/hooksniff/resources/__init__.py +58 -0
- hooksniff_python-0.4.3/hooksniff/resources/advanced.py +66 -0
- hooksniff_python-0.4.3/hooksniff/resources/alert.py +30 -0
- hooksniff_python-0.4.3/hooksniff/resources/analytics.py +18 -0
- hooksniff_python-0.4.3/hooksniff/resources/api_key.py +21 -0
- hooksniff_python-0.4.3/hooksniff/resources/application.py +27 -0
- hooksniff_python-0.4.3/hooksniff/resources/billing.py +24 -0
- hooksniff_python-0.4.3/hooksniff/resources/broadcast.py +27 -0
- hooksniff_python-0.4.3/hooksniff/resources/connector.py +32 -0
- hooksniff_python-0.4.3/hooksniff/resources/cortex.py +43 -0
- hooksniff_python-0.4.3/hooksniff/resources/endpoint.py +31 -0
- hooksniff_python-0.4.3/hooksniff/resources/health.py +15 -0
- hooksniff_python-0.4.3/hooksniff/resources/notification.py +22 -0
- hooksniff_python-0.4.3/hooksniff/resources/platform.py +28 -0
- hooksniff_python-0.4.3/hooksniff/resources/routing.py +20 -0
- hooksniff_python-0.4.3/hooksniff/resources/schema.py +25 -0
- hooksniff_python-0.4.3/hooksniff/resources/search.py +12 -0
- hooksniff_python-0.4.3/hooksniff/resources/stream.py +41 -0
- hooksniff_python-0.4.3/hooksniff/resources/team.py +33 -0
- hooksniff_python-0.4.3/hooksniff/resources/template.py +28 -0
- hooksniff_python-0.4.3/hooksniff/resources/transform.py +24 -0
- hooksniff_python-0.4.3/hooksniff/resources/webhook.py +34 -0
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/hooksniff/webhook.py +1 -1
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/pyproject.toml +1 -1
- hooksniff_python-0.4.2/hooksniff/resources.py +0 -450
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/.gitignore +0 -0
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/LICENSE +0 -0
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/hooksniff/client.py +0 -0
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/hooksniff/exceptions.py +0 -0
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/hooksniff/http_client.py +0 -0
- {hooksniff_python-0.4.2 → hooksniff_python-0.4.3}/test_live.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hooksniff-python
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: Official HookSniff SDK for Python - Webhook infrastructure for developers
|
|
5
5
|
Project-URL: Homepage, https://hooksniff.vercel.app
|
|
6
6
|
Project-URL: Repository, https://github.com/servetarslan02/hooksniff-python
|
|
@@ -34,7 +34,7 @@ pip install hooksniff-python
|
|
|
34
34
|
## Quick Start
|
|
35
35
|
|
|
36
36
|
```python
|
|
37
|
-
from
|
|
37
|
+
from hooksniff import HookSniff
|
|
38
38
|
|
|
39
39
|
hs = HookSniff("hr_live_...")
|
|
40
40
|
|
|
@@ -156,7 +156,7 @@ delivery = hs.webhook.replay("msg_123")
|
|
|
156
156
|
### Webhook Verification
|
|
157
157
|
|
|
158
158
|
```python
|
|
159
|
-
from
|
|
159
|
+
from hooksniff import Webhook, WebhookVerificationError
|
|
160
160
|
|
|
161
161
|
wh = Webhook("whsec_...")
|
|
162
162
|
|
|
@@ -173,7 +173,7 @@ def handle_webhook(request):
|
|
|
173
173
|
### Error Handling
|
|
174
174
|
|
|
175
175
|
```python
|
|
176
|
-
from
|
|
176
|
+
from hooksniff import AuthenticationError, NotFoundError, RateLimitError
|
|
177
177
|
|
|
178
178
|
try:
|
|
179
179
|
hs.endpoint.get("invalid_id")
|
|
@@ -11,7 +11,7 @@ pip install hooksniff-python
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```python
|
|
14
|
-
from
|
|
14
|
+
from hooksniff import HookSniff
|
|
15
15
|
|
|
16
16
|
hs = HookSniff("hr_live_...")
|
|
17
17
|
|
|
@@ -133,7 +133,7 @@ delivery = hs.webhook.replay("msg_123")
|
|
|
133
133
|
### Webhook Verification
|
|
134
134
|
|
|
135
135
|
```python
|
|
136
|
-
from
|
|
136
|
+
from hooksniff import Webhook, WebhookVerificationError
|
|
137
137
|
|
|
138
138
|
wh = Webhook("whsec_...")
|
|
139
139
|
|
|
@@ -150,7 +150,7 @@ def handle_webhook(request):
|
|
|
150
150
|
### Error Handling
|
|
151
151
|
|
|
152
152
|
```python
|
|
153
|
-
from
|
|
153
|
+
from hooksniff import AuthenticationError, NotFoundError, RateLimitError
|
|
154
154
|
|
|
155
155
|
try:
|
|
156
156
|
hs.endpoint.get("invalid_id")
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""HookSniff SDK resources."""
|
|
2
|
+
|
|
3
|
+
from .application import ApplicationResource
|
|
4
|
+
from .endpoint import EndpointResource
|
|
5
|
+
from .webhook import WebhookResource
|
|
6
|
+
from .api_key import ApiKeyResource
|
|
7
|
+
from .analytics import AnalyticsResource
|
|
8
|
+
from .search import SearchResource
|
|
9
|
+
from .health import HealthResource
|
|
10
|
+
from .billing import BillingResource
|
|
11
|
+
from .notification import NotificationResource
|
|
12
|
+
from .cortex import CortexResource
|
|
13
|
+
from .team import TeamResource
|
|
14
|
+
from .alert import AlertResource
|
|
15
|
+
from .template import TemplateResource
|
|
16
|
+
from .schema import SchemaResource
|
|
17
|
+
from .connector import ConnectorResource
|
|
18
|
+
from .stream import StreamResource
|
|
19
|
+
from .advanced import (
|
|
20
|
+
BackgroundTaskResource,
|
|
21
|
+
IntegrationResource,
|
|
22
|
+
ServiceTokenResource,
|
|
23
|
+
OperationalWebhookResource,
|
|
24
|
+
)
|
|
25
|
+
from .routing import RateLimitResource, AuditResource
|
|
26
|
+
from .platform import SsoResource, CustomDomainResource, EnvironmentResource
|
|
27
|
+
from .broadcast import BroadcastResource
|
|
28
|
+
from .transform import TransformResource
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"ApplicationResource",
|
|
32
|
+
"EndpointResource",
|
|
33
|
+
"WebhookResource",
|
|
34
|
+
"ApiKeyResource",
|
|
35
|
+
"AnalyticsResource",
|
|
36
|
+
"SearchResource",
|
|
37
|
+
"HealthResource",
|
|
38
|
+
"BillingResource",
|
|
39
|
+
"NotificationResource",
|
|
40
|
+
"CortexResource",
|
|
41
|
+
"TeamResource",
|
|
42
|
+
"AlertResource",
|
|
43
|
+
"TemplateResource",
|
|
44
|
+
"SchemaResource",
|
|
45
|
+
"ConnectorResource",
|
|
46
|
+
"StreamResource",
|
|
47
|
+
"BackgroundTaskResource",
|
|
48
|
+
"IntegrationResource",
|
|
49
|
+
"ServiceTokenResource",
|
|
50
|
+
"OperationalWebhookResource",
|
|
51
|
+
"RateLimitResource",
|
|
52
|
+
"AuditResource",
|
|
53
|
+
"SsoResource",
|
|
54
|
+
"CustomDomainResource",
|
|
55
|
+
"EnvironmentResource",
|
|
56
|
+
"BroadcastResource",
|
|
57
|
+
"TransformResource",
|
|
58
|
+
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Advanced resources: Background tasks, Integrations, Service tokens, Operational webhooks."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BackgroundTaskResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", "/v1/background-tasks")
|
|
13
|
+
|
|
14
|
+
def get(self, task_id: str) -> Dict[str, Any]:
|
|
15
|
+
return self.http.request("GET", f"/v1/background-tasks/{task_id}")
|
|
16
|
+
|
|
17
|
+
def cancel(self, task_id: str) -> None:
|
|
18
|
+
self.http.request("POST", f"/v1/background-tasks/{task_id}/cancel")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class IntegrationResource:
|
|
22
|
+
def __init__(self, http: HttpClient):
|
|
23
|
+
self.http = http
|
|
24
|
+
|
|
25
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
26
|
+
return self.http.request("GET", "/v1/integrations")
|
|
27
|
+
|
|
28
|
+
def get(self, integration_id: str) -> Dict[str, Any]:
|
|
29
|
+
return self.http.request("GET", f"/v1/integrations/{integration_id}")
|
|
30
|
+
|
|
31
|
+
def delete(self, integration_id: str) -> None:
|
|
32
|
+
self.http.request("DELETE", f"/v1/integrations/{integration_id}")
|
|
33
|
+
|
|
34
|
+
def rotate_key(self, integration_id: str) -> Dict[str, Any]:
|
|
35
|
+
return self.http.request("POST", f"/v1/integrations/{integration_id}/rotate-key")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ServiceTokenResource:
|
|
39
|
+
def __init__(self, http: HttpClient):
|
|
40
|
+
self.http = http
|
|
41
|
+
|
|
42
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
43
|
+
return self.http.request("GET", "/v1/service-tokens")
|
|
44
|
+
|
|
45
|
+
def create(self, name: str) -> Dict[str, Any]:
|
|
46
|
+
return self.http.request("POST", "/v1/service-tokens", {"name": name})
|
|
47
|
+
|
|
48
|
+
def delete(self, token_id: str) -> None:
|
|
49
|
+
self.http.request("DELETE", f"/v1/service-tokens/{token_id}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class OperationalWebhookResource:
|
|
53
|
+
def __init__(self, http: HttpClient):
|
|
54
|
+
self.http = http
|
|
55
|
+
|
|
56
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
57
|
+
return self.http.request("GET", "/v1/operational-webhooks")
|
|
58
|
+
|
|
59
|
+
def create(self, url: str, events: List[str]) -> Dict[str, Any]:
|
|
60
|
+
return self.http.request("POST", "/v1/operational-webhooks", {"url": url, "events": events})
|
|
61
|
+
|
|
62
|
+
def get(self, webhook_id: str) -> Dict[str, Any]:
|
|
63
|
+
return self.http.request("GET", f"/v1/operational-webhooks/{webhook_id}")
|
|
64
|
+
|
|
65
|
+
def delete(self, webhook_id: str) -> None:
|
|
66
|
+
self.http.request("DELETE", f"/v1/operational-webhooks/{webhook_id}")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Alert resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AlertResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
response = self.http.request("GET", "/v1/alerts")
|
|
13
|
+
return response if isinstance(response, list) else response.get("alerts", [])
|
|
14
|
+
|
|
15
|
+
def create(self, name: str, condition: str, threshold: int, channels: List[str]) -> Dict[str, Any]:
|
|
16
|
+
return self.http.request("POST", "/v1/alerts", {
|
|
17
|
+
"name": name, "condition": condition, "threshold": threshold, "channels": channels
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
def get(self, alert_id: str) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("GET", f"/v1/alerts/{alert_id}")
|
|
22
|
+
|
|
23
|
+
def update(self, alert_id: str, **kwargs) -> Dict[str, Any]:
|
|
24
|
+
return self.http.request("PUT", f"/v1/alerts/{alert_id}", kwargs)
|
|
25
|
+
|
|
26
|
+
def delete(self, alert_id: str) -> None:
|
|
27
|
+
self.http.request("DELETE", f"/v1/alerts/{alert_id}")
|
|
28
|
+
|
|
29
|
+
def list_events(self, alert_id: str) -> List[Dict[str, Any]]:
|
|
30
|
+
return self.http.request("GET", f"/v1/alerts/{alert_id}/events")
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Analytics resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AnalyticsResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def deliveries(self, range: str = "24h") -> Any:
|
|
12
|
+
return self.http.request("GET", f"/v1/analytics/deliveries?range={range}")
|
|
13
|
+
|
|
14
|
+
def success_rate(self, range: str = "24h") -> Any:
|
|
15
|
+
return self.http.request("GET", f"/v1/analytics/success-rate?range={range}")
|
|
16
|
+
|
|
17
|
+
def latency(self, range: str = "24h") -> Any:
|
|
18
|
+
return self.http.request("GET", f"/v1/analytics/latency?range={range}")
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""API Key resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ApiKeyResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", "/v1/api-keys")
|
|
13
|
+
|
|
14
|
+
def create(self, name: str) -> Dict[str, Any]:
|
|
15
|
+
return self.http.request("POST", "/v1/api-keys", {"name": name})
|
|
16
|
+
|
|
17
|
+
def delete(self, api_key_id: str) -> None:
|
|
18
|
+
self.http.request("DELETE", f"/v1/api-keys/{api_key_id}")
|
|
19
|
+
|
|
20
|
+
def rotate(self, api_key_id: str) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("POST", f"/v1/api-keys/{api_key_id}/rotate")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Application resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
from ..http_client import HttpClient, PaginatedList
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ApplicationResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def create(self, name: str, description: str = None) -> Dict[str, Any]:
|
|
12
|
+
body: Dict[str, Any] = {"name": name}
|
|
13
|
+
if description:
|
|
14
|
+
body["description"] = description
|
|
15
|
+
return self.http.request("POST", "/v1/applications", body)
|
|
16
|
+
|
|
17
|
+
def list(self, per_page: int = 50) -> PaginatedList:
|
|
18
|
+
return PaginatedList(self.http, "/v1/applications", per_page=per_page)
|
|
19
|
+
|
|
20
|
+
def get(self, application_id: str) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("GET", f"/v1/applications/{application_id}")
|
|
22
|
+
|
|
23
|
+
def update(self, application_id: str, **kwargs) -> Dict[str, Any]:
|
|
24
|
+
return self.http.request("PUT", f"/v1/applications/{application_id}", kwargs)
|
|
25
|
+
|
|
26
|
+
def delete(self, application_id: str) -> None:
|
|
27
|
+
self.http.request("DELETE", f"/v1/applications/{application_id}")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Billing resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BillingResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def subscription(self) -> Dict[str, Any]:
|
|
12
|
+
return self.http.request("GET", "/v1/billing/subscription")
|
|
13
|
+
|
|
14
|
+
def upgrade(self, plan: str) -> Dict[str, Any]:
|
|
15
|
+
return self.http.request("POST", "/v1/billing/upgrade", {"plan": plan})
|
|
16
|
+
|
|
17
|
+
def portal(self) -> Dict[str, Any]:
|
|
18
|
+
return self.http.request("POST", "/v1/billing/portal")
|
|
19
|
+
|
|
20
|
+
def usage(self) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("GET", "/v1/billing/usage")
|
|
22
|
+
|
|
23
|
+
def invoices(self) -> Dict[str, Any]:
|
|
24
|
+
return self.http.request("GET", "/v1/billing/invoices")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Broadcast resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BroadcastResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", "/v1/broadcasts")
|
|
13
|
+
|
|
14
|
+
def create(self, title: str, message: str, scheduled_at: str = None) -> Dict[str, Any]:
|
|
15
|
+
body: Dict[str, Any] = {"title": title, "message": message}
|
|
16
|
+
if scheduled_at:
|
|
17
|
+
body["scheduled_at"] = scheduled_at
|
|
18
|
+
return self.http.request("POST", "/v1/broadcasts", body)
|
|
19
|
+
|
|
20
|
+
def get(self, broadcast_id: str) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("GET", f"/v1/broadcasts/{broadcast_id}")
|
|
22
|
+
|
|
23
|
+
def delete(self, broadcast_id: str) -> None:
|
|
24
|
+
self.http.request("DELETE", f"/v1/broadcasts/{broadcast_id}")
|
|
25
|
+
|
|
26
|
+
def send(self, broadcast_id: str) -> None:
|
|
27
|
+
self.http.request("POST", f"/v1/broadcasts/{broadcast_id}/send")
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Connector resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ConnectorResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", "/v1/connectors")
|
|
13
|
+
|
|
14
|
+
def get(self, connector_id: str) -> Dict[str, Any]:
|
|
15
|
+
return self.http.request("GET", f"/v1/connectors/{connector_id}")
|
|
16
|
+
|
|
17
|
+
def list_configs(self) -> List[Dict[str, Any]]:
|
|
18
|
+
return self.http.request("GET", "/v1/connectors/configs")
|
|
19
|
+
|
|
20
|
+
def create_config(self, connector_id: str, name: str, config: Dict[str, Any]) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("POST", "/v1/connectors/configs", {
|
|
22
|
+
"connector_id": connector_id, "name": name, "config": config
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
def get_config(self, config_id: str) -> Dict[str, Any]:
|
|
26
|
+
return self.http.request("GET", f"/v1/connectors/configs/{config_id}")
|
|
27
|
+
|
|
28
|
+
def update_config(self, config_id: str, **kwargs) -> Dict[str, Any]:
|
|
29
|
+
return self.http.request("PUT", f"/v1/connectors/configs/{config_id}", kwargs)
|
|
30
|
+
|
|
31
|
+
def delete_config(self, config_id: str) -> None:
|
|
32
|
+
self.http.request("DELETE", f"/v1/connectors/configs/{config_id}")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Cortex AI resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CortexResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def insights(self) -> List[Dict[str, Any]]:
|
|
12
|
+
response = self.http.request("GET", "/v1/cortex/insights")
|
|
13
|
+
if isinstance(response, dict) and "insights" in response:
|
|
14
|
+
raw = response["insights"]
|
|
15
|
+
result = []
|
|
16
|
+
for row in raw:
|
|
17
|
+
if isinstance(row, list) and len(row) >= 10:
|
|
18
|
+
result.append({
|
|
19
|
+
"id": row[0],
|
|
20
|
+
"customer_id": row[1],
|
|
21
|
+
"type": row[2],
|
|
22
|
+
"title": row[3],
|
|
23
|
+
"description": row[4],
|
|
24
|
+
"severity": row[5],
|
|
25
|
+
"metadata": row[7] if len(row) > 7 else {},
|
|
26
|
+
"created_at": row[9] if len(row) > 9 else None,
|
|
27
|
+
})
|
|
28
|
+
else:
|
|
29
|
+
result.append(row)
|
|
30
|
+
return result
|
|
31
|
+
return response if isinstance(response, list) else []
|
|
32
|
+
|
|
33
|
+
def anomalies(self, endpoint_id: str = None) -> List[Dict[str, Any]]:
|
|
34
|
+
path = "/v1/cortex/anomalies"
|
|
35
|
+
if endpoint_id:
|
|
36
|
+
path += f"?endpoint_id={endpoint_id}"
|
|
37
|
+
return self.http.request("GET", path)
|
|
38
|
+
|
|
39
|
+
def predict(self, endpoint_id: str) -> Dict[str, Any]:
|
|
40
|
+
return self.http.request("GET", f"/v1/cortex/predict/{endpoint_id}")
|
|
41
|
+
|
|
42
|
+
def auto_heal(self, endpoint_id: str) -> Dict[str, Any]:
|
|
43
|
+
return self.http.request("POST", f"/v1/cortex/auto-heal/{endpoint_id}")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Endpoint resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
from ..http_client import HttpClient, PaginatedList
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class EndpointResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def create(self, url: str, application_id: str, description: str = None, **kwargs) -> Dict[str, Any]:
|
|
12
|
+
body: Dict[str, Any] = {"url": url, "application_id": application_id}
|
|
13
|
+
if description:
|
|
14
|
+
body["description"] = description
|
|
15
|
+
body.update(kwargs)
|
|
16
|
+
return self.http.request("POST", "/v1/endpoints", body)
|
|
17
|
+
|
|
18
|
+
def list(self, per_page: int = 50) -> PaginatedList:
|
|
19
|
+
return PaginatedList(self.http, "/v1/endpoints", per_page=per_page)
|
|
20
|
+
|
|
21
|
+
def get(self, endpoint_id: str) -> Dict[str, Any]:
|
|
22
|
+
return self.http.request("GET", f"/v1/endpoints/{endpoint_id}")
|
|
23
|
+
|
|
24
|
+
def update(self, endpoint_id: str, **kwargs) -> Dict[str, Any]:
|
|
25
|
+
return self.http.request("PUT", f"/v1/endpoints/{endpoint_id}", kwargs)
|
|
26
|
+
|
|
27
|
+
def delete(self, endpoint_id: str) -> None:
|
|
28
|
+
self.http.request("DELETE", f"/v1/endpoints/{endpoint_id}")
|
|
29
|
+
|
|
30
|
+
def rotate_secret(self, endpoint_id: str) -> Dict[str, Any]:
|
|
31
|
+
return self.http.request("POST", f"/v1/endpoints/{endpoint_id}/rotate-secret")
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Health resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class HealthResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def check(self) -> Dict[str, Any]:
|
|
12
|
+
return self.http.request("GET", "/health")
|
|
13
|
+
|
|
14
|
+
def outbound_ips(self) -> Dict[str, Any]:
|
|
15
|
+
return self.http.request("GET", "/v1/outbound-ips")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Notification resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class NotificationResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self, per_page: int = 20) -> Dict[str, Any]:
|
|
12
|
+
return self.http.request("GET", f"/v1/notifications?per_page={per_page}")
|
|
13
|
+
|
|
14
|
+
def get_unread_count(self) -> Dict[str, Any]:
|
|
15
|
+
response = self.http.request("GET", "/v1/notifications/unread-count")
|
|
16
|
+
return {"count": response.get("unread_count", 0)}
|
|
17
|
+
|
|
18
|
+
def mark_read(self, notification_id: str) -> None:
|
|
19
|
+
self.http.request("POST", f"/v1/notifications/{notification_id}/read")
|
|
20
|
+
|
|
21
|
+
def mark_all_read(self) -> None:
|
|
22
|
+
self.http.request("POST", "/v1/notifications/read-all")
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Platform resources: SSO, Custom domains, Environments."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SsoResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def get_config(self) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", "/v1/sso/config")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CustomDomainResource:
|
|
16
|
+
def __init__(self, http: HttpClient):
|
|
17
|
+
self.http = http
|
|
18
|
+
|
|
19
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
20
|
+
return self.http.request("GET", "/v1/custom-domains")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class EnvironmentResource:
|
|
24
|
+
def __init__(self, http: HttpClient):
|
|
25
|
+
self.http = http
|
|
26
|
+
|
|
27
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
28
|
+
return self.http.request("GET", "/v1/environments")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Routing resources: Rate limits, Audit log."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RateLimitResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", "/v1/rate-limits")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AuditResource:
|
|
16
|
+
def __init__(self, http: HttpClient):
|
|
17
|
+
self.http = http
|
|
18
|
+
|
|
19
|
+
def list(self) -> Dict[str, Any]:
|
|
20
|
+
return self.http.request("GET", "/v1/audit-log")
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Schema resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SchemaResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
response = self.http.request("GET", "/v1/schemas")
|
|
13
|
+
return response if isinstance(response, list) else response.get("schemas", [])
|
|
14
|
+
|
|
15
|
+
def create(self, name: str, schema: Dict[str, Any]) -> Dict[str, Any]:
|
|
16
|
+
return self.http.request("POST", "/v1/schemas", {"name": name, "schema": schema})
|
|
17
|
+
|
|
18
|
+
def get(self, schema_id: str) -> Dict[str, Any]:
|
|
19
|
+
return self.http.request("GET", f"/v1/schemas/{schema_id}")
|
|
20
|
+
|
|
21
|
+
def delete(self, schema_id: str) -> None:
|
|
22
|
+
self.http.request("DELETE", f"/v1/schemas/{schema_id}")
|
|
23
|
+
|
|
24
|
+
def validate(self, schema_id: str, data: Any) -> Dict[str, Any]:
|
|
25
|
+
return self.http.request("POST", f"/v1/schemas/{schema_id}/validate", {"data": data})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Search resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SearchResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def deliveries(self, query: str, page: int = 1, per_page: int = 20) -> Dict[str, Any]:
|
|
12
|
+
return self.http.request("GET", f"/v1/search?q={query}&page={page}&per_page={per_page}")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Stream resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StreamResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list_channels(self) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", "/v1/stream/channels")
|
|
13
|
+
|
|
14
|
+
def create_channel(self, name: str, description: str = None) -> Dict[str, Any]:
|
|
15
|
+
body: Dict[str, Any] = {"name": name}
|
|
16
|
+
if description:
|
|
17
|
+
body["description"] = description
|
|
18
|
+
return self.http.request("POST", "/v1/stream/channels", body)
|
|
19
|
+
|
|
20
|
+
def get_channel(self, channel_id: str) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("GET", f"/v1/stream/channels/{channel_id}")
|
|
22
|
+
|
|
23
|
+
def delete_channel(self, channel_id: str) -> None:
|
|
24
|
+
self.http.request("DELETE", f"/v1/stream/channels/{channel_id}")
|
|
25
|
+
|
|
26
|
+
def list_messages(self, channel_id: str) -> List[Dict[str, Any]]:
|
|
27
|
+
return self.http.request("GET", f"/v1/stream/channels/{channel_id}/messages")
|
|
28
|
+
|
|
29
|
+
def publish(self, channel_id: str, event: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
|
30
|
+
return self.http.request("POST", "/v1/stream/publish", {
|
|
31
|
+
"channel_id": channel_id, "event": event, "data": data
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
def list_subscriptions(self) -> List[Dict[str, Any]]:
|
|
35
|
+
return self.http.request("GET", "/v1/stream/subscriptions")
|
|
36
|
+
|
|
37
|
+
def get_subscription(self, subscription_id: str) -> Dict[str, Any]:
|
|
38
|
+
return self.http.request("GET", f"/v1/stream/subscriptions/{subscription_id}")
|
|
39
|
+
|
|
40
|
+
def disconnect_subscription(self, subscription_id: str) -> None:
|
|
41
|
+
self.http.request("DELETE", f"/v1/stream/subscriptions/{subscription_id}")
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Team resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TeamResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", "/v1/teams")
|
|
13
|
+
|
|
14
|
+
def create(self, name: str, description: str = None) -> Dict[str, Any]:
|
|
15
|
+
body: Dict[str, Any] = {"name": name}
|
|
16
|
+
if description:
|
|
17
|
+
body["description"] = description
|
|
18
|
+
return self.http.request("POST", "/v1/teams", body)
|
|
19
|
+
|
|
20
|
+
def get(self, team_id: str) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("GET", f"/v1/teams/{team_id}")
|
|
22
|
+
|
|
23
|
+
def delete(self, team_id: str) -> None:
|
|
24
|
+
self.http.request("DELETE", f"/v1/teams/{team_id}")
|
|
25
|
+
|
|
26
|
+
def list_members(self, team_id: str) -> List[Dict[str, Any]]:
|
|
27
|
+
return self.http.request("GET", f"/v1/teams/{team_id}/members")
|
|
28
|
+
|
|
29
|
+
def invite_member(self, team_id: str, email: str, role: str = "viewer") -> Dict[str, Any]:
|
|
30
|
+
return self.http.request("POST", f"/v1/teams/{team_id}/members", {"email": email, "role": role})
|
|
31
|
+
|
|
32
|
+
def remove_member(self, team_id: str, member_id: str) -> None:
|
|
33
|
+
self.http.request("DELETE", f"/v1/teams/{team_id}/members/{member_id}")
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Template resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TemplateResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self) -> List[Dict[str, Any]]:
|
|
12
|
+
response = self.http.request("GET", "/v1/templates")
|
|
13
|
+
return response if isinstance(response, list) else response.get("templates", [])
|
|
14
|
+
|
|
15
|
+
def create(self, name: str, content: str, description: str = None) -> Dict[str, Any]:
|
|
16
|
+
body: Dict[str, Any] = {"name": name, "content": content}
|
|
17
|
+
if description:
|
|
18
|
+
body["description"] = description
|
|
19
|
+
return self.http.request("POST", "/v1/templates", body)
|
|
20
|
+
|
|
21
|
+
def get(self, template_id: str) -> Dict[str, Any]:
|
|
22
|
+
return self.http.request("GET", f"/v1/templates/{template_id}")
|
|
23
|
+
|
|
24
|
+
def update(self, template_id: str, **kwargs) -> Dict[str, Any]:
|
|
25
|
+
return self.http.request("PUT", f"/v1/templates/{template_id}", kwargs)
|
|
26
|
+
|
|
27
|
+
def delete(self, template_id: str) -> None:
|
|
28
|
+
self.http.request("DELETE", f"/v1/templates/{template_id}")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Transform resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TransformResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def list(self, endpoint_id: str) -> List[Dict[str, Any]]:
|
|
12
|
+
return self.http.request("GET", f"/v1/endpoints/{endpoint_id}/transforms")
|
|
13
|
+
|
|
14
|
+
def create(self, endpoint_id: str, name: str, code: str) -> Dict[str, Any]:
|
|
15
|
+
return self.http.request("POST", f"/v1/endpoints/{endpoint_id}/transforms", {"name": name, "code": code})
|
|
16
|
+
|
|
17
|
+
def get(self, endpoint_id: str, transform_id: str) -> Dict[str, Any]:
|
|
18
|
+
return self.http.request("GET", f"/v1/endpoints/{endpoint_id}/transforms/{transform_id}")
|
|
19
|
+
|
|
20
|
+
def update(self, endpoint_id: str, transform_id: str, **kwargs) -> Dict[str, Any]:
|
|
21
|
+
return self.http.request("PUT", f"/v1/endpoints/{endpoint_id}/transforms/{transform_id}", kwargs)
|
|
22
|
+
|
|
23
|
+
def delete(self, endpoint_id: str, transform_id: str) -> None:
|
|
24
|
+
self.http.request("DELETE", f"/v1/endpoints/{endpoint_id}/transforms/{transform_id}")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Webhook resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List
|
|
4
|
+
from ..http_client import HttpClient, PaginatedList
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class WebhookResource:
|
|
8
|
+
def __init__(self, http: HttpClient):
|
|
9
|
+
self.http = http
|
|
10
|
+
|
|
11
|
+
def send(self, endpoint_id: str, event: str, data: Dict[str, Any], idempotency_key: str = None) -> Dict[str, Any]:
|
|
12
|
+
body = {"endpoint_id": endpoint_id, "event": event, "data": data}
|
|
13
|
+
options = {"idempotency_key": idempotency_key} if idempotency_key else None
|
|
14
|
+
return self.http.request("POST", "/v1/webhooks", body, options)
|
|
15
|
+
|
|
16
|
+
def send_batch(self, webhooks: List[Dict[str, Any]]) -> Dict[str, Any]:
|
|
17
|
+
return self.http.request("POST", "/v1/webhooks/batch", {"webhooks": webhooks})
|
|
18
|
+
|
|
19
|
+
def list(self, per_page: int = 50, endpoint_id: str = None, status: str = None) -> PaginatedList:
|
|
20
|
+
params: Dict[str, str] = {}
|
|
21
|
+
if endpoint_id:
|
|
22
|
+
params["endpoint_id"] = endpoint_id
|
|
23
|
+
if status:
|
|
24
|
+
params["status"] = status
|
|
25
|
+
return PaginatedList(self.http, "/v1/webhooks", params=params, per_page=per_page)
|
|
26
|
+
|
|
27
|
+
def get(self, webhook_id: str) -> Dict[str, Any]:
|
|
28
|
+
return self.http.request("GET", f"/v1/webhooks/{webhook_id}")
|
|
29
|
+
|
|
30
|
+
def replay(self, webhook_id: str) -> Dict[str, Any]:
|
|
31
|
+
return self.http.request("POST", f"/v1/webhooks/{webhook_id}/replay")
|
|
32
|
+
|
|
33
|
+
def batch_replay(self, webhook_ids: List[str]) -> Dict[str, Any]:
|
|
34
|
+
return self.http.request("POST", "/v1/webhooks/batch-replay", {"webhook_ids": webhook_ids})
|
|
@@ -1,450 +0,0 @@
|
|
|
1
|
-
from typing import Any, Dict, List, Optional
|
|
2
|
-
from .http_client import HttpClient, PaginatedList
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ApplicationResource:
|
|
6
|
-
def __init__(self, http: HttpClient):
|
|
7
|
-
self.http = http
|
|
8
|
-
|
|
9
|
-
def create(self, name: str, description: str = None) -> Dict[str, Any]:
|
|
10
|
-
body = {"name": name}
|
|
11
|
-
if description:
|
|
12
|
-
body["description"] = description
|
|
13
|
-
return self.http.request("POST", "/v1/applications", body)
|
|
14
|
-
|
|
15
|
-
def list(self, per_page: int = 50) -> PaginatedList:
|
|
16
|
-
return PaginatedList(self.http, "/v1/applications", per_page=per_page)
|
|
17
|
-
|
|
18
|
-
def get(self, application_id: str) -> Dict[str, Any]:
|
|
19
|
-
return self.http.request("GET", f"/v1/applications/{application_id}")
|
|
20
|
-
|
|
21
|
-
def update(self, application_id: str, **kwargs) -> Dict[str, Any]:
|
|
22
|
-
return self.http.request("PUT", f"/v1/applications/{application_id}", kwargs)
|
|
23
|
-
|
|
24
|
-
def delete(self, application_id: str) -> None:
|
|
25
|
-
self.http.request("DELETE", f"/v1/applications/{application_id}")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class EndpointResource:
|
|
29
|
-
def __init__(self, http: HttpClient):
|
|
30
|
-
self.http = http
|
|
31
|
-
|
|
32
|
-
def create(self, url: str, application_id: str, description: str = None, **kwargs) -> Dict[str, Any]:
|
|
33
|
-
body = {"url": url, "application_id": application_id}
|
|
34
|
-
if description:
|
|
35
|
-
body["description"] = description
|
|
36
|
-
body.update(kwargs)
|
|
37
|
-
return self.http.request("POST", "/v1/endpoints", body)
|
|
38
|
-
|
|
39
|
-
def list(self, per_page: int = 50) -> PaginatedList:
|
|
40
|
-
return PaginatedList(self.http, "/v1/endpoints", per_page=per_page)
|
|
41
|
-
|
|
42
|
-
def get(self, endpoint_id: str) -> Dict[str, Any]:
|
|
43
|
-
return self.http.request("GET", f"/v1/endpoints/{endpoint_id}")
|
|
44
|
-
|
|
45
|
-
def update(self, endpoint_id: str, **kwargs) -> Dict[str, Any]:
|
|
46
|
-
return self.http.request("PUT", f"/v1/endpoints/{endpoint_id}", kwargs)
|
|
47
|
-
|
|
48
|
-
def delete(self, endpoint_id: str) -> None:
|
|
49
|
-
self.http.request("DELETE", f"/v1/endpoints/{endpoint_id}")
|
|
50
|
-
|
|
51
|
-
def rotate_secret(self, endpoint_id: str) -> Dict[str, Any]:
|
|
52
|
-
return self.http.request("POST", f"/v1/endpoints/{endpoint_id}/rotate-secret")
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class WebhookResource:
|
|
56
|
-
def __init__(self, http: HttpClient):
|
|
57
|
-
self.http = http
|
|
58
|
-
|
|
59
|
-
def send(self, endpoint_id: str, event: str, data: Dict[str, Any], idempotency_key: str = None) -> Dict[str, Any]:
|
|
60
|
-
body = {"endpoint_id": endpoint_id, "event": event, "data": data}
|
|
61
|
-
options = {"idempotency_key": idempotency_key} if idempotency_key else None
|
|
62
|
-
return self.http.request("POST", "/v1/webhooks", body, options)
|
|
63
|
-
|
|
64
|
-
def send_batch(self, webhooks: List[Dict[str, Any]]) -> Dict[str, Any]:
|
|
65
|
-
return self.http.request("POST", "/v1/webhooks/batch", {"webhooks": webhooks})
|
|
66
|
-
|
|
67
|
-
def list(self, per_page: int = 50, endpoint_id: str = None, status: str = None) -> PaginatedList:
|
|
68
|
-
params = {}
|
|
69
|
-
if endpoint_id:
|
|
70
|
-
params["endpoint_id"] = endpoint_id
|
|
71
|
-
if status:
|
|
72
|
-
params["status"] = status
|
|
73
|
-
return PaginatedList(self.http, "/v1/webhooks", params=params, per_page=per_page)
|
|
74
|
-
|
|
75
|
-
def get(self, webhook_id: str) -> Dict[str, Any]:
|
|
76
|
-
return self.http.request("GET", f"/v1/webhooks/{webhook_id}")
|
|
77
|
-
|
|
78
|
-
def replay(self, webhook_id: str) -> Dict[str, Any]:
|
|
79
|
-
return self.http.request("POST", f"/v1/webhooks/{webhook_id}/replay")
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class ApiKeyResource:
|
|
83
|
-
def __init__(self, http: HttpClient):
|
|
84
|
-
self.http = http
|
|
85
|
-
|
|
86
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
87
|
-
return self.http.request("GET", "/v1/api-keys")
|
|
88
|
-
|
|
89
|
-
def create(self, name: str) -> Dict[str, Any]:
|
|
90
|
-
return self.http.request("POST", "/v1/api-keys", {"name": name})
|
|
91
|
-
|
|
92
|
-
def delete(self, api_key_id: str) -> None:
|
|
93
|
-
self.http.request("DELETE", f"/v1/api-keys/{api_key_id}")
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
class AnalyticsResource:
|
|
97
|
-
def __init__(self, http: HttpClient):
|
|
98
|
-
self.http = http
|
|
99
|
-
|
|
100
|
-
def deliveries(self, range: str = "24h") -> Any:
|
|
101
|
-
return self.http.request("GET", f"/v1/analytics/deliveries?range={range}")
|
|
102
|
-
|
|
103
|
-
def success_rate(self, range: str = "24h") -> Any:
|
|
104
|
-
return self.http.request("GET", f"/v1/analytics/success-rate?range={range}")
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
class SearchResource:
|
|
108
|
-
def __init__(self, http: HttpClient):
|
|
109
|
-
self.http = http
|
|
110
|
-
|
|
111
|
-
def deliveries(self, query: str, page: int = 1, per_page: int = 20) -> Dict[str, Any]:
|
|
112
|
-
return self.http.request("GET", f"/v1/search?q={query}&page={page}&per_page={per_page}")
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class HealthResource:
|
|
116
|
-
def __init__(self, http: HttpClient):
|
|
117
|
-
self.http = http
|
|
118
|
-
|
|
119
|
-
def check(self) -> Dict[str, Any]:
|
|
120
|
-
return self.http.request("GET", "/health")
|
|
121
|
-
|
|
122
|
-
def outbound_ips(self) -> Dict[str, Any]:
|
|
123
|
-
return self.http.request("GET", "/v1/outbound-ips")
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
class BillingResource:
|
|
127
|
-
def __init__(self, http: HttpClient):
|
|
128
|
-
self.http = http
|
|
129
|
-
|
|
130
|
-
def subscription(self) -> Dict[str, Any]:
|
|
131
|
-
return self.http.request("GET", "/v1/billing/subscription")
|
|
132
|
-
|
|
133
|
-
def upgrade(self, plan: str) -> Dict[str, Any]:
|
|
134
|
-
return self.http.request("POST", "/v1/billing/upgrade", {"plan": plan})
|
|
135
|
-
|
|
136
|
-
def portal(self) -> Dict[str, Any]:
|
|
137
|
-
return self.http.request("POST", "/v1/billing/portal")
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
class NotificationResource:
|
|
141
|
-
def __init__(self, http: HttpClient):
|
|
142
|
-
self.http = http
|
|
143
|
-
|
|
144
|
-
def list(self, per_page: int = 20) -> Dict[str, Any]:
|
|
145
|
-
return self.http.request("GET", f"/v1/notifications?per_page={per_page}")
|
|
146
|
-
|
|
147
|
-
def get_unread_count(self) -> Dict[str, Any]:
|
|
148
|
-
response = self.http.request("GET", "/v1/notifications/unread-count")
|
|
149
|
-
return {"count": response.get("unread_count", 0)}
|
|
150
|
-
|
|
151
|
-
def mark_read(self, notification_id: str) -> None:
|
|
152
|
-
self.http.request("POST", f"/v1/notifications/{notification_id}/read")
|
|
153
|
-
|
|
154
|
-
def mark_all_read(self) -> None:
|
|
155
|
-
self.http.request("POST", "/v1/notifications/read-all")
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
class CortexResource:
|
|
159
|
-
def __init__(self, http: HttpClient):
|
|
160
|
-
self.http = http
|
|
161
|
-
|
|
162
|
-
def insights(self) -> List[Dict[str, Any]]:
|
|
163
|
-
response = self.http.request("GET", "/v1/cortex/insights")
|
|
164
|
-
if isinstance(response, dict) and "insights" in response:
|
|
165
|
-
raw = response["insights"]
|
|
166
|
-
result = []
|
|
167
|
-
for row in raw:
|
|
168
|
-
if isinstance(row, list) and len(row) >= 10:
|
|
169
|
-
result.append({
|
|
170
|
-
"id": row[0],
|
|
171
|
-
"customer_id": row[1],
|
|
172
|
-
"type": row[2],
|
|
173
|
-
"title": row[3],
|
|
174
|
-
"description": row[4],
|
|
175
|
-
"severity": row[5],
|
|
176
|
-
"metadata": row[7] if len(row) > 7 else {},
|
|
177
|
-
"created_at": row[9] if len(row) > 9 else None,
|
|
178
|
-
})
|
|
179
|
-
else:
|
|
180
|
-
result.append(row)
|
|
181
|
-
return result
|
|
182
|
-
return response if isinstance(response, list) else []
|
|
183
|
-
|
|
184
|
-
def anomalies(self, endpoint_id: str = None) -> List[Dict[str, Any]]:
|
|
185
|
-
path = "/v1/cortex/anomalies"
|
|
186
|
-
if endpoint_id:
|
|
187
|
-
path += f"?endpoint_id={endpoint_id}"
|
|
188
|
-
return self.http.request("GET", path)
|
|
189
|
-
|
|
190
|
-
def predict(self, endpoint_id: str) -> Dict[str, Any]:
|
|
191
|
-
return self.http.request("GET", f"/v1/cortex/predict/{endpoint_id}")
|
|
192
|
-
|
|
193
|
-
def auto_heal(self, endpoint_id: str) -> Dict[str, Any]:
|
|
194
|
-
return self.http.request("POST", f"/v1/cortex/auto-heal/{endpoint_id}")
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
class TeamResource:
|
|
198
|
-
def __init__(self, http: HttpClient):
|
|
199
|
-
self.http = http
|
|
200
|
-
|
|
201
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
202
|
-
return self.http.request("GET", "/v1/teams")
|
|
203
|
-
|
|
204
|
-
def create(self, name: str, description: str = None) -> Dict[str, Any]:
|
|
205
|
-
body = {"name": name}
|
|
206
|
-
if description:
|
|
207
|
-
body["description"] = description
|
|
208
|
-
return self.http.request("POST", "/v1/teams", body)
|
|
209
|
-
|
|
210
|
-
def get(self, team_id: str) -> Dict[str, Any]:
|
|
211
|
-
return self.http.request("GET", f"/v1/teams/{team_id}")
|
|
212
|
-
|
|
213
|
-
def delete(self, team_id: str) -> None:
|
|
214
|
-
self.http.request("DELETE", f"/v1/teams/{team_id}")
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
class AlertResource:
|
|
218
|
-
def __init__(self, http: HttpClient):
|
|
219
|
-
self.http = http
|
|
220
|
-
|
|
221
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
222
|
-
response = self.http.request("GET", "/v1/alerts")
|
|
223
|
-
return response if isinstance(response, list) else response.get("alerts", [])
|
|
224
|
-
|
|
225
|
-
def create(self, name: str, condition: str, threshold: int, channels: List[str]) -> Dict[str, Any]:
|
|
226
|
-
return self.http.request("POST", "/v1/alerts", {
|
|
227
|
-
"name": name, "condition": condition, "threshold": threshold, "channels": channels
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
def get(self, alert_id: str) -> Dict[str, Any]:
|
|
231
|
-
return self.http.request("GET", f"/v1/alerts/{alert_id}")
|
|
232
|
-
|
|
233
|
-
def delete(self, alert_id: str) -> None:
|
|
234
|
-
self.http.request("DELETE", f"/v1/alerts/{alert_id}")
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
class TemplateResource:
|
|
238
|
-
def __init__(self, http: HttpClient):
|
|
239
|
-
self.http = http
|
|
240
|
-
|
|
241
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
242
|
-
response = self.http.request("GET", "/v1/templates")
|
|
243
|
-
return response if isinstance(response, list) else response.get("templates", [])
|
|
244
|
-
|
|
245
|
-
def get(self, template_id: str) -> Dict[str, Any]:
|
|
246
|
-
return self.http.request("GET", f"/v1/templates/{template_id}")
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
class SchemaResource:
|
|
250
|
-
def __init__(self, http: HttpClient):
|
|
251
|
-
self.http = http
|
|
252
|
-
|
|
253
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
254
|
-
response = self.http.request("GET", "/v1/schemas")
|
|
255
|
-
return response if isinstance(response, list) else response.get("schemas", [])
|
|
256
|
-
|
|
257
|
-
def create(self, name: str, schema: Dict[str, Any]) -> Dict[str, Any]:
|
|
258
|
-
return self.http.request("POST", "/v1/schemas", {"name": name, "schema": schema})
|
|
259
|
-
|
|
260
|
-
def get(self, schema_id: str) -> Dict[str, Any]:
|
|
261
|
-
return self.http.request("GET", f"/v1/schemas/{schema_id}")
|
|
262
|
-
|
|
263
|
-
def delete(self, schema_id: str) -> None:
|
|
264
|
-
self.http.request("DELETE", f"/v1/schemas/{schema_id}")
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
class ConnectorResource:
|
|
268
|
-
def __init__(self, http: HttpClient):
|
|
269
|
-
self.http = http
|
|
270
|
-
|
|
271
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
272
|
-
return self.http.request("GET", "/v1/connectors")
|
|
273
|
-
|
|
274
|
-
def get(self, connector_id: str) -> Dict[str, Any]:
|
|
275
|
-
return self.http.request("GET", f"/v1/connectors/{connector_id}")
|
|
276
|
-
|
|
277
|
-
def list_configs(self) -> List[Dict[str, Any]]:
|
|
278
|
-
return self.http.request("GET", "/v1/connectors/configs")
|
|
279
|
-
|
|
280
|
-
def create_config(self, connector_id: str, name: str, config: Dict[str, Any]) -> Dict[str, Any]:
|
|
281
|
-
return self.http.request("POST", "/v1/connectors/configs", {
|
|
282
|
-
"connector_id": connector_id, "name": name, "config": config
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
class StreamResource:
|
|
287
|
-
def __init__(self, http: HttpClient):
|
|
288
|
-
self.http = http
|
|
289
|
-
|
|
290
|
-
def list_channels(self) -> List[Dict[str, Any]]:
|
|
291
|
-
return self.http.request("GET", "/v1/stream/channels")
|
|
292
|
-
|
|
293
|
-
def create_channel(self, name: str, description: str = None) -> Dict[str, Any]:
|
|
294
|
-
body = {"name": name}
|
|
295
|
-
if description:
|
|
296
|
-
body["description"] = description
|
|
297
|
-
return self.http.request("POST", "/v1/stream/channels", body)
|
|
298
|
-
|
|
299
|
-
def get_channel(self, channel_id: str) -> Dict[str, Any]:
|
|
300
|
-
return self.http.request("GET", f"/v1/stream/channels/{channel_id}")
|
|
301
|
-
|
|
302
|
-
def delete_channel(self, channel_id: str) -> None:
|
|
303
|
-
self.http.request("DELETE", f"/v1/stream/channels/{channel_id}")
|
|
304
|
-
|
|
305
|
-
def publish(self, channel_id: str, event: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
|
306
|
-
return self.http.request("POST", "/v1/stream/publish", {
|
|
307
|
-
"channel_id": channel_id, "event": event, "data": data
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
def list_subscriptions(self) -> List[Dict[str, Any]]:
|
|
311
|
-
return self.http.request("GET", "/v1/stream/subscriptions")
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
class BackgroundTaskResource:
|
|
315
|
-
def __init__(self, http: HttpClient):
|
|
316
|
-
self.http = http
|
|
317
|
-
|
|
318
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
319
|
-
return self.http.request("GET", "/v1/background-tasks")
|
|
320
|
-
|
|
321
|
-
def get(self, task_id: str) -> Dict[str, Any]:
|
|
322
|
-
return self.http.request("GET", f"/v1/background-tasks/{task_id}")
|
|
323
|
-
|
|
324
|
-
def cancel(self, task_id: str) -> None:
|
|
325
|
-
self.http.request("POST", f"/v1/background-tasks/{task_id}/cancel")
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
class IntegrationResource:
|
|
329
|
-
def __init__(self, http: HttpClient):
|
|
330
|
-
self.http = http
|
|
331
|
-
|
|
332
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
333
|
-
return self.http.request("GET", "/v1/integrations")
|
|
334
|
-
|
|
335
|
-
def get(self, integration_id: str) -> Dict[str, Any]:
|
|
336
|
-
return self.http.request("GET", f"/v1/integrations/{integration_id}")
|
|
337
|
-
|
|
338
|
-
def delete(self, integration_id: str) -> None:
|
|
339
|
-
self.http.request("DELETE", f"/v1/integrations/{integration_id}")
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
class ServiceTokenResource:
|
|
343
|
-
def __init__(self, http: HttpClient):
|
|
344
|
-
self.http = http
|
|
345
|
-
|
|
346
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
347
|
-
return self.http.request("GET", "/v1/service-tokens")
|
|
348
|
-
|
|
349
|
-
def create(self, name: str) -> Dict[str, Any]:
|
|
350
|
-
return self.http.request("POST", "/v1/service-tokens", {"name": name})
|
|
351
|
-
|
|
352
|
-
def delete(self, token_id: str) -> None:
|
|
353
|
-
self.http.request("DELETE", f"/v1/service-tokens/{token_id}")
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
class OperationalWebhookResource:
|
|
357
|
-
def __init__(self, http: HttpClient):
|
|
358
|
-
self.http = http
|
|
359
|
-
|
|
360
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
361
|
-
return self.http.request("GET", "/v1/operational-webhooks")
|
|
362
|
-
|
|
363
|
-
def create(self, url: str, events: List[str]) -> Dict[str, Any]:
|
|
364
|
-
return self.http.request("POST", "/v1/operational-webhooks", {"url": url, "events": events})
|
|
365
|
-
|
|
366
|
-
def get(self, webhook_id: str) -> Dict[str, Any]:
|
|
367
|
-
return self.http.request("GET", f"/v1/operational-webhooks/{webhook_id}")
|
|
368
|
-
|
|
369
|
-
def delete(self, webhook_id: str) -> None:
|
|
370
|
-
self.http.request("DELETE", f"/v1/operational-webhooks/{webhook_id}")
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
class RateLimitResource:
|
|
374
|
-
def __init__(self, http: HttpClient):
|
|
375
|
-
self.http = http
|
|
376
|
-
|
|
377
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
378
|
-
return self.http.request("GET", "/v1/rate-limits")
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
class AuditResource:
|
|
382
|
-
def __init__(self, http: HttpClient):
|
|
383
|
-
self.http = http
|
|
384
|
-
|
|
385
|
-
def list(self) -> Dict[str, Any]:
|
|
386
|
-
return self.http.request("GET", "/v1/audit-log")
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
class SsoResource:
|
|
390
|
-
def __init__(self, http: HttpClient):
|
|
391
|
-
self.http = http
|
|
392
|
-
|
|
393
|
-
def get_config(self) -> List[Dict[str, Any]]:
|
|
394
|
-
return self.http.request("GET", "/v1/sso/config")
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
class CustomDomainResource:
|
|
398
|
-
def __init__(self, http: HttpClient):
|
|
399
|
-
self.http = http
|
|
400
|
-
|
|
401
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
402
|
-
return self.http.request("GET", "/v1/custom-domains")
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
class EnvironmentResource:
|
|
406
|
-
def __init__(self, http: HttpClient):
|
|
407
|
-
self.http = http
|
|
408
|
-
|
|
409
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
410
|
-
return self.http.request("GET", "/v1/environments")
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
class BroadcastResource:
|
|
414
|
-
def __init__(self, http: HttpClient):
|
|
415
|
-
self.http = http
|
|
416
|
-
|
|
417
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
418
|
-
return self.http.request("GET", "/v1/broadcasts")
|
|
419
|
-
|
|
420
|
-
def create(self, title: str, message: str, scheduled_at: str = None) -> Dict[str, Any]:
|
|
421
|
-
body = {"title": title, "message": message}
|
|
422
|
-
if scheduled_at:
|
|
423
|
-
body["scheduled_at"] = scheduled_at
|
|
424
|
-
return self.http.request("POST", "/v1/broadcasts", body)
|
|
425
|
-
|
|
426
|
-
def get(self, broadcast_id: str) -> Dict[str, Any]:
|
|
427
|
-
return self.http.request("GET", f"/v1/broadcasts/{broadcast_id}")
|
|
428
|
-
|
|
429
|
-
def delete(self, broadcast_id: str) -> None:
|
|
430
|
-
self.http.request("DELETE", f"/v1/broadcasts/{broadcast_id}")
|
|
431
|
-
|
|
432
|
-
def send(self, broadcast_id: str) -> None:
|
|
433
|
-
self.http.request("POST", f"/v1/broadcasts/{broadcast_id}/send")
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
class TransformResource:
|
|
437
|
-
def __init__(self, http: HttpClient):
|
|
438
|
-
self.http = http
|
|
439
|
-
|
|
440
|
-
def list(self, endpoint_id: str) -> List[Dict[str, Any]]:
|
|
441
|
-
return self.http.request("GET", f"/v1/endpoints/{endpoint_id}/transforms")
|
|
442
|
-
|
|
443
|
-
def create(self, endpoint_id: str, name: str, code: str) -> Dict[str, Any]:
|
|
444
|
-
return self.http.request("POST", f"/v1/endpoints/{endpoint_id}/transforms", {"name": name, "code": code})
|
|
445
|
-
|
|
446
|
-
def get(self, endpoint_id: str, transform_id: str) -> Dict[str, Any]:
|
|
447
|
-
return self.http.request("GET", f"/v1/endpoints/{endpoint_id}/transforms/{transform_id}")
|
|
448
|
-
|
|
449
|
-
def delete(self, endpoint_id: str, transform_id: str) -> None:
|
|
450
|
-
self.http.request("DELETE", f"/v1/endpoints/{endpoint_id}/transforms/{transform_id}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|