memori-client 0.1.9 → 0.2.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 +4 -4
- data/backend_overrides.jsonc +4 -0
- data/engine_overrides.jsonc +3 -0
- data/lib/memori_client/client.rb +49 -0
- data/lib/memori_client/client_factory.rb +105 -0
- data/lib/memori_client/engine/hmac_helper.rb +1 -1
- data/lib/memori_client/http_client.rb +4 -17
- data/lib/memori_client/operation.rb +132 -0
- data/lib/memori_client/proxy/client.rb +115 -0
- data/lib/memori_client/resource.rb +174 -26
- data/lib/memori_client/resource_proxy.rb +25 -0
- data/lib/memori_client/response.rb +48 -0
- data/lib/memori_client/swagger/get_module_and_method.rb +44 -0
- data/lib/memori_client/swagger/process_specification.rb +127 -0
- data/lib/memori_client/swagger/schema_store.rb +26 -0
- data/lib/memori_client.rb +14 -42
- data/lib/tasks/memori_client.rake +0 -7
- metadata +17 -90
- data/doc/MemoriClient::Backend::V1::Asset.md +0 -117
- data/doc/MemoriClient::Backend::V2::ActionLog.md +0 -37
- data/doc/MemoriClient::Backend::V2::Analysis.md +0 -39
- data/doc/MemoriClient::Backend::V2::Asset.md +0 -102
- data/doc/MemoriClient::Backend::V2::Badge.md +0 -64
- data/doc/MemoriClient::Backend::V2::CompletionConfig.md +0 -115
- data/doc/MemoriClient::Backend::V2::ConsumptionLog.md +0 -57
- data/doc/MemoriClient::Backend::V2::ImportExport.md +0 -180
- data/doc/MemoriClient::Backend::V2::Integration.md +0 -117
- data/doc/MemoriClient::Backend::V2::Invitation.md +0 -179
- data/doc/MemoriClient::Backend::V2::Memori.md +0 -394
- data/doc/MemoriClient::Backend::V2::MemoriList.md +0 -147
- data/doc/MemoriClient::Backend::V2::Notification.md +0 -31
- data/doc/MemoriClient::Backend::V2::Process.md +0 -64
- data/doc/MemoriClient::Backend::V2::Tenant.md +0 -142
- data/doc/MemoriClient::Backend::V2::User.md +0 -647
- data/doc/MemoriClient::Engine::V2::ChatLog.md +0 -82
- data/doc/MemoriClient::Engine::V2::ContextVar.md +0 -46
- data/doc/MemoriClient::Engine::V2::CorrelationPair.md +0 -72
- data/doc/MemoriClient::Engine::V2::CustomDictionary.md +0 -108
- data/doc/MemoriClient::Engine::V2::Dialog.md +0 -152
- data/doc/MemoriClient::Engine::V2::EventLog.md +0 -85
- data/doc/MemoriClient::Engine::V2::ExpertReference.md +0 -116
- data/doc/MemoriClient::Engine::V2::Function.md +0 -140
- data/doc/MemoriClient::Engine::V2::Intent.md +0 -225
- data/doc/MemoriClient::Engine::V2::LocalizationKey.md +0 -105
- data/doc/MemoriClient::Engine::V2::Medium.md +0 -118
- data/doc/MemoriClient::Engine::V2::Memory.md +0 -244
- data/doc/MemoriClient::Engine::V2::NLP.md +0 -100
- data/doc/MemoriClient::Engine::V2::Person.md +0 -114
- data/doc/MemoriClient::Engine::V2::Search.md +0 -151
- data/doc/MemoriClient::Engine::V2::Session.md +0 -55
- data/doc/MemoriClient::Engine::V2::Stat.md +0 -18
- data/doc/MemoriClient::Engine::V2::Topic.md +0 -80
- data/doc/MemoriClient::Engine::V2::UnansweredQuestion.md +0 -75
- data/doc/MemoriClient::Engine::V2::User.md +0 -140
- data/doc/MemoriClient::Engine::V2::WebHook.md +0 -67
- data/lib/memori_client/backend/resource.rb +0 -39
- data/lib/memori_client/backend/resources.rb +0 -16
- data/lib/memori_client/backend/v1/asset.rb +0 -120
- data/lib/memori_client/backend/v2/action_log.rb +0 -44
- data/lib/memori_client/backend/v2/analysis.rb +0 -54
- data/lib/memori_client/backend/v2/asset.rb +0 -130
- data/lib/memori_client/backend/v2/badge.rb +0 -77
- data/lib/memori_client/backend/v2/completion_config.rb +0 -202
- data/lib/memori_client/backend/v2/consumption_log.rb +0 -70
- data/lib/memori_client/backend/v2/import_export.rb +0 -327
- data/lib/memori_client/backend/v2/integration.rb +0 -180
- data/lib/memori_client/backend/v2/invitation.rb +0 -252
- data/lib/memori_client/backend/v2/memori.rb +0 -954
- data/lib/memori_client/backend/v2/memori_list.rb +0 -152
- data/lib/memori_client/backend/v2/notification.rb +0 -32
- data/lib/memori_client/backend/v2/process.rb +0 -70
- data/lib/memori_client/backend/v2/tenant.rb +0 -293
- data/lib/memori_client/backend/v2/user.rb +0 -1520
- data/lib/memori_client/configuration.rb +0 -20
- data/lib/memori_client/engine/resource.rb +0 -13
- data/lib/memori_client/engine/resources.rb +0 -21
- data/lib/memori_client/engine/v2/chat_log.rb +0 -92
- data/lib/memori_client/engine/v2/completion_log.rb +0 -17
- data/lib/memori_client/engine/v2/context_var.rb +0 -48
- data/lib/memori_client/engine/v2/correlation_pair.rb +0 -99
- data/lib/memori_client/engine/v2/custom_dictionary.rb +0 -152
- data/lib/memori_client/engine/v2/dialog.rb +0 -223
- data/lib/memori_client/engine/v2/event_log.rb +0 -98
- data/lib/memori_client/engine/v2/expert_reference.rb +0 -176
- data/lib/memori_client/engine/v2/function.rb +0 -220
- data/lib/memori_client/engine/v2/intent.rb +0 -336
- data/lib/memori_client/engine/v2/localization_key.rb +0 -144
- data/lib/memori_client/engine/v2/medium.rb +0 -178
- data/lib/memori_client/engine/v2/memori.rb +0 -329
- data/lib/memori_client/engine/v2/memory.rb +0 -477
- data/lib/memori_client/engine/v2/nlp.rb +0 -137
- data/lib/memori_client/engine/v2/person.rb +0 -170
- data/lib/memori_client/engine/v2/private/memori.rb +0 -17
- data/lib/memori_client/engine/v2/private/memori_block.rb +0 -24
- data/lib/memori_client/engine/v2/prompted_question.rb +0 -121
- data/lib/memori_client/engine/v2/search.rb +0 -318
- data/lib/memori_client/engine/v2/session.rb +0 -80
- data/lib/memori_client/engine/v2/stat.rb +0 -20
- data/lib/memori_client/engine/v2/topic.rb +0 -88
- data/lib/memori_client/engine/v2/unanswered_question.rb +0 -108
- data/lib/memori_client/engine/v2/user.rb +0 -152
- data/lib/memori_client/engine/v2/web_hook.rb +0 -128
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7592af5e2d26be8087d2a19c7e5159a4fabbecc4c009975ccbd9578281ab26be
|
|
4
|
+
data.tar.gz: ed1fbe1cbc4af3d2013ec9ea40c9b67bb7a3bd4058dbd7cd220750ff95797368
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: da3adc611208ccb5ca49c04b5734b9c43e97679956341552a9af2f4f080db316203ad5b4a8ba476a02b1f0ea7c377526dc9435f4cd62b47d2cd7ec30e00ebcf0
|
|
7
|
+
data.tar.gz: f114260a0ee34f9b6085b60201df408419ba554978d83af9e21ee0c329a40cc58364e158f3628ec83ce1ad519d82d592ad729e1eb13e312ab036976924230c1b
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'pry'
|
|
2
|
+
class MemoriClient::Client
|
|
3
|
+
attr_reader :version_proxies
|
|
4
|
+
attr_reader :namespace
|
|
5
|
+
attr_reader :kind
|
|
6
|
+
def initialize(namespace:, kind:, uri:, api_root:)
|
|
7
|
+
@namespace = namespace
|
|
8
|
+
@kind = kind
|
|
9
|
+
@uri = uri
|
|
10
|
+
@api_root = api_root
|
|
11
|
+
@version_proxies = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def load_swagger_spec
|
|
15
|
+
if @swagger.nil?
|
|
16
|
+
@swagger = MemoriClient::Swagger::ProcessSpecification.new(uri: @uri, kind: @kind).call
|
|
17
|
+
@swagger.each do |key, list|
|
|
18
|
+
register_resource(key, list)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def register_resource(key, list)
|
|
26
|
+
_, _, version, klass = key.split('::')
|
|
27
|
+
version.downcase!
|
|
28
|
+
klass = klass.underscore
|
|
29
|
+
if @version_proxies[version].nil?
|
|
30
|
+
version_proxy = MemoriClient::ResourceProxy.new(api_root: @api_root, version: version)
|
|
31
|
+
@version_proxies[version] = version_proxy
|
|
32
|
+
else
|
|
33
|
+
version_proxy = @version_proxies[version]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
resource = version_proxy.register_resource(klass)
|
|
37
|
+
list.each do |item|
|
|
38
|
+
resource.register_operation(item)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def method_missing(method, *args, &block)
|
|
43
|
+
if @version_proxies.key?(method.to_s)
|
|
44
|
+
@version_proxies[method.to_s]
|
|
45
|
+
else
|
|
46
|
+
super
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MemoriClient
|
|
4
|
+
# ClientFactory is a singleton class responsible for creating and caching
|
|
5
|
+
# MemoriClient::Client instances for different namespaces and kinds.
|
|
6
|
+
#
|
|
7
|
+
# This factory pattern ensures that only one client instance exists per
|
|
8
|
+
# namespace/kind combination, improving performance and resource usage.
|
|
9
|
+
#
|
|
10
|
+
# @example Basic usage
|
|
11
|
+
# factory = MemoriClient::ClientFactory.instance
|
|
12
|
+
# client = factory.get_client(
|
|
13
|
+
# namespace: 'my_app',
|
|
14
|
+
# kind: MemoriClient::ClientFactory::Kinds::BACKEND,
|
|
15
|
+
# uri: 'https://api.example.com',
|
|
16
|
+
# api_root: '/api/v1'
|
|
17
|
+
# )
|
|
18
|
+
#
|
|
19
|
+
# @since 1.0.0
|
|
20
|
+
class ClientFactory
|
|
21
|
+
include Singleton
|
|
22
|
+
|
|
23
|
+
# Defines the available client kinds that can be created by the factory.
|
|
24
|
+
# Each kind represents a different type of service or API endpoint.
|
|
25
|
+
module Kinds
|
|
26
|
+
# Backend API client for core application services
|
|
27
|
+
BACKEND = 'backend'
|
|
28
|
+
|
|
29
|
+
# Engine API client for processing and analysis services
|
|
30
|
+
ENGINE = 'engine'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Initializes a new ClientFactory instance.
|
|
34
|
+
# Sets up empty hashes to cache backend and engine clients by namespace.
|
|
35
|
+
def initialize
|
|
36
|
+
@backend_clients = {}
|
|
37
|
+
@engine_clients = {}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Gets or creates a cached client instance for the specified parameters.
|
|
41
|
+
#
|
|
42
|
+
# This method implements a lazy initialization pattern where clients are
|
|
43
|
+
# only created when first requested and then cached for subsequent use.
|
|
44
|
+
#
|
|
45
|
+
# @param namespace [String] The namespace identifier for the client.
|
|
46
|
+
# Used as a cache key to ensure unique clients per namespace.
|
|
47
|
+
# @param kind [String] The type of client to create.
|
|
48
|
+
# Must be one of the values defined in {Kinds}.
|
|
49
|
+
# @param uri [String] The base URI for the Swagger specification.
|
|
50
|
+
# @param api_root [String] The API root URL.
|
|
51
|
+
#
|
|
52
|
+
# @return [MemoriClient::Client] A cached or newly created client instance.
|
|
53
|
+
#
|
|
54
|
+
# @raise [RuntimeError] If an invalid kind is provided.
|
|
55
|
+
#
|
|
56
|
+
# @example Get a backend client
|
|
57
|
+
# client = factory.get_client(
|
|
58
|
+
# namespace: 'production',
|
|
59
|
+
# kind: Kinds::BACKEND,
|
|
60
|
+
# uri: 'https://api.memori.ai',
|
|
61
|
+
# api_root: '/api/v1'
|
|
62
|
+
# )
|
|
63
|
+
#
|
|
64
|
+
# @example Get an engine client
|
|
65
|
+
# client = factory.get_client(
|
|
66
|
+
# namespace: 'staging',
|
|
67
|
+
# kind: Kinds::ENGINE,
|
|
68
|
+
# uri: 'https://engine.memori.ai',
|
|
69
|
+
# api_root: '/engine/v1'
|
|
70
|
+
# )
|
|
71
|
+
def get_client(namespace:, kind:, uri:, api_root:)
|
|
72
|
+
# Validate that the provided kind is supported
|
|
73
|
+
raise "Invalid kind: #{kind}" unless known_kinds.include?(kind)
|
|
74
|
+
|
|
75
|
+
case kind
|
|
76
|
+
when Kinds::BACKEND
|
|
77
|
+
# Use memoization to return cached client or create new one
|
|
78
|
+
@backend_clients[namespace] ||= MemoriClient::Client.new(namespace: namespace,
|
|
79
|
+
kind: kind,
|
|
80
|
+
uri: uri,
|
|
81
|
+
api_root: api_root)
|
|
82
|
+
when Kinds::ENGINE
|
|
83
|
+
# Use memoization to return cached client or create new one
|
|
84
|
+
@engine_clients[namespace] ||= MemoriClient::Client.new(namespace: namespace,
|
|
85
|
+
kind: kind,
|
|
86
|
+
uri: uri,
|
|
87
|
+
api_root: api_root)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
# Returns an array of all known client kinds.
|
|
94
|
+
#
|
|
95
|
+
# This method dynamically retrieves all constants defined in the Kinds module
|
|
96
|
+
# to provide a list of valid client types for validation.
|
|
97
|
+
#
|
|
98
|
+
# @return [Array<String>] Array of valid client kind strings.
|
|
99
|
+
def known_kinds
|
|
100
|
+
Kinds.constants.map do |k|
|
|
101
|
+
Kernel.const_get "MemoriClient::ClientFactory::Kinds::#{k}"
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -8,7 +8,7 @@ class MemoriClient::Engine::HMACHelper
|
|
|
8
8
|
|
|
9
9
|
def initialize(app_id, key, max_delta_secs = 30)
|
|
10
10
|
# Check arguments
|
|
11
|
-
raise ArgumentError, "HMAC: invalid appID" if app_id.nil?
|
|
11
|
+
raise ArgumentError, "HMAC: invalid appID" if app_id.nil? || app_id <= 0 || app_id == ''
|
|
12
12
|
raise ArgumentError, "HMAC: invalid key" if key.nil? || key.to_s == "00000000-0000-0000-0000-000000000000"
|
|
13
13
|
|
|
14
14
|
# Initialization
|
|
@@ -12,7 +12,7 @@ class MemoriClient::HttpClient
|
|
|
12
12
|
request = Net::HTTP::Get.new(uri)
|
|
13
13
|
headers.each { |k, v| request[k] = v }
|
|
14
14
|
request["Content-Type"] ||= "application/json" unless headers.key?('Content-Type')
|
|
15
|
-
request.basic_auth(*basic_auth) if basic_auth.
|
|
15
|
+
request.basic_auth(*basic_auth) if !basic_auth.nil?
|
|
16
16
|
|
|
17
17
|
req_options = { use_ssl: uri.scheme == "https" }
|
|
18
18
|
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
|
@@ -35,6 +35,7 @@ class MemoriClient::HttpClient
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def post(url, headers: {}, payload:)
|
|
38
|
+
puts "post #{url}"
|
|
38
39
|
url = URI(url)
|
|
39
40
|
https = Net::HTTP.new(url.host, url.port)
|
|
40
41
|
https.use_ssl = url.scheme == 'https'
|
|
@@ -47,6 +48,7 @@ class MemoriClient::HttpClient
|
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
def post_file(url, file:)
|
|
51
|
+
puts "post_file #{url}"
|
|
50
52
|
url = URI(url)
|
|
51
53
|
https = Net::HTTP.new(url.host, url.port)
|
|
52
54
|
https.use_ssl = url.scheme == 'https'
|
|
@@ -71,21 +73,6 @@ class MemoriClient::HttpClient
|
|
|
71
73
|
private
|
|
72
74
|
|
|
73
75
|
def handle_response(response, request)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if request['Content-Type'] == 'application/json'
|
|
77
|
-
if body.nil? || body == ''
|
|
78
|
-
response_body = {}
|
|
79
|
-
else
|
|
80
|
-
response_body = JSON.parse(body)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
[
|
|
84
|
-
response.code,
|
|
85
|
-
(body.nil? ? {} : response_body)
|
|
86
|
-
]
|
|
87
|
-
else
|
|
88
|
-
[response.code, body]
|
|
89
|
-
end
|
|
76
|
+
MemoriClient::Response.new(response, request: request)
|
|
90
77
|
end
|
|
91
78
|
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
module MemoriClient
|
|
2
|
+
class Operation
|
|
3
|
+
def initialize(item, version:, key:)
|
|
4
|
+
@item = item
|
|
5
|
+
@version = version
|
|
6
|
+
@key = key
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def generate_method_code(method)
|
|
10
|
+
module_name = method[:module]
|
|
11
|
+
method_name = method[:method_name]
|
|
12
|
+
qualified_method = [module_name, method_name].join('#')
|
|
13
|
+
|
|
14
|
+
params_list = []
|
|
15
|
+
(method[:params] || {}).each do |k, required|
|
|
16
|
+
if required
|
|
17
|
+
params_list << "#{k}:"
|
|
18
|
+
else
|
|
19
|
+
params_list << "#{k}: nil"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
params_definition = (method[:spec]['parameters'] || []).map do |param|
|
|
24
|
+
{
|
|
25
|
+
name: param['name'],
|
|
26
|
+
description: param['description'],
|
|
27
|
+
required: param['required'] == true,
|
|
28
|
+
type: param['schema']['type']
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
payload_keys = []
|
|
33
|
+
payload_required_keys = []
|
|
34
|
+
|
|
35
|
+
if method[:request_body]
|
|
36
|
+
params_list << "payload: {}"
|
|
37
|
+
|
|
38
|
+
params_definition << {
|
|
39
|
+
name: 'payload',
|
|
40
|
+
description: 'request payload',
|
|
41
|
+
required: false,
|
|
42
|
+
type: 'Hash',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
request_body_schema_ref = method.dig(:spec, 'requestBody', 'content', 'application/json', 'schema', '$ref')
|
|
46
|
+
|
|
47
|
+
# Note:
|
|
48
|
+
# capturing required keys is not exact as sometimes there are two keys where
|
|
49
|
+
# only one must be present or at least one.
|
|
50
|
+
# So we report requirement of the key in the documentation but we do not
|
|
51
|
+
# enforce any check on the presence.
|
|
52
|
+
# We validate the valid key instead
|
|
53
|
+
key = request_body_schema_ref.split('/').last
|
|
54
|
+
schema = MemoriClient::Swagger::SchemaStore.instance.get(key)
|
|
55
|
+
required_keys = schema['required'] || []
|
|
56
|
+
schema['properties'].each do |key, value|
|
|
57
|
+
required = value['nullable'] == false || required_keys.include?(key)
|
|
58
|
+
payload_keys << key
|
|
59
|
+
payload_required_keys << key if required
|
|
60
|
+
params_definition << {
|
|
61
|
+
name: "payload.#{key}",
|
|
62
|
+
description: '',
|
|
63
|
+
required: required,
|
|
64
|
+
type: value['type']&.titleize,
|
|
65
|
+
indent: 2
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
payload_keys.sort!
|
|
71
|
+
payload_required_keys.sort!
|
|
72
|
+
signature = "#{method_name}(#{params_list.join(', ')})"
|
|
73
|
+
|
|
74
|
+
params_list_doc = params_definition.each_with_object([]) do |param, acc|
|
|
75
|
+
if param[:indent]
|
|
76
|
+
prefix = " " * param[:indent]
|
|
77
|
+
else
|
|
78
|
+
prefix = ""
|
|
79
|
+
end
|
|
80
|
+
acc << "#{prefix}- `#{param[:name]}`: **#{param[:type]}** #{param[:description]}. #{param[:required] ? 'required' : 'optional' }"
|
|
81
|
+
end.join("\n")
|
|
82
|
+
|
|
83
|
+
optional_payload_code = ''
|
|
84
|
+
if payload_keys.size > 0
|
|
85
|
+
optional_payload_code = <<-EOS
|
|
86
|
+
payload_keys = [
|
|
87
|
+
#{payload_keys.map { |k| " '#{k}'," }.join("\n") }
|
|
88
|
+
]
|
|
89
|
+
payload_required_keys = %w[#{payload_required_keys.join(' ')}]
|
|
90
|
+
validate_payload!(args[:payload], keys: payload_keys, required: payload_required_keys)
|
|
91
|
+
EOS
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
output = <<-EOS
|
|
95
|
+
## #{method_name}
|
|
96
|
+
|
|
97
|
+
Summary:
|
|
98
|
+
#{method[:summary].gsub("\n", ' ').gsub("\r", ' ')}
|
|
99
|
+
|
|
100
|
+
Signature: `#{signature}`
|
|
101
|
+
Invokation: `client.#{@version}.#{@key.downcase}.#{signature}`
|
|
102
|
+
|
|
103
|
+
HTTP API: #{method[:method].upcase} #{method[:path]}`
|
|
104
|
+
|
|
105
|
+
EOS
|
|
106
|
+
|
|
107
|
+
if params_list_doc.size > 0
|
|
108
|
+
output << <<-EOS
|
|
109
|
+
Parameters:
|
|
110
|
+
|
|
111
|
+
#{params_list_doc}
|
|
112
|
+
EOS
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
output << "\n"
|
|
116
|
+
|
|
117
|
+
output
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def markdown_documentation
|
|
121
|
+
# #{@item[:method_name]}
|
|
122
|
+
#{@item[:path]}
|
|
123
|
+
<<~MARKDOWN
|
|
124
|
+
#{generate_method_code(@item)}
|
|
125
|
+
MARKDOWN
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def spec
|
|
129
|
+
@item
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'open-uri'
|
|
4
|
+
|
|
5
|
+
# Initialize a DB Proxy Client, which connects to the AIsuru proxy client to interact with
|
|
6
|
+
# backend and engine databases, in read-only mode.
|
|
7
|
+
# Usage:
|
|
8
|
+
#
|
|
9
|
+
# client = AisuruProxyClient.new(base_url: "https://...", api_key: "XXX")
|
|
10
|
+
#
|
|
11
|
+
# Status:
|
|
12
|
+
# client.status
|
|
13
|
+
#
|
|
14
|
+
# Tables list and table information
|
|
15
|
+
# client.tables(id: 'backend', schema: 'memoriai')
|
|
16
|
+
# client.table_schema(id: 'backend', schema: 'memoriai', table: 'ActionLog')
|
|
17
|
+
#
|
|
18
|
+
# SQL Query
|
|
19
|
+
# sql = <<~SQL
|
|
20
|
+
# SELECT * FROM memoriai."ActionLog"
|
|
21
|
+
# LIMIT 10
|
|
22
|
+
# OFFSET 0
|
|
23
|
+
# SQL
|
|
24
|
+
# client.query(id: 'backend', sql: sql)
|
|
25
|
+
class MemoriClient::Proxy::Client
|
|
26
|
+
CONNECTIONS = ['backend', 'engine'].freeze
|
|
27
|
+
|
|
28
|
+
# @param base_url [String] The base URL for the API
|
|
29
|
+
# @param api_key [String] The API key for authentication
|
|
30
|
+
def initialize(base_url:, api_key:)
|
|
31
|
+
@base_url = base_url
|
|
32
|
+
@api_key = api_key
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Get the status of the API
|
|
36
|
+
def status
|
|
37
|
+
path = "api/v1/status"
|
|
38
|
+
uri = URI.join(@base_url, path)
|
|
39
|
+
response = get(uri)
|
|
40
|
+
[response.code, response.body]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Get a list of tables for a specific connection
|
|
44
|
+
# @param id [String] The connection ID
|
|
45
|
+
# @param schema [String] The schema name (optional)
|
|
46
|
+
def tables(id:, schema: nil)
|
|
47
|
+
unless CONNECTIONS.include?(id)
|
|
48
|
+
raise ArgumentError, "Invalid connection id: #{id}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
path = "api/v1/#{id}/tables"
|
|
52
|
+
path += "?schema=#{schema}" if schema
|
|
53
|
+
uri = URI.join(@base_url, path)
|
|
54
|
+
response = get(uri)
|
|
55
|
+
[response.code, response.body]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Get the schema of a specific table
|
|
59
|
+
# @param id [String] The connection ID
|
|
60
|
+
# @param schema [String] The schema name (optional)
|
|
61
|
+
# @param table [String] The table name
|
|
62
|
+
def table_schema(id:, schema: nil, table:)
|
|
63
|
+
unless CONNECTIONS.include?(id)
|
|
64
|
+
raise ArgumentError, "Invalid connection id: #{id}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
path = "api/v1/#{id}/tables/#{table}/schema"
|
|
68
|
+
path += "?schema=#{schema}" if schema
|
|
69
|
+
uri = URI.join(@base_url, path)
|
|
70
|
+
response = get(uri)
|
|
71
|
+
[response.code, response.body]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Execute a SQL query
|
|
75
|
+
# @param id [String] The connection ID
|
|
76
|
+
# @param sql [String] The SQL query
|
|
77
|
+
def query(id:, sql:)
|
|
78
|
+
unless CONNECTIONS.include?(id)
|
|
79
|
+
raise ArgumentError, "Invalid connection id: #{id}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
path = "api/v1/#{id}/query"
|
|
83
|
+
uri = URI.join(@base_url, path)
|
|
84
|
+
response = post_raw_content(uri, sql)
|
|
85
|
+
[response.code, response.body]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def get(uri)
|
|
91
|
+
request = Net::HTTP::Get.new(uri)
|
|
92
|
+
request["X-Api-Key"] = @api_key
|
|
93
|
+
|
|
94
|
+
req_options = { use_ssl: uri.scheme == "https" }
|
|
95
|
+
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
|
96
|
+
http.request(request)
|
|
97
|
+
end
|
|
98
|
+
response
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def post_raw_content(uri, content)
|
|
102
|
+
request = Net::HTTP::Post.new(uri)
|
|
103
|
+
request["X-Api-Key"] = @api_key
|
|
104
|
+
request["Content-Type"] = "text/plain"
|
|
105
|
+
request["Accept"] = "application/json"
|
|
106
|
+
request.body = content
|
|
107
|
+
|
|
108
|
+
req_options = { use_ssl: uri.scheme == "https" }
|
|
109
|
+
|
|
110
|
+
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
|
111
|
+
http.request(request)
|
|
112
|
+
end
|
|
113
|
+
response
|
|
114
|
+
end
|
|
115
|
+
end
|