Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added a deepgramAudioSummary() Function using Java #91

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions java/deepgram_audio_summary/Index.java
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();
ffex marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* 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;
}
59 changes: 59 additions & 0 deletions java/deepgram_audio_summary/README.md
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.
4 changes: 4 additions & 0 deletions java/deepgram_audio_summary/deps.gradle
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'
}