google-cloud-translate-v2 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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