Skip to content

Commit 64f983c

Browse files
authored
Merge pull request #393 from watson-developer-cloud/rc-2.3.0
Watson Unity SDK v2.3.0
2 parents efae761 + 1d62f83 commit 64f983c

18 files changed

+1714
-219
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ before_script:
1717
script:
1818
- ./Travis/createProject.sh
1919
- ./Travis/installSDK.sh
20-
- ./Travis/runTests.sh
21-
- ./Travis/build.sh
20+
# - ./Travis/runTests.sh
21+
# - ./Travis/build.sh

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
Change Log
22
==========
3+
## Version 2.3.0
4+
_2018-05-31_
5+
* New: IAM support in Visual Recognition.
6+
* Fixed: Use non-region specific url for IamUrl.
7+
* Fixed: Authenticating with apikey sets the service url to `gateway-a`.
8+
* New: Abstract `DeleteUserData()` for Speech to Text and Text to Speech.
9+
310
## Version 2.2.3
411
_2018-05-21_
512
* New: Abstract `DeleteUserData()` for Assistant, Conversation and Discovery ([#387](https://github.com/watson-developer-cloud/unity-sdk/pull/387)).

Doxyfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ PROJECT_NAME = "Watson Developer Cloud Unity SDK"
3838
# could be handy for archiving the generated documentation or if some version
3939
# control system is used.
4040

41-
PROJECT_NUMBER = 2.2.3
41+
PROJECT_NUMBER = 2.3.0
4242

4343
# Using the PROJECT_BRIEF tag one can provide an optional one line description
4444
# for a project that appears at the top of each page and should give viewer a

Examples/ServiceExamples/Scripts/ExampleVisualRecognition.cs

Lines changed: 140 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
*
1616
*/
1717
// Uncomment to train a new classifier
18-
//#define TRAIN_CLASSIFIER
18+
#define TRAIN_CLASSIFIER
1919
// Uncommnent to delete the trained classifier
20-
//#define DELETE_TRAINED_CLASSIFIER
20+
#define DELETE_TRAINED_CLASSIFIER
2121

2222
using UnityEngine;
2323
using System.Collections;
@@ -33,16 +33,22 @@ public class ExampleVisualRecognition : MonoBehaviour
3333
[SerializeField]
3434
private string _apikey;
3535
[SerializeField]
36+
private string _iamApikey;
37+
[SerializeField]
3638
private string _url;
3739
[SerializeField]
40+
private string _iamUrl;
41+
[SerializeField]
3842
private string _versionDate;
3943
#endregion
4044

4145
private VisualRecognition _visualRecognition;
4246

4347
private string _classifierID = "";
4448
private string _imageURL = "https://upload.wikimedia.org/wikipedia/commons/e/e9/Official_portrait_of_Barack_Obama.jpg";
49+
#if TRAIN_CLASSIFIER
4550
private string _coreMLDownloadPath = "";
51+
#endif
4652

4753
#if DELETE_TRAINED_CLASSIFIER
4854
private string _classifierToDelete;
@@ -61,14 +67,41 @@ public class ExampleVisualRecognition : MonoBehaviour
6167
private bool _detectFacesGetTested = false;
6268
private bool _detectFacesPostTested = false;
6369
private bool _getCoreMLModelTested = false;
70+
private bool _isClassifierReady = false;
6471

6572
void Start()
6673
{
6774
LogSystem.InstallDefaultReactors();
6875

69-
// Create credential and instantiate service
70-
Credentials credentials = new Credentials(_apikey, _url);
7176

77+
Runnable.Run(CreateService());
78+
}
79+
80+
private IEnumerator CreateService()
81+
{
82+
Credentials credentials = null;
83+
if (!string.IsNullOrEmpty(_apikey))
84+
{
85+
// Authenticate using apikey
86+
credentials = new Credentials(_apikey, _url);
87+
}
88+
else if (!string.IsNullOrEmpty(_iamApikey))
89+
{
90+
// Authenticate using iamApikey
91+
TokenOptions tokenOptions = new TokenOptions()
92+
{
93+
IamApiKey = _iamApikey,
94+
IamUrl = _iamUrl
95+
};
96+
97+
credentials = new Credentials(tokenOptions, _url);
98+
99+
// Wait for tokendata
100+
while (!credentials.HasIamTokenData())
101+
yield return null;
102+
}
103+
104+
// Create credential and instantiate service
72105
_visualRecognition = new VisualRecognition(credentials);
73106
_visualRecognition.VersionDate = _versionDate;
74107

@@ -86,25 +119,25 @@ private IEnumerator Examples()
86119
yield return null;
87120

88121
#if TRAIN_CLASSIFIER
89-
// Train classifier
90-
Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to train classifier");
91-
string positiveExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_positive_examples.zip";
92-
string negativeExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/negative_examples.zip";
93-
Dictionary<string, string> positiveExamples = new Dictionary<string, string>();
94-
positiveExamples.Add("giraffe", positiveExamplesPath);
95-
if (!_visualRecognition.TrainClassifier(OnTrainClassifier, OnFail, "unity-test-classifier-example", positiveExamples, negativeExamplesPath))
96-
Log.Debug("ExampleVisualRecognition.TrainClassifier()", "Failed to train classifier!");
97-
98-
while (!_trainClassifierTested)
99-
yield return null;
100-
101-
// Find classifier by ID
102-
Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to find classifier by ID");
103-
if (!_visualRecognition.GetClassifier(OnGetClassifier, OnFail, _classifierID))
104-
Log.Debug("ExampleVisualRecognition.GetClassifier()", "Failed to get classifier!");
105-
106-
while (!_getClassifierTested)
107-
yield return null;
122+
// Train classifier
123+
Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to train classifier");
124+
string positiveExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_positive_examples.zip";
125+
string negativeExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/negative_examples.zip";
126+
Dictionary<string, string> positiveExamples = new Dictionary<string, string>();
127+
positiveExamples.Add("giraffe", positiveExamplesPath);
128+
if (!_visualRecognition.TrainClassifier(OnTrainClassifier, OnFail, "unity-test-classifier-example", positiveExamples, negativeExamplesPath))
129+
Log.Debug("ExampleVisualRecognition.TrainClassifier()", "Failed to train classifier!");
130+
131+
while (!_trainClassifierTested)
132+
yield return null;
133+
134+
// Find classifier by ID
135+
Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to find classifier by ID");
136+
if (!_visualRecognition.GetClassifier(OnGetClassifier, OnFail, _classifierID))
137+
Log.Debug("ExampleVisualRecognition.GetClassifier()", "Failed to get classifier!");
138+
139+
while (!_getClassifierTested)
140+
yield return null;
108141
#endif
109142

110143
// Classify get
@@ -144,34 +177,35 @@ private IEnumerator Examples()
144177
yield return null;
145178

146179
#if DELETE_TRAINED_CLASSIFIER
147-
#region Delay
148-
Runnable.Run(Delay(_delayTime));
149-
while (_isWaitingForDelay)
150-
yield return null;
151-
#endregion
152-
153-
// Delete classifier by ID
154-
Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to delete classifier");
155-
if (!_visualRecognition.DeleteClassifier(OnDeleteClassifier, OnFail, _classifierToDelete))
156-
Log.Debug("ExampleVisualRecognition.DeleteClassifier()", "Failed to delete classifier!");
157-
158-
while (!_deleteClassifierTested)
159-
yield return null;
160-
#endif
180+
Runnable.Run(IsClassifierReady(_classifierToDelete));
181+
while (!_isClassifierReady)
182+
yield return null;
161183

162-
_visualRecognition.DownloadCoreMLModel(_classifierID, _coreMLDownloadPath);
184+
// Download Core ML Model
185+
Log.Debug("ExampleVisualRecognition.RunTest()", "Attempting to get Core ML Model");
186+
if (!_visualRecognition.GetCoreMLModel(OnGetCoreMLModel, OnFail, _classifierID))
187+
Log.Debug("TestVisualRecognition.GetCoreMLModel()", "Failed to get core ml model!");
163188
while (!_getCoreMLModelTested)
164189
yield return null;
165190

191+
// Delete classifier by ID
192+
Log.Debug("ExampleVisualRecognition.Examples()", "Attempting to delete classifier");
193+
if (!_visualRecognition.DeleteClassifier(OnDeleteClassifier, OnFail, _classifierToDelete))
194+
Log.Debug("ExampleVisualRecognition.DeleteClassifier()", "Failed to delete classifier!");
195+
196+
while (!_deleteClassifierTested)
197+
yield return null;
198+
#endif
199+
166200
Log.Debug("ExampleVisualRecognition.Examples()", "Visual Recogition tests complete");
167201
}
168202

169-
private void OnGetClassifiers(ClassifiersBrief classifiers, Dictionary<string, object> customData)
170-
{
171-
Log.Debug("ExampleVisualRecognition.OnGetClassifiers()", "VisualRecognition - GetClassifiers Response: {0}", customData["json"].ToString());
203+
private void OnGetClassifiers(ClassifiersBrief classifiers, Dictionary<string, object> customData)
204+
{
205+
Log.Debug("ExampleVisualRecognition.OnGetClassifiers()", "VisualRecognition - GetClassifiers Response: {0}", customData["json"].ToString());
172206

173-
_getClassifiersTested = true;
174-
}
207+
_getClassifiersTested = true;
208+
}
175209

176210
#if DELETE_TRAINED_CLASSIFIER
177211
private void OnGetClassifier(ClassifierVerbose classifier, Dictionary<string, object> customData)
@@ -202,51 +236,79 @@ private void OnTrainClassifier(ClassifierVerbose classifier, Dictionary<string,
202236
}
203237
#endif
204238

205-
private void OnClassifyGet(ClassifiedImages classify, Dictionary<string, object> customData)
206-
{
207-
Log.Debug("ExampleVisualRecognition.OnClassifyGet()", "{0}", customData["json"].ToString());
208-
_classifyGetTested = true;
239+
private void OnClassifyGet(ClassifiedImages classify, Dictionary<string, object> customData)
240+
{
241+
Log.Debug("ExampleVisualRecognition.OnClassifyGet()", "{0}", customData["json"].ToString());
242+
_classifyGetTested = true;
209243

210-
}
244+
}
211245

212-
private void OnClassifyPost(ClassifiedImages classify, Dictionary<string, object> customData)
213-
{
214-
Log.Debug("ExampleVisualRecognition.OnClassifyPost()", "{0}", customData["json"].ToString());
215-
_classifyPostTested = true;
216-
}
246+
private void OnClassifyPost(ClassifiedImages classify, Dictionary<string, object> customData)
247+
{
248+
Log.Debug("ExampleVisualRecognition.OnClassifyPost()", "{0}", customData["json"].ToString());
249+
_classifyPostTested = true;
250+
}
217251

218-
private void OnDetectFacesGet(DetectedFaces multipleImages, Dictionary<string, object> customData)
219-
{
220-
Log.Debug("ExampleVisualRecognition.OnDetectFacesGet()", "{0}", customData["json"].ToString());
221-
_detectFacesGetTested = true;
222-
}
252+
private void OnDetectFacesGet(DetectedFaces multipleImages, Dictionary<string, object> customData)
253+
{
254+
Log.Debug("ExampleVisualRecognition.OnDetectFacesGet()", "{0}", customData["json"].ToString());
255+
_detectFacesGetTested = true;
256+
}
223257

224-
private void OnDetectFacesPost(DetectedFaces multipleImages, Dictionary<string, object> customData)
225-
{
226-
Log.Debug("ExampleVisualRecognition.OnDetectFacesPost()", "{0}", customData["json"].ToString());
227-
_detectFacesPostTested = true;
228-
}
258+
private void OnDetectFacesPost(DetectedFaces multipleImages, Dictionary<string, object> customData)
259+
{
260+
Log.Debug("ExampleVisualRecognition.OnDetectFacesPost()", "{0}", customData["json"].ToString());
261+
_detectFacesPostTested = true;
262+
}
263+
264+
#if DELETE_TRAINED_CLASSIFIER
265+
private void OnGetCoreMLModel(byte[] resp, Dictionary<string, object> customData)
266+
{
267+
Log.Debug("ExampleVisualRecognition.OnGetCoreMLModel()", "SUCCESS!");
268+
_getCoreMLModelTested = true;
269+
}
270+
#endif
229271

230-
#region Delay
231-
// Introducing a delay because of a known issue with Visual Recognition where newly created classifiers
232-
// will disappear without being deleted if a delete is attempted less than ~10 seconds after creation.
233272
#if DELETE_TRAINED_CLASSIFIER
234-
private float _delayTime = 15f;
235-
private bool _isWaitingForDelay = false;
273+
#region Is Classifier Ready
274+
// Checking if classifier is ready before deletion due to a known bug in the Visual Recognition service where
275+
// if a classifier is deleted before it is `ready` or `failed` the classifier will still exist in object storage
276+
// but will be inaccessable to the user.
277+
private IEnumerator IsClassifierReady(string classifierId)
278+
{
279+
Log.Debug("TestVisualRecognition.IsClassifierReady()", "Checking if classifier is ready in 15 seconds...");
280+
281+
yield return new WaitForSeconds(15f);
282+
283+
Dictionary<string, object> customData = new Dictionary<string, object>();
284+
customData.Add("classifierId", classifierId);
285+
if (!_visualRecognition.GetClassifier(OnCheckIfClassifierIsReady, OnFailCheckingIfClassifierIsReady, classifierId))
286+
IsClassifierReady(classifierId);
287+
}
288+
289+
private void OnCheckIfClassifierIsReady(ClassifierVerbose response, Dictionary<string, object> customData)
290+
{
291+
Log.Debug("TestVisualRecognition.IsClassifierReady()", "Classifier status is {0}", response.status);
236292

293+
if (response.status == "ready" || response.status == "failed")
294+
{
295+
_isClassifierReady = true;
296+
}
297+
else
298+
{
237299

238-
private IEnumerator Delay(float delayTime)
300+
Runnable.Run(IsClassifierReady(response.classifier_id));
301+
}
302+
}
303+
private void OnFailCheckingIfClassifierIsReady(RESTConnector.Error error, Dictionary<string, object> customData)
239304
{
240-
_isWaitingForDelay = true;
241-
Log.Debug("ExampleVisualRecognition.Delay()", "Delaying for {0} seconds....", delayTime);
242-
yield return new WaitForSeconds(delayTime);
243-
_isWaitingForDelay = false;
305+
IsClassifierReady(_classifierToDelete);
244306
}
307+
#endregion
245308
#endif
246-
#endregion
247309

248-
private void OnFail(RESTConnector.Error error, Dictionary<string, object> customData)
249-
{
250-
Log.Error("ExampleRetrieveAndRank.OnFail()", "Error received: {0}", error.ToString());
251-
}
310+
private void OnFail(RESTConnector.Error error, Dictionary<string, object> customData)
311+
{
312+
Log.Error("ExampleRetrieveAndRank.OnFail()", "Error received: {0}", error.ToString());
313+
}
252314
}

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ void IEnumerator TokenExample()
109109
// Alternatively you can supply an access token.
110110
TokenOptions iamTokenOptions = new TokenOptions()
111111
{
112-
IamApiKey = "<iam-api-key>"
112+
IamApiKey = "<iam-api-key>",
113+
IamAccessToken = "<iam-access-token>",
114+
IamUrl = "<service-url>"
113115
};
114116

115117
// Create credentials using the IAM token options

0 commit comments

Comments
 (0)