Skip to content

Commit 8ff7fa4

Browse files
author
Kyle Bridburg
authored
AISDK-198: Add sentiment analysis client to java SDK (#44)
1 parent fa9e089 commit 8ff7fa4

23 files changed

+1512
-11
lines changed

examples/AsyncTranscribeLocalMediaFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class AsyncTranscribeLocalMediaFile {
1515

1616
public static void main(String[] args) {
1717
// Assign your access token to a String
18-
String accessToken = "your_access_token";
18+
String accessToken = "<YOUR_ACCESS_TOKEN>";
1919

2020
// Initialize the ApiClient with your access token
2121
ApiClient apiClient = new ApiClient(accessToken);

examples/AsyncTranscribeMediaUrl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class AsyncTranscribeMediaUrl {
1515

1616
public static void main(String[] args) {
1717
// Assign your access token to a String
18-
String accessToken = "your_access_token";
18+
String accessToken = "<YOUR_ACCESS_TOKEN>";
1919

2020
// Initialize the ApiClient with your access token
2121
ApiClient apiClient = new ApiClient(accessToken);

examples/CustomVocabularies.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class CustomVocabularies {
1212

1313
public static void main(String[] args) {
1414
// Assign your access token to a String
15-
String accessToken = "your_access_token";
15+
String accessToken = "<YOUR_ACCESS_TOKEN>";
1616

1717
// Initialize the CustomVocabulariesClient with your access token
1818
CustomVocabulariesClient customVocabulariesClient = new CustomVocabulariesClient(accessToken);

examples/SentimentAnalysis.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package ai.rev;
2+
3+
import ai.rev.sentimentanalysis.models.SentimentAnalysisJobOptions;
4+
import ai.rev.sentimentanalysis.models.SentimentAnalysisJob;
5+
import ai.rev.sentimentanalysis.models.SentimentAnalysisJobStatus;
6+
import ai.rev.sentimentanalysis.models.SentimentAnalysisResult;
7+
import ai.rev.sentimentanalysis.SentimentAnalysisClient;
8+
9+
import java.io.IOException;
10+
import java.util.Arrays;
11+
12+
public class SentimentAnalysis {
13+
14+
public static void main(String[] args) {
15+
// Assign your access token to a String
16+
String accessToken = "<YOUR_ACCESS_TOKEN>";
17+
18+
// Initialize the SentimentAnalysisClient with your access token
19+
SentimentAnalysisClient sentimentAnalysisClient = new SentimentAnalysisClient(accessToken);
20+
21+
// Create SentimentAnalysisJobOptions for your submission
22+
SentimentAnalysisJobOptions jobOptions = new SentimentAnalysisJobOptions();
23+
String textSubmission = "An orange is a fruit of various citrus species in the family Rutaceae " +
24+
"it primarily refers to Citrus sinensis which is also called sweet orange, " +
25+
"to distinguish it from the related Citrus aurantium, referred to as bitter orange. " +
26+
"The sweet orange reproduces asexually. varieties of sweet orange arise through mutations. " +
27+
"The orange is a hybrid between pomelo (Citrus maxima) and mandarin (Citrus reticulata). " +
28+
"The chloroplast genome, and therefore the maternal line, is that of pomelo. " +
29+
"The sweet orange has had its full genome sequenced.";
30+
31+
32+
SentimentAnalysisJob submittedJob;
33+
try {
34+
submittedJob = sentimentAnalysisClient.submitJobText(textSubmission, jobOptions);
35+
} catch (IOException e) {
36+
throw new RuntimeException("Failed to submit sentiment analysis job " + e.getMessage());
37+
}
38+
39+
String jobId = submittedJob.getJobId();
40+
System.out.println("Job Id: " + jobId);
41+
System.out.println("Job Status: " + submittedJob.getJobStatus());
42+
System.out.println("Created On: " + submittedJob.getCreatedOn());
43+
44+
// Waits 5 seconds between each status check to see if job is complete
45+
boolean isProcessingComplete = false;
46+
while (!isProcessingComplete) {
47+
SentimentAnalysisJob retrievedJob;
48+
try {
49+
retrievedJob = sentimentAnalysisClient.getJobDetails(jobId);
50+
} catch (IOException e) {
51+
throw new RuntimeException(
52+
"Failed to retrieve sentiment analysis job info ["
53+
+ jobId
54+
+ "] "
55+
+ e.getMessage());
56+
}
57+
58+
SentimentAnalysisJobStatus status = retrievedJob.getJobStatus();
59+
if (status == SentimentAnalysisJobStatus.COMPLETED
60+
|| status == SentimentAnalysisJobStatus.FAILED) {
61+
System.out.println(
62+
"Processing for "
63+
+ jobId
64+
+ ": "
65+
+ status);
66+
isProcessingComplete = true;
67+
} else {
68+
try {
69+
Thread.sleep(5000);
70+
} catch (InterruptedException e) {
71+
e.printStackTrace();
72+
}
73+
}
74+
}
75+
76+
try {
77+
SentimentAnalysisResult result =
78+
sentimentAnalysisClient.getResultObject(jobId);
79+
} catch (IOException e) {
80+
e.printStackTrace();
81+
}
82+
83+
/*
84+
* The job can now be deleted. Deleting the job will remove ALL information
85+
* about the job from the Rev AI servers. Subsequent requests to Rev AI that
86+
* use the deleted jobs Id will return 404's.
87+
*/
88+
// apiClient.deleteJob(jobId);
89+
}
90+
}

examples/StreamingFromLocalFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class StreamingFromLocalFile {
1919

2020
public static void main(String[] args) throws InterruptedException {
2121
// Assign your access token to a String
22-
String accessToken = "your_access_token";
22+
String accessToken = "<YOUR_ACCESS_TOKEN>";
2323

2424
// Configure the streaming content type
2525
StreamContentType streamContentType = new StreamContentType();

examples/TopicExtraction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class TopicExtraction {
1313

1414
public static void main(String[] args) {
1515
// Assign your access token to a String
16-
String accessToken = "your_access_token";
16+
String accessToken = "<YOUR_ACCESS_TOKEN>";
1717

1818
// Initialize the TopicExtractionClient with your access token
1919
TopicExtractionClient topicExtractionClient = new TopicExtractionClient(accessToken);
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
package ai.rev.sentimentanalysis;
2+
3+
import ai.rev.helpers.ClientHelper;
4+
import ai.rev.speechtotext.ApiClient;
5+
import ai.rev.speechtotext.models.asynchronous.RevAiJob;
6+
import ai.rev.speechtotext.models.asynchronous.RevAiJobOptions;
7+
import ai.rev.sentimentanalysis.models.Sentiment;
8+
import ai.rev.sentimentanalysis.models.SentimentAnalysisJob;
9+
import ai.rev.sentimentanalysis.models.SentimentAnalysisJobOptions;
10+
import ai.rev.sentimentanalysis.models.SentimentAnalysisResult;
11+
import ai.rev.speechtotext.models.asynchronous.RevAiTranscript;
12+
import okhttp3.OkHttpClient;
13+
import retrofit2.Retrofit;
14+
15+
import java.io.IOException;
16+
import java.util.HashMap;
17+
import java.util.List;
18+
import java.util.Map;
19+
20+
/**
21+
* The SentimentAnalysisClient object provides methods to send and retrieve information from all the
22+
* Rev AI Sentiment Analysis API endpoints using the Retrofit HTTP client.
23+
*/
24+
public class SentimentAnalysisClient {
25+
26+
private OkHttpClient client;
27+
28+
/** Interface that SentimentAnalysisClient methods use to make requests */
29+
public SentimentAnalysisInterface apiInterface;
30+
31+
/**
32+
* Constructs the API client used to send HTTP requests to Rev AI. The user access token can be
33+
* generated on the website at <a
34+
* href="https://www.rev.ai/access_token">https://www.rev.ai/access_token</a>.
35+
*
36+
* @param accessToken Rev AI authorization token associate with the account.
37+
* @throws IllegalArgumentException If the access token is null or empty.
38+
*/
39+
public SentimentAnalysisClient(String accessToken) {
40+
if (accessToken == null || accessToken.isEmpty()) {
41+
throw new IllegalArgumentException("Access token must be provided");
42+
}
43+
this.client = ClientHelper.createOkHttpClient(accessToken);
44+
Retrofit retrofit = ClientHelper.createRetrofitInstance(client, "sentiment_analysis", "v1");
45+
this.apiInterface = retrofit.create(SentimentAnalysisInterface.class);
46+
}
47+
48+
/** Manually closes the connection when the code is running in a JVM */
49+
public void closeConnection() {
50+
client.dispatcher().executorService().shutdown();
51+
client.connectionPool().evictAll();
52+
}
53+
54+
/**
55+
* This method sends a GET request to the /jobs endpoint and returns a list of {@link SentimentAnalysisJob}
56+
* objects.
57+
*
58+
* @param limit The maximum number of jobs to return. The default is 100, max is 1000.
59+
* @param startingAfter The job ID at which the list begins.
60+
* @return A list of {@link SentimentAnalysisJob} objects.
61+
* @throws IOException If the response has a status code > 399.
62+
* @see SentimentAnalysisJob
63+
* @see <a
64+
* href="https://docs.rev.ai/api/sentiment-analysis/reference/#operation/GetListOfSentimentAnalysisJobs">https://docs.rev.ai/api/sentiment-analysis/reference/#operation/GetListOfSentimentAnalysisJobs</a>
65+
*/
66+
public List<SentimentAnalysisJob> getListOfJobs(Integer limit, String startingAfter) throws IOException {
67+
Map<String, String> options = new HashMap<>();
68+
if (startingAfter != null) {
69+
options.put("starting_after", startingAfter);
70+
}
71+
if (limit != null) {
72+
options.put("limit", String.valueOf(limit));
73+
}
74+
return apiInterface.getListOfJobs(options).execute().body();
75+
}
76+
77+
/**
78+
* Overload of {@link SentimentAnalysisClient#getListOfJobs(Integer, String)} without the optional startingAfter
79+
* parameter.
80+
*
81+
* @param limit The maximum number of jobs to return. The default is 100, max is 1000.
82+
* @return A list of {@link SentimentAnalysisJob} objects.
83+
* @throws IOException If the response has a status code > 399.
84+
*/
85+
public List<SentimentAnalysisJob> getListOfJobs(Integer limit) throws IOException {
86+
return getListOfJobs(limit, null);
87+
}
88+
89+
/**
90+
* Overload of {@link SentimentAnalysisClient#getListOfJobs(Integer, String)} without the optional limit
91+
* parameter.
92+
*
93+
* @param startingAfter The job ID at which the list begins.
94+
* @return A list of {@link SentimentAnalysisJob} objects.
95+
* @throws IOException If the response has a status code > 399.
96+
*/
97+
public List<SentimentAnalysisJob> getListOfJobs(String startingAfter) throws IOException {
98+
return getListOfJobs(null, startingAfter);
99+
}
100+
101+
/**
102+
* Overload of {@link SentimentAnalysisClient#getListOfJobs(Integer, String)} without the optional limit and
103+
* startingAfter parameter.
104+
*
105+
* @return A list of {@link SentimentAnalysisJob} objects.
106+
* @throws IOException If the response has a status code > 399.
107+
*/
108+
public List<SentimentAnalysisJob> getListOfJobs() throws IOException {
109+
return getListOfJobs(null, null);
110+
}
111+
112+
/**
113+
* This method sends a GET request to the /jobs/{id} endpoint and returns a {@link SentimentAnalysisJob}
114+
* object.
115+
*
116+
* @param id The ID of the job to return an object for.
117+
* @return A {@link SentimentAnalysisJob} object.
118+
* @throws IOException If the response has a status code > 399.
119+
* @throws IllegalArgumentException If the job ID is null.
120+
*/
121+
public SentimentAnalysisJob getJobDetails(String id) throws IOException {
122+
if (id == null || id.isEmpty()) {
123+
throw new IllegalArgumentException("Job ID must be provided");
124+
}
125+
return apiInterface.getJobDetails(id).execute().body();
126+
}
127+
128+
/**
129+
* This method sends a DELETE request to the /jobs/{id} endpoint.
130+
*
131+
* @param id The Id of the job to be deleted.
132+
* @throws IOException If the response has a status code > 399.
133+
* @throws IllegalArgumentException If the job ID is null.
134+
* @see <a
135+
* href="https://docs.rev.ai/api/sentiment-analysis/reference/#operation/DeleteSentimentAnalysisJobById">https://docs.rev.ai/api/sentiment-analysis/reference/#operation/DeleteSentimentAnalysisJobById</a>
136+
*/
137+
public void deleteJob(String id) throws IOException {
138+
if (id == null) {
139+
throw new IllegalArgumentException("Job ID must be provided");
140+
}
141+
apiInterface.deleteJob(id).execute();
142+
}
143+
144+
/**
145+
* The method sends a GET request to the /jobs/{id}/result endpoint and returns a {@link
146+
* SentimentAnalysisResult} object.
147+
*
148+
* @param id The ID of the job to return a result for.
149+
* @return SentimentAnalysisResult The result object.
150+
* @throws IOException If the response has a status code > 399.
151+
* @see SentimentAnalysisResult
152+
*/
153+
public SentimentAnalysisResult getResultObject(String id, Sentiment filterFor) throws IOException {
154+
Map<String, Object> options = new HashMap<>();
155+
options.put("filter_for", filterFor.getSentiment());
156+
return apiInterface.getResultObject(id, options).execute().body();
157+
}
158+
159+
/**
160+
* The method sends a GET request to the /jobs/{id}/result endpoint and returns a {@link
161+
* SentimentAnalysisResult} object.
162+
*
163+
* @param id The ID of the job to return a result for.
164+
* @return SentimentAnalysisResult The result object.
165+
* @throws IOException If the response has a status code > 399.
166+
* @see SentimentAnalysisResult
167+
*/
168+
public SentimentAnalysisResult getResultObject(String id) throws IOException {
169+
Map<String, Object> options = new HashMap<>();
170+
return apiInterface.getResultObject(id, options).execute().body();
171+
}
172+
173+
/**
174+
* The method sends a POST request to the /jobs endpoint, starts a sentiment analysis job for the
175+
* provided text and returns a {@link SentimentAnalysisJob} object.
176+
*
177+
* @param text Text to have sentiments detected on it.
178+
* @param options The sentiment analysis options associated with this job.
179+
* @return SentimentAnalysisJob A representation of the sentiment analysis job.
180+
* @throws IOException If the response has a status code > 399.
181+
* @throws IllegalArgumentException if the text is null.
182+
* @see SentimentAnalysisJob
183+
* @see <a
184+
* href="https://docs.rev.ai/api/sentiment-analysis/reference/#operation/SubmitSentimentAnalysisJob">https://docs.rev.ai/api/sentiment-analysis/reference/#operation/SubmitSentimentAnalysisJob</a>
185+
*/
186+
public SentimentAnalysisJob submitJobText(String text, SentimentAnalysisJobOptions options) throws IOException {
187+
if (text == null) {
188+
throw new IllegalArgumentException("Text must be provided");
189+
}
190+
if (options == null) {
191+
options = new SentimentAnalysisJobOptions();
192+
}
193+
options.setText(text);
194+
return apiInterface.submitJob(options).execute().body();
195+
}
196+
197+
/**
198+
* An overload of {@link SentimentAnalysisClient#submitJobText(String, SentimentAnalysisJobOptions)} without the additional
199+
* sentiment analysis options.
200+
*
201+
* @param text Text to have sentiments detected on it.
202+
* @return SentimentAnalysisJob A representation of the sentiment analysis job.
203+
* @throws IOException If the response has a status code > 399.
204+
* @throws IllegalArgumentException if the text is null.
205+
* @see SentimentAnalysisJob
206+
* @see SentimentAnalysisClient#submitJobText(String, SentimentAnalysisJobOptions)
207+
*/
208+
public SentimentAnalysisJob submitJobText(String text) throws IOException {
209+
return submitJobText(text, null);
210+
}
211+
212+
/**
213+
* The method sends a POST request to the /jobs endpoint, starts a sentiment analysis job for the
214+
* provided RevAiTranscript and returns a {@link SentimentAnalysisJob} object.
215+
*
216+
* @param json RevAiTranscript to submit for sentiment analysis
217+
* @param options The sentiment analysis options associated with this job.
218+
* @return SentimentAnalysisJob A representation of the sentiment analysis job.
219+
* @throws IOException If the response has a status code > 399.
220+
* @throws IllegalArgumentException if the json is null.
221+
* @see SentimentAnalysisJob
222+
* @see <a
223+
* href="https://docs.rev.ai/api/sentiment-analysis/reference/#operation/SubmitSentimentAnalysisJob">https://docs.rev.ai/api/sentiment-analysis/reference/#operation/SubmitSentimentAnalysisJob</a>
224+
*/
225+
public SentimentAnalysisJob submitJobJson(RevAiTranscript json, SentimentAnalysisJobOptions options) throws IOException {
226+
if (json == null) {
227+
throw new IllegalArgumentException("Json must be provided");
228+
}
229+
if (options == null) {
230+
options = new SentimentAnalysisJobOptions();
231+
}
232+
options.setJson(json);
233+
return apiInterface.submitJob(options).execute().body();
234+
}
235+
236+
/**
237+
* An overload of {@link SentimentAnalysisClient#submitJobText(String, SentimentAnalysisJobOptions)} without the additional
238+
* sentiment analysis options.
239+
*
240+
* @param json RevAiTranscript to submit for sentiment analysis
241+
* @return SentimentAnalysisJob A representation of the sentiment analysis job.
242+
* @throws IOException If the response has a status code > 399.
243+
* @throws IllegalArgumentException if the json is null.
244+
* @see SentimentAnalysisJob
245+
* @see SentimentAnalysisClient#submitJobJson(RevAiTranscript, SentimentAnalysisJobOptions)
246+
*/
247+
public SentimentAnalysisJob submitJobJson(RevAiTranscript json) throws IOException {
248+
return submitJobJson(json, null);
249+
}
250+
}
251+

0 commit comments

Comments
 (0)