Skip to content

Commit 71f061f

Browse files
Merge pull request #285 from dvonthenen/prerecorded-callback-example
Fix for `transcribe_url_callback` and `transcribe_file_callback` with Example
2 parents a5276bb + 97fc62f commit 71f061f

File tree

9 files changed

+212
-10
lines changed

9 files changed

+212
-10
lines changed

deepgram/clients/prerecorded/v1/async_client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ async def transcribe_url(
5757
if options is not None and options.callback is not None:
5858
self.logger.debug("PreRecordedClient.transcribe_url LEAVE")
5959
return await self.transcribe_url_callback(
60-
source, options["callback"], options, addons, timeout, endpoint
60+
source, options.callback, options, addons, timeout, endpoint
6161
)
6262

6363
url = f"{self.config.url}/{endpoint}"
@@ -120,7 +120,7 @@ async def transcribe_url_callback(
120120
url = f"{self.config.url}/{endpoint}"
121121
if options is None:
122122
options = {}
123-
options["callback"] = callback
123+
options.callback = callback
124124
if is_url_source(source):
125125
body = source
126126
else:
@@ -178,7 +178,7 @@ async def transcribe_file(
178178
if options is not None and options.callback is not None:
179179
self.logger.debug("PreRecordedClient.transcribe_file LEAVE")
180180
return await self.transcribe_file_callback(
181-
source, options["callback"], options, addons, timeout, endpoint
181+
source, options.callback, options, addons, timeout, endpoint
182182
)
183183

184184
url = f"{self.config.url}/{endpoint}"
@@ -242,7 +242,7 @@ async def transcribe_file_callback(
242242
url = f"{self.config.url}/{endpoint}"
243243
if options is None:
244244
options = {}
245-
options["callback"] = callback
245+
options.callback = callback
246246
if is_buffer_source(source):
247247
body = source["buffer"]
248248
elif is_readstream_source(source):
@@ -264,7 +264,7 @@ async def transcribe_file_callback(
264264
self.logger.info("options: %s", options)
265265
self.logger.info("addons: %s", addons)
266266
result = await self.post(
267-
url, options=options, addons=addons, json=body, timeout=timeout
267+
url, options=options, addons=addons, content=body, timeout=timeout
268268
)
269269
self.logger.info("json: %s", result)
270270
res = AsyncPrerecordedResponse.from_json(result)

deepgram/clients/prerecorded/v1/client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def transcribe_url(
5757
if options is not None and options.callback is not None:
5858
self.logger.debug("PreRecordedClient.transcribe_url LEAVE")
5959
return self.transcribe_url_callback(
60-
source, options["callback"], options, addons, timeout, endpoint
60+
source, options.callback, options, addons, timeout, endpoint
6161
)
6262

6363
url = f"{self.config.url}/{endpoint}"
@@ -120,7 +120,7 @@ def transcribe_url_callback(
120120
url = f"{self.config.url}/{endpoint}"
121121
if options is None:
122122
options = {}
123-
options["callback"] = callback
123+
options.callback = callback
124124
if is_url_source(source):
125125
body = source
126126
else:
@@ -178,7 +178,7 @@ def transcribe_file(
178178
if options is not None and options.callback is not None:
179179
self.logger.debug("PreRecordedClient.transcribe_file LEAVE")
180180
return self.transcribe_file_callback(
181-
source, options["callback"], options, addons, timeout, endpoint
181+
source, options.callback, options, addons, timeout, endpoint
182182
)
183183

184184
url = f"{self.config.url}/{endpoint}"
@@ -242,7 +242,7 @@ def transcribe_file_callback(
242242
url = f"{self.config.url}/{endpoint}"
243243
if options is None:
244244
options = {}
245-
options["callback"] = callback
245+
options.callback = callback
246246
if is_buffer_source(source):
247247
body = source["buffer"]
248248
elif is_readstream_source(source):
@@ -264,7 +264,7 @@ def transcribe_file_callback(
264264
self.logger.info("options: %s", options)
265265
self.logger.info("addons: %s", addons)
266266
result = self.post(
267-
url, options=options, addons=addons, json=body, timeout=timeout
267+
url, options=options, addons=addons, content=body, timeout=timeout
268268
)
269269
self.logger.info("json: %s", result)
270270
res = AsyncPrerecordedResponse.from_json(result)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Callback Example
2+
3+
This example shows how to use the [Callback](https://developers.deepgram.com/docs/callback) functionality on the Prerecorded API.
4+
5+
> **_NOTE:_** To use this example, the `endpoint` component must run somewhere with a public-facing IP address. You cannot run this example locally behind your typical firewall.
6+
7+
## Configuration
8+
9+
This example consists of two components:
10+
- `endpoint`: which is an example of what a callback endpoint would look like. Reminder: this requires running with a public-facing IP address
11+
- `callback`: which is just a Deepgram client posts a PreRecorded transcription request using a local audio file preamble.wav (or using an audio file at a hosted URL, like [https://static.deepgram.com/examples/Bueller-Life-moves-pretty-fast.wav](https://static.deepgram.com/examples/Bueller-Life-moves-pretty-fast.wav).
12+
13+
The `callback` component requires the Deepgram API Key environment variable to be configured to run.
14+
15+
```sh
16+
export DEEPGRAM_API_KEY=YOUR-APP-KEY-HERE
17+
```
18+
19+
### Prerequisites: Public-facing Endpoint
20+
21+
This example requires that the Deepgram platform be able to reach your `endpoint` which means the IP address must be publically hosted. This could be an EC2 instance on AWS, an instance on GCP, etc. Another option is using [ngrok](https://ngrok.com/).
22+
23+
`ngrok` brief overview: run ngrok http 8080 which opens up the local host port 8080, and gives a public URL https://e00a-42-156-98-177.ngrok-free.app/ (for example). Then in another terminal, run nc -l 8080 to listen on port 8080 for incoming messages. The `CALL_BACK_URL` should then be set to `https://e00a-42-156-98-177.ngrok-free.app`.
24+
25+
## Installation
26+
27+
Run the `endpoint` application using an SSL certificate to a system on the public-facing internet.
28+
29+
On the `callback` project, modify the IP address constant in the code with the public-facing IP address of your EC2, GCP, etc instance.
30+
31+
```Python
32+
CALL_BACK_URL = (
33+
"https://127.0.0.1:8000" # TODO: MUST REPLACE WITH YOUR OWN CALLBACK ENDPOINT
34+
)
35+
```
36+
37+
Then run the `callback` application. This can be done from your local laptop.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Copyright 2023 Deepgram SDK contributors. All Rights Reserved.
2+
# Use of this source code is governed by a MIT license that can be found in the LICENSE file.
3+
# SPDX-License-Identifier: MIT
4+
5+
import os
6+
from dotenv import load_dotenv
7+
import logging, verboselogs
8+
from datetime import datetime, timedelta
9+
10+
from deepgram import (
11+
DeepgramClient,
12+
DeepgramClientOptions,
13+
PrerecordedOptions,
14+
FileSource,
15+
UrlSource,
16+
)
17+
18+
load_dotenv()
19+
20+
AUDIO_FILE = "preamble.wav"
21+
CALL_BACK_URL = (
22+
"https://127.0.0.1:8000" # TODO: MUST REPLACE WITH YOUR OWN CALLBACK ENDPOINT
23+
)
24+
25+
26+
def main():
27+
try:
28+
# STEP 1 Create a Deepgram client using the API key in the environment variables
29+
config = DeepgramClientOptions(
30+
verbose=logging.SPAM,
31+
)
32+
33+
deepgram = DeepgramClient("", config)
34+
35+
# STEP 2 Call the transcribe_file method on the prerecorded class
36+
with open(AUDIO_FILE, "rb") as file:
37+
buffer_data = file.read()
38+
39+
payload: FileSource = {
40+
"buffer": buffer_data,
41+
}
42+
# For URL hosted audio files, comment out the above and uncomment the below
43+
# payload: UrlSource = {
44+
# "url": "https://static.deepgram.com/examples/Bueller-Life-moves-pretty-fast.wav"
45+
# }
46+
47+
options = PrerecordedOptions(
48+
model="nova-2",
49+
smart_format=True,
50+
utterances=True,
51+
)
52+
53+
response = deepgram.listen.prerecorded.v("1").transcribe_file_callback(
54+
payload, CALL_BACK_URL, options=options
55+
)
56+
# For URL hosted audio files, comment out the above and uncomment the below
57+
# response = deepgram.listen.prerecorded.v("1").transcribe_url_callback(
58+
# payload, CALL_BACK_URL, options=options
59+
# )
60+
print(response.to_json(indent=4))
61+
62+
except Exception as e:
63+
print(f"Exception: {e}")
64+
65+
66+
if __name__ == "__main__":
67+
main()
823 KB
Binary file not shown.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDoDCCAogCCQCtyWzcpdOQUDANBgkqhkiG9w0BAQUFADCBkTELMAkGA1UEBhMC
3+
VVMxCzAJBgNVBAgMAkNBMRMwEQYDVQQHDApMb25nIEJlYWNoMREwDwYDVQQKDAhT
4+
eW1ibC5haTEbMBkGA1UECwwSRGV2ZWxvcGVyIEFkdm9jYWN5MRIwEAYDVQQDDAkx
5+
MjcuMC4wLjExHDAaBgkqhkiG9w0BCQEWDXNwYW1Ac3ltYmwuYWkwHhcNMjIxMTIx
6+
MTYyOTM3WhcNMjMxMTIxMTYyOTM3WjCBkTELMAkGA1UEBhMCVVMxCzAJBgNVBAgM
7+
AkNBMRMwEQYDVQQHDApMb25nIEJlYWNoMREwDwYDVQQKDAhTeW1ibC5haTEbMBkG
8+
A1UECwwSRGV2ZWxvcGVyIEFkdm9jYWN5MRIwEAYDVQQDDAkxMjcuMC4wLjExHDAa
9+
BgkqhkiG9w0BCQEWDXNwYW1Ac3ltYmwuYWkwggEiMA0GCSqGSIb3DQEBAQUAA4IB
10+
DwAwggEKAoIBAQCv6xZu8caNs847YIVVsjE7odfcyFKsrIkXsUDyImkLNNLBCSQ8
11+
xMrNiVo4OoKwcpqGR1NsSoblFYoruE41gA5R2nbILIbNeu5Sq+Kqljtuci7kDog1
12+
OX8yliEVkSECJZ7uGGb811p8R9BDsZqUXk/gZTKknbYFon6fQkvbmucSBHHA98TC
13+
s3WhP/F7zCVwK1u3oX67TjfmN+RXkXwlC2FjnDjoc8TWRHtnV9Nv71i0ss5Ep6GB
14+
G6iwsM86C+bEhQYzGbT/oZexeP+1NuKBhhtXfvlo5aXP1RRfCGsCE5UcxVXE7Cid
15+
UGK0XQ9cHFgW8/axbP+WFWvbyqpE2hSFpZ3zAgMBAAEwDQYJKoZIhvcNAQEFBQAD
16+
ggEBAEsKMNI16CzuuM8dcLbzsxu490AEqlwbzCnEUqqEbe0m3z9rz3HTG6KV6ejc
17+
2ABl0MtSxGeW4K6Vb0+AC61NXa0snnDVFHNd8McsVvSSpnwvVll8S7oCjFviDzu3
18+
FYDlhqI8c7SNJNjC5FL4fV0P7IwR8cN3wn0hfd3dKzxvTVvU5AWA3S33M494ewrt
19+
HZE1CTX6Al+hghjSXOrpd1yvD1UBlYvnASHh+whRlAN2V9IpZEo9IpQB12sj97lZ
20+
Lw+O53Ysn1PR0WuTdjgmtc3m//6QrHQOxcOLxl8Jyi0uXclFv8Oy0VmUbZe18MzA
21+
n70mi+NaDxTrsFCL9goHUjc6uhw=
22+
-----END CERTIFICATE-----
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIC1zCCAb8CAQAwgZExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTETMBEGA1UE
3+
BwwKTG9uZyBCZWFjaDERMA8GA1UECgwIU3ltYmwuYWkxGzAZBgNVBAsMEkRldmVs
4+
b3BlciBBZHZvY2FjeTESMBAGA1UEAwwJMTI3LjAuMC4xMRwwGgYJKoZIhvcNAQkB
5+
Fg1zcGFtQHN5bWJsLmFpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
6+
r+sWbvHGjbPOO2CFVbIxO6HX3MhSrKyJF7FA8iJpCzTSwQkkPMTKzYlaODqCsHKa
7+
hkdTbEqG5RWKK7hONYAOUdp2yCyGzXruUqviqpY7bnIu5A6INTl/MpYhFZEhAiWe
8+
7hhm/NdafEfQQ7GalF5P4GUypJ22BaJ+n0JL25rnEgRxwPfEwrN1oT/xe8wlcCtb
9+
t6F+u0435jfkV5F8JQthY5w46HPE1kR7Z1fTb+9YtLLORKehgRuosLDPOgvmxIUG
10+
Mxm0/6GXsXj/tTbigYYbV375aOWlz9UUXwhrAhOVHMVVxOwonVBitF0PXBxYFvP2
11+
sWz/lhVr28qqRNoUhaWd8wIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAIB+1Lcx
12+
ywJvr3DQc3gkSNDZp5sR9hK65wjwt2dhzgbSBsbGPPyf0q54QCc9UPz37XSp/xkl
13+
vU1T12SMK53JIXwizoj47BM51hhrfIs0Ky6msrL2+FyAPBTQpYbVLg3AvqFZUejl
14+
Gj2kcG3nvTMtex3ktoHwOAfdvVhqWYqGomkQseVep6mAx/8soJycohtT6K255tyN
15+
IyMkNO8KZA+R8jVSjFIbMM5YG3dBqj//s0+Qb49dN/TybRmUAeuMQEnk737vzz63
16+
1w/58UGpshqBOwf4/jz1nESxXvDOgGu8ygMbaBe/uEI68szTGGXl4FZvRy3nHDsz
17+
Nn5k5SNMwaAQkW0=
18+
-----END CERTIFICATE REQUEST-----
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCv6xZu8caNs847
3+
YIVVsjE7odfcyFKsrIkXsUDyImkLNNLBCSQ8xMrNiVo4OoKwcpqGR1NsSoblFYor
4+
uE41gA5R2nbILIbNeu5Sq+Kqljtuci7kDog1OX8yliEVkSECJZ7uGGb811p8R9BD
5+
sZqUXk/gZTKknbYFon6fQkvbmucSBHHA98TCs3WhP/F7zCVwK1u3oX67TjfmN+RX
6+
kXwlC2FjnDjoc8TWRHtnV9Nv71i0ss5Ep6GBG6iwsM86C+bEhQYzGbT/oZexeP+1
7+
NuKBhhtXfvlo5aXP1RRfCGsCE5UcxVXE7CidUGK0XQ9cHFgW8/axbP+WFWvbyqpE
8+
2hSFpZ3zAgMBAAECggEAAkdoXf2R1eobZNeGQqrxSlV5Z2nM8GG30O/B6KEbfUKs
9+
7EVDC+p8uhbqbUoMwV5qtAyefwukHbmetZxInxbOmK7c1REGmgjap4WEhTM3B+JA
10+
y0GI8C+Tf0NEoHPl2pJEMc9tHh9oE64We5oEZ6GlJUIKWumUHxSQ0V1ZgDnMfoY8
11+
ttl/NpShMF9lz67GnaMcGNwrXr2a/oKEXUdAuOZKyS9vP80WLWAYzLGSBa2FEMmJ
12+
tumLb8EEQpWRPOPTwylPAJcV/67FjH/g4DCA8NgyevI2/lH/ZHlp0UYC5vLqzN8Z
13+
zN4MalYC+6ZWZSM//gyhxvXZ3j+WNUERSv+ndTk+YQKBgQDabhzExPgpzgtnQpg5
14+
hnJpcGmxdp6ajFz70AI1sU6rWisAItwF8g6xHIH4TkHhhn3oyJ4Xtzt7jOaT011t
15+
IVmks2uNoONjO4yFmLvkQORn4opvkdya+gm68acceb3jdKI663MmfLLUXKaHVpwN
16+
zP0kzWuKD++kCtHMphqK3LKXMQKBgQDOLRmzE8pxNtXNvgBFCqwPiSxGNZ3nfi+t
17+
MIhW/YhW6RypeTQ/NFWzIzklO79VUQCUidRdEmh21XGisDxMtnIw+5VAKliE40Aw
18+
hGTxLn+HsQ1IPxD3/3bVJkU2Htpxfo4/WClRnZ9E3wD++6hayGtDY6peRrBY5plq
19+
t31dXyoGYwKBgQCPEAevqQKQ/u7hFvD03GYbQRE4tmRy/PP5yedom1TXThtT34EU
20+
M9IDlpRZuYfU2m2lBaDmD5DZ/xMWRx2t2GYKRalv/axw1hPXfI2zlf0DPZFGOdav
21+
eozc8GFveR0x2LZYuNWWo53NEVHQ2p0jPNugOxrwNjfSzXNUAobn5FzkQQKBgDPc
22+
alt+PezucydWhLDZN2CNC6L5d6e0OP/idlkTWwkph/klMLw5SNlPod84wS8Pugqj
23+
BNUIfVhu5i+bDv/o4J5rmiZSwINkuk+57b4xCQkzwviKTJVlIBoLj1tGtYHY6KUM
24+
YxBRiq+DPLfmy3lScpC38DHYrCEgmDScxR8IggSrAoGBAJldUpe90FsKz26Eef6s
25+
ZTbWRT9BB3GQc4IhtWr23RmOGEiORRglHtHRIzaBose23ZTjCa/A9hkF6p+vtqBf
26+
RUzmHCNtK7n5yQMhqJPiLLhVlyzApsUwtlNPvjIOn7a6wbHu5U/1nrYDlOicSATx
27+
QgUzTpG/aebRgw9E35figb4p
28+
-----END PRIVATE KEY-----
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from http.server import HTTPServer, BaseHTTPRequestHandler
2+
import ssl
3+
from io import BytesIO
4+
5+
6+
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
7+
def do_POST(self):
8+
content_length = int(self.headers["Content-Length"])
9+
body = self.rfile.read(content_length)
10+
print("\n\n")
11+
print(f"body: {body}")
12+
print("\n\n")
13+
self.send_response(200)
14+
self.end_headers()
15+
16+
17+
def main():
18+
context = ssl.SSLContext()
19+
context.load_cert_chain("localhost.crt", "localhost.key")
20+
21+
httpd = HTTPServer(("localhost", 8000), SimpleHTTPRequestHandler)
22+
httpd.socket = context.wrap_socket(
23+
httpd.socket,
24+
server_side=True,
25+
)
26+
httpd.serve_forever()
27+
28+
29+
if __name__ == "__main__":
30+
main()

0 commit comments

Comments
 (0)