t-tech-investments 0.2.0 → 0.2.2
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/.cursor/rules/sdk-architecture.mdc +1 -1
- data/CHANGELOG.md +9 -0
- data/README.md +2 -0
- data/lib/t/tech/investments/proto_loader.rb +59 -16
- data/lib/t/tech/investments/services/market_data_facade.rb +9 -7
- data/lib/t/tech/investments/version.rb +1 -1
- data/sig/t/tech/investments.rbs +10 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4bf8867c825875c3ae7f360a619639d0a4625a9f32f3a068e1c3636f649fbff5
|
|
4
|
+
data.tar.gz: c062acc25e8df6ffe8503331b054a481390e051c0be0cb99a895d7dbf8bd2be8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b9e479135ca5169147c694d1c0e10369a5dda50d81e783b1a0ddb18c5cf385734e40ff1ffe31b3df12db2d9033e23ef2ebd80389d1733161b6028ff93d04d08d
|
|
7
|
+
data.tar.gz: d808c48241f5af9c48ce21709443c44555d9efec9719947c32a6aded19cb862b9611559ceaa4ed354dc83e7e9db433f661c9f932aa2f8ece215cb93cbb7de48f
|
|
@@ -15,7 +15,7 @@ alwaysApply: true
|
|
|
15
15
|
|
|
16
16
|
- `Services` не вызывают gRPC stub напрямую — только через `Transport`.
|
|
17
17
|
- Публичный API не возвращает protobuf по умолчанию (только `raw:`/debug, если нужен).
|
|
18
|
-
- `Transport` без бизнес-логики; только: metadata, deadlines,
|
|
18
|
+
- `Transport` без бизнес-логики; только: metadata, deadlines, error mapping. Retry и управление состоянием соединения — **не** зона ответственности библиотеки; пользователь сам реализует повторные попытки при необходимости.
|
|
19
19
|
- `Coercers/Mappers` — чистые и детерминированные (без IO/сети).
|
|
20
20
|
|
|
21
21
|
## Контракты (invest-contracts)
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.2] - Unreleased
|
|
4
|
+
|
|
5
|
+
- Version bump for next development cycle
|
|
6
|
+
|
|
7
|
+
## [0.2.1] - 2026-02-06
|
|
8
|
+
|
|
9
|
+
- ProtoLoader: harden loading order and market data signatures; add specs
|
|
10
|
+
- Docs: clarify retry responsibility and client cleanup; remove stray gem artifact
|
|
11
|
+
|
|
3
12
|
## [0.2.0] - 2026-02-06
|
|
4
13
|
|
|
5
14
|
- Client: services exposed via Registry (method_missing), no hardcoded list; facades (e.g. market_data) discovered dynamically
|
data/README.md
CHANGED
|
@@ -142,6 +142,8 @@ client = T::Tech::Investments.client(
|
|
|
142
142
|
- **Prod vs Sandbox**: distinguish environments only by the endpoint from the docs:
|
|
143
143
|
- **Prod**: `invest-public-api.tbank.ru:443`
|
|
144
144
|
- **Sandbox**: `sandbox-invest-public-api.tbank.ru:443`
|
|
145
|
+
- **Retries and connection state**: the library does not retry failed calls. The application is responsible for retries, reconnects, and connection state; implement retry logic in your code if needed.
|
|
146
|
+
- **Long-lived processes**: when shutting down or discarding a client, call `client.transport.close` to release gRPC channel and stubs.
|
|
145
147
|
|
|
146
148
|
### Unary requests (data fetch)
|
|
147
149
|
|
|
@@ -8,22 +8,65 @@ module T
|
|
|
8
8
|
module ProtoLoader
|
|
9
9
|
PROTO_DIR = File.expand_path("proto", __dir__)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
@load_mutex = Mutex.new
|
|
12
|
+
@load_cv = ConditionVariable.new
|
|
13
|
+
@loaded = false
|
|
14
|
+
@loading = false
|
|
15
|
+
@loading_thread = nil
|
|
16
|
+
@load_error = nil
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
def load!
|
|
20
|
+
@load_mutex.synchronize do
|
|
21
|
+
return if @loaded
|
|
22
|
+
|
|
23
|
+
if @loading
|
|
24
|
+
if @loading_thread == Thread.current
|
|
25
|
+
raise RuntimeError, "ProtoLoader.load! re-entrant call while loading"
|
|
26
|
+
end
|
|
27
|
+
@load_cv.wait(@load_mutex) while @loading
|
|
28
|
+
return if @loaded
|
|
29
|
+
raise @load_error if @load_error
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@load_error = nil
|
|
33
|
+
@loading = true
|
|
34
|
+
@loading_thread = Thread.current
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
begin
|
|
38
|
+
load_files
|
|
39
|
+
@load_mutex.synchronize do
|
|
40
|
+
@loaded = true
|
|
41
|
+
@loading = false
|
|
42
|
+
@loading_thread = nil
|
|
43
|
+
@load_cv.broadcast
|
|
44
|
+
end
|
|
45
|
+
rescue StandardError => e
|
|
46
|
+
@load_mutex.synchronize do
|
|
47
|
+
@load_error = e
|
|
48
|
+
@loading = false
|
|
49
|
+
@loading_thread = nil
|
|
50
|
+
@load_cv.broadcast
|
|
51
|
+
end
|
|
52
|
+
raise
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def load_files
|
|
59
|
+
$LOAD_PATH.unshift(PROTO_DIR) unless $LOAD_PATH.include?(PROTO_DIR)
|
|
60
|
+
pb_files = Dir[File.join(PROTO_DIR, "*_pb.rb")]
|
|
61
|
+
.reject { |f| f.end_with?("_services_pb.rb") }
|
|
62
|
+
.map { |f| File.basename(f, ".rb") }
|
|
63
|
+
.sort
|
|
64
|
+
services_files = Dir[File.join(PROTO_DIR, "*_services_pb.rb")]
|
|
65
|
+
.map { |f| File.basename(f, ".rb") }
|
|
66
|
+
.sort
|
|
67
|
+
pb_files = pb_files.partition { |f| f == "common_pb" }.flatten
|
|
68
|
+
(pb_files + services_files).each { |f| require f }
|
|
69
|
+
end
|
|
27
70
|
end
|
|
28
71
|
end
|
|
29
72
|
end
|
|
@@ -18,14 +18,16 @@ module T
|
|
|
18
18
|
#
|
|
19
19
|
# @param timeout [Integer, nil] optional stream timeout in seconds
|
|
20
20
|
# @yield [MarketDataStreamSession] session to subscribe and call each_event on
|
|
21
|
-
def stream(timeout: nil
|
|
22
|
-
session = nil
|
|
23
|
-
return unless block_given?
|
|
24
|
-
|
|
21
|
+
def stream(timeout: nil)
|
|
25
22
|
session = MarketDataStreamSession.new(@transport, timeout: timeout)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
return session unless block_given?
|
|
24
|
+
|
|
25
|
+
begin
|
|
26
|
+
yield session
|
|
27
|
+
ensure
|
|
28
|
+
session.close
|
|
29
|
+
end
|
|
30
|
+
nil
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def method_missing(method_name, *args, **kwargs, &block)
|
data/sig/t/tech/investments.rbs
CHANGED
|
@@ -141,6 +141,16 @@ module T::Tech::Investments
|
|
|
141
141
|
class MarketDataFacade
|
|
142
142
|
def initialize: (UnaryAdapter unary_adapter, Transport transport) -> void
|
|
143
143
|
def stream: (?timeout: Integer) { (MarketDataStreamSession) -> void } -> void
|
|
144
|
+
def stream: (?timeout: Integer) -> MarketDataStreamSession
|
|
145
|
+
def get_candles: (**untyped kwargs) -> untyped
|
|
146
|
+
def get_last_prices: (**untyped kwargs) -> untyped
|
|
147
|
+
def get_order_book: (**untyped kwargs) -> untyped
|
|
148
|
+
def get_trading_status: (**untyped kwargs) -> untyped
|
|
149
|
+
def get_trading_statuses: (**untyped kwargs) -> untyped
|
|
150
|
+
def get_last_trades: (**untyped kwargs) -> untyped
|
|
151
|
+
def get_close_prices: (**untyped kwargs) -> untyped
|
|
152
|
+
def get_tech_analysis: (**untyped kwargs) -> untyped
|
|
153
|
+
def get_market_values: (**untyped kwargs) -> untyped
|
|
144
154
|
end
|
|
145
155
|
end
|
|
146
156
|
|