chefu_academy 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.
- checksums.yaml +7 -0
- data/README.md +16 -0
- data/lib/chefu_academy/client.rb +169 -0
- data/lib/chefu_academy.rb +4 -0
- metadata +47 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 56cf1309b2b9aec7c93d650ea719bd128fdfee851bfb765ba2ccef9956819f3f
|
|
4
|
+
data.tar.gz: 05053aba56bc1c0ff0bf957d3df4c559622306efbda75429acf7a1c874391881
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 6794e73aa2e4217d8a77d66d0c8a2388c1d62bbc0e747b80f95380e66bf6550ac3becc6a8903cba632a1a78c1eea5adf8312b6b6b631f8ab660b6f1186d98551
|
|
7
|
+
data.tar.gz: ea113d018beb72e2ff917feb90ed4223ea8fce0b039e1ad06cc9e635066b49889aa330ad31bd3665942398bd4216820b0510c350b231b3cd2c7aa1ee0d0a0d3f
|
data/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# CheFu Academy Ruby Client
|
|
2
|
+
|
|
3
|
+
Official Ruby gem source for the CheFu Academy API.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
client = CheFuAcademy::Client.new(api_key: 'chf_publicId_secret')
|
|
9
|
+
courses = client.list_courses(limit: 5)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Local Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bundle install
|
|
16
|
+
```
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'uri'
|
|
4
|
+
|
|
5
|
+
module CheFuAcademy
|
|
6
|
+
DEFAULT_BASE_URL = 'https://api.chefuinc.com/api'
|
|
7
|
+
|
|
8
|
+
class Error < StandardError
|
|
9
|
+
attr_reader :status_code, :details
|
|
10
|
+
|
|
11
|
+
def initialize(message, status_code: nil, details: nil)
|
|
12
|
+
super(message)
|
|
13
|
+
@status_code = status_code
|
|
14
|
+
@details = details
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Client
|
|
19
|
+
attr_accessor :api_key, :auth_token
|
|
20
|
+
|
|
21
|
+
def initialize(api_key: nil, auth_token: nil, base_url: DEFAULT_BASE_URL, timeout: 10)
|
|
22
|
+
@api_key = api_key
|
|
23
|
+
@auth_token = auth_token
|
|
24
|
+
@base_url = base_url.delete_suffix('/')
|
|
25
|
+
@timeout = timeout
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def login(email:, password:)
|
|
29
|
+
session = request('POST', '/auth/login', body: { email: email, password: password }, api_key_auth: false)
|
|
30
|
+
self.auth_token = session['idToken'] || session['token']
|
|
31
|
+
session
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def register(email:, password:, fullname:)
|
|
35
|
+
request('POST', '/auth/register', body: { email: email, password: password, fullname: fullname }, api_key_auth: false)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def refresh(refresh_token:)
|
|
39
|
+
session = request('POST', '/auth/refresh', body: { refreshToken: refresh_token }, api_key_auth: false)
|
|
40
|
+
self.auth_token = session['idToken'] || session['token']
|
|
41
|
+
session
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def list_courses(**query)
|
|
45
|
+
request('GET', '/courses', query: query)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def search_courses(**query)
|
|
49
|
+
request('GET', '/courses/search', query: query)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def featured_courses(**query)
|
|
53
|
+
request('GET', '/courses/featured', query: query)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def course_categories
|
|
57
|
+
request('GET', '/courses/categories')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def course(course_id)
|
|
61
|
+
request('GET', "/courses/#{escape(course_id)}")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def course_chapters(course_id)
|
|
65
|
+
request('GET', "/courses/#{escape(course_id)}/chapters")
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def course_chapter(course_id, chapter_index)
|
|
69
|
+
request('GET', "/courses/#{escape(course_id)}/chapters/#{chapter_index}")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def course_lessons(course_id, chapter_index)
|
|
73
|
+
request('GET', "/courses/#{escape(course_id)}/chapters/#{chapter_index}/lessons")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def course_quiz(course_id)
|
|
77
|
+
request('GET', "/courses/#{escape(course_id)}/quiz")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def course_flashcards(course_id)
|
|
81
|
+
request('GET', "/courses/#{escape(course_id)}/flashcards")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def course_qa(course_id)
|
|
85
|
+
request('GET', "/courses/#{escape(course_id)}/qa")
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def list_videos(**query)
|
|
89
|
+
request('GET', '/videos', query: query)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def search_videos(**query)
|
|
93
|
+
request('GET', '/videos/search', query: query)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def videos_by_category(category)
|
|
97
|
+
request('GET', "/videos/category/#{escape(category)}")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def video(video_id)
|
|
101
|
+
request('GET', "/videos/#{escape(video_id)}")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def create_key(name: nil)
|
|
105
|
+
request('POST', '/keys/create', body: { name: name }, user_auth: true, api_key_auth: false)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def list_keys
|
|
109
|
+
request('GET', '/keys/list', user_auth: true, api_key_auth: false)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def revoke_key(key_id)
|
|
113
|
+
request('POST', '/keys/revoke', body: { keyId: key_id }, user_auth: true, api_key_auth: false)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
private
|
|
117
|
+
|
|
118
|
+
def request(method, path, query: {}, body: nil, user_auth: false, api_key_auth: true)
|
|
119
|
+
token = user_auth ? auth_token : api_key
|
|
120
|
+
raise Error.new('User authentication is required.', status_code: 401) if user_auth && blank?(token)
|
|
121
|
+
raise Error.new('API key is required.', status_code: 401) if api_key_auth && !user_auth && blank?(token)
|
|
122
|
+
|
|
123
|
+
uri = URI("#{@base_url}#{path}")
|
|
124
|
+
clean_query = query.reject { |_key, value| value.nil? || value.to_s.empty? }
|
|
125
|
+
uri.query = URI.encode_www_form(clean_query) unless clean_query.empty?
|
|
126
|
+
|
|
127
|
+
request = Net::HTTP.const_get(method.capitalize).new(uri)
|
|
128
|
+
request['Accept'] = 'application/json'
|
|
129
|
+
request['Authorization'] = "Bearer #{token}" unless blank?(token)
|
|
130
|
+
if body
|
|
131
|
+
request['Content-Type'] = 'application/json'
|
|
132
|
+
request.body = JSON.generate(body)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https', read_timeout: @timeout) do |http|
|
|
136
|
+
http.request(request)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
decoded = response.body.nil? || response.body.empty? ? nil : JSON.parse(response.body)
|
|
140
|
+
unless response.is_a?(Net::HTTPSuccess)
|
|
141
|
+
raise Error.new(error_message(decoded, response.body), status_code: response.code.to_i, details: decoded)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
decoded
|
|
145
|
+
rescue JSON::ParserError => error
|
|
146
|
+
raise Error.new("JSON parse error: #{error.message}")
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def escape(value)
|
|
150
|
+
URI.encode_www_form_component(value.to_s).gsub('+', '%20')
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def blank?(value)
|
|
154
|
+
value.nil? || value.to_s.empty?
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def error_message(decoded, raw)
|
|
158
|
+
if decoded.is_a?(Hash)
|
|
159
|
+
message = decoded['message']
|
|
160
|
+
return message.join(' ') if message.is_a?(Array)
|
|
161
|
+
return message if message.is_a?(String) && !message.empty?
|
|
162
|
+
error = decoded['error']
|
|
163
|
+
return error if error.is_a?(String) && !error.empty?
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
raw.nil? || raw.empty? ? 'CheFu Academy request failed.' : raw
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: chefu_academy
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- CheFu Inc
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-06-03 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description:
|
|
14
|
+
email:
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- README.md
|
|
20
|
+
- lib/chefu_academy.rb
|
|
21
|
+
- lib/chefu_academy/client.rb
|
|
22
|
+
homepage: https://github.com/CheFu-code/CheFu-Academy-SDK
|
|
23
|
+
licenses:
|
|
24
|
+
- MIT
|
|
25
|
+
metadata:
|
|
26
|
+
homepage_uri: https://github.com/CheFu-code/CheFu-Academy-SDK
|
|
27
|
+
source_code_uri: https://github.com/CheFu-code/CheFu-Academy-SDK/tree/main/clients/ruby
|
|
28
|
+
post_install_message:
|
|
29
|
+
rdoc_options: []
|
|
30
|
+
require_paths:
|
|
31
|
+
- lib
|
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
33
|
+
requirements:
|
|
34
|
+
- - ">="
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '3.0'
|
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '0'
|
|
42
|
+
requirements: []
|
|
43
|
+
rubygems_version: 3.5.22
|
|
44
|
+
signing_key:
|
|
45
|
+
specification_version: 4
|
|
46
|
+
summary: Official Ruby client for the CheFu Academy API
|
|
47
|
+
test_files: []
|