school21_api_sdk 0.2.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c977aa4a81ec303760a605cfa0bc0cb4508cf1cc8fe930419681cbdad2f76365
4
- data.tar.gz: 540db30ea6fb420599b0d54b8f6236fcc7ccda97bb6fc29a2a65d2b8ae9b78d9
3
+ metadata.gz: a8b8fc46a01614de5e5b6cfb19de30d5471eb154d293a02d7eab835f8c2042bd
4
+ data.tar.gz: ef32e49acfbb13fc44384c0b58b26b3633c1878a6a7c8e5ab86f9eb9efbd1287
5
5
  SHA512:
6
- metadata.gz: d9ce8af9eaae1316e4e77f62448efb983d14a8c36bb281021fd9ef4dfa1c1ed92a3362be512410fdf62bb9f33095c76990bb944e054888e82c4218613bd055a4
7
- data.tar.gz: 874a6d4bc32e73deb6324bd57831650cea4f070c2c25d4cdf7dc7f699baff4df123a67e3f22e05081e5580155f4bb24dde9caa17cf5d1ec62e35ddc9fc053180
6
+ metadata.gz: becf9958c2bc4dcc57fb0ecb8d6b0b5473c47b800375c6e70e92c209cb47c569c5759e79d887a3a423cfeac01b3e072936221ce4570daf01302c35fc1f010ef7
7
+ data.tar.gz: a2fdb94e72a53583d147732ba4971653335c1f9ed2cb6ef0bc74b2a73d42b2632415d327198f3d3e7abb2865bcd1ab5f1fc8289c6162e6bd8c5c030d7bd874f8
data/README.md CHANGED
@@ -32,15 +32,22 @@ password = 'your_password_here'
32
32
 
33
33
  client = School21::Client.configure do |config|
34
34
  config.credentials = { login: login, password: password }
35
- config.enable_logging = true # false by default
35
+
36
+ # If you want to log client's requests and responses (turned off by default)
37
+ config.enable_logging = true
36
38
  end
39
+
40
+ # Request access token from the API server.
41
+ # Access token is stored inside client object and reused for API requests.
42
+ # If access token is expired client will automatically request a new one.
43
+ client.authenticate!
37
44
  ```
38
45
 
39
46
  - Select the domain specific API that you want to use. This API has all endpoints related to that domain. Here's an example of `Participant API` and a call to `/participants/:login`
40
47
 
41
48
  ```ruby
42
49
  participants_api = client.participants_api
43
- response = participants_api.participants('ikael@student.21-school.ru')
50
+ response = participants_api.participant('peer_nickname')
44
51
 
45
52
  if response.success?
46
53
  puts response.data
@@ -57,4 +64,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
57
64
 
58
65
  ## Contributing
59
66
 
60
- Bug reports and pull requests are welcome on GitHub at https://github.com/ikael21/school21_api_sdk.
67
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/ikael21/school21_api_sdk>.
@@ -9,10 +9,7 @@ module School21
9
9
  .form_param(new_parameter('password', key: :grant_type))
10
10
  .form_param(new_parameter('s21-open-api', key: :client_id))
11
11
 
12
- new_api_call_builder
13
- .request(new_request)
14
- .response(new_response_handler)
15
- .execute
12
+ execute_request(new_request)
16
13
  end
17
14
  end
18
15
  end
@@ -49,5 +49,18 @@ module School21
49
49
  .key(key)
50
50
  .value(value)
51
51
  end
52
+
53
+ def authenticated_request(...)
54
+ auth_participant = CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT)
55
+
56
+ new_request_builder(...).auth(auth_participant)
57
+ end
58
+
59
+ def execute_request(new_request)
60
+ new_api_call_builder
61
+ .request(new_request)
62
+ .response(new_response_handler)
63
+ .execute
64
+ end
52
65
  end
53
66
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module School21
4
+ class CampusesApi < BaseApi
5
+ def campuses
6
+ path = '/campuses'
7
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
8
+
9
+ execute_request(new_request)
10
+ end
11
+
12
+ def campus_participants(campus_id, options: {})
13
+ path = "/campuses/#{campus_id}/participants"
14
+ default_options = { limit: 50, offset: 0 }.merge(options)
15
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
16
+
17
+ default_options.each do |key, value|
18
+ new_request.query_param(new_parameter(value, key:))
19
+ end
20
+
21
+ execute_request(new_request)
22
+ end
23
+
24
+ def campus_coalitions(campus_id, options: {})
25
+ path = "/campuses/#{campus_id}/coalitions"
26
+ default_options = { limit: 50, offset: 0 }.merge(options)
27
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
28
+
29
+ default_options.each do |key, value|
30
+ new_request.query_param(new_parameter(value, key:))
31
+ end
32
+
33
+ execute_request(new_request)
34
+ end
35
+
36
+ def campus_clusters(campus_id, options: {})
37
+ path = "/campuses/#{campus_id}/clusters"
38
+ default_options = { limit: 50, offset: 0 }.merge(options)
39
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
40
+
41
+ default_options.each do |key, value|
42
+ new_request.query_param(new_parameter(value, key:))
43
+ end
44
+
45
+ execute_request(new_request)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module School21
4
+ class ClustersApi < BaseApi
5
+ def cluster_map(cluster_id, options: {})
6
+ path = "/clusters/#{cluster_id}/map"
7
+ default_options = { limit: 50, offset: 0 }.merge(options)
8
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
9
+
10
+ default_options.each do |key, value|
11
+ new_request.query_param(new_parameter(value, key:))
12
+ end
13
+
14
+ execute_request(new_request)
15
+ end
16
+ end
17
+ end
@@ -2,36 +2,30 @@
2
2
 
3
3
  module School21
4
4
  class ParticipantsApi < BaseApi
5
- def participants(login)
5
+ def participant(login)
6
6
  path = "/participants/#{login}"
7
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
8
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
7
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
9
8
 
10
- new_api_call_builder
11
- .request(new_request)
12
- .response(new_response_handler)
13
- .execute
9
+ execute_request(new_request)
14
10
  end
15
11
 
16
- def participants_projects(login, options: {})
12
+ def participant_projects(login, options: {})
17
13
  path = "/participants/#{login}/projects"
18
- default_options = { limit: 1000, offset: 0 }.merge(options)
14
+ default_options = { limit: 10, offset: 0 }.merge(options)
15
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
19
16
 
20
- parameters = default_options.map do |key, value|
21
- new_parameter(value, key:)
17
+ default_options.each do |key, value|
18
+ new_request.query_param(new_parameter(value, key:))
22
19
  end
23
20
 
24
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
25
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
21
+ execute_request(new_request)
22
+ end
26
23
 
27
- parameters.each do |parameter|
28
- new_request.query_param(parameter)
29
- end
24
+ def participant_project(login, project_id)
25
+ path = "/participants/#{login}/projects/#{project_id}"
26
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
30
27
 
31
- new_api_call_builder
32
- .request(new_request)
33
- .response(new_response_handler)
34
- .execute
28
+ execute_request(new_request)
35
29
  end
36
30
  end
37
31
  end
@@ -2,36 +2,23 @@
2
2
 
3
3
  module School21
4
4
  class ProjectsApi < BaseApi
5
- def projects(project_id)
5
+ def project(project_id)
6
6
  path = "/projects/#{project_id}"
7
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
8
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
7
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
9
8
 
10
- new_api_call_builder
11
- .request(new_request)
12
- .response(new_response_handler)
13
- .execute
9
+ execute_request(new_request)
14
10
  end
15
11
 
16
- def projects_participants(project_id, options: {})
12
+ def project_participants(project_id, options: {})
17
13
  path = "/projects/#{project_id}/participants"
18
- default_options = { limit: 1000, offset: 0 }.merge(options)
14
+ default_options = { limit: 10, offset: 0 }.merge(options)
15
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
19
16
 
20
- parameters = default_options.map do |key, value|
21
- new_parameter(value, key:)
17
+ default_options.each do |key, value|
18
+ new_request.query_param(new_parameter(value, key:))
22
19
  end
23
20
 
24
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
25
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
26
-
27
- parameters.each do |parameter|
28
- new_request.query_param(parameter)
29
- end
30
-
31
- new_api_call_builder
32
- .request(new_request)
33
- .response(new_response_handler)
34
- .execute
21
+ execute_request(new_request)
35
22
  end
36
23
  end
37
24
  end
@@ -4,86 +4,108 @@ module School21
4
4
  class Client
5
5
  include CoreLibrary
6
6
 
7
- def self.configure(&)
8
- new(&)
7
+ attr_reader :config, :access_token
8
+
9
+ class << self
10
+ def configure(&) = new(&)
9
11
  end
10
12
 
11
13
  def initialize(&block)
12
14
  raise 'A block must be given' unless block_given?
13
15
  raise 'You must provide block argument that represents config instance' if block.arity != 1
14
16
 
15
- @config = GlobalConfig
16
- .new
17
- .base_uri_executor(BaseApi.method(:base_uri))
17
+ @config = GlobalConfig.new.base_uri_executor(BaseApi.method(:base_uri))
18
18
 
19
19
  yield(@config)
20
20
 
21
21
  validate_credentials!
22
22
 
23
- initialize_logging
23
+ initialize_logging if @config.enable_logging
24
24
 
25
25
  http_client = FaradayClient.new(@config.client_configuration)
26
26
  @config.client_configuration.set_http_client(http_client)
27
+ end
27
28
 
28
- initialize_auth!
29
+ def authenticate!
30
+ @access_token = request_access_token!
31
+
32
+ initialize_auth_managers
29
33
  end
30
34
 
31
- def auth_api = @auth_api ||= AuthApi.new(@config)
35
+ def auth_api
36
+ @auth_api ||= AuthApi.new(config)
37
+ end
32
38
 
33
39
  def participants_api
34
- initialize_auth! if @access_token.expired?
35
-
36
- ParticipantsApi.new(@config)
40
+ authenticate! if access_token.expired?
41
+ ParticipantsApi.new(config)
37
42
  end
38
43
 
39
44
  def projects_api
40
- initialize_auth! if @access_token.expired?
45
+ authenticate! if access_token.expired?
46
+ ProjectsApi.new(config)
47
+ end
48
+
49
+ def campuses_api
50
+ authenticate! if access_token.expired?
51
+ CampusesApi.new(config)
52
+ end
41
53
 
42
- ProjectsApi.new(@config)
54
+ def clusters_api
55
+ authenticate! if access_token.expired?
56
+ ClustersApi.new(config)
43
57
  end
44
58
 
45
59
  private
46
60
 
47
61
  def validate_credentials!
48
- login = @config.credentials[:login]
49
- password = @config.credentials[:password]
62
+ login = config.credentials[:login]
63
+ password = config.credentials[:password]
50
64
 
51
65
  raise "Login can't be nil or empty" if login.nil? || login.empty?
52
66
  raise "Password can't be nil or empty" if password.nil? || password.empty?
53
67
  end
54
68
 
55
- def initialize_auth!
56
- @access_token = request_access_token!
57
-
58
- initialize_auth_managers
59
- end
60
-
61
69
  def initialize_auth_managers
62
70
  auth_managers = {}
63
-
64
- creds = BearerAuthCredentials.new(access_token: @access_token)
71
+ creds = BearerAuthCredentials.new(access_token:)
65
72
  auth_managers[BaseApi::SINGLE_AUTH_PARTICIPANT] = AuthorizationHeader.new(creds)
66
73
 
67
- @config.auth_managers = auth_managers
74
+ config.auth_managers = auth_managers
68
75
  end
69
76
 
70
77
  def request_access_token!
71
- auth_api_response = auth_api.token(login: @config.credentials[:login], password: @config.credentials[:password])
78
+ auth_api_response = auth_api.token(
79
+ login: config.credentials[:login],
80
+ password: config.credentials[:password]
81
+ )
82
+
72
83
  raise 'Access Token Error' unless auth_api_response.success?
73
84
 
74
85
  AccessToken.new(*auth_api_response.data.values_at(:access_token, :expires_in))
75
86
  end
76
87
 
88
+ def semantic_logger
89
+ SemanticLogger.default_level = :trace
90
+ SemanticLogger.add_appender(io: $stdout, formatter: :color)
91
+
92
+ SemanticLogger[self.class.to_s]
93
+ end
94
+
77
95
  def initialize_logging
78
- return unless @config.enable_logging
96
+ logger = if config.logger.nil?
97
+ semantic_logger
98
+ else
99
+ config.logger
100
+ end
79
101
 
80
102
  headers_to_exclude = ['Authorization']
81
- api_logging_config = ApiLoggingConfig.new(nil, nil, nil, nil, false)
103
+ api_logging_config = ApiLoggingConfig.new(logger, nil, nil, nil, false)
82
104
  api_logging_config.request_logging_config = ApiRequestLoggingConfiguration.new(true, true, headers_to_exclude,
83
105
  nil, nil, true)
84
106
  api_logging_config.response_logging_config = ApiResponseLoggingConfiguration.new(true, true, nil, nil, nil)
85
107
 
86
- @config.client_configuration.logging_configuration = api_logging_config
108
+ config.client_configuration.logging_configuration = api_logging_config
87
109
  end
88
110
  end
89
111
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module School21
4
4
  class ClientConfig < CoreLibrary::HttpClientConfiguration
5
- attr_writer :logging_configuration
5
+ attr_writer :logging_configuration, :timeout
6
6
  end
7
7
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module School21
4
4
  class GlobalConfig < CoreLibrary::GlobalConfiguration
5
- attr_accessor :auth_managers, :enable_logging, :credentials
5
+ attr_accessor :auth_managers, :enable_logging, :credentials, :logger
6
6
  attr_writer :client_configuration
7
7
 
8
8
  def initialize(client_configuration: ClientConfig.new)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module School21
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.0'
5
5
  end
data/lib/school21.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'apimatic_core'
4
4
  require 'apimatic_faraday_client_adapter'
5
+ require 'semantic_logger'
5
6
 
6
7
  require 'active_support/all'
7
8
 
@@ -13,6 +14,8 @@ require_relative 'school21/api/base_api'
13
14
  require_relative 'school21/api/participants_api'
14
15
  require_relative 'school21/api/auth_api'
15
16
  require_relative 'school21/api/projects_api'
17
+ require_relative 'school21/api/campuses_api'
18
+ require_relative 'school21/api/clusters_api'
16
19
 
17
20
  require_relative 'school21/config/api_logging_config'
18
21
  require_relative 'school21/config/client_config'
data/test/client_test.rb CHANGED
@@ -34,7 +34,7 @@ describe 'Client Test' do
34
34
  it 'successfully stubs client auth' do
35
35
  stub = stub_token
36
36
 
37
- valid_init_client
37
+ valid_init_client.authenticate!
38
38
 
39
39
  assert_requested(stub)
40
40
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module BaseStub
4
4
  BASE_AUTH_URL = 'https://auth.sberclass.ru'
5
- API_V1_URL = 'https://edu-api.21-school.ru/services/21-school/api/v1'
5
+ BASE_API_V1_URL = 'https://edu-api.21-school.ru/services/21-school/api/v1'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: school21_api_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Yudin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-11 00:00:00.000000000 Z
11
+ date: 2024-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: semantic_logger
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: ''
84
98
  email:
85
99
  - ikael.fess@gmail.com
@@ -94,6 +108,8 @@ files:
94
108
  - lib/school21.rb
95
109
  - lib/school21/api/auth_api.rb
96
110
  - lib/school21/api/base_api.rb
111
+ - lib/school21/api/campuses_api.rb
112
+ - lib/school21/api/clusters_api.rb
97
113
  - lib/school21/api/participants_api.rb
98
114
  - lib/school21/api/projects_api.rb
99
115
  - lib/school21/auth/access_token.rb
@@ -128,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
144
  - !ruby/object:Gem::Version
129
145
  version: '0'
130
146
  requirements: []
131
- rubygems_version: 3.5.11
147
+ rubygems_version: 3.5.17
132
148
  signing_key:
133
149
  specification_version: 4
134
150
  summary: School21 API SDK