forked from open-runtimes/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request open-runtimes#91 from ffex/feat-4498-deepgram-audi…
…o-summary added a deepgramAudioSummary() Function using Java
- Loading branch information
Showing
3 changed files
with
245 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
import java.util.Collections; | ||
import java.util.stream.Collectors; | ||
import java.util.*; | ||
import java.util.stream.*; | ||
import java.net.HttpURLConnection; | ||
import java.net.ProtocolException; | ||
import java.net.URL; | ||
import java.io.BufferedReader; | ||
import java.io.InputStreamReader; | ||
import java.io.OutputStream; | ||
|
||
import com.google.gson.Gson; | ||
import org.apache.commons.validator.routines.UrlValidator; | ||
|
||
final Gson gson=new Gson(); | ||
|
||
public RuntimeResponse main(RuntimeRequest req,RuntimeResponse res)throws Exception{ | ||
// Validate that values present in the request are not empty (payload, variables) | ||
RuntimeResponse errorResponse=checkEmptyPayloadAndVariables(req,res); | ||
if(errorResponse!=null){ | ||
return errorResponse; | ||
} | ||
|
||
// Validate the requested payload (URL) | ||
String payloadString=req.getPayload().toString(); | ||
|
||
errorResponse=validatePayload(payloadString,res); | ||
if(errorResponse!=null){ | ||
return errorResponse; | ||
} | ||
|
||
Map<String, Object> payload = gson.fromJson(payloadString,Map.class); | ||
|
||
// Get file url from payload | ||
String fileurl=payload.get("fileUrl").toString(); | ||
|
||
// Name API key is not empty | ||
String apiKeyVariable="DEEPGRAM_SECRET_KEY"; | ||
|
||
errorResponse=checkEmptyAPIKey(req,res,apiKeyVariable); | ||
if(errorResponse!=null){ | ||
return errorResponse; | ||
} | ||
|
||
String apiKey=req.getVariables().get(apiKeyVariable).toString(); | ||
|
||
String deepgramData=""; | ||
Map<String, Object> responseData=new HashMap<>(); | ||
|
||
try{ | ||
deepgramData=generateSummary(fileurl,apiKey); | ||
}catch(Exception e){ | ||
responseData.put("success",false); | ||
responseData.put("message","Something went wrong while generating the summary, please check with the developers. Error: "+e.getMessage());//TODO | ||
return res.json(responseData); | ||
} | ||
responseData.put("success",true); | ||
responseData.put("deepgramData",deepgramData); | ||
|
||
return res.json(responseData); | ||
} | ||
|
||
|
||
/** | ||
* This method will send a POST request to the specified endpoint and return the Deepgram's response | ||
* | ||
* @param requestBody is the Request Body for the POST request containing the URL to the wav file to Summarize | ||
* @param apiKey is the access token used by Deepgram to summarize | ||
* @return the Deepgram's response to the POST request | ||
* @throws Exception in case of malformed URL, I/O exception, etc. | ||
*/ | ||
private String generateSummary(String requestBody,String apiKey)throws Exception{ | ||
String endpointUrl="https://api.deepgram.com/v1/listen?summarize=true&punctuate=true"; | ||
URL url=new URL(endpointUrl); | ||
HttpURLConnection con=(HttpURLConnection)url.openConnection(); | ||
|
||
con.setRequestMethod("POST"); | ||
con.setRequestProperty("Content-Type","application/json"); | ||
con.setRequestProperty("Authorization","Token "+apiKey); | ||
|
||
con.setDoOutput(true); | ||
|
||
//prepare request body | ||
requestBody="{\"url\":\""+requestBody+"\"}"; | ||
|
||
OutputStream os=con.getOutputStream(); | ||
byte[] input=requestBody.getBytes("utf-8"); | ||
os.write(input,0,input.length); | ||
|
||
StringBuilder response=new StringBuilder(); | ||
|
||
BufferedReader br=new BufferedReader(new InputStreamReader(con.getInputStream(),"utf-8")); | ||
String responseLine=null; | ||
while((responseLine=br.readLine())!=null){ | ||
response.append(responseLine.trim()); | ||
} | ||
|
||
br.close(); | ||
con.disconnect(); | ||
|
||
return response.toString(); | ||
} | ||
|
||
/** | ||
* This method validates that a non-empty API key is present in variables | ||
* | ||
* @param req is the received POST request | ||
* @return null if non-empty API key is present, otherwise an error response | ||
*/ | ||
private RuntimeResponse checkEmptyAPIKey(RuntimeRequest req,RuntimeResponse res,String apiKeyVariable){ | ||
Map<String, String> variables=req.getVariables(); | ||
|
||
if(!variables.containsKey(apiKeyVariable) ||variables.get(apiKeyVariable)==null||variables.get(apiKeyVariable).trim().isEmpty()){ | ||
Map<String, Object> responseData=new HashMap<>(); | ||
responseData.put("success",false); | ||
responseData.put("message","Please pass a non-empty API Key "+apiKeyVariable+" for Deepgram"); | ||
|
||
return res.json(responseData); | ||
} | ||
|
||
return null; | ||
} | ||
/** | ||
* This method validates that non-empty URL is present in the payload | ||
* | ||
* @param payload is the object that contains the URL | ||
* @return null if payload is valid, otherwise an error response | ||
*/ | ||
private RuntimeResponse validatePayload(String payloadString,RuntimeResponse res){ | ||
Map<String, Object> responseData=new HashMap<>(); | ||
Map<String, Object> payload=new HashMap<>();; | ||
try{ | ||
payload=gson.fromJson(payloadString,Map.class); | ||
} catch (Exception e) { | ||
responseData.put("success",false); | ||
responseData.put("message","The payload is invalid. Example of valid payload:{\"fileUrl\": \"...\"}"); | ||
return res.json(responseData); | ||
} | ||
|
||
// Validate that payload has fileUrl | ||
if(!payload.containsKey("fileUrl")){ | ||
responseData.put("success",false); | ||
responseData.put("message","Please provide a valid file URL"); | ||
return res.json(responseData); | ||
} | ||
|
||
String fileUrl=payload.get("fileUrl").toString(); | ||
|
||
// Validate the URL | ||
UrlValidator urlValidator=new UrlValidator(); | ||
if(!urlValidator.isValid(fileUrl)){ | ||
responseData.put("success",false); | ||
responseData.put("message","Provided URL: "+fileUrl+" is not valid, please provide a valid, correctly formed URL"); | ||
return res.json(responseData); | ||
} | ||
|
||
return null; | ||
} | ||
/** | ||
* This function will validate that the payload and variables are non-empty in the request | ||
* | ||
* @param req is the received POST request | ||
* @return null is nothing is empty, otherwise an error response | ||
*/ | ||
private RuntimeResponse checkEmptyPayloadAndVariables(RuntimeRequest req,RuntimeResponse res){ | ||
|
||
Map<String, Object> responseData=new HashMap<>(); | ||
|
||
if(req.getPayload()==null||req.getPayload().trim().isEmpty()||req.getPayload().trim().equals("{}")){ | ||
responseData.put("success",false); | ||
responseData.put("message","Payload is empty, expected a payload with provider and URL"); | ||
return res.json(responseData); | ||
|
||
} | ||
if(req.getVariables()==null){ | ||
responseData.put("success",false); | ||
responseData.put("message","Empty function variables found. You need to pass an API key for the provider"); | ||
return res.json(responseData); | ||
} | ||
|
||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# 💻 Deepgram Audio Summary | ||
|
||
A Java Cloud Function for generating a summary using [Deepgram](https://deepgram.com/) | ||
|
||
_Deepgram Example input:_ | ||
|
||
```json | ||
{"fileUrl": "https://static.deepgram.com/examples/interview_speech-analytics.wav"} | ||
``` | ||
_Deepgram Example output:_ | ||
|
||
```json | ||
{ | ||
"success": true, | ||
"deepgramData": {} | ||
} | ||
``` | ||
|
||
_Error Example output:_ | ||
|
||
```json | ||
{ | ||
"success": false, | ||
"message":"Please provide a valid file URL." | ||
} | ||
``` | ||
|
||
|
||
## 📝 Variables | ||
|
||
List of variables used by this cloud function. These must be passed within 'variables' section of the request: | ||
|
||
**DEEPGRAM_SECRET_KEY** - This API key would be the access token used by Deepgram for generating the Summary. | ||
|
||
## 🚀 Deployment | ||
|
||
1. Clone this repository, and enter this function folder: | ||
|
||
``` | ||
$ git clone https://github.com/open-runtimes/examples.git && cd examples | ||
$ cd java/deepgram_audio_summary | ||
``` | ||
|
||
2. Enter this function folder and build the code: | ||
``` | ||
docker run -e INTERNAL_RUNTIME_ENTRYPOINT=Index.java --rm --interactive --tty --volume $PWD:/usr/code openruntimes/java:v2-11.0 sh /usr/local/src/build.sh | ||
``` | ||
As a result, a `code.tar.gz` file will be generated. | ||
|
||
3. Start the Open Runtime: | ||
``` | ||
docker run -p 3000:3000 -e INTERNAL_RUNTIME_KEY=secret-key --rm --interactive --tty --volume $PWD/code.tar.gz:/tmp/code.tar.gz:ro openruntimes/java:v2-11.0 sh /usr/local/src/start.sh | ||
``` | ||
|
||
Your function is now listening on port `3000`, and you can execute it by sending `POST` request with appropriate authorization headers. To learn more about runtime, you can visit Java runtime [README](https://github.com/open-runtimes/open-runtimes/tree/main/runtimes/java-11.0). | ||
|
||
## 📝 Notes | ||
- This function is designed for use with Appwrite Cloud Functions. You can learn more about it in [Appwrite docs](https://appwrite.io/docs/functions). | ||
- This example is compatible with Java 11.0. Other versions may work but are not guarenteed to work as they haven't been tested. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
dependencies { | ||
implementation 'com.google.code.gson:gson:2.9.0' | ||
implementation 'commons-validator:commons-validator:1.7' | ||
} |