python-terminusgps 35.0.0__py3-none-any.whl → 35.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-terminusgps
3
- Version: 35.0.0
3
+ Version: 35.1.0
4
4
  Summary: Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more.
5
5
  Project-URL: Documentation, https://docs.terminusgps.com
6
6
  Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
@@ -15,9 +15,8 @@ terminusgps/authorizenet/tests/test_auth.py,sha256=sdByYrcv8RKjcJckOHbyHH1z_M4qr
15
15
  terminusgps/authorizenet/tests/test_profiles.py,sha256=tvLBY0iSAC33RlWiBP_NSnPskUQBjfrf0YHMpR-m22k,7566
16
16
  terminusgps/authorizenet/tests/test_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  terminusgps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- terminusgps/aws/notifications.py,sha256=HQDsxvFh_8vpAvoOo0K_3nteV0ArM-kgSeMhNzBx3es,9618
18
+ terminusgps/aws/notifications.py,sha256=i6BR4G-uw5m9i4FaHzjmLZb3ufdqSpeFfg3MwTXILVI,7296
19
19
  terminusgps/aws/secrets.py,sha256=MxQEmmBLpMUQ2tYAsHdCYf-7RZ84LiogdKcTsACX5dw,361
20
- terminusgps/aws/speech.py,sha256=8d4kLzc1obzW7uAhlSBmPWh_hw92d1eydcIiQROTj7A,4563
21
20
  terminusgps/aws/utils.py,sha256=68GWcllu4h41qzFiKdUkWOAA4LDsTPqRY446VRMxYsY,116
22
21
  terminusgps/aws/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
22
  terminusgps/aws/tests/test_notifications.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -55,7 +54,7 @@ terminusgps/wialon/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
55
54
  terminusgps/wialon/tests/test_items.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
55
  terminusgps/wialon/tests/test_session.py,sha256=9mBlYchMo9NeqRIZsmxYzrM1zBHorqu4ooxqSNppLpI,1336
57
56
  terminusgps/wialon/tests/test_utils.py,sha256=SK4PxJQGECFnzx_EQeRAQfsQ5_3FLaVcis2W9u_ibuI,1730
58
- python_terminusgps-35.0.0.dist-info/METADATA,sha256=FJGCV_uc4f3OcIqAv0Lyl2w9jSFw2X6a-0Ev1wNU3xc,1616
59
- python_terminusgps-35.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
60
- python_terminusgps-35.0.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
61
- python_terminusgps-35.0.0.dist-info/RECORD,,
57
+ python_terminusgps-35.1.0.dist-info/METADATA,sha256=uIku-n8_UI-SA-M-ojn5NpxbNoP9Yjmn6G-bKMJ9WO8,1616
58
+ python_terminusgps-35.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
59
+ python_terminusgps-35.1.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
60
+ python_terminusgps-35.1.0.dist-info/RECORD,,
@@ -1,173 +1,75 @@
1
- import asyncio
2
1
  import os
3
- import uuid
4
- from collections.abc import Sequence
5
2
  from contextlib import AsyncExitStack
6
3
 
7
4
  from aiobotocore.session import AioSession
8
5
 
9
- from terminusgps.django.validators import validate_e164_phone_number
10
6
 
7
+ class AsyncNotificationManager:
8
+ """Asyncronously delivers notifications using `AWS End User Messaging <https://docs.aws.amazon.com/end-user-messaging/>`_."""
11
9
 
12
- class AsyncPollyManager:
13
10
  def __init__(
14
- self, bucket_name: str | None = None, region_name: str = "us-east-1"
15
- ) -> None:
16
- self._exit_stack = AsyncExitStack()
17
- self._polly_client = None
18
- self._region_name = region_name
19
- self._bucket_name = bucket_name or os.getenv("AWS_POLLY_BUCKET_NAME", "")
20
-
21
- @property
22
- def region_name(self) -> str:
23
- """
24
- An AWS region name.
25
-
26
- :type: :py:obj:`str`
27
-
28
- """
29
- return self._region_name
30
-
31
- @property
32
- def bucket_name(self) -> str:
33
- """
34
- The AWS bucket that will host audio files.
35
-
36
- :type: :py:obj:`str`
37
-
38
- """
39
- return self._bucket_name
40
-
41
- async def __aenter__(self) -> "AsyncPollyManager":
42
- """
43
- Creates an asyncronous session and client.
44
-
45
- :returns: The polly manager.
46
- :rtype: :py:obj:`~terminusgps.aws.notifications.AsyncPollyManager`
47
-
48
- """
49
- session = AioSession()
50
- self._polly_client = await self._exit_stack.enter_async_context(
51
- session.create_client("polly", region_name=self.region_name)
52
- )
53
- return self
54
-
55
- async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
56
- """
57
- Destroys the asyncronous session.
58
-
59
- :param exc_type: Exception type.
60
- :param exc_val: Exception value.
61
- :param exc_tb: Exception traceback.
62
- :returns: Nothing.
63
- :rtype: :py:obj:`None`
64
-
65
- """
66
- await self._exit_stack.__aexit__(exc_type, exc_val, exc_tb)
67
-
68
- async def synthesize_speech(
69
- self,
70
- message: str,
71
- format: str = "ogg_vorbis",
72
- sample_rate: int = 22050,
73
- language_code: str = "en-US",
74
- ) -> None:
75
- """
76
- Synthesizes the message into an audio file and saves it to the S3 bucket.
77
-
78
- :param message: A message to be read aloud.
79
- :type message: :py:obj:`str`
80
- :param format: A file format. Default is ``"ogg_vorbis"``.
81
- :type format: :py:obj:`str`
82
- :param sample_rate: The audio frequency in Hz. Default is ``22050``.
83
- :type sample_rate: :py:obj:`int`
84
- :param language_code: The language to use in the synthesis. Default is ``"en-US"``.
85
- :type language_code: :py:obj:`str`
86
- :returns: Nothing.
87
- :rtype: :py:obj:`None`
88
-
89
- """
90
- await self._polly_client.start_speech_synthesis_task(
91
- **{
92
- "Engine": "standard",
93
- "LanguageCode": language_code,
94
- "OutputFormat": format,
95
- "OutputS3BucketName": self.bucket_name,
96
- "SampleRate": str(sample_rate),
97
- "Text": f"<speak>{message}</speak>",
98
- "TextType": "ssml",
99
- "VoiceId": "Joanna",
100
- }
101
- )
102
-
103
- async def synthesize_speech_batch(
104
11
  self,
105
- messages: Sequence[str],
106
- format: str = "ogg_vorbis",
107
- sample_rate: int = 22050,
108
- language_code: str = "en-US",
12
+ origin_pool_arn: str | None = os.getenv("AWS_MESSAGING_ORIGIN_POOL"),
13
+ configuration_set: str | None = os.getenv("AWS_MESSAGING_CONFIGURATION"),
14
+ max_sms_price: str = "0.20",
15
+ max_voice_price: str = "0.20",
16
+ region_name: str = "us-east-1",
17
+ debug_enabled: bool = False,
109
18
  ) -> None:
110
19
  """
111
- Synthesizes a sequence of messages into audio files and saves them to the S3 bucket.
112
-
113
- :param messages: A sequence of messages to be read aloud.
114
- :type messages: :py:obj:`Sequence`
115
- :param format: A file format. Default is ``"ogg_vorbis"``.
116
- :type format: :py:obj:`str`
117
- :param sample_rate: The audio frequency in Hz. Default is ``22050``.
118
- :type sample_rate: :py:obj:`int`
119
- :param language_code: The language to use in the synthesis. Default is ``"en-US"``.
120
- :type language_code: :py:obj:`str`
20
+ Sets attributes on the notification manager.
21
+
22
+ :param origin_pool_arn: A phone pool ARN for notification dispatch. Default is :envvar:`AWS_MESSAGING_ORIGIN_POOL`.
23
+ :type origin_pool_arn: :py:obj:`str` | :py:obj:`None`
24
+ :param configuration_set: An end-user messaging configuration set ARN. Default is :envvar:`AWS_MESSAGING_CONFIGURATION`.
25
+ :type configuration_set: :py:obj:`str` | :py:obj:`None`
26
+ :param max_sms_price: Max price to spend on a single SMS message.
27
+ :type max_sms_price: :py:obj:`str`
28
+ :param max_voice_price: Max price to spend per minute on a single voice message.
29
+ :type max_voice_price: :py:obj:`str`
30
+ :param region_name: An AWS region name used to open an AWS client.
31
+ :type region_name: :py:obj:`str`
32
+ :param debug_enabled: Whether or not to enable debug mode.
33
+ :type debug_enabled: :py:obj:`None`
34
+ :raises ValueError: If ``origin_pool_arn`` wasn't provided and :envvar:`AWS_MESSAGING_ORIGIN_POOL` wasn't set.
35
+ :raises ValueError: If ``configuration_set`` wasn't provided and :envvar:`AWS_MESSAGING_CONFIGURATION` wasn't set.
121
36
  :returns: Nothing.
122
37
  :rtype: :py:obj:`None`
123
38
 
124
39
  """
125
- await asyncio.gather(
126
- *[
127
- self.synthesize_speech(
128
- message=message,
129
- format=format,
130
- sample_rate=sample_rate,
131
- language_code=language_code,
132
- )
133
- for message in messages
134
- ]
135
- )
136
-
40
+ if origin_pool_arn is None:
41
+ raise ValueError(f"'origin_pool_arn' is required, got '{origin_pool_arn}'.")
42
+ if configuration_set is None:
43
+ raise ValueError(
44
+ f"'configuration_set' is required, got '{configuration_set}'."
45
+ )
137
46
 
138
- class AsyncNotificationManager:
139
- def __init__(
140
- self, group_id: str | None = None, region_name: str = "us-east-1"
141
- ) -> None:
142
- """
143
- Sets :py:attr:`group_id` and :py:attr:`region_name`.
144
-
145
- :returns: Nothing.
146
- :rtype: :py:obj:`None`
147
-
148
- """
149
47
  self._exit_stack = AsyncExitStack()
150
- self._sns_client = None
48
+ self._pinpoint_client = None
151
49
  self._region_name = region_name
152
- self.group_id = group_id
50
+ self._origin_pool_arn = origin_pool_arn
51
+ self._configuration_set = configuration_set
52
+ self._max_sms_price = max_sms_price
53
+ self._max_voice_price = max_voice_price
54
+ self._debug = debug_enabled
153
55
 
154
56
  async def __aenter__(self) -> "AsyncNotificationManager":
155
57
  """
156
- Creates an asyncronous session and client.
58
+ Creates asyncronous clients.
157
59
 
158
60
  :returns: The notification manager.
159
61
  :rtype: :py:obj:`~terminusgps.aws.notifications.AsyncNotificationManager`
160
62
 
161
63
  """
162
64
  session = AioSession()
163
- self._sns_client = await self._exit_stack.enter_async_context(
164
- session.create_client("sns", region_name=self.region_name)
65
+ self._pinpoint_client = await self._exit_stack.enter_async_context(
66
+ session.create_client("pinpoint-sms-voice-v2", region_name=self.region_name)
165
67
  )
166
68
  return self
167
69
 
168
70
  async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
169
71
  """
170
- Destroys the asyncronous session.
72
+ Destroys asyncronous clients.
171
73
 
172
74
  :param exc_type: Exception type.
173
75
  :param exc_val: Exception value.
@@ -189,123 +91,107 @@ class AsyncNotificationManager:
189
91
  return self._region_name
190
92
 
191
93
  @property
192
- def group_id(self) -> str:
193
- """
194
- A message group id.
195
-
196
- :type: :py:obj:`str`
94
+ def configuration_set(self) -> str:
95
+ return self._configuration_set
197
96
 
198
- """
199
- return str(self._group_id)
200
-
201
- @group_id.setter
202
- def group_id(self, other: str | None) -> None:
203
- """
204
- Sets :py:attr:`group_id` to ``other``.
97
+ @property
98
+ def origin_pool(self) -> str:
99
+ return self._origin_pool_arn
205
100
 
206
- If ``other`` isn't provided, instead set :py:attr:`group_id` to :py:func:`~uuid.uuid4`.
101
+ @property
102
+ def max_sms_price(self) -> str:
103
+ return self._max_sms_price
207
104
 
208
- :param other: A message group id.
209
- :type other: :py:obj:`str` | :py:obj:`None`
210
- :returns: Nothing.
211
- :rtype: :py:obj:`None`
105
+ @property
106
+ def max_voice_price(self) -> str:
107
+ return self._max_voice_price
212
108
 
213
- """
214
- if not other:
215
- other = str(uuid.uuid4())
216
- self._group_id = other
109
+ @property
110
+ def debug(self) -> bool:
111
+ return self._debug
217
112
 
218
113
  async def send_sms(
219
- self, to_number: str, message: str, message_id: str | None = None
220
- ) -> None:
114
+ self,
115
+ phone: str,
116
+ message: str,
117
+ ttl: int = 300,
118
+ dry_run: bool = False,
119
+ feedback: bool = False,
120
+ ) -> dict:
221
121
  """
222
- Sends an sms to ``to_number``.
122
+ Texts ``message`` to ``phone`` via sms.
223
123
 
224
- :param to_number: A destination phone number.
225
- :type to_number: :py:obj:`str`
124
+ :param phone: A destination phone number.
125
+ :type phone: :py:obj:`str`
226
126
  :param message: A message body.
227
127
  :type message: :py:obj:`str`
228
- :param message_id: A message deduplication id. :py:func:`~uuid.uuid4` is used if ``message_id`` was not provided.
229
- :type message_id: :py:obj:`str` | :py:obj:`None`
230
- :raises ValidationError: If ``to_number`` wasn't a valid E.164 formatted phone number.
231
- :returns: Nothing.
232
- :rtype: :py:obj:`None`
233
-
234
- """
235
- validate_e164_phone_number(to_number)
236
-
237
- if not message_id:
238
- message_id = str(uuid.uuid4())
239
-
240
- await self._sns_client.publish(
128
+ :param ttl: Time to live in ms. Default is ``300``.
129
+ :type ttl: :py:obj:`int`
130
+ :param dry_run: Whether or not to execute the voice message as a dry run. Default is :py:obj:`False`.
131
+ :type dry_run: :py:obj:`bool`
132
+ :param feedback: Whether or not to include message feedback in the response. Default is :py:obj:`False`.
133
+ :type feedback: :py:obj:`bool`
134
+ :raises AssertionError: If :py:attr:`_pinpoint_client` wasn't set.
135
+ :returns: A voice message response.
136
+ :rtype: :py:obj:`dict`
137
+
138
+ """
139
+ assert self._pinpoint_client, "Asyncronous client wasn't set."
140
+ return await self._pinpoint_client.send_text_message(
241
141
  **{
242
- "PhoneNumber": to_number,
243
- "Message": message,
244
- "MessageDeduplicationId": message_id,
245
- "MessageGroupId": self.group_id,
142
+ "DestinationPhoneNumber": phone,
143
+ "OriginationIdentity": self.origin_pool,
144
+ "MessageBody": message,
145
+ "MessageType": "TRANSACTIONAL",
146
+ "ConfigurationSetName": self.configuration_set,
147
+ "MaxPrice": self.max_sms_price,
148
+ "TimeToLive": ttl,
149
+ "DryRun": dry_run or self.debug,
150
+ "MessageFeedbackEnabled": feedback,
246
151
  }
247
152
  )
248
153
 
249
- async def send_push(
250
- self, target_arn: str, message: str, message_id: str | None = None
251
- ) -> None:
154
+ async def send_voice(
155
+ self,
156
+ phone: str,
157
+ message: str,
158
+ ttl: int = 300,
159
+ voice_id: str = "Joanna",
160
+ dry_run: bool = False,
161
+ feedback: bool = False,
162
+ ) -> dict:
252
163
  """
253
- Sends a push notification to ``target_arn``.
164
+ Calls ``phone`` and reads ``message`` aloud.
254
165
 
255
- :param target_arn: An AWS resource ARN.
256
- :type target_arn: :py:obj:`str`
166
+ :param phone: A destination phone number.
167
+ :type phone: :py:obj:`str`
257
168
  :param message: A message body.
258
169
  :type message: :py:obj:`str`
259
- :param message_id: A message deduplication id. :py:func:`~uuid.uuid4` is used if ``message_id`` was not provided.
260
- :type message_id: :py:obj:`str` | :py:obj:`None`
261
- :returns: Nothing.
262
- :rtype: :py:obj:`None`
263
-
264
- """
265
- if not message_id:
266
- message_id = str(uuid.uuid4())
267
-
268
- await self._sns_client.publish(
170
+ :param ttl: Time to live in ms. Default is ``300``.
171
+ :type ttl: :py:obj:`int`
172
+ :param voice_id: A voice id to use for speech synthesis.
173
+ :type voice_id: :py:obj:`str`
174
+ :param dry_run: Whether or not to execute the voice message as a dry run. Default is :py:obj:`False`.
175
+ :type dry_run: :py:obj:`bool`
176
+ :param feedback: Whether or not to include message feedback in the response. Default is :py:obj:`False`.
177
+ :type feedback: :py:obj:`bool`
178
+ :raises AssertionError: If :py:attr:`_pinpoint_client` wasn't set.
179
+ :returns: A voice message response.
180
+ :rtype: :py:obj:`dict`
181
+
182
+ """
183
+ assert self._pinpoint_client, "Asyncronous client wasn't set."
184
+ return await self._pinpoint_client.send_voice_message(
269
185
  **{
270
- "TargetArn": target_arn,
271
- "Message": message,
272
- "MessageDeduplicationId": message_id,
273
- "MessageGroupId": self.group_id,
186
+ "DestinationPhoneNumber": phone,
187
+ "OriginationIdentity": self.origin_pool,
188
+ "MessageBody": message,
189
+ "MessageBodyTextType": "TEXT",
190
+ "VoiceId": voice_id.upper(),
191
+ "ConfigurationSetName": self.configuration_set,
192
+ "MaxPricePerMinute": self.max_voice_price,
193
+ "TimeToLive": ttl,
194
+ "DryRun": dry_run or self.debug,
195
+ "MessageFeedbackEnabled": feedback,
274
196
  }
275
197
  )
276
-
277
- async def send_sms_batch(self, to_numbers: Sequence[str], message: str) -> None:
278
- """
279
- Sends an sms message to each phone number in ``to_numbers``.
280
-
281
- :param to_numbers: A sequence of phone numbers.
282
- :type to_numbers: :py:obj:`~collections.abc.Sequence`
283
- :param message: A message body.
284
- :type message: :py:obj:`str`
285
- :raises ValidationError: If a ``to_number`` wasn't a valid E.164 formatted phone number.
286
- :returns: Nothing.
287
- :rtype: :py:obj:`None`
288
-
289
- """
290
- for to_number in to_numbers:
291
- validate_e164_phone_number(to_number)
292
-
293
- await asyncio.gather(
294
- *[self.send_sms(to_number=num, message=message) for num in to_numbers]
295
- )
296
-
297
- async def send_push_batch(self, target_arns: Sequence[str], message: str) -> None:
298
- """
299
- Sends a push notification to each AWS resource by ARN in ``target_arns``.
300
-
301
- :param target_arns: A sequence of AWS resource ARNs.
302
- :type target_arns: :py:obj:`~collections.abc.Sequence`
303
- :param message: A message body.
304
- :type message: :py:obj:`str`
305
- :returns: Nothing.
306
- :rtype: :py:obj:`None`
307
-
308
- """
309
- await asyncio.gather(
310
- *[self.send_push(target_arn=arn, message=message) for arn in target_arns]
311
- )
terminusgps/aws/speech.py DELETED
@@ -1,146 +0,0 @@
1
- import asyncio
2
- import os
3
- from collections.abc import Sequence
4
- from contextlib import AsyncExitStack
5
-
6
- from aiobotocore.session import AioSession
7
-
8
-
9
- class AsyncSpeechSynthesisManager:
10
- def __init__(
11
- self, bucket_name: str | None = None, region_name: str = "us-east-1"
12
- ) -> None:
13
- self._exit_stack = AsyncExitStack()
14
- self._polly_client = None
15
- self._region_name = region_name
16
- self._bucket_name = bucket_name or os.getenv("AWS_POLLY_BUCKET_NAME", "")
17
-
18
- @property
19
- def region_name(self) -> str:
20
- """
21
- An AWS region name.
22
-
23
- :type: :py:obj:`str`
24
-
25
- """
26
- return self._region_name
27
-
28
- @property
29
- def bucket_name(self) -> str:
30
- """
31
- The AWS bucket that will host audio files.
32
-
33
- :type: :py:obj:`str`
34
-
35
- """
36
- return self._bucket_name
37
-
38
- async def __aenter__(self) -> "AsyncSpeechSynthesisManager":
39
- """
40
- Creates an asyncronous session and client.
41
-
42
- :returns: The polly manager.
43
- :rtype: :py:obj:`~terminusgps.aws.notifications.AsyncPollyManager`
44
-
45
- """
46
- session = AioSession()
47
- self._polly_client = await self._exit_stack.enter_async_context(
48
- session.create_client("polly", region_name=self.region_name)
49
- )
50
- return self
51
-
52
- async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
53
- """
54
- Destroys the asyncronous session.
55
-
56
- :param exc_type: Exception type.
57
- :param exc_val: Exception value.
58
- :param exc_tb: Exception traceback.
59
- :returns: Nothing.
60
- :rtype: :py:obj:`None`
61
-
62
- """
63
- await self._exit_stack.__aexit__(exc_type, exc_val, exc_tb)
64
-
65
- async def synthesize_speech(
66
- self,
67
- message: str,
68
- format: str = "ogg_vorbis",
69
- sample_rate: int = 22050,
70
- language_code: str = "en-US",
71
- ) -> None:
72
- """
73
- Synthesizes the message into an audio file and saves it to the S3 bucket.
74
-
75
- :param message: A message to be read aloud.
76
- :type message: :py:obj:`str`
77
- :param format: A file format. Default is ``"ogg_vorbis"``.
78
- :type format: :py:obj:`str`
79
- :param sample_rate: The audio frequency in Hz. Default is ``22050``.
80
- :type sample_rate: :py:obj:`int`
81
- :param language_code: The language to use in the synthesis. Default is ``"en-US"``.
82
- :type language_code: :py:obj:`str`
83
- :returns: The audio file URI.
84
- :rtype: :py:obj:`str`
85
-
86
- """
87
- response = await self._polly_client.start_speech_synthesis_task(
88
- **{
89
- "Engine": "standard",
90
- "LanguageCode": language_code,
91
- "OutputFormat": format,
92
- "OutputS3BucketName": self.bucket_name,
93
- "SampleRate": str(sample_rate),
94
- "Text": f"<speak>{message}</speak>",
95
- "TextType": "ssml",
96
- "VoiceId": "Joanna",
97
- }
98
- )
99
- print(f"{response = }")
100
- return response.get("SynthesisTask", {}).get("OutputUri", "")
101
-
102
- async def synthesize_speech_batch(
103
- self,
104
- messages: Sequence[str],
105
- format: str = "ogg_vorbis",
106
- sample_rate: int = 22050,
107
- language_code: str = "en-US",
108
- ) -> None:
109
- """
110
- Synthesizes a sequence of messages into audio files and saves them to the S3 bucket.
111
-
112
- :param messages: A sequence of messages to be read aloud.
113
- :type messages: :py:obj:`Sequence`
114
- :param format: A file format. Default is ``"ogg_vorbis"``.
115
- :type format: :py:obj:`str`
116
- :param sample_rate: The audio frequency in Hz. Default is ``22050``.
117
- :type sample_rate: :py:obj:`int`
118
- :param language_code: The language to use in the synthesis. Default is ``"en-US"``.
119
- :type language_code: :py:obj:`str`
120
- :returns: A list of audio file URIs.
121
- :rtype: :py:obj:`list`
122
-
123
- """
124
- await asyncio.gather(
125
- *[
126
- self.synthesize_speech(
127
- message=message,
128
- format=format,
129
- sample_rate=sample_rate,
130
- language_code=language_code,
131
- )
132
- for message in messages
133
- ]
134
- )
135
-
136
-
137
- async def main() -> None:
138
- async with AsyncSpeechSynthesisManager() as manager:
139
- uri = await manager.synthesize_speech(
140
- "Oh yeah, I'm creating another test audio file."
141
- )
142
- print(f"{uri = }")
143
-
144
-
145
- if __name__ == "__main__":
146
- asyncio.run(main())