google-cloud-translate-v2 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,132 @@
1
+ # Copyright 2020 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Google
17
+ module Cloud
18
+ module Translate
19
+ module V2
20
+ ##
21
+ # # Detection
22
+ #
23
+ # Represents a detect language query result. Returned by {Google::Cloud::Translate::V2::Api#detect}.
24
+ #
25
+ # @see https://cloud.google.com/translation/docs/detecting-language Detecting Language
26
+ #
27
+ # @example
28
+ # require "google/cloud/translate/v2"
29
+ #
30
+ # translate = Google::Cloud::Translate::V2.new
31
+ #
32
+ # detections = translate.detect "chien", "chat"
33
+ #
34
+ # detections.size #=> 2
35
+ # detections[0].text #=> "chien"
36
+ # detections[0].language #=> "fr"
37
+ # detections[0].confidence #=> 0.7109375
38
+ # detections[1].text #=> "chat"
39
+ # detections[1].language #=> "en"
40
+ # detections[1].confidence #=> 0.59922177
41
+ #
42
+ class Detection
43
+ ##
44
+ # The text upon which the language detection was performed.
45
+ #
46
+ # @return [String]
47
+ attr_reader :text
48
+
49
+ ##
50
+ # The list of detection results for the given text. The most likely language is listed first, and its
51
+ # attributes can be accessed through {#language} and {#confidence}.
52
+ #
53
+ # @return [Array<Detection::Result>]
54
+ attr_reader :results
55
+
56
+ ##
57
+ # @private Create a new object.
58
+ def initialize text, results
59
+ @text = text
60
+ @results = results
61
+ end
62
+
63
+ ##
64
+ # The confidence that the language detection result is correct. The closer this value is to 1, the higher the
65
+ # confidence in language detection.
66
+ #
67
+ # @return [Float] a value between 0 and 1
68
+ def confidence
69
+ return nil if results.empty?
70
+ results.first.confidence
71
+ end
72
+
73
+ ##
74
+ # The most likely language that was detected. This is an [ISO
75
+ # 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code.
76
+ #
77
+ # @return [String] the language code
78
+ def language
79
+ return nil if results.empty?
80
+ results.first.language
81
+ end
82
+
83
+ ##
84
+ # @private New Detection from a ListDetectionsResponse object as defined by the Google API Client object.
85
+ def self.from_gapi gapi, text
86
+ res = text.zip(Array(gapi["detections"])).map do |txt, detections|
87
+ results = detections.map { |g| Result.from_gapi g }
88
+ new txt, results
89
+ end
90
+ return res.first if res.size == 1
91
+ res
92
+ end
93
+
94
+ ##
95
+ # # Result
96
+ #
97
+ # Represents an individual result in a {Google::Cloud::Translate::V2::Detection} result.
98
+ #
99
+ class Result
100
+ ##
101
+ # The confidence that the language detection result is correct. The closer this value is to 1, the higher
102
+ # the confidence in language detection.
103
+ #
104
+ # @return [Float] a value between 0 and 1
105
+ attr_reader :confidence
106
+
107
+ ##
108
+ # The language detected. This is an [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
109
+ # language code.
110
+ #
111
+ # @return [String] the language code
112
+ attr_reader :language
113
+
114
+ ##
115
+ # @private Create a new object.
116
+ def initialize confidence, language
117
+ @confidence = confidence
118
+ @language = language
119
+ end
120
+
121
+ ##
122
+ # @private New Detection::Result from a DetectionsResource object as defined by the Google API Client
123
+ # object.
124
+ def self.from_gapi gapi
125
+ new gapi["confidence"], gapi["language"]
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,68 @@
1
+ # Copyright 2020 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Google
17
+ module Cloud
18
+ module Translate
19
+ module V2
20
+ ##
21
+ # # Language
22
+ #
23
+ # Represents a supported languages query result. Returned by {Google::Cloud::Translate::V2::Api#languages}.
24
+ #
25
+ # @see https://cloud.google.com/translation/docs/discovering-supported-languages Discovering Supported Languages
26
+ #
27
+ # @example
28
+ # require "google/cloud/translate/v2"
29
+ #
30
+ # translate = Google::Cloud::Translate::V2.new
31
+ #
32
+ # languages = translate.languages "en"
33
+ #
34
+ # languages.size #=> 104
35
+ # languages[0].code #=> "af"
36
+ # languages[0].name #=> "Afrikaans"
37
+ #
38
+ class Language
39
+ ##
40
+ # The language code. This is an [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language
41
+ # code.
42
+ #
43
+ # @return [String]
44
+ attr_reader :code
45
+
46
+ ##
47
+ # The localized name of the language, if available.
48
+ #
49
+ # @return [String]
50
+ attr_reader :name
51
+
52
+ ##
53
+ # @private Create a new object.
54
+ def initialize code, name
55
+ @code = code
56
+ @name = name
57
+ end
58
+
59
+ ##
60
+ # @private New Language from a LanguagesResource object as defined by the Google API Client object.
61
+ def self.from_gapi gapi
62
+ new gapi["language"], gapi["name"]
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,210 @@
1
+ # Copyright 2020 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/errors"
17
+ require "google/cloud/translate/v2/credentials"
18
+ require "google/cloud/translate/v2/version"
19
+ require "faraday"
20
+ require "uri"
21
+
22
+ module Google
23
+ module Cloud
24
+ module Translate
25
+ module V2
26
+ ##
27
+ # @private
28
+ # Represents the Translation API REST service, exposing the API calls.
29
+ class Service #:nodoc:
30
+ API_VERSION = "v2".freeze
31
+ API_URL = "https://translation.googleapis.com".freeze
32
+
33
+ # @private
34
+ attr_accessor :project_id, :credentials, :retries, :timeout, :key
35
+
36
+ ##
37
+ # Creates a new Service instance.
38
+ def initialize project_id, credentials, retries: nil, timeout: nil, key: nil, host: nil
39
+ @project_id = project_id
40
+ @credentials = credentials
41
+ @retries = retries
42
+ @timeout = timeout
43
+ @key = key
44
+ @host = host || API_URL
45
+ end
46
+
47
+ ##
48
+ # Returns Hash of ListTranslationsResponse JSON
49
+ def translate text, to: nil, from: nil, format: nil, model: nil, cid: nil
50
+ body = {
51
+ q: Array(text), target: to, source: from, format: format,
52
+ model: model, cid: cid
53
+ }.delete_if { |_k, v| v.nil? }.to_json
54
+
55
+ post "/language/translate/v2", body
56
+ end
57
+
58
+ ##
59
+ # Returns API::ListDetectionsResponse
60
+ def detect text
61
+ body = { q: Array(text) }.to_json
62
+
63
+ post "language/translate/v2/detect", body
64
+ end
65
+
66
+ ##
67
+ # Returns API::ListLanguagesResponse
68
+ def languages language = nil
69
+ body = { target: language }.to_json
70
+
71
+ post "language/translate/v2/languages", body
72
+ end
73
+
74
+ def inspect
75
+ self.class.to_s
76
+ end
77
+
78
+ protected
79
+
80
+ def post path, body = nil
81
+ response = execute do
82
+ http.post path do |req|
83
+ req.headers.merge! default_http_headers
84
+ req.body = body unless body.nil?
85
+
86
+ if @key
87
+ req.params = { key: @key }
88
+ else
89
+ sign_http_request! req
90
+ end
91
+ end
92
+ end
93
+
94
+ return JSON.parse(response.body)["data"] if response.success?
95
+
96
+ raise Google::Cloud::Error.gapi_error_class_for(response.status)
97
+ rescue Faraday::ConnectionFailed
98
+ raise Google::Cloud::ResourceExhaustedError
99
+ end
100
+
101
+ ##
102
+ # The HTTP object that makes calls to API.
103
+ # This must be a Faraday object.
104
+ def http
105
+ @http ||= Faraday.new url: @host, request: {
106
+ open_timeout: @timeout, timeout: @timeout
107
+ }.delete_if { |_k, v| v.nil? }
108
+ end
109
+
110
+ ##
111
+ # The default HTTP headers to be sent on all API calls.
112
+ def default_http_headers
113
+ @default_http_headers ||= begin
114
+ lib_version = Google::Cloud::Translate::V2::VERSION
115
+ headers = {
116
+ "User-Agent" => "gcloud-ruby/#{lib_version}",
117
+ "google-cloud-resource-prefix" => "projects/#{@project}",
118
+ "Content-Type" => "application/json",
119
+ "x-goog-api-client" => "gl-ruby/#{RUBY_VERSION} gccl/#{lib_version}"
120
+ }
121
+ headers["x-goog-user-project"] = credentials.quota_project_id if credentials.respond_to? :quota_project_id
122
+ headers
123
+ end
124
+ end
125
+
126
+ ##
127
+ # Make a request and apply incremental backoff
128
+ def execute
129
+ backoff = Backoff.new retries: retries
130
+ backoff.execute do
131
+ yield
132
+ end
133
+ rescue Faraday::ConnectionFailed
134
+ raise Google::Cloud::ResourceExhaustedError
135
+ end
136
+
137
+ ##
138
+ # Sign Oauth2 API calls.
139
+ def sign_http_request! request
140
+ client = credentials.client
141
+ return if client.nil?
142
+
143
+ client.fetch_access_token! if client.expires_within? 30
144
+ client.generate_authenticated_request request: request
145
+ request
146
+ end
147
+
148
+ ##
149
+ # @private Backoff
150
+ class Backoff
151
+ class << self
152
+ attr_accessor :retries
153
+ attr_accessor :http_codes
154
+ attr_accessor :reasons
155
+ attr_accessor :backoff # :nodoc:
156
+ end
157
+
158
+ # Set the default values
159
+ self.retries = 3
160
+ self.http_codes = [500, 503]
161
+ self.reasons = ["rateLimitExceeded", "userRateLimitExceeded"]
162
+ self.backoff = ->(retries) { sleep retries.to_i }
163
+
164
+ def initialize options = {} #:nodoc:
165
+ @max_retries = (options[:retries] || Backoff.retries).to_i
166
+ @http_codes = (options[:http_codes] || Backoff.http_codes).to_a
167
+ @reasons = (options[:reasons] || Backoff.reasons).to_a
168
+ @backoff = options[:backoff] || Backoff.backoff
169
+ end
170
+
171
+ def execute #:nodoc:
172
+ current_retries = 0
173
+ loop do
174
+ response = yield # Expecting Faraday::Response
175
+ return response if response.success?
176
+ break response unless retry? response, current_retries
177
+ current_retries += 1
178
+ @backoff.call current_retries
179
+ end
180
+ end
181
+
182
+ protected
183
+
184
+ def retry? result, current_retries #:nodoc:
185
+ if current_retries < @max_retries
186
+ return true if retry_http_code? result
187
+ return true if retry_error_reason? result
188
+ end
189
+ false
190
+ end
191
+
192
+ def retry_http_code? response #:nodoc:
193
+ @http_codes.include? response.status
194
+ end
195
+
196
+ def retry_error_reason? response #:nodoc:
197
+ result = JSON.parse response.body
198
+ if result && result["error"] && result["error"]["errors"]
199
+ Array(result["error"]["errors"]).each do |error|
200
+ return true if error["reason"] && @reasons.include?(error["reason"])
201
+ end
202
+ end
203
+ false
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,120 @@
1
+ # Copyright 2020 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Google
17
+ module Cloud
18
+ module Translate
19
+ module V2
20
+ ##
21
+ # # Translation
22
+ #
23
+ # Represents a translation query result. Returned by {Google::Cloud::Translate::V2::Api#translate}.
24
+ #
25
+ # @see https://cloud.google.com/translation/docs/translating-text#Translate Translating Text
26
+ #
27
+ # @example
28
+ # require "google/cloud/translate/v2"
29
+ #
30
+ # translate = Google::Cloud::Translate::V2.new
31
+ #
32
+ # translation = translate.translate "Hello world!", to: "la"
33
+ #
34
+ # translation.to_s #=> "Salve mundi!"
35
+ #
36
+ # translation.from #=> "en"
37
+ # translation.origin #=> "Hello world!"
38
+ # translation.to #=> "la"
39
+ # translation.text #=> "Salve mundi!"
40
+ #
41
+ class Translation
42
+ ##
43
+ # The translated result.
44
+ #
45
+ # @return [String]
46
+ attr_reader :text
47
+ alias to_s text
48
+ alias to_str text
49
+
50
+ ##
51
+ # The original query text that was translated.
52
+ #
53
+ # @return [String]
54
+ attr_reader :origin
55
+
56
+ ##
57
+ # The target language into which the text was translated.
58
+ #
59
+ # @return [String]
60
+ attr_reader :to
61
+ alias language to
62
+ alias target to
63
+
64
+ ##
65
+ # The source language from which the text was translated.
66
+ #
67
+ # @return [String]
68
+ attr_reader :from
69
+ alias source from
70
+
71
+ ##
72
+ # The translation model. Can be either `base` for the Phrase-Based Machine Translation (PBMT) model, or `nmt`
73
+ # for the Neural Machine Translation (NMT) model. If you did not include a model parameter with your request,
74
+ # then this field is not included in the response.
75
+ #
76
+ # @return [String]
77
+ attr_reader :model
78
+
79
+ ##
80
+ # @private Create a new object.
81
+ def initialize text, to, origin, from, model, detected
82
+ @text = text
83
+ @to = to
84
+ @origin = origin
85
+ @from = from
86
+ @model = model
87
+ @detected = detected
88
+ end
89
+
90
+ ##
91
+ # Determines if the source language was detected by the Google Cloud Cloud Translation API.
92
+ #
93
+ # @return [Boolean] `true` if the source language was detected by the Cloud Translation API, `false` if the
94
+ # source language was provided in the request
95
+ def detected?
96
+ @detected
97
+ end
98
+
99
+ ##
100
+ # @private New Translation from a TranslationsListResponse object as defined by the Google API Client object.
101
+ def self.from_gapi_list gapi, text, to, from
102
+ res = text.zip(Array(gapi["translations"])).map do |origin, g|
103
+ from_gapi g, to, origin, from
104
+ end
105
+ return res.first if res.size == 1
106
+ res
107
+ end
108
+
109
+ ##
110
+ # @private New Translation from a TranslationsResource object as defined by the Google API Client object.
111
+ def self.from_gapi gapi, to, origin, from
112
+ from ||= gapi["detectedSourceLanguage"]
113
+ detected = !gapi["detectedSourceLanguage"].nil?
114
+ new gapi["translatedText"], to, origin, from, gapi["model"], detected
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end