aircall-api 1.1.0__py3-none-any.whl

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.
@@ -0,0 +1,270 @@
1
+ """Resource module for managing calls"""
2
+ from aircall.resources.base import BaseResource
3
+ from aircall.models import Call
4
+
5
+ class CallResource(BaseResource):
6
+ """
7
+ API Resource for Aircall Calls
8
+
9
+ Handles operations relating to calls including status, voicemails, insights and summaries
10
+ """
11
+ def list_calls(self, page: int = 1, per_page: int = 20) -> list[Call]:
12
+ """
13
+ List all calls with pagination.
14
+
15
+ Args:
16
+ page: Page number (default 1)
17
+ per_page: Results per page (default 20, max 50)
18
+
19
+ Returns:
20
+ list[Call]: List of Call objects
21
+ """
22
+ response = self._get("/calls", params={"page": page, "per_page": per_page})
23
+ return [Call(**c) for c in response["calls"]]
24
+
25
+ def get(self, call_id: int) -> Call:
26
+ """
27
+ Get a specific call by ID.
28
+
29
+ Args:
30
+ call_id: The ID of the call to retrieve
31
+
32
+ Returns:
33
+ Call: The call object
34
+ """
35
+ response = self._get(f"/calls/{call_id}")
36
+ return Call(**response["call"])
37
+
38
+ def search(self, **params) -> list[Call]:
39
+ """
40
+ Search for calls with various filters.
41
+
42
+ Args:
43
+ **params: Search parameters (from, to, tags, etc.)
44
+
45
+ Returns:
46
+ list[Call]: List of Call objects matching the search criteria
47
+ """
48
+ response = self._get("/calls/search", params=params)
49
+ return [Call(**c) for c in response["calls"]]
50
+
51
+ def transfer(self, call_id: int, number_id: int, comment: str = None) -> dict:
52
+ """
53
+ Transfer a call to another number.
54
+
55
+ Args:
56
+ call_id: The ID of the call to transfer
57
+ number_id: The ID of the number to transfer to
58
+ comment: Optional comment for the transfer
59
+
60
+ Returns:
61
+ dict: Transfer response
62
+ """
63
+ self._logger.info("Transferring call %s to number %s", call_id, number_id)
64
+ data = {"number_id": number_id}
65
+ if comment:
66
+ data["comment"] = comment
67
+ result = self._post(f"/calls/{call_id}/transfers", json=data)
68
+ self._logger.info("Successfully transferred call %s", call_id)
69
+ return result
70
+
71
+ def add_comment(self, call_id: int, content: str) -> dict:
72
+ """
73
+ Add a comment to a call.
74
+
75
+ Args:
76
+ call_id: The ID of the call
77
+ content: The comment content
78
+
79
+ Returns:
80
+ dict: Comment response
81
+ """
82
+ return self._post(f"/calls/{call_id}/comments", json={"content": content})
83
+
84
+ def add_tags(self, call_id: int, tags: list[str]) -> dict:
85
+ """
86
+ Add tags to a call.
87
+
88
+ Args:
89
+ call_id: The ID of the call
90
+ tags: List of tag names to add
91
+
92
+ Returns:
93
+ dict: Tags response
94
+ """
95
+ return self._post(f"/calls/{call_id}/tags", json={"tags": tags})
96
+
97
+ def archive(self, call_id: int) -> dict:
98
+ """
99
+ Archive a call.
100
+
101
+ Args:
102
+ call_id: The ID of the call to archive
103
+
104
+ Returns:
105
+ dict: Archive response
106
+ """
107
+ return self._put(f"/calls/{call_id}/archive")
108
+
109
+ def unarchive(self, call_id: int) -> dict:
110
+ """
111
+ Unarchive a call.
112
+
113
+ Args:
114
+ call_id: The ID of the call to unarchive
115
+
116
+ Returns:
117
+ dict: Unarchive response
118
+ """
119
+ return self._put(f"/calls/{call_id}/unarchive")
120
+
121
+ def pause_recording(self, call_id: int) -> dict:
122
+ """
123
+ Pause recording for a call.
124
+
125
+ Args:
126
+ call_id: The ID of the call
127
+
128
+ Returns:
129
+ dict: Pause recording response
130
+ """
131
+ return self._post(f"/calls/{call_id}/pause_recording")
132
+
133
+ def resume_recording(self, call_id: int) -> dict:
134
+ """
135
+ Resume recording for a call.
136
+
137
+ Args:
138
+ call_id: The ID of the call
139
+
140
+ Returns:
141
+ dict: Resume recording response
142
+ """
143
+ return self._post(f"/calls/{call_id}/resume_recording")
144
+
145
+ def delete_recording(self, call_id: int) -> dict:
146
+ """
147
+ Delete the recording of a call.
148
+
149
+ Args:
150
+ call_id: The ID of the call
151
+
152
+ Returns:
153
+ dict: Delete recording response
154
+ """
155
+ self._logger.warning("Deleting recording for call %s", call_id)
156
+ result = self._delete(f"/calls/{call_id}/recording")
157
+ self._logger.info("Successfully deleted recording for call %s", call_id)
158
+ return result
159
+
160
+ def delete_voicemail(self, call_id: int) -> dict:
161
+ """
162
+ Delete the voicemail of a call.
163
+
164
+ Args:
165
+ call_id: The ID of the call
166
+
167
+ Returns:
168
+ dict: Delete voicemail response
169
+ """
170
+ self._logger.warning("Deleting voicemail for call %s", call_id)
171
+ result = self._delete(f"/calls/{call_id}/voicemail")
172
+ self._logger.info("Successfully deleted voicemail for call %s", call_id)
173
+ return result
174
+
175
+ def add_insight_cards(self, call_id: int, cards: list[dict]) -> dict:
176
+ """
177
+ Add insight cards to a call.
178
+
179
+ Args:
180
+ call_id: The ID of the call
181
+ cards: List of insight card objects
182
+
183
+ Returns:
184
+ dict: Insight cards response
185
+ """
186
+ return self._post(f"/calls/{call_id}/insight_cards", json={"cards": cards})
187
+
188
+ def get_transcription(self, call_id: int) -> dict:
189
+ """
190
+ Get the transcription of a call.
191
+
192
+ Args:
193
+ call_id: The ID of the call
194
+
195
+ Returns:
196
+ dict: Transcription data
197
+ """
198
+ return self._get(f"/calls/{call_id}/transcription")
199
+
200
+ def get_realtime_transcription(self, call_id: int) -> dict:
201
+ """
202
+ Get the real-time transcription of a call.
203
+
204
+ Args:
205
+ call_id: The ID of the call
206
+
207
+ Returns:
208
+ dict: Real-time transcription data
209
+ """
210
+ return self._get(f"/calls/{call_id}/realtime_transcription")
211
+
212
+ def get_sentiments(self, call_id: int) -> dict:
213
+ """
214
+ Get sentiment analysis for a call.
215
+
216
+ Args:
217
+ call_id: The ID of the call
218
+
219
+ Returns:
220
+ dict: Sentiment analysis data
221
+ """
222
+ return self._get(f"/calls/{call_id}/sentiments")
223
+
224
+ def get_topics(self, call_id: int) -> dict:
225
+ """
226
+ Get topics discussed in a call.
227
+
228
+ Args:
229
+ call_id: The ID of the call
230
+
231
+ Returns:
232
+ dict: Topics data
233
+ """
234
+ return self._get(f"/calls/{call_id}/topics")
235
+
236
+ def get_summary(self, call_id: int) -> dict:
237
+ """
238
+ Get the summary of a call.
239
+
240
+ Args:
241
+ call_id: The ID of the call
242
+
243
+ Returns:
244
+ dict: Call summary data
245
+ """
246
+ return self._get(f"/calls/{call_id}/summary")
247
+
248
+ def get_action_items(self, call_id: int) -> dict:
249
+ """
250
+ Get action items from a call.
251
+
252
+ Args:
253
+ call_id: The ID of the call
254
+
255
+ Returns:
256
+ dict: Action items data
257
+ """
258
+ return self._get(f"/calls/{call_id}/action_items")
259
+
260
+ def get_playbook_result(self, call_id: int) -> dict:
261
+ """
262
+ Get playbook results for a call.
263
+
264
+ Args:
265
+ call_id: The ID of the call
266
+
267
+ Returns:
268
+ dict: Playbook result data
269
+ """
270
+ return self._get(f"/calls/{call_id}/playbook_result")
@@ -0,0 +1,29 @@
1
+ """Resource module for managing company information"""
2
+ from aircall.resources.base import BaseResource
3
+ from aircall.models import Company
4
+
5
+
6
+ class CompanyResource(BaseResource):
7
+ """
8
+ API Resource for Aircall Company.
9
+
10
+ Provides read-only access to company information.
11
+ Companies cannot be updated or deleted via the API.
12
+ """
13
+
14
+ def get(self) -> Company:
15
+ """
16
+ Get company information.
17
+
18
+ Returns:
19
+ Company: Company object with name, users_count, and numbers_count
20
+
21
+ Note:
22
+ Companies are read-only and can only be modified via the Aircall Dashboard.
23
+
24
+ Example:
25
+ >>> company = client.company.get()
26
+ >>> print(company.name, company.users_count, company.numbers_count)
27
+ """
28
+ response = self._get("/company")
29
+ return Company(**response["company"])
@@ -0,0 +1,192 @@
1
+ """Resource module for managing contacts"""
2
+ from aircall.resources.base import BaseResource
3
+ from aircall.models import Contact
4
+
5
+
6
+ class ContactResource(BaseResource):
7
+ """
8
+ API Resource for Aircall Contacts.
9
+
10
+ Handles operations relating to contacts including phone numbers and emails.
11
+ """
12
+
13
+ def list_contacts(self, page: int = 1, per_page: int = 20) -> list[Contact]:
14
+ """
15
+ List all contacts with pagination.
16
+
17
+ Args:
18
+ page: Page number (default 1)
19
+ per_page: Results per page (default 20, max 50)
20
+
21
+ Returns:
22
+ list[Contact]: List of Contact objects
23
+ """
24
+ response = self._get("/contacts", params={"page": page, "per_page": per_page})
25
+ return [Contact(**c) for c in response["contacts"]]
26
+
27
+ def search(self, **params) -> list[Contact]:
28
+ """
29
+ Search for contacts with various filters.
30
+
31
+ Args:
32
+ **params: Search parameters (phone_number, email, etc.)
33
+
34
+ Returns:
35
+ list[Contact]: List of Contact objects matching the search criteria
36
+ """
37
+ response = self._get("/contacts/search", params=params)
38
+ return [Contact(**c) for c in response["contacts"]]
39
+
40
+ def get(self, contact_id: int) -> Contact:
41
+ """
42
+ Get a specific contact by ID.
43
+
44
+ Args:
45
+ contact_id: The ID of the contact to retrieve
46
+
47
+ Returns:
48
+ Contact: The contact object
49
+ """
50
+ response = self._get(f"/contacts/{contact_id}")
51
+ return Contact(**response["contact"])
52
+
53
+ def create(self, **kwargs) -> Contact:
54
+ """
55
+ Create a new contact.
56
+
57
+ Args:
58
+ **kwargs: Contact data (first_name, last_name, phone_numbers, emails, etc.)
59
+
60
+ Returns:
61
+ Contact: The created contact object
62
+ """
63
+ response = self._post("/contacts", json=kwargs)
64
+ return Contact(**response["contact"])
65
+
66
+ def update(self, contact_id: int, **kwargs) -> Contact:
67
+ """
68
+ Update a contact.
69
+
70
+ Args:
71
+ contact_id: The ID of the contact to update
72
+ **kwargs: Contact fields to update
73
+
74
+ Returns:
75
+ Contact: The updated contact object
76
+ """
77
+ response = self._post(f"/contacts/{contact_id}", json=kwargs)
78
+ return Contact(**response["contact"])
79
+
80
+ def delete(self, contact_id: int) -> dict:
81
+ """
82
+ Delete a contact.
83
+
84
+ Args:
85
+ contact_id: The ID of the contact to delete
86
+
87
+ Returns:
88
+ dict: Delete response
89
+ """
90
+ return self._delete(f"/contacts/{contact_id}")
91
+
92
+ def add_phone_number(self, contact_id: int, value: str, label: str = None) -> dict:
93
+ """
94
+ Add a phone number to a contact.
95
+
96
+ Args:
97
+ contact_id: The ID of the contact
98
+ value: The phone number value
99
+ label: Optional label for the phone number
100
+
101
+ Returns:
102
+ dict: Phone number response
103
+ """
104
+ data = {"value": value}
105
+ if label:
106
+ data["label"] = label
107
+ return self._post(f"/contacts/{contact_id}/phone_details", json=data)
108
+
109
+ def update_phone_number(self, contact_id: int, phone_number_id: int,
110
+ value: str = None, label: str = None) -> dict:
111
+ """
112
+ Update a phone number from a contact.
113
+
114
+ Args:
115
+ contact_id: The ID of the contact
116
+ phone_number_id: The ID of the phone number to update
117
+ value: New phone number value
118
+ label: New label for the phone number
119
+
120
+ Returns:
121
+ dict: Update phone number response
122
+ """
123
+ data = {}
124
+ if value:
125
+ data["value"] = value
126
+ if label:
127
+ data["label"] = label
128
+ return self._put(f"/contacts/{contact_id}/phone_details/{phone_number_id}", json=data)
129
+
130
+ def delete_phone_number(self, contact_id: int, phone_number_id: int) -> dict:
131
+ """
132
+ Delete a phone number from a contact.
133
+
134
+ Args:
135
+ contact_id: The ID of the contact
136
+ phone_number_id: The ID of the phone number to delete
137
+
138
+ Returns:
139
+ dict: Delete phone number response
140
+ """
141
+ return self._delete(f"/contacts/{contact_id}/phone_details/{phone_number_id}")
142
+
143
+ def add_email(self, contact_id: int, value: str, label: str = None) -> dict:
144
+ """
145
+ Add an email to a contact.
146
+
147
+ Args:
148
+ contact_id: The ID of the contact
149
+ value: The email address
150
+ label: Optional label for the email
151
+
152
+ Returns:
153
+ dict: Email response
154
+ """
155
+ data = {"value": value}
156
+ if label:
157
+ data["label"] = label
158
+ return self._post(f"/contacts/{contact_id}/email_details", json=data)
159
+
160
+ def update_email(self, contact_id: int, email_id: int,
161
+ value: str = None, label: str = None) -> dict:
162
+ """
163
+ Update an email from a contact.
164
+
165
+ Args:
166
+ contact_id: The ID of the contact
167
+ email_id: The ID of the email to update
168
+ value: New email address
169
+ label: New label for the email
170
+
171
+ Returns:
172
+ dict: Update email response
173
+ """
174
+ data = {}
175
+ if value:
176
+ data["value"] = value
177
+ if label:
178
+ data["label"] = label
179
+ return self._put(f"/contacts/{contact_id}/email_details/{email_id}", json=data)
180
+
181
+ def delete_email(self, contact_id: int, email_id: int) -> dict:
182
+ """
183
+ Delete an email from a contact.
184
+
185
+ Args:
186
+ contact_id: The ID of the contact
187
+ email_id: The ID of the email to delete
188
+
189
+ Returns:
190
+ dict: Delete email response
191
+ """
192
+ return self._delete(f"/contacts/{contact_id}/email_details/{email_id}")
@@ -0,0 +1,90 @@
1
+ """Resource module for managing dialer campaigns"""
2
+ from aircall.resources.base import BaseResource
3
+ from aircall.models import DialerCampaign
4
+
5
+
6
+ class DialerCampaignResource(BaseResource):
7
+ """
8
+ API Resource for Aircall Dialer Campaigns (Power Dialer).
9
+
10
+ All operations are scoped to a specific user.
11
+ """
12
+
13
+ def get(self, user_id: int) -> DialerCampaign:
14
+ """
15
+ Retrieve a user's dialer campaign.
16
+
17
+ Args:
18
+ user_id: The ID of the user
19
+
20
+ Returns:
21
+ DialerCampaign: The dialer campaign object
22
+ """
23
+ response = self._get(f"/users/{user_id}/dialer_campaign")
24
+ return DialerCampaign(**response["dialer_campaign"])
25
+
26
+ def create(self, user_id: int, **kwargs) -> DialerCampaign:
27
+ """
28
+ Create a dialer campaign for a user.
29
+
30
+ Args:
31
+ user_id: The ID of the user
32
+ **kwargs: Dialer campaign data (number_id, phone_numbers, etc.)
33
+
34
+ Returns:
35
+ DialerCampaign: The created dialer campaign object
36
+ """
37
+ response = self._post(f"/users/{user_id}/dialer_campaign", json=kwargs)
38
+ return DialerCampaign(**response["dialer_campaign"])
39
+
40
+ def delete(self, user_id: int) -> dict:
41
+ """
42
+ Delete a user's dialer campaign.
43
+
44
+ Args:
45
+ user_id: The ID of the user
46
+
47
+ Returns:
48
+ dict: Delete response
49
+ """
50
+ return self._delete(f"/users/{user_id}/dialer_campaign")
51
+
52
+ def get_phone_numbers(self, user_id: int) -> list[dict]:
53
+ """
54
+ Retrieve phone numbers from a user's dialer campaign.
55
+
56
+ Args:
57
+ user_id: The ID of the user
58
+
59
+ Returns:
60
+ list[dict]: List of phone numbers in the campaign
61
+ """
62
+ response = self._get(f"/users/{user_id}/dialer_campaign/phone_numbers")
63
+ return response.get("phone_numbers", [])
64
+
65
+ def add_phone_numbers(self, user_id: int, phone_numbers: list[str]) -> dict:
66
+ """
67
+ Add phone numbers to a user's dialer campaign.
68
+
69
+ Args:
70
+ user_id: The ID of the user
71
+ phone_numbers: List of phone numbers to add
72
+
73
+ Returns:
74
+ dict: Add phone numbers response
75
+ """
76
+ return self._post(f"/users/{user_id}/dialer_campaign/phone_numbers",
77
+ json={"phone_numbers": phone_numbers})
78
+
79
+ def delete_phone_number(self, user_id: int, phone_number_id: int) -> dict:
80
+ """
81
+ Delete a phone number from a user's dialer campaign.
82
+
83
+ Args:
84
+ user_id: The ID of the user
85
+ phone_number_id: The ID of the phone number to delete
86
+
87
+ Returns:
88
+ dict: Delete phone number response
89
+ """
90
+ return self._delete(f"/users/{user_id}/dialer_campaign/phone_numbers/{phone_number_id}")
@@ -0,0 +1,53 @@
1
+ """Resource module for managing integrations"""
2
+ from aircall.resources.base import BaseResource
3
+ from aircall.models import Integration
4
+
5
+
6
+ class IntegrationResource(BaseResource):
7
+ """
8
+ API Resource for Aircall Integrations.
9
+
10
+ Handles operations for managing third-party integrations.
11
+ """
12
+
13
+ def get(self) -> Integration:
14
+ """
15
+ Retrieve integration information for the current API client.
16
+
17
+ Returns:
18
+ Integration: The integration object
19
+
20
+ Example:
21
+ >>> integration = client.integration.get()
22
+ >>> print(integration.name, integration.active)
23
+ """
24
+ response = self._get("/integrations/me")
25
+ return Integration(**response["integration"])
26
+
27
+ def enable(self) -> Integration:
28
+ """
29
+ Enable the integration.
30
+
31
+ Returns:
32
+ Integration: The updated integration object
33
+
34
+ Example:
35
+ >>> integration = client.integration.enable()
36
+ >>> print(integration.active) # True
37
+ """
38
+ response = self._post("/integrations/enable")
39
+ return Integration(**response["integration"])
40
+
41
+ def disable(self) -> Integration:
42
+ """
43
+ Disable the integration.
44
+
45
+ Returns:
46
+ Integration: The updated integration object
47
+
48
+ Example:
49
+ >>> integration = client.integration.disable()
50
+ >>> print(integration.active) # False
51
+ """
52
+ response = self._post("/integrations/disable")
53
+ return Integration(**response["integration"])