Skip to content

Commit 25e6290

Browse files
authored
V2 SDK (#10)
* Switch to base url * Update to v3 api * Use JSON payloads * Adjust ruby versions * Disable arm test * Refactor proxy * Implement proxy spec * Add changelog * Add removed section * Adjust proxy spec * Disable ruby 2.0 * Adjust proxy * Adjust changelog * Update examples * Bump version * Adjust version * Add blank lines * Adjust readme * Update readme * Add deprecations * Add deprecations
1 parent bc17f08 commit 25e6290

File tree

11 files changed

+323
-270
lines changed

11 files changed

+323
-270
lines changed

.github/workflows/main.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ jobs:
66
strategy:
77
matrix:
88
ruby-version:
9-
- 2.0
9+
- 2.0.0
1010
- 2.7
11-
- 3.0
11+
- 3.0.0
1212
- 3.4
1313
- ruby-head
1414
- jruby-head
1515
image:
1616
- ubuntu-24.04
17-
- ubuntu-24.04-arm
17+
# - ubuntu-24.04-arm
1818
name: Ruby ${{ matrix.ruby-version }} on ${{ matrix.image }}
1919
steps:
2020
- uses: actions/checkout@v3

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
9+
## v2.0.0
10+
11+
### Added
12+
- `detect_batch` method for batch detections
13+
14+
### Changed
15+
- Switched to v3 API which uses an updated language detection model
16+
- ⚠️ `detect` method result fields are `language` and `score`
17+
- ⚠️ Proxy URL configured using `config.proxy`
18+
- Client connection is reused. If you change configuration after the client is initialized, you need to reset client using `DetectLanguage.client = nil`.
19+
20+
### Deprecated
21+
- Calling `detect` with array argument. Use `detect_batch` instead.
22+
- `simple_detect` - Use `detect_code` instead.
23+
- `user_status` - Use `account_status` instead.
24+
- `configuration` - Use `config` instead.
25+
26+
### Removed
27+
- Secure mode configuration. HTTPS is always used.
28+
- Ruby 1.x support

Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ gem 'rake'
66
gem 'json'
77

88
group :test do
9-
gem "rspec"
10-
end
9+
gem 'rspec'
10+
end

README.md

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ Detect Language API Ruby Client
66

77
Detects language of the given text. Returns detected language codes and scores.
88

9-
Before using Detect Language API client you have to setup your personal API key.
10-
You can get it by signing up at https://detectlanguage.com
119

1210
## Installation
1311

@@ -17,77 +15,70 @@ Add this line to your application's Gemfile:
1715
gem 'detect_language'
1816
```
1917

20-
Or install it yourself as:
18+
### Upgrading
2119

22-
```
23-
gem install detect_language
24-
```
20+
When upgrading please check [changelog](CHANGELOG.md) for breaking changes.
2521

2622
### Configuration
2723

28-
If you are using Rails, create initializer `config/initializers/detect_language.rb` and add following code there.
29-
Otherwise just integrate following code into your apps configuration.
24+
Get your personal API key by signing up at https://detectlanguage.com
3025

3126
```ruby
3227
DetectLanguage.configure do |config|
33-
config.api_key = "YOUR API KEY"
34-
35-
# enable secure mode (SSL) if you are passing sensitive data
36-
# config.secure = true
28+
config.api_key = 'YOUR API KEY'
3729
end
3830
```
3931

4032
## Usage
4133

42-
### Language detection
34+
### Detect language
4335

4436
```ruby
45-
DetectLanguage.detect("Buenos dias señor")
37+
DetectLanguage.detect('Dolce far niente')
4638
```
4739

4840
#### Result
4941

5042
```ruby
51-
[{"language"=>"es", "isReliable"=>true, "confidence"=>6.62}]
43+
[{"language" => "it", "score" => 0.5074}]
5244
```
5345

54-
### Simple language detection
46+
### Detect single code
5547

56-
If you need just a language code you can use `simple_detect`. It returns just the language code.
48+
If you need just a language code you can use `detect_code`.
5749

5850
```ruby
59-
DetectLanguage.simple_detect("Buenos dias señor")
51+
DetectLanguage.detect_code('Dolce far niente')
6052
```
6153

6254
#### Result
6355

6456
```ruby
65-
"es"
57+
"it"
6658
```
6759

6860
### Batch detection
6961

7062
It is possible to detect language of several texts with one request.
7163
This method is significantly faster than doing one request per text.
72-
To use batch detection just pass array of texts to `detect` method.
64+
To use batch detection just pass array of texts to `detect_batch` method.
7365

7466
```ruby
75-
DetectLanguage.detect(["Buenos dias señor", "Labas rytas"])
67+
DetectLanguage.detect_batch(['Dolce far niente', 'Labas rytas'])
7668
```
7769

7870
#### Result
7971

8072
Result is array of detections in the same order as the texts were passed.
8173

8274
```ruby
83-
[ [{"language"=>"es", "isReliable"=>true, "confidence"=>6.62}],
84-
[{"language"=>"lt", "isReliable"=>true, "confidence"=>6.82}] ]
75+
[[{"language" => "it", "score" => 0.5074}], [{"language" => "lt", "score" => 0.3063}]]
8576
```
8677

87-
### Getting your account status
78+
### Get your account status
8879

8980
```ruby
90-
DetectLanguage.user_status
81+
DetectLanguage.account_status
9182
```
9283

9384
#### Result
@@ -97,7 +88,7 @@ DetectLanguage.user_status
9788
"daily_requests_limit"=>5000, "daily_bytes_limit"=>1048576, "status"=>"ACTIVE"}
9889
```
9990

100-
### Getting list supported languages
91+
### Get list of supported languages
10192

10293
```ruby
10394
DetectLanguage.languages

lib/detect_language.rb

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,81 @@
55

66
module DetectLanguage
77
class << self
8-
attr_writer :configuration
8+
attr_writer :config
99

1010
def configure
11-
yield(configuration)
11+
yield(config)
1212
end
1313

14-
# The configuration object.
15-
# @see DetectLanguage.configure
16-
def configuration
17-
@configuration ||= Configuration.new
14+
def config
15+
@config ||= Configuration.new
1816
end
1917

2018
def client
21-
Thread.current[:detect_language_client] ||= Client.new(configuration)
19+
Thread.current[:detect_language_client] ||= Client.new(config)
2220
end
2321

24-
def detect(data)
25-
key = data.is_a?(Array) ? 'q[]' : 'q'
26-
result = client.post(:detect, key => data)
27-
result['data']['detections']
22+
def client=(client)
23+
Thread.current[:detect_language_client] = client
2824
end
2925

30-
def simple_detect(text)
26+
# @param query String
27+
# @return [Array<Hash>] Array of language detections
28+
def detect(query)
29+
if query.is_a?(Array)
30+
warn '[DEPRECATED] `DetectLanguage.detect` with an array of queries is deprecated. Use `DetectLanguage.detect_batch` instead.'
31+
return detect_batch(query)
32+
end
33+
34+
client.post('detect', q: query)
35+
end
36+
37+
# @param queries Array<String> Array of queries to detect languages for
38+
# @return [Array<Array<Hash>>] Array of language detections for each query
39+
def detect_batch(queries)
40+
raise(ArgumentError, 'Expected an Array of queries') unless queries.is_a?(Array)
41+
42+
client.post('detect-batch', q: queries)
43+
end
44+
45+
# @param text String
46+
# @return [String, nil] Detected language code or nil if no detection found
47+
def detect_code(text)
3148
detections = detect(text)
3249

33-
if detections.empty?
34-
nil
35-
else
36-
detections[0]['language']
37-
end
50+
return if detections.empty?
51+
52+
detections[0]['language']
3853
end
3954

40-
def user_status
41-
client.get('user/status')
55+
# @return [Hash] Account status information
56+
def account_status
57+
client.get('account/status')
4258
end
4359

60+
# @return [Array<Hash>] List of supported languages
4461
def languages
4562
client.get('languages')
4663
end
64+
65+
### DEPRECATED METHODS
66+
67+
# @deprecated Use `DetectLanguage.config` instead
68+
def configuration
69+
warn '[DEPRECATED] `DetectLanguage.configuration` is deprecated. Use `DetectLanguage.config` instead.'
70+
config
71+
end
72+
73+
# @deprecated Use `detect_code` instead
74+
def simple_detect(text)
75+
warn '[DEPRECATED] `DetectLanguage.simple_detect` is deprecated. Use `DetectLanguage.detect_code` instead.'
76+
detect_code(text)
77+
end
78+
79+
# @deprecated Use `DetectLanguage.account_status` instead
80+
def user_status
81+
warn '[DEPRECATED] `DetectLanguage.user_status` is deprecated. Use `DetectLanguage.account_status` instead.'
82+
account_status
83+
end
4784
end
4885
end

lib/detect_language/client.rb

Lines changed: 30 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,37 @@
1-
require 'cgi'
21
require 'net/http'
32
require 'net/https'
43
require 'json'
54

65
module DetectLanguage
76
class Client
8-
attr_reader :configuration
7+
attr_reader :config
98

10-
def initialize(configuration)
11-
@configuration = configuration
9+
def initialize(config)
10+
@config = config
1211
end
1312

14-
def post(method, params = {})
15-
execute(method, params, :http_method => Net::HTTP::Post)
13+
def post(path, payload = {})
14+
execute(Net::HTTP::Post, path, body: payload.to_json)
1615
end
1716

18-
def get(method, params = {})
19-
execute(method, params, :http_method => Net::HTTP::Get)
17+
def get(path)
18+
execute(Net::HTTP::Get, path)
2019
end
2120

2221
private
2322

24-
def execute(method, params, options)
25-
http = setup_http_connection
26-
http_method = options[:http_method]
27-
request = http_method.new(request_uri(method))
23+
def execute(method, path, body: nil)
24+
request = method.new(base_uri.path + path)
25+
request.body = body
2826

29-
if RUBY_VERSION == '1.8.7'
30-
set_form_data_18(request, params)
31-
else
32-
request.set_form_data(params)
33-
end
34-
35-
request['Authorization'] = 'Bearer ' + configuration.api_key.to_s
36-
request['User-Agent'] = configuration.user_agent
27+
request['Content-Type'] = 'application/json'
28+
request['Authorization'] = 'Bearer ' + config.api_key.to_s
29+
request['User-Agent'] = config.user_agent
3730

38-
response = http.request(request)
31+
response = connection.request(request)
3932

4033
case response
41-
when Net::HTTPSuccess, Net::HTTPUnauthorized then
34+
when Net::HTTPSuccess, Net::HTTPUnauthorized
4235
parse_response(response.body)
4336
else
4437
raise(Error, "Failure: #{response.class}")
@@ -55,44 +48,28 @@ def parse_response(response_body)
5548
end
5649
end
5750

58-
def request_uri(method)
59-
"/#{configuration.api_version}/#{method}"
51+
def base_uri
52+
@base_uri ||= URI(config.base_url)
6053
end
6154

62-
def setup_http_connection
63-
http =
64-
Net::HTTP::Proxy(configuration.proxy_host, configuration.proxy_port, configuration.proxy_user,
65-
configuration.proxy_pass).
66-
new(configuration.host, configuration.port)
67-
68-
http.read_timeout = configuration.http_read_timeout
69-
http.open_timeout = configuration.http_open_timeout
55+
def connection
56+
@connection ||= setup_connection
57+
end
7058

71-
if configuration.secure?
72-
http.use_ssl = true
73-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
59+
def setup_connection
60+
http = if config.proxy
61+
proxy = URI(config.proxy)
62+
Net::HTTP.new(base_uri.hostname, base_uri.port, proxy.hostname, proxy.port, proxy.user, proxy.password)
7463
else
75-
http.use_ssl = false
64+
Net::HTTP.new(base_uri.hostname, base_uri.port)
7665
end
7766

78-
http
79-
end
80-
81-
def set_form_data_18(request, params, sep = '&')
82-
request.body = params.map {|k,v|
83-
if v.instance_of?(Array)
84-
v.map {|e| "#{urlencode(k.to_s)}=#{urlencode(e.to_s)}"}.join(sep)
85-
else
86-
"#{urlencode(k.to_s)}=#{urlencode(v.to_s)}"
87-
end
88-
}.join(sep)
89-
90-
request.content_type = 'application/x-www-form-urlencoded'
91-
end
67+
http.use_ssl = base_uri.scheme == 'https'
68+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER if http.use_ssl?
69+
http.read_timeout = config.http_read_timeout
70+
http.open_timeout = config.http_open_timeout
9271

93-
def urlencode(str)
94-
CGI::escape(str)
72+
http
9573
end
96-
9774
end
9875
end

0 commit comments

Comments
 (0)