school21_api_sdk 0.3.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: e94bb6054dc91242b21c99220f3c30931f0b6b24418ef8f0ba140052f2220fb3
4
- data.tar.gz: f4fc58b78bfe7a25291cab9f34de83f5361ecd8afc929a500b7bb4958bbb54a2
3
+ metadata.gz: a8b8fc46a01614de5e5b6cfb19de30d5471eb154d293a02d7eab835f8c2042bd
4
+ data.tar.gz: ef32e49acfbb13fc44384c0b58b26b3633c1878a6a7c8e5ab86f9eb9efbd1287
5
5
  SHA512:
6
- metadata.gz: 379828e0c0f1bc42e3d66751ee73db4163fbaf35232d7200aa7fe552f36c08bf2f31dc702aeeac37cd72d0ea02dff01c0c89937f55284115ca10264d88ce9611
7
- data.tar.gz: 707c86e1a6fb0bc5b4c92e3f71ed720b3219ddf5c569a5fc4614f7f2c78a96a45356900f6f6df942dad41f89c06ed31cac2e28a6e4caf77f7715bf8ca02657c8
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
@@ -4,64 +4,45 @@ module School21
4
4
  class CampusesApi < BaseApi
5
5
  def campuses
6
6
  path = '/campuses'
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 campuses_participants(campus_id, options: {})
12
+ def campus_participants(campus_id, options: {})
17
13
  path = "/campuses/#{campus_id}/participants"
18
14
  default_options = { limit: 50, offset: 0 }.merge(options)
19
-
20
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
21
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
15
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
22
16
 
23
17
  default_options.each do |key, value|
24
18
  new_request.query_param(new_parameter(value, key:))
25
19
  end
26
20
 
27
- new_api_call_builder
28
- .request(new_request)
29
- .response(new_response_handler)
30
- .execute
21
+ execute_request(new_request)
31
22
  end
32
23
 
33
- def campuses_coalitions(campus_id, options: {})
24
+ def campus_coalitions(campus_id, options: {})
34
25
  path = "/campuses/#{campus_id}/coalitions"
35
26
  default_options = { limit: 50, offset: 0 }.merge(options)
36
-
37
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
38
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
27
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
39
28
 
40
29
  default_options.each do |key, value|
41
30
  new_request.query_param(new_parameter(value, key:))
42
31
  end
43
32
 
44
- new_api_call_builder
45
- .request(new_request)
46
- .response(new_response_handler)
47
- .execute
33
+ execute_request(new_request)
48
34
  end
49
35
 
50
- def campuses_clusters(campus_id, options: {})
36
+ def campus_clusters(campus_id, options: {})
51
37
  path = "/campuses/#{campus_id}/clusters"
52
38
  default_options = { limit: 50, offset: 0 }.merge(options)
53
-
54
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
55
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
39
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
56
40
 
57
41
  default_options.each do |key, value|
58
42
  new_request.query_param(new_parameter(value, key:))
59
43
  end
60
44
 
61
- new_api_call_builder
62
- .request(new_request)
63
- .response(new_response_handler)
64
- .execute
45
+ execute_request(new_request)
65
46
  end
66
47
  end
67
48
  end
@@ -2,21 +2,16 @@
2
2
 
3
3
  module School21
4
4
  class ClustersApi < BaseApi
5
- def clusters_map(cluster_id, options: {})
5
+ def cluster_map(cluster_id, options: {})
6
6
  path = "/clusters/#{cluster_id}/map"
7
- default_options = { limit: 50, offset: 0, occupied: true }.merge(options)
8
-
9
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
10
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
7
+ default_options = { limit: 50, offset: 0 }.merge(options)
8
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
11
9
 
12
10
  default_options.each do |key, value|
13
11
  new_request.query_param(new_parameter(value, key:))
14
12
  end
15
13
 
16
- new_api_call_builder
17
- .request(new_request)
18
- .response(new_response_handler)
19
- .execute
14
+ execute_request(new_request)
20
15
  end
21
16
  end
22
17
  end
@@ -2,32 +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
14
  default_options = { limit: 10, offset: 0 }.merge(options)
19
-
20
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
21
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
15
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
22
16
 
23
17
  default_options.each do |key, value|
24
18
  new_request.query_param(new_parameter(value, key:))
25
19
  end
26
20
 
27
- new_api_call_builder
28
- .request(new_request)
29
- .response(new_response_handler)
30
- .execute
21
+ execute_request(new_request)
22
+ end
23
+
24
+ def participant_project(login, project_id)
25
+ path = "/participants/#{login}/projects/#{project_id}"
26
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
27
+
28
+ execute_request(new_request)
31
29
  end
32
30
  end
33
31
  end
@@ -2,32 +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
14
  default_options = { limit: 10, offset: 0 }.merge(options)
19
-
20
- new_request = new_request_builder(HttpMethod::GET, path, :api_v1)
21
- .auth(CoreLibrary::Single.new(SINGLE_AUTH_PARTICIPANT))
15
+ new_request = authenticated_request(HttpMethod::GET, path, :api_v1)
22
16
 
23
17
  default_options.each do |key, value|
24
18
  new_request.query_param(new_parameter(value, key:))
25
19
  end
26
20
 
27
- new_api_call_builder
28
- .request(new_request)
29
- .response(new_response_handler)
30
- .execute
21
+ execute_request(new_request)
31
22
  end
32
23
  end
33
24
  end
@@ -4,96 +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
28
+
29
+ def authenticate!
30
+ @access_token = request_access_token!
27
31
 
28
- initialize_auth!
32
+ initialize_auth_managers
29
33
  end
30
34
 
31
35
  def auth_api
32
- @auth_api ||= AuthApi.new(@config)
36
+ @auth_api ||= AuthApi.new(config)
33
37
  end
34
38
 
35
39
  def participants_api
36
- initialize_auth! if @access_token.expired?
37
- ParticipantsApi.new(@config)
40
+ authenticate! if access_token.expired?
41
+ ParticipantsApi.new(config)
38
42
  end
39
43
 
40
44
  def projects_api
41
- initialize_auth! if @access_token.expired?
42
- ProjectsApi.new(@config)
45
+ authenticate! if access_token.expired?
46
+ ProjectsApi.new(config)
43
47
  end
44
48
 
45
49
  def campuses_api
46
- initialize_auth! if @access_token.expired?
47
- CampusesApi.new(@config)
50
+ authenticate! if access_token.expired?
51
+ CampusesApi.new(config)
48
52
  end
49
53
 
50
54
  def clusters_api
51
- initialize_auth! if @access_token.expired?
52
- ClustersApi.new(@config)
55
+ authenticate! if access_token.expired?
56
+ ClustersApi.new(config)
53
57
  end
54
58
 
55
59
  private
56
60
 
57
61
  def validate_credentials!
58
- login = @config.credentials[:login]
59
- password = @config.credentials[:password]
62
+ login = config.credentials[:login]
63
+ password = config.credentials[:password]
60
64
 
61
65
  raise "Login can't be nil or empty" if login.nil? || login.empty?
62
66
  raise "Password can't be nil or empty" if password.nil? || password.empty?
63
67
  end
64
68
 
65
- def initialize_auth!
66
- @access_token = request_access_token!
67
-
68
- initialize_auth_managers
69
- end
70
-
71
69
  def initialize_auth_managers
72
70
  auth_managers = {}
73
-
74
- creds = BearerAuthCredentials.new(access_token: @access_token)
71
+ creds = BearerAuthCredentials.new(access_token:)
75
72
  auth_managers[BaseApi::SINGLE_AUTH_PARTICIPANT] = AuthorizationHeader.new(creds)
76
73
 
77
- @config.auth_managers = auth_managers
74
+ config.auth_managers = auth_managers
78
75
  end
79
76
 
80
77
  def request_access_token!
81
- 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
+
82
83
  raise 'Access Token Error' unless auth_api_response.success?
83
84
 
84
85
  AccessToken.new(*auth_api_response.data.values_at(:access_token, :expires_in))
85
86
  end
86
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
+
87
95
  def initialize_logging
88
- return unless @config.enable_logging
96
+ logger = if config.logger.nil?
97
+ semantic_logger
98
+ else
99
+ config.logger
100
+ end
89
101
 
90
102
  headers_to_exclude = ['Authorization']
91
- api_logging_config = ApiLoggingConfig.new(nil, nil, nil, nil, false)
103
+ api_logging_config = ApiLoggingConfig.new(logger, nil, nil, nil, false)
92
104
  api_logging_config.request_logging_config = ApiRequestLoggingConfiguration.new(true, true, headers_to_exclude,
93
105
  nil, nil, true)
94
106
  api_logging_config.response_logging_config = ApiResponseLoggingConfiguration.new(true, true, nil, nil, nil)
95
107
 
96
- @config.client_configuration.logging_configuration = api_logging_config
108
+ config.client_configuration.logging_configuration = api_logging_config
97
109
  end
98
110
  end
99
111
  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.3.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
 
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.3.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-15 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