ruby-you 0.1.1
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.
- checksums.yaml +7 -0
- data/README.md +175 -0
- data/lib/you/client.rb +140 -0
- data/lib/you/configuration.rb +13 -0
- data/lib/you/error.rb +23 -0
- data/lib/you/version.rb +3 -0
- data/lib/you.rb +20 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 542555c1df3a5af0c3f0d7450d334ba2e2daf4b803f9a0786f16d5f3b07befb4
|
4
|
+
data.tar.gz: 01054bcce46bff8b1a124565c7101dffdd12b23e41f4bc22cb26d66bf6db91ad
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f013e19f9caea16b43191e4b9141d73ad67365ef6b434b4e8d7daa7ca9513ef72f7ec5156cdff3802ab4aba40e7cb7e757bc0636cf3e2d7f4c59c3cd0b1c37a3
|
7
|
+
data.tar.gz: 4feac155583bf3f567205dd77f2aa86fd55ca0a42a4631b6f34f130924ce1b13108c3787acd00c3fe8a0625cde52c723c3ec423603ba903a68385202ac1cf80a
|
data/README.md
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
# ruby-you
|
2
|
+
|
3
|
+
| Tests | Coverage |
|
4
|
+
|:-:|:-:|
|
5
|
+
| [](https://github.com/arkimedes-dev/ruby-you/actions/workflows/main.yml) | [](https://codecov.io/github/arkimedes-dev/ruby-you) |
|
6
|
+
|
7
|
+
|
8
|
+
A Ruby client for interacting with the You.com API, including the Smart, Research, Search, and News endpoints. This gem provides a simple and consistent interface, along with configurable retry logic, rate-limit handling, debugging options, and comprehensive error handling.
|
9
|
+
|
10
|
+
## Features
|
11
|
+
|
12
|
+
- **Smart API**: Send queries to `https://chat-api.you.com/smart`.
|
13
|
+
- **Research API**: Send queries to `https://chat-api.you.com/research`.
|
14
|
+
- **Search API**: Query `https://api.ydc-index.io/search` for web search results.
|
15
|
+
- **News API**: Query `https://api.ydc-index.io/news` for news results.
|
16
|
+
|
17
|
+
## Requirements
|
18
|
+
|
19
|
+
- Ruby 2.6 or higher.
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
Add this line to your application's Gemfile:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem 'ruby-you'
|
27
|
+
```
|
28
|
+
|
29
|
+
Then execute
|
30
|
+
|
31
|
+
```bash
|
32
|
+
bundle install
|
33
|
+
```
|
34
|
+
|
35
|
+
Or install it yourself as:
|
36
|
+
|
37
|
+
```bash
|
38
|
+
gem build ruby-you.gemspec
|
39
|
+
gem install ruby-you-0.1.1.gem
|
40
|
+
```
|
41
|
+
|
42
|
+
## Configuration
|
43
|
+
|
44
|
+
The client requires an API key. You can provide this as an environment variable YOU_API_KEY or pass it directly when initializing the client.
|
45
|
+
|
46
|
+
You can also configure logging and debugging:
|
47
|
+
|
48
|
+
```rb
|
49
|
+
require 'you'
|
50
|
+
|
51
|
+
You.configure do |config|
|
52
|
+
config.debug = true # enable debug mode for verbose logging
|
53
|
+
config.logger = Logger.new($stdout) # customize the logger, defaults to $stdout with WARN level
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
## Usage
|
58
|
+
|
59
|
+
```rb
|
60
|
+
require 'you'
|
61
|
+
|
62
|
+
client = You.client(api_key: "YOUR_API_KEY")
|
63
|
+
|
64
|
+
# Smart API
|
65
|
+
response = client.smart(query: "What is the capital of France?", instructions: "Respond in bullet points.")
|
66
|
+
puts response["answer"]
|
67
|
+
|
68
|
+
# Research API
|
69
|
+
research_result = client.research(query: "Explain quantum computing in simple terms")
|
70
|
+
puts research_result["answer"]
|
71
|
+
|
72
|
+
# Search API
|
73
|
+
search_result = client.search(query: "Ruby programming", num_web_results: 5, safesearch: "moderate")
|
74
|
+
puts search_result["hits"]
|
75
|
+
|
76
|
+
# News API
|
77
|
+
news_result = client.news(query: "latest tech news", count: 5, recency: "day")
|
78
|
+
puts news_result["news"]["results"]
|
79
|
+
```
|
80
|
+
|
81
|
+
## Endpoints and Parameters
|
82
|
+
|
83
|
+
### Smart API (POST /smart)
|
84
|
+
|
85
|
+
- query (String, required)
|
86
|
+
- chat_id (String, optional)
|
87
|
+
- instructions (String, optional)
|
88
|
+
|
89
|
+
### Research API (POST /research)
|
90
|
+
|
91
|
+
- query (String, required)
|
92
|
+
- chat_id (String, optional)
|
93
|
+
|
94
|
+
### Search API (GET /search)
|
95
|
+
|
96
|
+
- query (String, required)
|
97
|
+
- num_web_results (Integer, optional)
|
98
|
+
- offset (Integer, optional)
|
99
|
+
- country (String, optional)
|
100
|
+
- safesearch (String, optional, defaults to moderate)
|
101
|
+
|
102
|
+
### News API (GET /news)
|
103
|
+
|
104
|
+
- query (String, required)
|
105
|
+
- count (Integer, optional)
|
106
|
+
- offset (Integer, optional)
|
107
|
+
- country (String, optional)
|
108
|
+
- search_lang (String, optional)
|
109
|
+
- ui_lang (String, optional)
|
110
|
+
- safesearch (String, optional)
|
111
|
+
- spellcheck (Boolean, optional)
|
112
|
+
- recency (String, optional: day, week, month, year)
|
113
|
+
|
114
|
+
### Error Handling
|
115
|
+
|
116
|
+
The client raises custom exceptions for non-200 responses:
|
117
|
+
|
118
|
+
- You::BadRequestError (400)
|
119
|
+
- You::UnauthorizedError (401)
|
120
|
+
- You::ForbiddenError (403)
|
121
|
+
- You::NotFoundError (404)
|
122
|
+
- You::UnprocessableEntityError (422)
|
123
|
+
- You::RateLimitError (429)
|
124
|
+
- You::InternalServerError (500)
|
125
|
+
- You::BadGatewayError (502)
|
126
|
+
- You::ServiceUnavailableError (503)
|
127
|
+
- You::GatewayTimeoutError (504)
|
128
|
+
- You::Error for all other errors.
|
129
|
+
|
130
|
+
Rate-limit errors (429) are retried up to max_retries times with an exponential backoff or a Retry-After delay if provided by the server.
|
131
|
+
|
132
|
+
### Debugging and Logging
|
133
|
+
|
134
|
+
Set `You.configuration.debug = true` to enable detailed logs of requests and responses. These logs include:
|
135
|
+
|
136
|
+
- Outgoing request method, URL, and parameters.
|
137
|
+
- Response status code, headers, and body.
|
138
|
+
|
139
|
+
You can customize the logger with You.configuration.logger.
|
140
|
+
|
141
|
+
## Testing
|
142
|
+
|
143
|
+
This gem uses RSpec and WebMock for testing.
|
144
|
+
|
145
|
+
Install the dependencies:
|
146
|
+
|
147
|
+
```bash
|
148
|
+
bundle install
|
149
|
+
```
|
150
|
+
|
151
|
+
Run the tests:
|
152
|
+
|
153
|
+
```bash
|
154
|
+
rspec
|
155
|
+
```
|
156
|
+
|
157
|
+
The test suite covers:
|
158
|
+
|
159
|
+
- Successful requests
|
160
|
+
- Various error responses and the corresponding exceptions
|
161
|
+
- Rate-limit handling and retry logic
|
162
|
+
- Debug/logging functionality
|
163
|
+
|
164
|
+
## Contributing
|
165
|
+
|
166
|
+
- Fork the project
|
167
|
+
- Create a new feature branch (git checkout -b feature/my-feature)
|
168
|
+
- Commit your changes (git commit -m 'Add new feature')
|
169
|
+
- Push to the branch (git push origin feature/my-feature)
|
170
|
+
- Create a new Pull Request
|
171
|
+
- Release the gem: `bundle exec rake release`
|
172
|
+
|
173
|
+
## License
|
174
|
+
|
175
|
+
This project is licensed under the MIT License - see the [LICENSE.txt](https://github.com/arkimedes-dev/ruby-you/blob/main/LICENSE.txt) file for details.
|
data/lib/you/client.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
require "you/error"
|
2
|
+
require "uri"
|
3
|
+
require "faraday"
|
4
|
+
require "faraday/retry"
|
5
|
+
|
6
|
+
module You
|
7
|
+
class Client
|
8
|
+
SMART_API_BASE_URL = "https://chat-api.you.com".freeze
|
9
|
+
SEARCH_API_BASE_URL = "https://api.ydc-index.io".freeze
|
10
|
+
|
11
|
+
attr_accessor :api_key, :max_retries, :initial_wait_time
|
12
|
+
|
13
|
+
def initialize(api_key: nil, max_retries: 3, initial_wait_time: 1)
|
14
|
+
@api_key = api_key || ENV["YOU_API_KEY"]
|
15
|
+
|
16
|
+
raise You::Error, "No API key provided. Set YOU_API_KEY env or pass api_key." unless @api_key
|
17
|
+
|
18
|
+
@max_retries = max_retries
|
19
|
+
@initial_wait_time = initial_wait_time
|
20
|
+
end
|
21
|
+
|
22
|
+
# SMART Endpoint
|
23
|
+
def smart(query:, chat_id: nil, instructions: nil)
|
24
|
+
post("#{SMART_API_BASE_URL}/smart", {query: query, chat_id: chat_id, instructions: instructions}.compact)
|
25
|
+
end
|
26
|
+
|
27
|
+
# RESEARCH Endpoint
|
28
|
+
def research(query:, chat_id: nil)
|
29
|
+
post("#{SMART_API_BASE_URL}/research", {query: query, chat_id: chat_id}.compact)
|
30
|
+
end
|
31
|
+
|
32
|
+
# SEARCH Endpoint (GET)
|
33
|
+
def search(query:, **params)
|
34
|
+
get("#{SEARCH_API_BASE_URL}/search", {query: query}.merge(params))
|
35
|
+
end
|
36
|
+
|
37
|
+
# NEWS Endpoint (GET)
|
38
|
+
def news(query:, **params)
|
39
|
+
get("#{SEARCH_API_BASE_URL}/news", {query: query}.merge(params))
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def connection(base_url)
|
45
|
+
Faraday.new(base_url) do |faraday|
|
46
|
+
faraday.request :json
|
47
|
+
faraday.response :json
|
48
|
+
|
49
|
+
# If debug mode is on, we add a Faraday logger middleware that outputs to You.configuration.logger
|
50
|
+
if You.configuration.debug
|
51
|
+
faraday.response :logger, You.configuration.logger, {bodies: true}
|
52
|
+
end
|
53
|
+
|
54
|
+
# Retries a request after refreshing the token if we get an UnauthorizedError
|
55
|
+
faraday.request :retry, {
|
56
|
+
retry_statuses: [429, 500, 502, 503, 504],
|
57
|
+
methods: [:get, :post],
|
58
|
+
max: max_retries,
|
59
|
+
interval_randomness: 0.5,
|
60
|
+
interval: initial_wait_time,
|
61
|
+
backoff_factor: 2
|
62
|
+
}
|
63
|
+
|
64
|
+
faraday.adapter Faraday.default_adapter
|
65
|
+
faraday.headers["X-API-Key"] = @api_key
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def get(url, params = {})
|
70
|
+
log_request("GET", url, params)
|
71
|
+
resp = connection(base_url(url)).get do |req|
|
72
|
+
req.url endpoint_path(url)
|
73
|
+
req.params.update(params)
|
74
|
+
end
|
75
|
+
handle_response(resp)
|
76
|
+
end
|
77
|
+
|
78
|
+
def post(url, payload)
|
79
|
+
log_request("POST", url, payload)
|
80
|
+
resp = connection(base_url(url)).post do |req|
|
81
|
+
req.url endpoint_path(url)
|
82
|
+
req.body = payload
|
83
|
+
end
|
84
|
+
handle_response(resp)
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_response(response)
|
88
|
+
log_response(response)
|
89
|
+
case response.status
|
90
|
+
when 200
|
91
|
+
response.body
|
92
|
+
when 400
|
93
|
+
raise You::BadRequestError, "Bad Request: #{response.body}"
|
94
|
+
when 401
|
95
|
+
raise You::UnauthorizedError, "Unauthorized: #{response.body}"
|
96
|
+
when 403
|
97
|
+
raise You::ForbiddenError, "Forbidden: #{response.body}"
|
98
|
+
when 404
|
99
|
+
raise You::NotFoundError, "Not Found: #{response.body}"
|
100
|
+
when 422
|
101
|
+
raise You::UnprocessableEntityError, "Unprocessable Entity: #{response.body}"
|
102
|
+
when 429
|
103
|
+
retry_after = response.headers["Retry-After"]
|
104
|
+
msg = "Rate Limit Reached: #{response.body}"
|
105
|
+
msg << " (Retry-After: #{retry_after})" if retry_after
|
106
|
+
raise You::RateLimitError, msg
|
107
|
+
when 500
|
108
|
+
raise You::InternalServerError, "Internal Server Error: #{response.body}"
|
109
|
+
when 502
|
110
|
+
raise You::BadGatewayError, "Bad Gateway: #{response.body}"
|
111
|
+
when 503
|
112
|
+
raise You::ServiceUnavailableError, "Service Unavailable: #{response.body}"
|
113
|
+
when 504
|
114
|
+
raise You::GatewayTimeoutError, "Gateway Timeout: #{response.body}"
|
115
|
+
else
|
116
|
+
raise You::Error, "Request failed with status #{response.status}: #{response.body}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def base_url(full_url)
|
121
|
+
uri = URI(full_url)
|
122
|
+
"#{uri.scheme}://#{uri.host}"
|
123
|
+
end
|
124
|
+
|
125
|
+
def endpoint_path(full_url)
|
126
|
+
uri = URI(full_url)
|
127
|
+
uri.path
|
128
|
+
end
|
129
|
+
|
130
|
+
def log_request(method, url, params_or_body)
|
131
|
+
return unless You.configuration.debug
|
132
|
+
You.configuration.logger.info("You API Request: #{method} #{url} with #{params_or_body}")
|
133
|
+
end
|
134
|
+
|
135
|
+
def log_response(response)
|
136
|
+
return unless You.configuration.debug
|
137
|
+
You.configuration.logger.info("You API Response: Status #{response.status}, Headers: #{response.headers}, Body: #{response.body}")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
data/lib/you/error.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module You
|
2
|
+
class Error < StandardError; end
|
3
|
+
|
4
|
+
class BadRequestError < Error; end # 400
|
5
|
+
|
6
|
+
class UnauthorizedError < Error; end # 401
|
7
|
+
|
8
|
+
class ForbiddenError < Error; end # 403
|
9
|
+
|
10
|
+
class NotFoundError < Error; end # 404
|
11
|
+
|
12
|
+
class UnprocessableEntityError < Error; end # 422
|
13
|
+
|
14
|
+
class RateLimitError < Error; end # 429
|
15
|
+
|
16
|
+
class InternalServerError < Error; end # 500
|
17
|
+
|
18
|
+
class BadGatewayError < Error; end # 502
|
19
|
+
|
20
|
+
class ServiceUnavailableError < Error; end # 503
|
21
|
+
|
22
|
+
class GatewayTimeoutError < Error; end # 504
|
23
|
+
end
|
data/lib/you/version.rb
ADDED
data/lib/you.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "you/version"
|
2
|
+
require "you/configuration"
|
3
|
+
require "you/client"
|
4
|
+
|
5
|
+
module You
|
6
|
+
class << self
|
7
|
+
def configuration
|
8
|
+
@configuration ||= Configuration.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure
|
12
|
+
yield(configuration)
|
13
|
+
end
|
14
|
+
|
15
|
+
# A convenience method to access a default client directly
|
16
|
+
def client
|
17
|
+
@client ||= You::Client.new
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-you
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Mochetti
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday-retry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.10'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.10'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.17'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.17'
|
69
|
+
description: Provides a simple Ruby interface for interacting with the You.com Smart,
|
70
|
+
Research, Search, and News endpoints.
|
71
|
+
email:
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- README.md
|
77
|
+
- lib/you.rb
|
78
|
+
- lib/you/client.rb
|
79
|
+
- lib/you/configuration.rb
|
80
|
+
- lib/you/error.rb
|
81
|
+
- lib/you/version.rb
|
82
|
+
homepage: https://github.com/arkimedes-dev/ruby-you
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata:
|
86
|
+
homepage_uri: https://github.com/arkimedes-dev/ruby-you
|
87
|
+
source_code_uri: https://github.com/arkimedes-dev/ruby-you
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.6'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubygems_version: 3.5.16
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: A Ruby client for the You.com API.
|
107
|
+
test_files: []
|