From e5c5f4f7df7b8549e2d5b32a0a3555372d45ef5e Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Tue, 1 Oct 2019 15:20:27 -0500 Subject: [PATCH] refactor(Visual Recognition V4): Update based on the latest API definitions to remove `Base` files --- .../ServiceExample.cs | 4 +- .../IVisualRecognitionService.cs | 2 +- .../Model/AnalyzeResponse.cs | 2 +- .../Model/BaseCollection.cs | 66 - .../Model/BaseObject.cs | 40 - .../Model/Collection.cs | 2 +- .../Model/CollectionsList.cs | 2 +- .../Model/Error.cs | 2 +- .../Model/ErrorTarget.cs | 2 +- .../Model/ImageDetailsList.cs | 2 +- .../Model/{BaseError.cs => Warning.cs} | 4 +- .../VisualRecognitionService.cs | 1991 ++++++++--------- ...isualRecognitionServiceIntegrationTests.cs | 4 +- 13 files changed, 1008 insertions(+), 1115 deletions(-) delete mode 100644 src/IBM.Watson.VisualRecognition.v4/Model/BaseCollection.cs delete mode 100644 src/IBM.Watson.VisualRecognition.v4/Model/BaseObject.cs rename src/IBM.Watson.VisualRecognition.v4/Model/{BaseError.cs => Warning.cs} (95%) diff --git a/examples/IBM.Watson.VisualRecognition.v4.Examples/ServiceExample.cs b/examples/IBM.Watson.VisualRecognition.v4.Examples/ServiceExample.cs index b74da57601..1a8bb85e8b 100644 --- a/examples/IBM.Watson.VisualRecognition.v4.Examples/ServiceExample.cs +++ b/examples/IBM.Watson.VisualRecognition.v4.Examples/ServiceExample.cs @@ -280,9 +280,9 @@ public void AddTrainingData() VisualRecognitionService service = new VisualRecognitionService("2019-02-11", authenticator); - List objects = new List() + List objects = new List() { - new BaseObject() + new TrainingDataObject() { _Object = "2018-Fit", Location = new Location() diff --git a/src/IBM.Watson.VisualRecognition.v4/IVisualRecognitionService.cs b/src/IBM.Watson.VisualRecognition.v4/IVisualRecognitionService.cs index 122b171ab3..d1d9a03f1b 100644 --- a/src/IBM.Watson.VisualRecognition.v4/IVisualRecognitionService.cs +++ b/src/IBM.Watson.VisualRecognition.v4/IVisualRecognitionService.cs @@ -36,7 +36,7 @@ public partial interface IVisualRecognitionService DetailedResponse DeleteImage(string collectionId, string imageId); DetailedResponse GetJpegImage(string collectionId, string imageId, string size = null); DetailedResponse Train(string collectionId); - DetailedResponse AddImageTrainingData(string collectionId, string imageId, List objects = null); + DetailedResponse AddImageTrainingData(string collectionId, string imageId, List objects = null); DetailedResponse DeleteUserData(string customerId); } } diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/AnalyzeResponse.cs b/src/IBM.Watson.VisualRecognition.v4/Model/AnalyzeResponse.cs index dae5c67328..587bb3dff4 100644 --- a/src/IBM.Watson.VisualRecognition.v4/Model/AnalyzeResponse.cs +++ b/src/IBM.Watson.VisualRecognition.v4/Model/AnalyzeResponse.cs @@ -34,7 +34,7 @@ public class AnalyzeResponse /// Information about what might cause less than optimal output. /// [JsonProperty("warnings", NullValueHandling = NullValueHandling.Ignore)] - public List Warnings { get; set; } + public List Warnings { get; set; } /// /// A unique identifier of the request. Included only when an error or warning is returned. /// diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/BaseCollection.cs b/src/IBM.Watson.VisualRecognition.v4/Model/BaseCollection.cs deleted file mode 100644 index 4f1b3d283e..0000000000 --- a/src/IBM.Watson.VisualRecognition.v4/Model/BaseCollection.cs +++ /dev/null @@ -1,66 +0,0 @@ -/** -* (C) Copyright IBM Corp. 2018, 2019. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -using Newtonsoft.Json; -using System; - -namespace IBM.Watson.VisualRecognition.v4.Model -{ - /// - /// Base details about a collection. - /// - public class BaseCollection - { - /// - /// The identifier of the collection. - /// - [JsonProperty("collection_id", NullValueHandling = NullValueHandling.Ignore)] - public virtual string CollectionId { get; private set; } - /// - /// The name of the collection. The name can contain alphanumeric, underscore, hyphen, and dot characters. It - /// cannot begin with the reserved prefix `sys-`. - /// - [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] - public string Name { get; set; } - /// - /// The description of the collection. - /// - [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] - public string Description { get; set; } - /// - /// Date and time in Coordinated Universal Time (UTC) that the collection was created. - /// - [JsonProperty("created", NullValueHandling = NullValueHandling.Ignore)] - public virtual DateTime? Created { get; private set; } - /// - /// Date and time in Coordinated Universal Time (UTC) that the collection was most recently updated. - /// - [JsonProperty("updated", NullValueHandling = NullValueHandling.Ignore)] - public virtual DateTime? Updated { get; private set; } - /// - /// Number of images in the collection. - /// - [JsonProperty("image_count", NullValueHandling = NullValueHandling.Ignore)] - public virtual long? ImageCount { get; private set; } - /// - /// Training status information for the collection. - /// - [JsonProperty("training_status", NullValueHandling = NullValueHandling.Ignore)] - public virtual TrainingStatus TrainingStatus { get; private set; } - } - -} diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/BaseObject.cs b/src/IBM.Watson.VisualRecognition.v4/Model/BaseObject.cs deleted file mode 100644 index 097605e998..0000000000 --- a/src/IBM.Watson.VisualRecognition.v4/Model/BaseObject.cs +++ /dev/null @@ -1,40 +0,0 @@ -/** -* (C) Copyright IBM Corp. 2018, 2019. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -using Newtonsoft.Json; - -namespace IBM.Watson.VisualRecognition.v4.Model -{ - /// - /// Details about an object and its location. - /// - public class BaseObject - { - /// - /// The name of the object. The name can contain alphanumeric, underscore, hyphen, space, and dot characters. It - /// cannot begin with the reserved prefix `sys-`. - /// - [JsonProperty("object", NullValueHandling = NullValueHandling.Ignore)] - public string _Object { get; set; } - /// - /// Defines the location of the bounding box around the object. - /// - [JsonProperty("location", NullValueHandling = NullValueHandling.Ignore)] - public Location Location { get; set; } - } - -} diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/Collection.cs b/src/IBM.Watson.VisualRecognition.v4/Model/Collection.cs index 4004e050b4..0237042c0d 100644 --- a/src/IBM.Watson.VisualRecognition.v4/Model/Collection.cs +++ b/src/IBM.Watson.VisualRecognition.v4/Model/Collection.cs @@ -36,7 +36,7 @@ public class Collection [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] public string Name { get; set; } /// - /// The descripion of the collection. + /// The description of the collection. /// [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] public string Description { get; set; } diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/CollectionsList.cs b/src/IBM.Watson.VisualRecognition.v4/Model/CollectionsList.cs index 8d65305090..d0eda23a53 100644 --- a/src/IBM.Watson.VisualRecognition.v4/Model/CollectionsList.cs +++ b/src/IBM.Watson.VisualRecognition.v4/Model/CollectionsList.cs @@ -29,7 +29,7 @@ public class CollectionsList /// The collections in this service instance. /// [JsonProperty("collections", NullValueHandling = NullValueHandling.Ignore)] - public List Collections { get; set; } + public List Collections { get; set; } } } diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/Error.cs b/src/IBM.Watson.VisualRecognition.v4/Model/Error.cs index a94cdd730c..b17faa7201 100644 --- a/src/IBM.Watson.VisualRecognition.v4/Model/Error.cs +++ b/src/IBM.Watson.VisualRecognition.v4/Model/Error.cs @@ -69,7 +69,7 @@ public class CodeEnumValue [JsonProperty("more_info", NullValueHandling = NullValueHandling.Ignore)] public string MoreInfo { get; set; } /// - /// Details about the specfic area of the problem. + /// Details about the specific area of the problem. /// [JsonProperty("target", NullValueHandling = NullValueHandling.Ignore)] public ErrorTarget Target { get; set; } diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/ErrorTarget.cs b/src/IBM.Watson.VisualRecognition.v4/Model/ErrorTarget.cs index 0e4f15705b..673feada60 100644 --- a/src/IBM.Watson.VisualRecognition.v4/Model/ErrorTarget.cs +++ b/src/IBM.Watson.VisualRecognition.v4/Model/ErrorTarget.cs @@ -20,7 +20,7 @@ namespace IBM.Watson.VisualRecognition.v4.Model { /// - /// Details about the specfic area of the problem. + /// Details about the specific area of the problem. /// public class ErrorTarget { diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/ImageDetailsList.cs b/src/IBM.Watson.VisualRecognition.v4/Model/ImageDetailsList.cs index 9cb0567d56..c097a74f8c 100644 --- a/src/IBM.Watson.VisualRecognition.v4/Model/ImageDetailsList.cs +++ b/src/IBM.Watson.VisualRecognition.v4/Model/ImageDetailsList.cs @@ -34,7 +34,7 @@ public class ImageDetailsList /// Information about what might cause less than optimal output. /// [JsonProperty("warnings", NullValueHandling = NullValueHandling.Ignore)] - public List Warnings { get; set; } + public List Warnings { get; set; } /// /// A unique identifier of the request. Included only when an error or warning is returned. /// diff --git a/src/IBM.Watson.VisualRecognition.v4/Model/BaseError.cs b/src/IBM.Watson.VisualRecognition.v4/Model/Warning.cs similarity index 95% rename from src/IBM.Watson.VisualRecognition.v4/Model/BaseError.cs rename to src/IBM.Watson.VisualRecognition.v4/Model/Warning.cs index 9cc46743f6..94162fc785 100644 --- a/src/IBM.Watson.VisualRecognition.v4/Model/BaseError.cs +++ b/src/IBM.Watson.VisualRecognition.v4/Model/Warning.cs @@ -22,7 +22,7 @@ namespace IBM.Watson.VisualRecognition.v4.Model /// /// Details about a problem. /// - public class BaseError + public class Warning { /// /// Identifier of the problem. @@ -54,7 +54,7 @@ public class CodeEnumValue /// /// Identifier of the problem. - /// Constants for possible values can be found using BaseError.CodeEnumValue + /// Constants for possible values can be found using Warning.CodeEnumValue /// [JsonProperty("code", NullValueHandling = NullValueHandling.Ignore)] public string Code { get; set; } diff --git a/src/IBM.Watson.VisualRecognition.v4/VisualRecognitionService.cs b/src/IBM.Watson.VisualRecognition.v4/VisualRecognitionService.cs index dadab9019d..9ca8cccdab 100644 --- a/src/IBM.Watson.VisualRecognition.v4/VisualRecognitionService.cs +++ b/src/IBM.Watson.VisualRecognition.v4/VisualRecognitionService.cs @@ -1,996 +1,995 @@ -/** -* (C) Copyright IBM Corp. 2018, 2019. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -using System.Collections.Generic; -using System.IO; -using System.Net.Http; -using System.Text; -using IBM.Cloud.SDK.Core.Authentication; -using IBM.Cloud.SDK.Core.Http; -using IBM.Cloud.SDK.Core.Http.Extensions; -using IBM.Cloud.SDK.Core.Model; -using IBM.Cloud.SDK.Core.Service; -using IBM.Watson.VisualRecognition.v4.Model; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; - -namespace IBM.Watson.VisualRecognition.v4 -{ - public partial class VisualRecognitionService : IBMService, IVisualRecognitionService - { - const string serviceName = "visual_recognition"; - private const string defaultServiceUrl = "https://gateway.watsonplatform.net/visual-recognition/api"; - public string VersionDate { get; set; } - - public VisualRecognitionService(string versionDate) : this(versionDate, ConfigBasedAuthenticatorFactory.GetAuthenticator(serviceName)) { } - public VisualRecognitionService(IClient httpClient) : base(serviceName, httpClient) { } - - public VisualRecognitionService(string versionDate, IAuthenticator authenticator) : base(serviceName, authenticator) - { - if (string.IsNullOrEmpty(versionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - VersionDate = versionDate; - - if (string.IsNullOrEmpty(ServiceUrl)) - { - SetServiceUrl(defaultServiceUrl); - } - } - - /// - /// Analyze images. - /// - /// Analyze images by URL, by file, or both against your own collection. Make sure that - /// **training_status.objects.ready** is `true` for the feature before you use a collection to analyze images. - /// - /// Encode the image and .zip file names in UTF-8 if they contain non-ASCII characters. The service assumes - /// UTF-8 encoding if it encounters non-ASCII characters. - /// - /// The IDs of the collections to analyze. Separate multiple values with - /// commas. - /// The features to analyze. Separate multiple values with commas. - /// An array of image files (.jpg or .png) or .zip files with images. - /// - Include a maximum of 20 images in a request. - /// - Limit the .zip file to 100 MB. - /// - Limit each image file to 10 MB. - /// - /// You can also include an image with the **image_url** parameter. (optional) - /// An array of URLs of image files (.jpg or .png). - /// - Include a maximum of 20 images in a request. - /// - Limit each image file to 10 MB. - /// - Minimum width and height is 30 pixels, but the service tends to perform better with images that are at - /// least 300 x 300 pixels. Maximum is 5400 pixels for either height or width. - /// - /// You can also include images with the **images_file** parameter. (optional) - /// The minimum score a feature must have to be returned. (optional) - /// AnalyzeResponse - public DetailedResponse Analyze(List collectionIds, List features, List imagesFile = null, List imageUrl = null, float? threshold = null) - { - if (collectionIds == null || collectionIds.Count == 0) - { - throw new ArgumentNullException("`collectionIds` is required for `Analyze`"); - } - if (features == null || features.Count == 0) - { - throw new ArgumentNullException("`features` is required for `Analyze`"); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - var formData = new MultipartFormDataContent(); - - if (collectionIds != null) - { - var collectionIdsContent = new StringContent(string.Join(",", collectionIds.ToArray()), Encoding.UTF8, HttpMediaType.TEXT_PLAIN); - collectionIdsContent.Headers.ContentType = null; - formData.Add(collectionIdsContent, "collection_ids"); - } - - if (features != null) - { - var featuresContent = new StringContent(string.Join(",", features.ToArray()), Encoding.UTF8, HttpMediaType.TEXT_PLAIN); - featuresContent.Headers.ContentType = null; - formData.Add(featuresContent, "features"); - } - - if (imagesFile != null) - { - foreach (FileWithMetadata item in imagesFile) - { - var imagesFileContent = new ByteArrayContent(item.Data.ToArray()); - System.Net.Http.Headers.MediaTypeHeaderValue contentType; - System.Net.Http.Headers.MediaTypeHeaderValue.TryParse(item.ContentType, out contentType); - imagesFileContent.Headers.ContentType = contentType; - formData.Add(imagesFileContent, "images_file", item.Filename); - } - } - - if (imageUrl != null) - { - foreach (string item in imageUrl) - { - var imageUrlContent = new StringContent(item, Encoding.UTF8, HttpMediaType.TEXT_PLAIN); - imageUrlContent.Headers.ContentType = null; - formData.Add(imageUrlContent, "image_url"); - } - } - - if (threshold != null) - { - var thresholdContent = new StringContent(threshold.ToString(), Encoding.UTF8, HttpMediaType.TEXT_PLAIN); - thresholdContent.Headers.ContentType = null; - formData.Add(thresholdContent, "threshold"); - } - - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.PostAsync($"{this.Endpoint}/v4/analyze"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - restRequest.WithBodyContent(formData); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "Analyze")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - /// - /// Create a collection. - /// - /// Create a collection that can be used to store images. - /// - /// To create a collection without specifying a name and description, include an empty JSON object in the - /// request body. - /// - /// Encode the name and description in UTF-8 if they contain non-ASCII characters. The service assumes UTF-8 - /// encoding if it encounters non-ASCII characters. - /// - /// The new collection. - /// Collection - public DetailedResponse CreateCollection(string name = null, string description = null) - { - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - restRequest.WithHeader("Content-Type", "application/json"); - - JObject bodyObject = new JObject(); - if (!string.IsNullOrEmpty(name)) - { - bodyObject["name"] = name; - } - if (!string.IsNullOrEmpty(description)) - { - bodyObject["description"] = description; - } - var httpContent = new StringContent(JsonConvert.SerializeObject(bodyObject), Encoding.UTF8, HttpMediaType.APPLICATION_JSON); - restRequest.WithBodyContent(httpContent); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "CreateCollection")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// List collections. - /// - /// Retrieves a list of collections for the service instance. - /// - /// CollectionsList - public DetailedResponse ListCollections() - { - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "ListCollections")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// Get collection details. - /// - /// Get details of one collection. - /// - /// The identifier of the collection. - /// Collection - public DetailedResponse GetCollection(string collectionId) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `GetCollection`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections/{collectionId}"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "GetCollection")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// Update a collection. - /// - /// Update the name or description of a collection. - /// - /// Encode the name and description in UTF-8 if they contain non-ASCII characters. The service assumes UTF-8 - /// encoding if it encounters non-ASCII characters. - /// - /// The identifier of the collection. - /// The updated collection. (optional) - /// Collection - public DetailedResponse UpdateCollection(string collectionId, string name = null, string description = null) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `UpdateCollection`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections/{collectionId}"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - restRequest.WithHeader("Content-Type", "application/json"); - - JObject bodyObject = new JObject(); - if (!string.IsNullOrEmpty(name)) - { - bodyObject["name"] = name; - } - if (!string.IsNullOrEmpty(description)) - { - bodyObject["description"] = description; - } - var httpContent = new StringContent(JsonConvert.SerializeObject(bodyObject), Encoding.UTF8, HttpMediaType.APPLICATION_JSON); - restRequest.WithBodyContent(httpContent); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "UpdateCollection")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// Delete a collection. - /// - /// Delete a collection from the service instance. - /// - /// The identifier of the collection. - /// object - public DetailedResponse DeleteCollection(string collectionId) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `DeleteCollection`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.DeleteAsync($"{this.Endpoint}/v4/collections/{collectionId}"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "DeleteCollection")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - /// - /// Add images. - /// - /// Add images to a collection by URL, by file, or both. - /// - /// Encode the image and .zip file names in UTF-8 if they contain non-ASCII characters. The service assumes - /// UTF-8 encoding if it encounters non-ASCII characters. - /// - /// The identifier of the collection. - /// An array of image files (.jpg or .png) or .zip files with images. - /// - Include a maximum of 20 images in a request. - /// - Limit the .zip file to 100 MB. - /// - Limit each image file to 10 MB. - /// - /// You can also include an image with the **image_url** parameter. (optional) - /// The array of URLs of image files (.jpg or .png). - /// - Include a maximum of 20 images in a request. - /// - Limit each image file to 10 MB. - /// - Minimum width and height is 30 pixels, but the service tends to perform better with images that are at - /// least 300 x 300 pixels. Maximum is 5400 pixels for either height or width. - /// - /// You can also include images with the **images_file** parameter. (optional) - /// Training data for a single image. Include training data only if you add one image - /// with the request. - /// - /// The `object` property can contain alphanumeric, underscore, hyphen, space, and dot characters. It cannot - /// begin with the reserved prefix `sys-` and must be no longer than 32 characters. (optional) - /// ImageDetailsList - public DetailedResponse AddImages(string collectionId, List imagesFile = null, List imageUrl = null, string trainingData = null) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `AddImages`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - var formData = new MultipartFormDataContent(); - - if (imagesFile != null) - { - foreach (FileWithMetadata item in imagesFile) - { - var imagesFileContent = new ByteArrayContent(item.Data.ToArray()); - System.Net.Http.Headers.MediaTypeHeaderValue contentType; - System.Net.Http.Headers.MediaTypeHeaderValue.TryParse(item.ContentType, out contentType); - imagesFileContent.Headers.ContentType = contentType; - formData.Add(imagesFileContent, "images_file", item.Filename); - } - } - - if (imageUrl != null) - { - foreach (string item in imageUrl) - { - var imageUrlContent = new StringContent(item, Encoding.UTF8, HttpMediaType.TEXT_PLAIN); - imageUrlContent.Headers.ContentType = null; - formData.Add(imageUrlContent, "image_url"); - } - } - - if (trainingData != null) - { - var trainingDataContent = new StringContent(trainingData, Encoding.UTF8, HttpMediaType.TEXT_PLAIN); - trainingDataContent.Headers.ContentType = null; - formData.Add(trainingDataContent, "training_data"); - } - - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections/{collectionId}/images"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - restRequest.WithBodyContent(formData); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "AddImages")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// List images. - /// - /// Retrieves a list of images in a collection. - /// - /// The identifier of the collection. - /// ImageSummaryList - public DetailedResponse ListImages(string collectionId) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `ListImages`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections/{collectionId}/images"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "ListImages")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// Get image details. - /// - /// Get the details of an image in a collection. - /// - /// The identifier of the collection. - /// The identifier of the image. - /// ImageDetails - public DetailedResponse GetImageDetails(string collectionId, string imageId) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `GetImageDetails`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - if (string.IsNullOrEmpty(imageId)) - { - throw new ArgumentNullException("`imageId` is required for `GetImageDetails`"); - } - else - { - imageId = Uri.EscapeDataString(imageId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections/{collectionId}/images/{imageId}"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "GetImageDetails")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// Delete an image. - /// - /// Delete one image from a collection. - /// - /// The identifier of the collection. - /// The identifier of the image. - /// object - public DetailedResponse DeleteImage(string collectionId, string imageId) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `DeleteImage`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - if (string.IsNullOrEmpty(imageId)) - { - throw new ArgumentNullException("`imageId` is required for `DeleteImage`"); - } - else - { - imageId = Uri.EscapeDataString(imageId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.DeleteAsync($"{this.Endpoint}/v4/collections/{collectionId}/images/{imageId}"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "DeleteImage")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// Get a JPEG file of an image. - /// - /// Download a JPEG representation of an image. - /// - /// The identifier of the collection. - /// The identifier of the image. - /// Specify the image size. (optional, default to full) - /// byte[] - public DetailedResponse GetJpegImage(string collectionId, string imageId, string size = null) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `GetJpegImage`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - if (string.IsNullOrEmpty(imageId)) - { - throw new ArgumentNullException("`imageId` is required for `GetJpegImage`"); - } - else - { - imageId = Uri.EscapeDataString(imageId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections/{collectionId}/images/{imageId}/jpeg"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "image/jpeg"); - if (!string.IsNullOrEmpty(size)) - { - restRequest.WithArgument("size", size); - } - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "GetJpegImage")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = new DetailedResponse(); - result.Result = new System.IO.MemoryStream(restRequest.AsByteArray().Result); - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - /// - /// Train a collection. - /// - /// Start training on images in a collection. The collection must have enough training data and untrained data - /// (the **training_status.objects.data_changed** is `true`). If training is in progress, the request queues the - /// next training job. - /// - /// The identifier of the collection. - /// Collection - public DetailedResponse Train(string collectionId) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `Train`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections/{collectionId}/train"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "Train")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - - /// - /// Add training data to an image. - /// - /// Add, update, or delete training data for an image. Encode the object name in UTF-8 if it contains non-ASCII - /// characters. The service assumes UTF-8 encoding if it encounters non-ASCII characters. - /// - /// Elements in the request replace the existing elements. - /// - /// - To update the training data, provide both the unchanged and the new or changed values. - /// - /// - To delete the training data, provide an empty value for the training data. - /// - /// The identifier of the collection. - /// The identifier of the image. - /// Training data. Elements in the request replace the existing elements. - /// TrainingDataObjects - public DetailedResponse AddImageTrainingData(string collectionId, string imageId, List objects = null) - { - if (string.IsNullOrEmpty(collectionId)) - { - throw new ArgumentNullException("`collectionId` is required for `AddImageTrainingData`"); - } - else - { - collectionId = Uri.EscapeDataString(collectionId); - } - if (string.IsNullOrEmpty(imageId)) - { - throw new ArgumentNullException("`imageId` is required for `AddImageTrainingData`"); - } - else - { - imageId = Uri.EscapeDataString(imageId); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections/{collectionId}/images/{imageId}/training_data"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - restRequest.WithHeader("Content-Type", "application/json"); - - JObject bodyObject = new JObject(); - if (objects != null && objects.Count > 0) - { - bodyObject["objects"] = JToken.FromObject(objects); - } - var httpContent = new StringContent(JsonConvert.SerializeObject(bodyObject), Encoding.UTF8, HttpMediaType.APPLICATION_JSON); - restRequest.WithBodyContent(httpContent); - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "AddImageTrainingData")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - /// - /// Delete labeled data. - /// - /// Deletes all data associated with a specified customer ID. The method has no effect if no data is associated - /// with the customer ID. - /// - /// You associate a customer ID with data by passing the `X-Watson-Metadata` header with a request that passes - /// data. For more information about personal data and customer IDs, see [Information - /// security](https://cloud.ibm.com/docs/services/visual-recognition?topic=visual-recognition-information-security). - /// - /// The customer ID for which all data is to be deleted. - /// object - public DetailedResponse DeleteUserData(string customerId) - { - if (string.IsNullOrEmpty(customerId)) - { - throw new ArgumentNullException("`customerId` is required for `DeleteUserData`"); - } - - if (string.IsNullOrEmpty(VersionDate)) - { - throw new ArgumentNullException("versionDate cannot be null."); - } - - DetailedResponse result = null; - - try - { - IClient client = this.Client; - SetAuthentication(); - - var restRequest = client.DeleteAsync($"{this.Endpoint}/v4/user_data"); - - restRequest.WithArgument("version", VersionDate); - restRequest.WithHeader("Accept", "application/json"); - if (!string.IsNullOrEmpty(customerId)) - { - restRequest.WithArgument("customer_id", customerId); - } - - restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "DeleteUserData")); - restRequest.WithHeaders(customRequestHeaders); - ClearCustomRequestHeaders(); - - result = restRequest.As().Result; - if (result == null) - { - result = new DetailedResponse(); - } - } - catch (AggregateException ae) - { - throw ae.Flatten(); - } - - return result; - } - } -} +/** +* (C) Copyright IBM Corp. 2018, 2019. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Text; +using IBM.Cloud.SDK.Core.Authentication; +using IBM.Cloud.SDK.Core.Http; +using IBM.Cloud.SDK.Core.Http.Extensions; +using IBM.Cloud.SDK.Core.Model; +using IBM.Cloud.SDK.Core.Service; +using IBM.Watson.VisualRecognition.v4.Model; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; + +namespace IBM.Watson.VisualRecognition.v4 +{ + public partial class VisualRecognitionService : IBMService, IVisualRecognitionService + { + const string serviceName = "visual_recognition"; + private const string defaultServiceUrl = "https://gateway.watsonplatform.net/visual-recognition/api"; + public string VersionDate { get; set; } + + public VisualRecognitionService(string versionDate) : this(versionDate, ConfigBasedAuthenticatorFactory.GetAuthenticator(serviceName)) { } + public VisualRecognitionService(IClient httpClient) : base(serviceName, httpClient) { } + + public VisualRecognitionService(string versionDate, IAuthenticator authenticator) : base(serviceName, authenticator) + { + if (string.IsNullOrEmpty(versionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + VersionDate = versionDate; + + if (string.IsNullOrEmpty(ServiceUrl)) + { + SetServiceUrl(defaultServiceUrl); + } + } + + /// + /// Analyze images. + /// + /// Analyze images by URL, by file, or both against your own collection. Make sure that + /// **training_status.objects.ready** is `true` for the feature before you use a collection to analyze images. + /// + /// Encode the image and .zip file names in UTF-8 if they contain non-ASCII characters. The service assumes + /// UTF-8 encoding if it encounters non-ASCII characters. + /// + /// The IDs of the collections to analyze. + /// The features to analyze. + /// An array of image files (.jpg or .png) or .zip files with images. + /// - Include a maximum of 20 images in a request. + /// - Limit the .zip file to 100 MB. + /// - Limit each image file to 10 MB. + /// + /// You can also include an image with the **image_url** parameter. (optional) + /// An array of URLs of image files (.jpg or .png). + /// - Include a maximum of 20 images in a request. + /// - Limit each image file to 10 MB. + /// - Minimum width and height is 30 pixels, but the service tends to perform better with images that are at + /// least 300 x 300 pixels. Maximum is 5400 pixels for either height or width. + /// + /// You can also include images with the **images_file** parameter. (optional) + /// The minimum score a feature must have to be returned. (optional) + /// AnalyzeResponse + public DetailedResponse Analyze(List collectionIds, List features, List imagesFile = null, List imageUrl = null, float? threshold = null) + { + if (collectionIds == null || collectionIds.Count == 0) + { + throw new ArgumentNullException("`collectionIds` is required for `Analyze`"); + } + if (features == null || features.Count == 0) + { + throw new ArgumentNullException("`features` is required for `Analyze`"); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + var formData = new MultipartFormDataContent(); + + if (collectionIds != null) + { + var collectionIdsContent = new StringContent(string.Join(",", collectionIds.ToArray()), Encoding.UTF8, HttpMediaType.TEXT_PLAIN); + collectionIdsContent.Headers.ContentType = null; + formData.Add(collectionIdsContent, "collection_ids"); + } + + if (features != null) + { + var featuresContent = new StringContent(string.Join(",", features.ToArray()), Encoding.UTF8, HttpMediaType.TEXT_PLAIN); + featuresContent.Headers.ContentType = null; + formData.Add(featuresContent, "features"); + } + + if (imagesFile != null) + { + foreach (FileWithMetadata item in imagesFile) + { + var imagesFileContent = new ByteArrayContent(item.Data.ToArray()); + System.Net.Http.Headers.MediaTypeHeaderValue contentType; + System.Net.Http.Headers.MediaTypeHeaderValue.TryParse(item.ContentType, out contentType); + imagesFileContent.Headers.ContentType = contentType; + formData.Add(imagesFileContent, "images_file", item.Filename); + } + } + + if (imageUrl != null) + { + foreach (string item in imageUrl) + { + var imageUrlContent = new StringContent(item, Encoding.UTF8, HttpMediaType.TEXT_PLAIN); + imageUrlContent.Headers.ContentType = null; + formData.Add(imageUrlContent, "image_url"); + } + } + + if (threshold != null) + { + var thresholdContent = new StringContent(threshold.ToString(), Encoding.UTF8, HttpMediaType.TEXT_PLAIN); + thresholdContent.Headers.ContentType = null; + formData.Add(thresholdContent, "threshold"); + } + + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.PostAsync($"{this.Endpoint}/v4/analyze"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + restRequest.WithBodyContent(formData); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "Analyze")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + /// + /// Create a collection. + /// + /// Create a collection that can be used to store images. + /// + /// To create a collection without specifying a name and description, include an empty JSON object in the + /// request body. + /// + /// Encode the name and description in UTF-8 if they contain non-ASCII characters. The service assumes UTF-8 + /// encoding if it encounters non-ASCII characters. + /// + /// The new collection. + /// Collection + public DetailedResponse CreateCollection(string name = null, string description = null) + { + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + restRequest.WithHeader("Content-Type", "application/json"); + + JObject bodyObject = new JObject(); + if (!string.IsNullOrEmpty(name)) + { + bodyObject["name"] = name; + } + if (!string.IsNullOrEmpty(description)) + { + bodyObject["description"] = description; + } + var httpContent = new StringContent(JsonConvert.SerializeObject(bodyObject), Encoding.UTF8, HttpMediaType.APPLICATION_JSON); + restRequest.WithBodyContent(httpContent); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "CreateCollection")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// List collections. + /// + /// Retrieves a list of collections for the service instance. + /// + /// CollectionsList + public DetailedResponse ListCollections() + { + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "ListCollections")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// Get collection details. + /// + /// Get details of one collection. + /// + /// The identifier of the collection. + /// Collection + public DetailedResponse GetCollection(string collectionId) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `GetCollection`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections/{collectionId}"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "GetCollection")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// Update a collection. + /// + /// Update the name or description of a collection. + /// + /// Encode the name and description in UTF-8 if they contain non-ASCII characters. The service assumes UTF-8 + /// encoding if it encounters non-ASCII characters. + /// + /// The identifier of the collection. + /// The updated collection. (optional) + /// Collection + public DetailedResponse UpdateCollection(string collectionId, string name = null, string description = null) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `UpdateCollection`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections/{collectionId}"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + restRequest.WithHeader("Content-Type", "application/json"); + + JObject bodyObject = new JObject(); + if (!string.IsNullOrEmpty(name)) + { + bodyObject["name"] = name; + } + if (!string.IsNullOrEmpty(description)) + { + bodyObject["description"] = description; + } + var httpContent = new StringContent(JsonConvert.SerializeObject(bodyObject), Encoding.UTF8, HttpMediaType.APPLICATION_JSON); + restRequest.WithBodyContent(httpContent); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "UpdateCollection")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// Delete a collection. + /// + /// Delete a collection from the service instance. + /// + /// The identifier of the collection. + /// object + public DetailedResponse DeleteCollection(string collectionId) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `DeleteCollection`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.DeleteAsync($"{this.Endpoint}/v4/collections/{collectionId}"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "DeleteCollection")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + /// + /// Add images. + /// + /// Add images to a collection by URL, by file, or both. + /// + /// Encode the image and .zip file names in UTF-8 if they contain non-ASCII characters. The service assumes + /// UTF-8 encoding if it encounters non-ASCII characters. + /// + /// The identifier of the collection. + /// An array of image files (.jpg or .png) or .zip files with images. + /// - Include a maximum of 20 images in a request. + /// - Limit the .zip file to 100 MB. + /// - Limit each image file to 10 MB. + /// + /// You can also include an image with the **image_url** parameter. (optional) + /// The array of URLs of image files (.jpg or .png). + /// - Include a maximum of 20 images in a request. + /// - Limit each image file to 10 MB. + /// - Minimum width and height is 30 pixels, but the service tends to perform better with images that are at + /// least 300 x 300 pixels. Maximum is 5400 pixels for either height or width. + /// + /// You can also include images with the **images_file** parameter. (optional) + /// Training data for a single image. Include training data only if you add one image + /// with the request. + /// + /// The `object` property can contain alphanumeric, underscore, hyphen, space, and dot characters. It cannot + /// begin with the reserved prefix `sys-` and must be no longer than 32 characters. (optional) + /// ImageDetailsList + public DetailedResponse AddImages(string collectionId, List imagesFile = null, List imageUrl = null, string trainingData = null) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `AddImages`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + var formData = new MultipartFormDataContent(); + + if (imagesFile != null) + { + foreach (FileWithMetadata item in imagesFile) + { + var imagesFileContent = new ByteArrayContent(item.Data.ToArray()); + System.Net.Http.Headers.MediaTypeHeaderValue contentType; + System.Net.Http.Headers.MediaTypeHeaderValue.TryParse(item.ContentType, out contentType); + imagesFileContent.Headers.ContentType = contentType; + formData.Add(imagesFileContent, "images_file", item.Filename); + } + } + + if (imageUrl != null) + { + foreach (string item in imageUrl) + { + var imageUrlContent = new StringContent(item, Encoding.UTF8, HttpMediaType.TEXT_PLAIN); + imageUrlContent.Headers.ContentType = null; + formData.Add(imageUrlContent, "image_url"); + } + } + + if (trainingData != null) + { + var trainingDataContent = new StringContent(trainingData, Encoding.UTF8, HttpMediaType.TEXT_PLAIN); + trainingDataContent.Headers.ContentType = null; + formData.Add(trainingDataContent, "training_data"); + } + + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections/{collectionId}/images"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + restRequest.WithBodyContent(formData); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "AddImages")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// List images. + /// + /// Retrieves a list of images in a collection. + /// + /// The identifier of the collection. + /// ImageSummaryList + public DetailedResponse ListImages(string collectionId) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `ListImages`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections/{collectionId}/images"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "ListImages")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// Get image details. + /// + /// Get the details of an image in a collection. + /// + /// The identifier of the collection. + /// The identifier of the image. + /// ImageDetails + public DetailedResponse GetImageDetails(string collectionId, string imageId) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `GetImageDetails`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + if (string.IsNullOrEmpty(imageId)) + { + throw new ArgumentNullException("`imageId` is required for `GetImageDetails`"); + } + else + { + imageId = Uri.EscapeDataString(imageId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections/{collectionId}/images/{imageId}"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "GetImageDetails")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// Delete an image. + /// + /// Delete one image from a collection. + /// + /// The identifier of the collection. + /// The identifier of the image. + /// object + public DetailedResponse DeleteImage(string collectionId, string imageId) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `DeleteImage`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + if (string.IsNullOrEmpty(imageId)) + { + throw new ArgumentNullException("`imageId` is required for `DeleteImage`"); + } + else + { + imageId = Uri.EscapeDataString(imageId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.DeleteAsync($"{this.Endpoint}/v4/collections/{collectionId}/images/{imageId}"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "DeleteImage")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// Get a JPEG file of an image. + /// + /// Download a JPEG representation of an image. + /// + /// The identifier of the collection. + /// The identifier of the image. + /// Specify the image size. (optional, default to full) + /// byte[] + public DetailedResponse GetJpegImage(string collectionId, string imageId, string size = null) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `GetJpegImage`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + if (string.IsNullOrEmpty(imageId)) + { + throw new ArgumentNullException("`imageId` is required for `GetJpegImage`"); + } + else + { + imageId = Uri.EscapeDataString(imageId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.GetAsync($"{this.Endpoint}/v4/collections/{collectionId}/images/{imageId}/jpeg"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "image/jpeg"); + if (!string.IsNullOrEmpty(size)) + { + restRequest.WithArgument("size", size); + } + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "GetJpegImage")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = new DetailedResponse(); + result.Result = new System.IO.MemoryStream(restRequest.AsByteArray().Result); + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + /// + /// Train a collection. + /// + /// Start training on images in a collection. The collection must have enough training data and untrained data + /// (the **training_status.objects.data_changed** is `true`). If training is in progress, the request queues the + /// next training job. + /// + /// The identifier of the collection. + /// Collection + public DetailedResponse Train(string collectionId) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `Train`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections/{collectionId}/train"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "Train")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + + /// + /// Add training data to an image. + /// + /// Add, update, or delete training data for an image. Encode the object name in UTF-8 if it contains non-ASCII + /// characters. The service assumes UTF-8 encoding if it encounters non-ASCII characters. + /// + /// Elements in the request replace the existing elements. + /// + /// - To update the training data, provide both the unchanged and the new or changed values. + /// + /// - To delete the training data, provide an empty value for the training data. + /// + /// The identifier of the collection. + /// The identifier of the image. + /// Training data. Elements in the request replace the existing elements. + /// TrainingDataObjects + public DetailedResponse AddImageTrainingData(string collectionId, string imageId, List objects = null) + { + if (string.IsNullOrEmpty(collectionId)) + { + throw new ArgumentNullException("`collectionId` is required for `AddImageTrainingData`"); + } + else + { + collectionId = Uri.EscapeDataString(collectionId); + } + if (string.IsNullOrEmpty(imageId)) + { + throw new ArgumentNullException("`imageId` is required for `AddImageTrainingData`"); + } + else + { + imageId = Uri.EscapeDataString(imageId); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.PostAsync($"{this.Endpoint}/v4/collections/{collectionId}/images/{imageId}/training_data"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + restRequest.WithHeader("Content-Type", "application/json"); + + JObject bodyObject = new JObject(); + if (objects != null && objects.Count > 0) + { + bodyObject["objects"] = JToken.FromObject(objects); + } + var httpContent = new StringContent(JsonConvert.SerializeObject(bodyObject), Encoding.UTF8, HttpMediaType.APPLICATION_JSON); + restRequest.WithBodyContent(httpContent); + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "AddImageTrainingData")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + /// + /// Delete labeled data. + /// + /// Deletes all data associated with a specified customer ID. The method has no effect if no data is associated + /// with the customer ID. + /// + /// You associate a customer ID with data by passing the `X-Watson-Metadata` header with a request that passes + /// data. For more information about personal data and customer IDs, see [Information + /// security](https://cloud.ibm.com/docs/services/visual-recognition?topic=visual-recognition-information-security). + /// + /// The customer ID for which all data is to be deleted. + /// object + public DetailedResponse DeleteUserData(string customerId) + { + if (string.IsNullOrEmpty(customerId)) + { + throw new ArgumentNullException("`customerId` is required for `DeleteUserData`"); + } + + if (string.IsNullOrEmpty(VersionDate)) + { + throw new ArgumentNullException("versionDate cannot be null."); + } + + DetailedResponse result = null; + + try + { + IClient client = this.Client; + SetAuthentication(); + + var restRequest = client.DeleteAsync($"{this.Endpoint}/v4/user_data"); + + restRequest.WithArgument("version", VersionDate); + restRequest.WithHeader("Accept", "application/json"); + if (!string.IsNullOrEmpty(customerId)) + { + restRequest.WithArgument("customer_id", customerId); + } + + restRequest.WithHeaders(Common.GetSdkHeaders("watson_vision_combined", "v4", "DeleteUserData")); + restRequest.WithHeaders(customRequestHeaders); + ClearCustomRequestHeaders(); + + result = restRequest.As().Result; + if (result == null) + { + result = new DetailedResponse(); + } + } + catch (AggregateException ae) + { + throw ae.Flatten(); + } + + return result; + } + } +} diff --git a/test/VisualRecognition.v4.IntegrationTests/VisualRecognitionServiceIntegrationTests.cs b/test/VisualRecognition.v4.IntegrationTests/VisualRecognitionServiceIntegrationTests.cs index 4d6e28058d..368aae54f2 100644 --- a/test/VisualRecognition.v4.IntegrationTests/VisualRecognitionServiceIntegrationTests.cs +++ b/test/VisualRecognition.v4.IntegrationTests/VisualRecognitionServiceIntegrationTests.cs @@ -263,9 +263,9 @@ public void Training_Success() var imageId = addImagesResult.Result.Images[0].ImageId; var objectName = giraffeClassname; - List objects = new List() + List objects = new List() { - new BaseObject() + new TrainingDataObject() { _Object = objectName, Location = new Location()