wazzapi 0.4.0__tar.gz → 0.5.0__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.
Files changed (45) hide show
  1. {wazzapi-0.4.0 → wazzapi-0.5.0}/PKG-INFO +1 -1
  2. {wazzapi-0.4.0 → wazzapi-0.5.0}/pyproject.toml +1 -1
  3. {wazzapi-0.4.0 → wazzapi-0.5.0}/tests/smoke_test.py +1 -1
  4. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/__init__.py +1 -1
  5. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/client.py +13 -1
  6. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/__init__.py +9 -0
  7. wazzapi-0.5.0/wazzapi/models/campaigns.py +103 -0
  8. wazzapi-0.5.0/wazzapi/models/conversations.py +80 -0
  9. wazzapi-0.5.0/wazzapi/models/webhook_subscriptions.py +87 -0
  10. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/resources/__init__.py +6 -0
  11. wazzapi-0.5.0/wazzapi/resources/campaigns.py +87 -0
  12. wazzapi-0.5.0/wazzapi/resources/conversations.py +80 -0
  13. wazzapi-0.5.0/wazzapi/resources/devices.py +99 -0
  14. wazzapi-0.5.0/wazzapi/resources/webhook_subscriptions.py +80 -0
  15. wazzapi-0.4.0/wazzapi/resources/devices.py +0 -40
  16. {wazzapi-0.4.0 → wazzapi-0.5.0}/.gitignore +0 -0
  17. {wazzapi-0.4.0 → wazzapi-0.5.0}/README.md +0 -0
  18. {wazzapi-0.4.0 → wazzapi-0.5.0}/examples/create_template.py +0 -0
  19. {wazzapi-0.4.0 → wazzapi-0.5.0}/examples/list_contacts.py +0 -0
  20. {wazzapi-0.4.0 → wazzapi-0.5.0}/examples/list_devices.py +0 -0
  21. {wazzapi-0.4.0 → wazzapi-0.5.0}/examples/preview_template.py +0 -0
  22. {wazzapi-0.4.0 → wazzapi-0.5.0}/examples/send_message.py +0 -0
  23. {wazzapi-0.4.0 → wazzapi-0.5.0}/examples/verify_webhook.py +0 -0
  24. {wazzapi-0.4.0 → wazzapi-0.5.0}/tests/test_client.py +0 -0
  25. {wazzapi-0.4.0 → wazzapi-0.5.0}/tests/test_groups.py +0 -0
  26. {wazzapi-0.4.0 → wazzapi-0.5.0}/tests/test_media.py +0 -0
  27. {wazzapi-0.4.0 → wazzapi-0.5.0}/tests/test_resources.py +0 -0
  28. {wazzapi-0.4.0 → wazzapi-0.5.0}/tests/test_webhooks.py +0 -0
  29. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/errors.py +0 -0
  30. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/media.py +0 -0
  31. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/base.py +0 -0
  32. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/contacts.py +0 -0
  33. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/devices.py +0 -0
  34. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/groups.py +0 -0
  35. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/media.py +0 -0
  36. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/messages.py +0 -0
  37. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/templates.py +0 -0
  38. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/models/webhooks.py +0 -0
  39. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/py.typed +0 -0
  40. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/resources/base.py +0 -0
  41. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/resources/contacts.py +0 -0
  42. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/resources/groups.py +0 -0
  43. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/resources/messages.py +0 -0
  44. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/resources/templates.py +0 -0
  45. {wazzapi-0.4.0 → wazzapi-0.5.0}/wazzapi/webhooks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wazzapi
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Typed Python SDK for WazzAPI
5
5
  Project-URL: API, https://api.wazzapi.com
6
6
  Project-URL: Homepage, https://github.com/wazzapihq/wazzapi-py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "wazzapi"
3
- version = "0.4.0"
3
+ version = "0.5.0"
4
4
  description = "Typed Python SDK for WazzAPI"
5
5
  readme = { file = "README.md", content-type = "text/markdown" }
6
6
  requires-python = ">=3.10"
@@ -10,7 +10,7 @@ from wazzapi import (
10
10
 
11
11
 
12
12
  def main() -> None:
13
- assert __version__ == "0.4.0"
13
+ assert __version__ == "0.5.0"
14
14
 
15
15
  client = WazzapiClient(api_key="smoke-test-token")
16
16
  try:
@@ -16,7 +16,7 @@ from .webhooks import (
16
16
  verify_webhook_signature,
17
17
  )
18
18
 
19
- __version__ = "0.4.0"
19
+ __version__ = "0.5.0"
20
20
 
21
21
  __all__ = [
22
22
  "EVENT_HEADER",
@@ -7,7 +7,16 @@ import httpx
7
7
  from pydantic import BaseModel, TypeAdapter
8
8
 
9
9
  from .errors import WazzapiAPIError
10
- from .resources import ContactsResource, DevicesResource, GroupsResource, MessagesResource, TemplatesResource
10
+ from .resources import (
11
+ CampaignsResource,
12
+ ContactsResource,
13
+ ConversationsResource,
14
+ DevicesResource,
15
+ GroupsResource,
16
+ MessagesResource,
17
+ TemplatesResource,
18
+ WebhookSubscriptionsResource,
19
+ )
11
20
 
12
21
  DEFAULT_BASE_URL = "https://api.wazzapi.com"
13
22
 
@@ -38,11 +47,14 @@ class WazzapiClient:
38
47
  transport=transport,
39
48
  )
40
49
 
50
+ self.campaigns = CampaignsResource(self)
41
51
  self.contacts = ContactsResource(self)
52
+ self.conversations = ConversationsResource(self)
42
53
  self.devices = DevicesResource(self)
43
54
  self.groups = GroupsResource(self)
44
55
  self.messages = MessagesResource(self)
45
56
  self.templates = TemplatesResource(self)
57
+ self.webhook_subscriptions = WebhookSubscriptionsResource(self)
46
58
 
47
59
  @staticmethod
48
60
  def _build_headers(
@@ -1,6 +1,10 @@
1
1
  from .base import WazzapiModel
2
+ from .campaigns import *
3
+ from .campaigns import __all__ as campaigns_all
2
4
  from .contacts import *
3
5
  from .contacts import __all__ as contacts_all
6
+ from .conversations import *
7
+ from .conversations import __all__ as conversations_all
4
8
  from .devices import *
5
9
  from .devices import __all__ as devices_all
6
10
  from .groups import *
@@ -11,16 +15,21 @@ from .messages import *
11
15
  from .messages import __all__ as messages_all
12
16
  from .templates import *
13
17
  from .templates import __all__ as templates_all
18
+ from .webhook_subscriptions import *
19
+ from .webhook_subscriptions import __all__ as webhook_subscriptions_all
14
20
  from .webhooks import *
15
21
  from .webhooks import __all__ as webhooks_all
16
22
 
17
23
  __all__ = [
18
24
  "WazzapiModel",
25
+ *campaigns_all,
19
26
  *contacts_all,
27
+ *conversations_all,
20
28
  *devices_all,
21
29
  *groups_all,
22
30
  *media_all,
23
31
  *messages_all,
24
32
  *templates_all,
33
+ *webhook_subscriptions_all,
25
34
  *webhooks_all,
26
35
  ]
@@ -0,0 +1,103 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import datetime
4
+ from typing import Any
5
+
6
+ from .base import WazzapiModel
7
+
8
+
9
+ class CampaignCreateRequest(WazzapiModel):
10
+ name: str
11
+ whatsapp_account_id: str
12
+ recipient_type: str
13
+ description: str | None = None
14
+ template_id: str | None = None
15
+ message_type: str = "text"
16
+ custom_message: str | None = None
17
+ message_payload: dict[str, Any] | None = None
18
+ recipient_group_ids: list[str] | None = None
19
+ recipient_contact_ids: list[str] | None = None
20
+ scheduled_for: datetime | None = None
21
+
22
+
23
+ class CampaignUpdateRequest(WazzapiModel):
24
+ name: str | None = None
25
+ description: str | None = None
26
+ template_id: str | None = None
27
+ message_type: str | None = None
28
+ custom_message: str | None = None
29
+ message_payload: dict[str, Any] | None = None
30
+ recipient_type: str | None = None
31
+ recipient_group_ids: list[str] | None = None
32
+ recipient_contact_ids: list[str] | None = None
33
+ scheduled_for: datetime | None = None
34
+
35
+
36
+ class CampaignItem(WazzapiModel):
37
+ id: str
38
+ name: str
39
+ status: str
40
+ recipient_type: str
41
+ total_recipients: int
42
+ messages_sent: int
43
+ messages_delivered: int
44
+ messages_failed: int
45
+ whatsapp_account_id: str
46
+ message_type: str = "text"
47
+ recipient_contact_ids: list[str] | None = None
48
+ scheduled_for: str | None = None
49
+ created_at: str
50
+
51
+
52
+ class CampaignListResponse(WazzapiModel):
53
+ items: list[CampaignItem]
54
+ total: int
55
+ limit: int
56
+ offset: int
57
+
58
+
59
+ class CampaignResponse(WazzapiModel):
60
+ id: str
61
+ name: str
62
+ status: str
63
+ description: str | None = None
64
+ whatsapp_account_id: str
65
+ template_id: str | None = None
66
+ message_type: str = "text"
67
+ custom_message: str | None = None
68
+ message_payload: dict[str, Any] | None = None
69
+ recipient_type: str
70
+ recipient_group_ids: list[str] | None = None
71
+ recipient_contact_ids: list[str] | None = None
72
+ total_recipients: int = 0
73
+ messages_sent: int = 0
74
+ messages_delivered: int = 0
75
+ messages_failed: int = 0
76
+ scheduled_for: str | None = None
77
+ created_at: str | None = None
78
+ updated_at: str | None = None
79
+
80
+
81
+ class CampaignActionResponse(WazzapiModel):
82
+ success: bool
83
+ campaign_id: str
84
+ status: str
85
+
86
+
87
+ class CampaignExecuteResponse(WazzapiModel):
88
+ success: bool
89
+ campaign_id: str
90
+ status: str
91
+ total_recipients: int
92
+ job_id: str | None = None
93
+
94
+
95
+ __all__ = [
96
+ "CampaignActionResponse",
97
+ "CampaignCreateRequest",
98
+ "CampaignExecuteResponse",
99
+ "CampaignItem",
100
+ "CampaignListResponse",
101
+ "CampaignResponse",
102
+ "CampaignUpdateRequest",
103
+ ]
@@ -0,0 +1,80 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import datetime
4
+
5
+ from .base import WazzapiModel
6
+
7
+
8
+ class ConversationItem(WazzapiModel):
9
+ id: str
10
+ whatsapp_account_id: str
11
+ contact_id: str | None = None
12
+ phone_number: str
13
+ status: str
14
+ assignee_user_id: str | None = None
15
+ subject: str | None = None
16
+ last_message_preview: str | None = None
17
+ last_message_at: datetime | None = None
18
+ last_inbound_at: datetime | None = None
19
+ last_outbound_at: datetime | None = None
20
+ unread_count: int
21
+ created_at: datetime
22
+ updated_at: datetime
23
+
24
+
25
+ class ConversationListResponse(WazzapiModel):
26
+ conversations: list[ConversationItem]
27
+ total: int
28
+ limit: int
29
+ offset: int
30
+
31
+
32
+ class ConversationUpdateRequest(WazzapiModel):
33
+ status: str | None = None
34
+ assignee_user_id: str | None = None
35
+ clear_assignee: bool = False
36
+ mark_read: bool = False
37
+
38
+
39
+ class ConversationMessageItem(WazzapiModel):
40
+ id: str
41
+ direction: str
42
+ content: str
43
+ status: str
44
+ message_type: str
45
+ phone_number: str
46
+ whatsapp_message_id: str | None = None
47
+ created_at: datetime
48
+ sent_at: datetime | None = None
49
+ delivered_at: datetime | None = None
50
+ read_at: datetime | None = None
51
+
52
+
53
+ class ConversationMessageListResponse(WazzapiModel):
54
+ messages: list[ConversationMessageItem]
55
+ total: int
56
+ limit: int
57
+ offset: int
58
+
59
+
60
+ class ConversationReplyRequest(WazzapiModel):
61
+ content: str
62
+ whatsapp_account_id: str | None = None
63
+
64
+
65
+ class ConversationReplyResponse(WazzapiModel):
66
+ success: bool
67
+ message_id: str
68
+ conversation_id: str
69
+ status: str
70
+
71
+
72
+ __all__ = [
73
+ "ConversationItem",
74
+ "ConversationListResponse",
75
+ "ConversationMessageItem",
76
+ "ConversationMessageListResponse",
77
+ "ConversationReplyRequest",
78
+ "ConversationReplyResponse",
79
+ "ConversationUpdateRequest",
80
+ ]
@@ -0,0 +1,87 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import datetime
4
+
5
+ from .base import WazzapiModel
6
+
7
+
8
+ class WebhookCreateRequest(WazzapiModel):
9
+ url: str
10
+ subscribed_events: list[str]
11
+ secret: str | None = None
12
+ description: str | None = None
13
+
14
+
15
+ class WebhookUpdateRequest(WazzapiModel):
16
+ url: str | None = None
17
+ subscribed_events: list[str] | None = None
18
+ is_active: bool | None = None
19
+ description: str | None = None
20
+
21
+
22
+ class WebhookResponse(WazzapiModel):
23
+ id: str
24
+ url: str
25
+ secret_prefix: str
26
+ subscribed_events: list[str]
27
+ is_active: bool
28
+ status: str
29
+ failure_count: int
30
+ last_success_at: datetime | None = None
31
+ last_failure_at: datetime | None = None
32
+ description: str | None = None
33
+ created_at: datetime
34
+ updated_at: datetime
35
+
36
+
37
+ class WebhookListItem(WazzapiModel):
38
+ id: str
39
+ url: str
40
+ subscribed_events: list[str]
41
+ is_active: bool
42
+ status: str
43
+ failure_count: int
44
+ last_success_at: datetime | None = None
45
+ last_failure_at: datetime | None = None
46
+ description: str | None = None
47
+ created_at: datetime
48
+
49
+
50
+ class WebhookListResponse(WazzapiModel):
51
+ webhooks: list[WebhookListItem]
52
+ total: int
53
+
54
+
55
+ class WebhookEventListItem(WazzapiModel):
56
+ id: str
57
+ event_type: str
58
+ status: str
59
+ retry_count: int
60
+ response_code: int | None = None
61
+ error_message: str | None = None
62
+ created_at: datetime
63
+ delivered_at: datetime | None = None
64
+
65
+
66
+ class WebhookEventListResponse(WazzapiModel):
67
+ events: list[WebhookEventListItem]
68
+ total: int
69
+
70
+
71
+ class PingWebhookResponse(WazzapiModel):
72
+ success: bool
73
+ status_code: int | None = None
74
+ response_time_ms: int | None = None
75
+ error: str | None = None
76
+
77
+
78
+ __all__ = [
79
+ "PingWebhookResponse",
80
+ "WebhookCreateRequest",
81
+ "WebhookEventListItem",
82
+ "WebhookEventListResponse",
83
+ "WebhookListItem",
84
+ "WebhookListResponse",
85
+ "WebhookResponse",
86
+ "WebhookUpdateRequest",
87
+ ]
@@ -1,13 +1,19 @@
1
+ from .campaigns import CampaignsResource
1
2
  from .contacts import ContactsResource
3
+ from .conversations import ConversationsResource
2
4
  from .devices import DevicesResource
3
5
  from .groups import GroupsResource
4
6
  from .messages import MessagesResource
5
7
  from .templates import TemplatesResource
8
+ from .webhook_subscriptions import WebhookSubscriptionsResource
6
9
 
7
10
  __all__ = [
11
+ "CampaignsResource",
8
12
  "ContactsResource",
13
+ "ConversationsResource",
9
14
  "DevicesResource",
10
15
  "GroupsResource",
11
16
  "MessagesResource",
12
17
  "TemplatesResource",
18
+ "WebhookSubscriptionsResource",
13
19
  ]
@@ -0,0 +1,87 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from .. import models
6
+ from .base import BaseResource
7
+
8
+
9
+ class CampaignsResource(BaseResource):
10
+ def list(
11
+ self,
12
+ *,
13
+ limit: int | None = None,
14
+ offset: int | None = None,
15
+ status: str | None = None,
16
+ ) -> models.CampaignListResponse:
17
+ return self._client._request(
18
+ "GET",
19
+ "/api/v1/campaigns",
20
+ params={"limit": limit, "offset": offset, "status": status},
21
+ response_model=models.CampaignListResponse,
22
+ )
23
+
24
+ def create(
25
+ self,
26
+ payload: models.CampaignCreateRequest | dict[str, Any],
27
+ ) -> models.CampaignResponse:
28
+ return self._client._request(
29
+ "POST",
30
+ "/api/v1/campaigns",
31
+ json_body=payload,
32
+ response_model=models.CampaignResponse,
33
+ )
34
+
35
+ def get(self, campaign_id: str) -> models.CampaignResponse:
36
+ return self._client._request(
37
+ "GET",
38
+ f"/api/v1/campaigns/{campaign_id}",
39
+ response_model=models.CampaignResponse,
40
+ )
41
+
42
+ def update(
43
+ self,
44
+ campaign_id: str,
45
+ payload: models.CampaignUpdateRequest | dict[str, Any],
46
+ ) -> models.CampaignResponse:
47
+ return self._client._request(
48
+ "PATCH",
49
+ f"/api/v1/campaigns/{campaign_id}",
50
+ json_body=payload,
51
+ response_model=models.CampaignResponse,
52
+ )
53
+
54
+ def delete(self, campaign_id: str) -> None:
55
+ self._client._request("DELETE", f"/api/v1/campaigns/{campaign_id}")
56
+ return None
57
+
58
+ def execute(self, campaign_id: str) -> models.CampaignExecuteResponse:
59
+ return self._client._request(
60
+ "POST",
61
+ f"/api/v1/campaigns/{campaign_id}/execute",
62
+ response_model=models.CampaignExecuteResponse,
63
+ )
64
+
65
+ def pause(self, campaign_id: str) -> models.CampaignActionResponse:
66
+ return self._client._request(
67
+ "POST",
68
+ f"/api/v1/campaigns/{campaign_id}/pause",
69
+ response_model=models.CampaignActionResponse,
70
+ )
71
+
72
+ def resume(self, campaign_id: str) -> models.CampaignActionResponse:
73
+ return self._client._request(
74
+ "POST",
75
+ f"/api/v1/campaigns/{campaign_id}/resume",
76
+ response_model=models.CampaignActionResponse,
77
+ )
78
+
79
+ def cancel(self, campaign_id: str) -> models.CampaignActionResponse:
80
+ return self._client._request(
81
+ "POST",
82
+ f"/api/v1/campaigns/{campaign_id}/cancel",
83
+ response_model=models.CampaignActionResponse,
84
+ )
85
+
86
+
87
+ __all__ = ["CampaignsResource"]
@@ -0,0 +1,80 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from .. import models
6
+ from .base import BaseResource
7
+
8
+
9
+ class ConversationsResource(BaseResource):
10
+ def list(
11
+ self,
12
+ *,
13
+ limit: int | None = None,
14
+ offset: int | None = None,
15
+ status: str | None = None,
16
+ whatsapp_account_id: str | None = None,
17
+ assignee_user_id: str | None = None,
18
+ search: str | None = None,
19
+ ) -> models.ConversationListResponse:
20
+ return self._client._request(
21
+ "GET",
22
+ "/api/v1/conversations",
23
+ params={
24
+ "limit": limit,
25
+ "offset": offset,
26
+ "status": status,
27
+ "whatsapp_account_id": whatsapp_account_id,
28
+ "assignee_user_id": assignee_user_id,
29
+ "search": search,
30
+ },
31
+ response_model=models.ConversationListResponse,
32
+ )
33
+
34
+ def get(self, conversation_id: str) -> models.ConversationItem:
35
+ return self._client._request(
36
+ "GET",
37
+ f"/api/v1/conversations/{conversation_id}",
38
+ response_model=models.ConversationItem,
39
+ )
40
+
41
+ def update(
42
+ self,
43
+ conversation_id: str,
44
+ payload: models.ConversationUpdateRequest | dict[str, Any],
45
+ ) -> models.ConversationItem:
46
+ return self._client._request(
47
+ "PATCH",
48
+ f"/api/v1/conversations/{conversation_id}",
49
+ json_body=payload,
50
+ response_model=models.ConversationItem,
51
+ )
52
+
53
+ def list_messages(
54
+ self,
55
+ conversation_id: str,
56
+ *,
57
+ limit: int | None = None,
58
+ offset: int | None = None,
59
+ ) -> models.ConversationMessageListResponse:
60
+ return self._client._request(
61
+ "GET",
62
+ f"/api/v1/conversations/{conversation_id}/messages",
63
+ params={"limit": limit, "offset": offset},
64
+ response_model=models.ConversationMessageListResponse,
65
+ )
66
+
67
+ def reply(
68
+ self,
69
+ conversation_id: str,
70
+ payload: models.ConversationReplyRequest | dict[str, Any],
71
+ ) -> models.ConversationReplyResponse:
72
+ return self._client._request(
73
+ "POST",
74
+ f"/api/v1/conversations/{conversation_id}/reply",
75
+ json_body=payload,
76
+ response_model=models.ConversationReplyResponse,
77
+ )
78
+
79
+
80
+ __all__ = ["ConversationsResource"]
@@ -0,0 +1,99 @@
1
+ from __future__ import annotations
2
+
3
+ from .. import models
4
+ from .base import BaseResource
5
+
6
+
7
+ class DevicesResource(BaseResource):
8
+ def list(
9
+ self,
10
+ *,
11
+ limit: int | None = None,
12
+ offset: int | None = None,
13
+ status: str | None = None,
14
+ search: str | None = None,
15
+ sort_by: str | None = None,
16
+ sort_order: str | None = None,
17
+ ) -> models.DeviceListResponse:
18
+ return self._client._request(
19
+ "GET",
20
+ "/api/v1/devices",
21
+ params={
22
+ "limit": limit,
23
+ "offset": offset,
24
+ "status": status,
25
+ "search": search,
26
+ "sort_by": sort_by,
27
+ "sort_order": sort_order,
28
+ },
29
+ response_model=models.DeviceListResponse,
30
+ )
31
+
32
+ def get(self, device_id: str) -> models.DeviceResponse:
33
+ return self._client._request(
34
+ "GET",
35
+ f"/api/v1/devices/{device_id}",
36
+ response_model=models.DeviceResponse,
37
+ )
38
+
39
+ def link(self, payload: dict) -> dict:
40
+ return self._client._request(
41
+ "POST",
42
+ "/api/v1/devices",
43
+ json_body=payload,
44
+ response_model=dict,
45
+ )
46
+
47
+ def get_qr(self, device_id: str) -> dict:
48
+ return self._client._request(
49
+ "GET",
50
+ f"/api/v1/devices/{device_id}/qr",
51
+ response_model=dict,
52
+ )
53
+
54
+ def get_status(self, device_id: str) -> dict:
55
+ return self._client._request(
56
+ "GET",
57
+ f"/api/v1/devices/{device_id}/status",
58
+ response_model=dict,
59
+ )
60
+
61
+ def disconnect(self, device_id: str) -> dict:
62
+ return self._client._request(
63
+ "POST",
64
+ f"/api/v1/devices/{device_id}/disconnect",
65
+ response_model=dict,
66
+ )
67
+
68
+ def reconnect(self, device_id: str) -> dict:
69
+ return self._client._request(
70
+ "POST",
71
+ f"/api/v1/devices/{device_id}/reconnect",
72
+ response_model=dict,
73
+ )
74
+
75
+ def get_proxy(self, device_id: str) -> dict:
76
+ return self._client._request(
77
+ "GET",
78
+ f"/api/v1/devices/{device_id}/proxy",
79
+ response_model=dict,
80
+ )
81
+
82
+ def update_proxy(self, device_id: str, payload: dict) -> dict:
83
+ return self._client._request(
84
+ "PATCH",
85
+ f"/api/v1/devices/{device_id}/proxy",
86
+ json_body=payload,
87
+ response_model=dict,
88
+ )
89
+
90
+ def test_proxy(self, payload: dict) -> dict:
91
+ return self._client._request(
92
+ "POST",
93
+ "/api/v1/devices/proxy/test",
94
+ json_body=payload,
95
+ response_model=dict,
96
+ )
97
+
98
+
99
+ __all__ = ["DevicesResource"]
@@ -0,0 +1,80 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from .. import models
6
+ from .base import BaseResource
7
+
8
+
9
+ class WebhookSubscriptionsResource(BaseResource):
10
+ def list(
11
+ self,
12
+ *,
13
+ limit: int | None = None,
14
+ offset: int | None = None,
15
+ active_only: bool | None = None,
16
+ ) -> models.WebhookListResponse:
17
+ return self._client._request(
18
+ "GET",
19
+ "/api/v1/webhooks/subscriptions",
20
+ params={"limit": limit, "offset": offset, "active_only": active_only},
21
+ response_model=models.WebhookListResponse,
22
+ )
23
+
24
+ def create(
25
+ self,
26
+ payload: models.WebhookCreateRequest | dict[str, Any],
27
+ ) -> models.WebhookResponse:
28
+ return self._client._request(
29
+ "POST",
30
+ "/api/v1/webhooks/subscriptions",
31
+ json_body=payload,
32
+ response_model=models.WebhookResponse,
33
+ )
34
+
35
+ def get(self, webhook_id: str) -> models.WebhookResponse:
36
+ return self._client._request(
37
+ "GET",
38
+ f"/api/v1/webhooks/subscriptions/{webhook_id}",
39
+ response_model=models.WebhookResponse,
40
+ )
41
+
42
+ def update(
43
+ self,
44
+ webhook_id: str,
45
+ payload: models.WebhookUpdateRequest | dict[str, Any],
46
+ ) -> models.WebhookResponse:
47
+ return self._client._request(
48
+ "PATCH",
49
+ f"/api/v1/webhooks/subscriptions/{webhook_id}",
50
+ json_body=payload,
51
+ response_model=models.WebhookResponse,
52
+ )
53
+
54
+ def delete(self, webhook_id: str) -> None:
55
+ self._client._request("DELETE", f"/api/v1/webhooks/subscriptions/{webhook_id}")
56
+ return None
57
+
58
+ def list_events(
59
+ self,
60
+ webhook_id: str,
61
+ *,
62
+ limit: int | None = None,
63
+ offset: int | None = None,
64
+ ) -> models.WebhookEventListResponse:
65
+ return self._client._request(
66
+ "GET",
67
+ f"/api/v1/webhooks/subscriptions/{webhook_id}/events",
68
+ params={"limit": limit, "offset": offset},
69
+ response_model=models.WebhookEventListResponse,
70
+ )
71
+
72
+ def ping(self, webhook_id: str) -> models.PingWebhookResponse:
73
+ return self._client._request(
74
+ "POST",
75
+ f"/api/v1/webhooks/subscriptions/{webhook_id}/ping",
76
+ response_model=models.PingWebhookResponse,
77
+ )
78
+
79
+
80
+ __all__ = ["WebhookSubscriptionsResource"]
@@ -1,40 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from .. import models
4
- from .base import BaseResource
5
-
6
-
7
- class DevicesResource(BaseResource):
8
- def list(
9
- self,
10
- *,
11
- limit: int | None = None,
12
- offset: int | None = None,
13
- status: str | None = None,
14
- search: str | None = None,
15
- sort_by: str | None = None,
16
- sort_order: str | None = None,
17
- ) -> models.DeviceListResponse:
18
- return self._client._request(
19
- "GET",
20
- "/api/v1/devices",
21
- params={
22
- "limit": limit,
23
- "offset": offset,
24
- "status": status,
25
- "search": search,
26
- "sort_by": sort_by,
27
- "sort_order": sort_order,
28
- },
29
- response_model=models.DeviceListResponse,
30
- )
31
-
32
- def get(self, device_id: str) -> models.DeviceResponse:
33
- return self._client._request(
34
- "GET",
35
- f"/api/v1/devices/{device_id}",
36
- response_model=models.DeviceResponse,
37
- )
38
-
39
-
40
- __all__ = ["DevicesResource"]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes