openai 0.77.0 → 0.78.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 +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +102 -4
- data/lib/openai/client.rb +7 -10
- data/lib/openai/http_client.rb +97 -0
- data/lib/openai/internal/read_io_adapter.rb +137 -0
- data/lib/openai/internal/transport/base_client.rb +84 -25
- data/lib/openai/internal/type/base_stream.rb +1 -1
- data/lib/openai/internal/util.rb +7 -85
- data/lib/openai/net_http_client.rb +281 -0
- data/lib/openai/version.rb +1 -1
- data/lib/openai.rb +2 -1
- data/rbi/openai/client.rbi +4 -2
- data/rbi/openai/http_client.rbi +63 -0
- data/rbi/openai/internal/read_io_adapter.rbi +47 -0
- data/rbi/openai/internal/transport/base_client.rbi +21 -5
- data/rbi/openai/internal/type/base_stream.rbi +1 -1
- data/rbi/openai/internal/util.rbi +0 -40
- data/rbi/openai/net_http_client.rbi +64 -0
- data/sig/openai/client.rbs +2 -1
- data/sig/openai/http_client.rbs +41 -0
- data/sig/openai/internal/read_io_adapter.rbs +21 -0
- data/sig/openai/internal/transport/base_client.rbs +10 -3
- data/sig/openai/internal/type/base_stream.rbs +1 -1
- data/sig/openai/internal/util.rbs +0 -16
- data/sig/openai/net_http_client.rbs +34 -0
- metadata +12 -6
- data/lib/openai/internal/transport/pooled_net_requester.rb +0 -210
- data/rbi/openai/internal/transport/pooled_net_requester.rbi +0 -82
- data/sig/openai/internal/transport/pooled_net_requester.rbs +0 -48
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
module OpenAI
|
|
4
|
+
class NetHTTPClient < OpenAI::HTTPClient
|
|
5
|
+
KEEP_ALIVE_TIMEOUT = 30
|
|
6
|
+
|
|
7
|
+
DEFAULT_MAX_CONNECTIONS = T.let(T.unsafe(nil), Integer)
|
|
8
|
+
|
|
9
|
+
sig { params(url: URI::Generic).returns(Net::HTTP) }
|
|
10
|
+
private def connect(url:)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
sig { params(conn: Net::HTTP, deadline: Float).void }
|
|
14
|
+
private def calibrate_socket_timeout(conn, deadline)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
sig do
|
|
18
|
+
params(
|
|
19
|
+
request: OpenAI::HTTPClient::Request,
|
|
20
|
+
blk: T.proc.params(arg0: String).void
|
|
21
|
+
).returns([Net::HTTPGenericRequest, T.proc.void])
|
|
22
|
+
end
|
|
23
|
+
private def build_request(request, &blk)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
sig do
|
|
27
|
+
params(
|
|
28
|
+
url: URI::Generic,
|
|
29
|
+
deadline: Float,
|
|
30
|
+
blk: T.proc.params(arg0: Net::HTTP).void
|
|
31
|
+
).void
|
|
32
|
+
end
|
|
33
|
+
private def with_pool(url, deadline:, &blk)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
sig { params(url: URI::Generic).returns(Net::HTTP) }
|
|
37
|
+
private def configured_connection(url)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
sig { void }
|
|
41
|
+
def close
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
sig do
|
|
45
|
+
params(request: OpenAI::HTTPClient::Request).returns(
|
|
46
|
+
OpenAI::HTTPClient::Response
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
def execute(request)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
sig do
|
|
53
|
+
params(
|
|
54
|
+
size: Integer,
|
|
55
|
+
connection_configurator: T.nilable(T.proc.params(http: Net::HTTP).void)
|
|
56
|
+
).returns(T.attached_class)
|
|
57
|
+
end
|
|
58
|
+
def self.new(
|
|
59
|
+
size: OpenAI::NetHTTPClient::DEFAULT_MAX_CONNECTIONS,
|
|
60
|
+
&connection_configurator
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
data/sig/openai/client.rbs
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module OpenAI
|
|
2
|
+
interface _HTTPClient
|
|
3
|
+
def execute: (
|
|
4
|
+
OpenAI::HTTPClient::Request request
|
|
5
|
+
) -> OpenAI::HTTPClient::Response
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class HTTPClient
|
|
9
|
+
class Request
|
|
10
|
+
attr_reader method: Symbol
|
|
11
|
+
attr_reader url: URI::Generic
|
|
12
|
+
attr_reader headers: ::Hash[String, String]
|
|
13
|
+
attr_reader body: top
|
|
14
|
+
attr_reader timeout: Float
|
|
15
|
+
|
|
16
|
+
def initialize: (
|
|
17
|
+
method: Symbol,
|
|
18
|
+
url: URI::Generic,
|
|
19
|
+
headers: ::Hash[String, String],
|
|
20
|
+
body: top,
|
|
21
|
+
timeout: Float
|
|
22
|
+
) -> void
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class Response
|
|
26
|
+
attr_reader status: Integer
|
|
27
|
+
attr_reader headers: ::Hash[String, String]
|
|
28
|
+
attr_reader body: Enumerable[String]
|
|
29
|
+
|
|
30
|
+
def initialize: (
|
|
31
|
+
status: Integer,
|
|
32
|
+
headers: ::Hash[String, String],
|
|
33
|
+
body: String | Enumerable[String]
|
|
34
|
+
) -> void
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def execute: (
|
|
38
|
+
OpenAI::HTTPClient::Request request
|
|
39
|
+
) -> OpenAI::HTTPClient::Response
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module OpenAI
|
|
2
|
+
module Internal
|
|
3
|
+
module Util
|
|
4
|
+
class ReadIOAdapter
|
|
5
|
+
def close?: -> bool?
|
|
6
|
+
|
|
7
|
+
def close: -> void
|
|
8
|
+
|
|
9
|
+
private def read_enum: (Integer? max_len) -> String
|
|
10
|
+
|
|
11
|
+
def read: (?Integer? max_len, ?String? out_string) -> String?
|
|
12
|
+
|
|
13
|
+
def initialize: (
|
|
14
|
+
String | Pathname | StringIO | Enumerable[String] src
|
|
15
|
+
) {
|
|
16
|
+
(String arg0) -> void
|
|
17
|
+
} -> void
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -48,6 +48,8 @@ module OpenAI
|
|
|
48
48
|
headers: ::Hash[String, String]
|
|
49
49
|
) -> bool
|
|
50
50
|
|
|
51
|
+
def self.request_body_replayable?: (top body) -> bool
|
|
52
|
+
|
|
51
53
|
def self.follow_redirect: (
|
|
52
54
|
OpenAI::Internal::Transport::BaseClient::request_input request,
|
|
53
55
|
status: Integer,
|
|
@@ -74,7 +76,7 @@ module OpenAI
|
|
|
74
76
|
attr_reader idempotency_header: String?
|
|
75
77
|
|
|
76
78
|
# @api private
|
|
77
|
-
attr_reader requester: OpenAI::
|
|
79
|
+
attr_reader requester: OpenAI::_HTTPClient
|
|
78
80
|
|
|
79
81
|
def initialize: (
|
|
80
82
|
base_url: String,
|
|
@@ -85,7 +87,8 @@ module OpenAI
|
|
|
85
87
|
?headers: ::Hash[String, (String
|
|
86
88
|
| Integer
|
|
87
89
|
| ::Array[(String | Integer)?])?],
|
|
88
|
-
?idempotency_header: String
|
|
90
|
+
?idempotency_header: String?,
|
|
91
|
+
?http_client: OpenAI::_HTTPClient?
|
|
89
92
|
) -> void
|
|
90
93
|
|
|
91
94
|
private def auth_headers: -> ::Hash[String, String]
|
|
@@ -105,6 +108,10 @@ module OpenAI
|
|
|
105
108
|
OpenAI::request_options opts
|
|
106
109
|
) -> OpenAI::Internal::Transport::BaseClient::request_input
|
|
107
110
|
|
|
111
|
+
private def request_replayable?: (
|
|
112
|
+
OpenAI::Internal::Transport::BaseClient::request_input request
|
|
113
|
+
) -> bool
|
|
114
|
+
|
|
108
115
|
private def retry_delay: (
|
|
109
116
|
::Hash[String, String] headers,
|
|
110
117
|
retry_count: Integer
|
|
@@ -123,7 +130,7 @@ module OpenAI
|
|
|
123
130
|
redirect_count: Integer,
|
|
124
131
|
retry_count: Integer,
|
|
125
132
|
send_retry_header: bool
|
|
126
|
-
) ->
|
|
133
|
+
) -> OpenAI::HTTPClient::Response
|
|
127
134
|
|
|
128
135
|
def request: (
|
|
129
136
|
Symbol method,
|
|
@@ -87,22 +87,6 @@ module OpenAI
|
|
|
87
87
|
| ::Array[(String | Integer)?])?] headers
|
|
88
88
|
) -> ::Hash[String, String]
|
|
89
89
|
|
|
90
|
-
class ReadIOAdapter
|
|
91
|
-
def close?: -> bool?
|
|
92
|
-
|
|
93
|
-
def close: -> void
|
|
94
|
-
|
|
95
|
-
private def read_enum: (Integer? max_len) -> String
|
|
96
|
-
|
|
97
|
-
def read: (?Integer? max_len, ?String? out_string) -> String?
|
|
98
|
-
|
|
99
|
-
def initialize: (
|
|
100
|
-
String | Pathname | StringIO | Enumerable[String] src
|
|
101
|
-
) {
|
|
102
|
-
(String arg0) -> void
|
|
103
|
-
} -> void
|
|
104
|
-
end
|
|
105
|
-
|
|
106
90
|
def self?.writable_enum: {
|
|
107
91
|
(Enumerator::Yielder y) -> void
|
|
108
92
|
} -> Enumerable[String]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module OpenAI
|
|
2
|
+
class NetHTTPClient < OpenAI::HTTPClient
|
|
3
|
+
KEEP_ALIVE_TIMEOUT: 30
|
|
4
|
+
|
|
5
|
+
DEFAULT_MAX_CONNECTIONS: Integer
|
|
6
|
+
|
|
7
|
+
private def connect: (url: URI::Generic) -> top
|
|
8
|
+
|
|
9
|
+
private def calibrate_socket_timeout: (top conn, Float deadline) -> void
|
|
10
|
+
|
|
11
|
+
private def build_request: (
|
|
12
|
+
OpenAI::HTTPClient::Request request
|
|
13
|
+
) {
|
|
14
|
+
(String arg0) -> void
|
|
15
|
+
} -> [top, (^-> void)]
|
|
16
|
+
|
|
17
|
+
private def with_pool: (
|
|
18
|
+
URI::Generic url,
|
|
19
|
+
deadline: Float
|
|
20
|
+
) {
|
|
21
|
+
(top arg0) -> void
|
|
22
|
+
} -> void
|
|
23
|
+
|
|
24
|
+
private def configured_connection: (URI::Generic url) -> top
|
|
25
|
+
|
|
26
|
+
def close: -> void
|
|
27
|
+
|
|
28
|
+
def execute: (
|
|
29
|
+
OpenAI::HTTPClient::Request request
|
|
30
|
+
) -> OpenAI::HTTPClient::Response
|
|
31
|
+
|
|
32
|
+
def initialize: (?size: Integer) ?{ (Net::HTTP) -> void } -> void
|
|
33
|
+
end
|
|
34
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openai
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.78.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenAI
|
|
@@ -43,14 +43,14 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - ">="
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version:
|
|
46
|
+
version: 2.2.3
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
53
|
+
version: 2.2.3
|
|
54
54
|
email: support@openai.com
|
|
55
55
|
executables: []
|
|
56
56
|
extensions: []
|
|
@@ -87,15 +87,16 @@ files:
|
|
|
87
87
|
- lib/openai/helpers/structured_output/json_schema_converter.rb
|
|
88
88
|
- lib/openai/helpers/structured_output/parsed_json.rb
|
|
89
89
|
- lib/openai/helpers/structured_output/union_of.rb
|
|
90
|
+
- lib/openai/http_client.rb
|
|
90
91
|
- lib/openai/internal.rb
|
|
91
92
|
- lib/openai/internal/conversation_cursor_page.rb
|
|
92
93
|
- lib/openai/internal/cursor_page.rb
|
|
93
94
|
- lib/openai/internal/next_cursor_page.rb
|
|
94
95
|
- lib/openai/internal/page.rb
|
|
95
96
|
- lib/openai/internal/provider.rb
|
|
97
|
+
- lib/openai/internal/read_io_adapter.rb
|
|
96
98
|
- lib/openai/internal/stream.rb
|
|
97
99
|
- lib/openai/internal/transport/base_client.rb
|
|
98
|
-
- lib/openai/internal/transport/pooled_net_requester.rb
|
|
99
100
|
- lib/openai/internal/type/array_of.rb
|
|
100
101
|
- lib/openai/internal/type/base_model.rb
|
|
101
102
|
- lib/openai/internal/type/base_page.rb
|
|
@@ -1196,6 +1197,7 @@ files:
|
|
|
1196
1197
|
- lib/openai/models/webhooks/response_incomplete_webhook_event.rb
|
|
1197
1198
|
- lib/openai/models/webhooks/unwrap_webhook_event.rb
|
|
1198
1199
|
- lib/openai/models/webhooks/webhook_unwrap_params.rb
|
|
1200
|
+
- lib/openai/net_http_client.rb
|
|
1199
1201
|
- lib/openai/provider.rb
|
|
1200
1202
|
- lib/openai/providers/bedrock.rb
|
|
1201
1203
|
- lib/openai/request_options.rb
|
|
@@ -1310,15 +1312,16 @@ files:
|
|
|
1310
1312
|
- rbi/openai/helpers/structured_output/enum_of.rbi
|
|
1311
1313
|
- rbi/openai/helpers/structured_output/json_schema_converter.rbi
|
|
1312
1314
|
- rbi/openai/helpers/structured_output/union_of.rbi
|
|
1315
|
+
- rbi/openai/http_client.rbi
|
|
1313
1316
|
- rbi/openai/internal.rbi
|
|
1314
1317
|
- rbi/openai/internal/conversation_cursor_page.rbi
|
|
1315
1318
|
- rbi/openai/internal/cursor_page.rbi
|
|
1316
1319
|
- rbi/openai/internal/next_cursor_page.rbi
|
|
1317
1320
|
- rbi/openai/internal/page.rbi
|
|
1318
1321
|
- rbi/openai/internal/provider.rbi
|
|
1322
|
+
- rbi/openai/internal/read_io_adapter.rbi
|
|
1319
1323
|
- rbi/openai/internal/stream.rbi
|
|
1320
1324
|
- rbi/openai/internal/transport/base_client.rbi
|
|
1321
|
-
- rbi/openai/internal/transport/pooled_net_requester.rbi
|
|
1322
1325
|
- rbi/openai/internal/type/array_of.rbi
|
|
1323
1326
|
- rbi/openai/internal/type/base_model.rbi
|
|
1324
1327
|
- rbi/openai/internal/type/base_page.rbi
|
|
@@ -2418,6 +2421,7 @@ files:
|
|
|
2418
2421
|
- rbi/openai/models/webhooks/response_incomplete_webhook_event.rbi
|
|
2419
2422
|
- rbi/openai/models/webhooks/unwrap_webhook_event.rbi
|
|
2420
2423
|
- rbi/openai/models/webhooks/webhook_unwrap_params.rbi
|
|
2424
|
+
- rbi/openai/net_http_client.rbi
|
|
2421
2425
|
- rbi/openai/provider.rbi
|
|
2422
2426
|
- rbi/openai/providers.rbi
|
|
2423
2427
|
- rbi/openai/request_options.rbi
|
|
@@ -2521,15 +2525,16 @@ files:
|
|
|
2521
2525
|
- sig/openai/client.rbs
|
|
2522
2526
|
- sig/openai/errors.rbs
|
|
2523
2527
|
- sig/openai/file_part.rbs
|
|
2528
|
+
- sig/openai/http_client.rbs
|
|
2524
2529
|
- sig/openai/internal.rbs
|
|
2525
2530
|
- sig/openai/internal/conversation_cursor_page.rbs
|
|
2526
2531
|
- sig/openai/internal/cursor_page.rbs
|
|
2527
2532
|
- sig/openai/internal/next_cursor_page.rbs
|
|
2528
2533
|
- sig/openai/internal/page.rbs
|
|
2529
2534
|
- sig/openai/internal/provider.rbs
|
|
2535
|
+
- sig/openai/internal/read_io_adapter.rbs
|
|
2530
2536
|
- sig/openai/internal/stream.rbs
|
|
2531
2537
|
- sig/openai/internal/transport/base_client.rbs
|
|
2532
|
-
- sig/openai/internal/transport/pooled_net_requester.rbs
|
|
2533
2538
|
- sig/openai/internal/type/array_of.rbs
|
|
2534
2539
|
- sig/openai/internal/type/base_model.rbs
|
|
2535
2540
|
- sig/openai/internal/type/base_page.rbs
|
|
@@ -3629,6 +3634,7 @@ files:
|
|
|
3629
3634
|
- sig/openai/models/webhooks/response_incomplete_webhook_event.rbs
|
|
3630
3635
|
- sig/openai/models/webhooks/unwrap_webhook_event.rbs
|
|
3631
3636
|
- sig/openai/models/webhooks/webhook_unwrap_params.rbs
|
|
3637
|
+
- sig/openai/net_http_client.rbs
|
|
3632
3638
|
- sig/openai/provider.rbs
|
|
3633
3639
|
- sig/openai/providers.rbs
|
|
3634
3640
|
- sig/openai/request_options.rbs
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module OpenAI
|
|
4
|
-
module Internal
|
|
5
|
-
module Transport
|
|
6
|
-
# @api private
|
|
7
|
-
class PooledNetRequester
|
|
8
|
-
extend OpenAI::Internal::Util::SorbetRuntimeSupport
|
|
9
|
-
|
|
10
|
-
# from the golang stdlib
|
|
11
|
-
# https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49
|
|
12
|
-
KEEP_ALIVE_TIMEOUT = 30
|
|
13
|
-
|
|
14
|
-
DEFAULT_MAX_CONNECTIONS = [Etc.nprocessors, 99].max
|
|
15
|
-
|
|
16
|
-
class << self
|
|
17
|
-
# @api private
|
|
18
|
-
#
|
|
19
|
-
# @param cert_store [OpenSSL::X509::Store]
|
|
20
|
-
# @param url [URI::Generic]
|
|
21
|
-
#
|
|
22
|
-
# @return [Net::HTTP]
|
|
23
|
-
def connect(cert_store:, url:)
|
|
24
|
-
port =
|
|
25
|
-
case [url.port, url.scheme]
|
|
26
|
-
in [Integer, _]
|
|
27
|
-
url.port
|
|
28
|
-
in [nil, "http" | "ws"]
|
|
29
|
-
Net::HTTP.http_default_port
|
|
30
|
-
in [nil, "https" | "wss"]
|
|
31
|
-
Net::HTTP.https_default_port
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
Net::HTTP.new(url.host, port).tap do
|
|
35
|
-
_1.use_ssl = %w[https wss].include?(url.scheme)
|
|
36
|
-
_1.max_retries = 0
|
|
37
|
-
|
|
38
|
-
(_1.cert_store = cert_store) if _1.use_ssl?
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# @api private
|
|
43
|
-
#
|
|
44
|
-
# @param conn [Net::HTTP]
|
|
45
|
-
# @param deadline [Float]
|
|
46
|
-
def calibrate_socket_timeout(conn, deadline)
|
|
47
|
-
timeout = deadline - OpenAI::Internal::Util.monotonic_secs
|
|
48
|
-
conn.open_timeout = conn.read_timeout = conn.write_timeout = conn.continue_timeout = timeout
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# @api private
|
|
52
|
-
#
|
|
53
|
-
# @param request [Hash{Symbol=>Object}] .
|
|
54
|
-
#
|
|
55
|
-
# @option request [Symbol] :method
|
|
56
|
-
#
|
|
57
|
-
# @option request [URI::Generic] :url
|
|
58
|
-
#
|
|
59
|
-
# @option request [Hash{String=>String}] :headers
|
|
60
|
-
#
|
|
61
|
-
# @param blk [Proc]
|
|
62
|
-
#
|
|
63
|
-
# @yieldparam [String]
|
|
64
|
-
# @return [Array(Net::HTTPGenericRequest, Proc)]
|
|
65
|
-
def build_request(request, &blk)
|
|
66
|
-
method, url, headers, body = request.fetch_values(:method, :url, :headers, :body)
|
|
67
|
-
req = Net::HTTPGenericRequest.new(
|
|
68
|
-
method.to_s.upcase,
|
|
69
|
-
!body.nil?,
|
|
70
|
-
method != :head,
|
|
71
|
-
URI(url.to_s) # ensure we construct a URI class of the right scheme
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
headers.each { req[_1] = _2 }
|
|
75
|
-
|
|
76
|
-
case body
|
|
77
|
-
in nil
|
|
78
|
-
req["content-length"] ||= 0 unless req["transfer-encoding"]
|
|
79
|
-
in String
|
|
80
|
-
req["content-length"] ||= body.bytesize.to_s unless req["transfer-encoding"]
|
|
81
|
-
req.body_stream = OpenAI::Internal::Util::ReadIOAdapter.new(body, &blk)
|
|
82
|
-
in StringIO
|
|
83
|
-
req["content-length"] ||= body.size.to_s unless req["transfer-encoding"]
|
|
84
|
-
req.body_stream = OpenAI::Internal::Util::ReadIOAdapter.new(body, &blk)
|
|
85
|
-
in Pathname | IO | Enumerator
|
|
86
|
-
req["transfer-encoding"] ||= "chunked" unless req["content-length"]
|
|
87
|
-
req.body_stream = OpenAI::Internal::Util::ReadIOAdapter.new(body, &blk)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
[req, req.body_stream&.method(:close)]
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# @api private
|
|
95
|
-
#
|
|
96
|
-
# @param url [URI::Generic]
|
|
97
|
-
# @param deadline [Float]
|
|
98
|
-
# @param blk [Proc]
|
|
99
|
-
#
|
|
100
|
-
# @raise [Timeout::Error]
|
|
101
|
-
# @yieldparam [Net::HTTP]
|
|
102
|
-
private def with_pool(url, deadline:, &blk)
|
|
103
|
-
origin = OpenAI::Internal::Util.uri_origin(url)
|
|
104
|
-
timeout = deadline - OpenAI::Internal::Util.monotonic_secs
|
|
105
|
-
pool =
|
|
106
|
-
@mutex.synchronize do
|
|
107
|
-
@pools[origin] ||= ConnectionPool.new(size: @size) do
|
|
108
|
-
self.class.connect(cert_store: @cert_store, url: url)
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
pool.with(timeout: timeout, &blk)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# @api private
|
|
116
|
-
#
|
|
117
|
-
# @param request [Hash{Symbol=>Object}] .
|
|
118
|
-
#
|
|
119
|
-
# @option request [Symbol] :method
|
|
120
|
-
#
|
|
121
|
-
# @option request [URI::Generic] :url
|
|
122
|
-
#
|
|
123
|
-
# @option request [Hash{String=>String}] :headers
|
|
124
|
-
#
|
|
125
|
-
# @option request [Object] :body
|
|
126
|
-
#
|
|
127
|
-
# @option request [Float] :deadline
|
|
128
|
-
#
|
|
129
|
-
# @return [Array(Integer, Net::HTTPResponse, Enumerable<String>)]
|
|
130
|
-
def execute(request)
|
|
131
|
-
url, deadline = request.fetch_values(:url, :deadline)
|
|
132
|
-
|
|
133
|
-
req = nil
|
|
134
|
-
finished = false
|
|
135
|
-
|
|
136
|
-
# rubocop:disable Metrics/BlockLength
|
|
137
|
-
enum = Enumerator.new do |y|
|
|
138
|
-
next if finished
|
|
139
|
-
|
|
140
|
-
with_pool(url, deadline: deadline) do |conn|
|
|
141
|
-
eof = false
|
|
142
|
-
closing = nil
|
|
143
|
-
::Thread.handle_interrupt(Object => :never) do
|
|
144
|
-
::Thread.handle_interrupt(Object => :immediate) do
|
|
145
|
-
req, closing = self.class.build_request(request) do
|
|
146
|
-
self.class.calibrate_socket_timeout(conn, deadline)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
self.class.calibrate_socket_timeout(conn, deadline)
|
|
150
|
-
unless conn.started?
|
|
151
|
-
conn.keep_alive_timeout = self.class::KEEP_ALIVE_TIMEOUT
|
|
152
|
-
conn.start
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
self.class.calibrate_socket_timeout(conn, deadline)
|
|
156
|
-
::Kernel.catch(:jump) do
|
|
157
|
-
conn.request(req) do |rsp|
|
|
158
|
-
y << [req, rsp]
|
|
159
|
-
::Kernel.throw(:jump) if finished
|
|
160
|
-
|
|
161
|
-
rsp.read_body do |bytes|
|
|
162
|
-
y << bytes.force_encoding(Encoding::BINARY)
|
|
163
|
-
::Kernel.throw(:jump) if finished
|
|
164
|
-
|
|
165
|
-
self.class.calibrate_socket_timeout(conn, deadline)
|
|
166
|
-
end
|
|
167
|
-
eof = true
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
ensure
|
|
172
|
-
begin
|
|
173
|
-
conn.finish if !eof && conn&.started?
|
|
174
|
-
ensure
|
|
175
|
-
closing&.call
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
rescue Timeout::Error
|
|
180
|
-
raise OpenAI::Errors::APITimeoutError.new(url: url, request: req)
|
|
181
|
-
rescue StandardError
|
|
182
|
-
raise OpenAI::Errors::APIConnectionError.new(url: url, request: req)
|
|
183
|
-
end
|
|
184
|
-
# rubocop:enable Metrics/BlockLength
|
|
185
|
-
|
|
186
|
-
_, response = enum.next
|
|
187
|
-
body = OpenAI::Internal::Util.fused_enum(enum, external: true) do
|
|
188
|
-
finished = true
|
|
189
|
-
loop { enum.next }
|
|
190
|
-
end
|
|
191
|
-
[Integer(response.code), response, body]
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
# @api private
|
|
195
|
-
#
|
|
196
|
-
# @param size [Integer]
|
|
197
|
-
def initialize(size: self.class::DEFAULT_MAX_CONNECTIONS)
|
|
198
|
-
@mutex = Mutex.new
|
|
199
|
-
@size = size
|
|
200
|
-
@cert_store = OpenSSL::X509::Store.new.tap(&:set_default_paths)
|
|
201
|
-
@pools = {}
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
define_sorbet_constant!(:Request) do
|
|
205
|
-
T.type_alias { {method: Symbol, url: URI::Generic, headers: T::Hash[String, String], body: T.anything, deadline: Float} }
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
end
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# typed: strong
|
|
2
|
-
|
|
3
|
-
module OpenAI
|
|
4
|
-
module Internal
|
|
5
|
-
module Transport
|
|
6
|
-
# @api private
|
|
7
|
-
class PooledNetRequester
|
|
8
|
-
extend OpenAI::Internal::Util::SorbetRuntimeSupport
|
|
9
|
-
|
|
10
|
-
Request =
|
|
11
|
-
T.type_alias do
|
|
12
|
-
{
|
|
13
|
-
method: Symbol,
|
|
14
|
-
url: URI::Generic,
|
|
15
|
-
headers: T::Hash[String, String],
|
|
16
|
-
body: T.anything,
|
|
17
|
-
deadline: Float
|
|
18
|
-
}
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# from the golang stdlib
|
|
22
|
-
# https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49
|
|
23
|
-
KEEP_ALIVE_TIMEOUT = 30
|
|
24
|
-
|
|
25
|
-
DEFAULT_MAX_CONNECTIONS = T.let(T.unsafe(nil), Integer)
|
|
26
|
-
|
|
27
|
-
class << self
|
|
28
|
-
# @api private
|
|
29
|
-
sig do
|
|
30
|
-
params(cert_store: OpenSSL::X509::Store, url: URI::Generic).returns(
|
|
31
|
-
Net::HTTP
|
|
32
|
-
)
|
|
33
|
-
end
|
|
34
|
-
def connect(cert_store:, url:)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# @api private
|
|
38
|
-
sig { params(conn: Net::HTTP, deadline: Float).void }
|
|
39
|
-
def calibrate_socket_timeout(conn, deadline)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# @api private
|
|
43
|
-
sig do
|
|
44
|
-
params(
|
|
45
|
-
request: OpenAI::Internal::Transport::PooledNetRequester::Request,
|
|
46
|
-
blk: T.proc.params(arg0: String).void
|
|
47
|
-
).returns([Net::HTTPGenericRequest, T.proc.void])
|
|
48
|
-
end
|
|
49
|
-
def build_request(request, &blk)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# @api private
|
|
54
|
-
sig do
|
|
55
|
-
params(
|
|
56
|
-
url: URI::Generic,
|
|
57
|
-
deadline: Float,
|
|
58
|
-
blk: T.proc.params(arg0: Net::HTTP).void
|
|
59
|
-
).void
|
|
60
|
-
end
|
|
61
|
-
private def with_pool(url, deadline:, &blk)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# @api private
|
|
65
|
-
sig do
|
|
66
|
-
params(
|
|
67
|
-
request: OpenAI::Internal::Transport::PooledNetRequester::Request
|
|
68
|
-
).returns([Integer, Net::HTTPResponse, T::Enumerable[String]])
|
|
69
|
-
end
|
|
70
|
-
def execute(request)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# @api private
|
|
74
|
-
sig { params(size: Integer).returns(T.attached_class) }
|
|
75
|
-
def self.new(
|
|
76
|
-
size: OpenAI::Internal::Transport::PooledNetRequester::DEFAULT_MAX_CONNECTIONS
|
|
77
|
-
)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
module OpenAI
|
|
2
|
-
module Internal
|
|
3
|
-
module Transport
|
|
4
|
-
class PooledNetRequester
|
|
5
|
-
extend OpenAI::Internal::Util::SorbetRuntimeSupport
|
|
6
|
-
|
|
7
|
-
type request =
|
|
8
|
-
{
|
|
9
|
-
method: Symbol,
|
|
10
|
-
url: URI::Generic,
|
|
11
|
-
headers: ::Hash[String, String],
|
|
12
|
-
body: top,
|
|
13
|
-
deadline: Float
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
KEEP_ALIVE_TIMEOUT: 30
|
|
17
|
-
|
|
18
|
-
DEFAULT_MAX_CONNECTIONS: Integer
|
|
19
|
-
|
|
20
|
-
def self.connect: (
|
|
21
|
-
cert_store: OpenSSL::X509::Store,
|
|
22
|
-
url: URI::Generic
|
|
23
|
-
) -> top
|
|
24
|
-
|
|
25
|
-
def self.calibrate_socket_timeout: (top conn, Float deadline) -> void
|
|
26
|
-
|
|
27
|
-
def self.build_request: (
|
|
28
|
-
OpenAI::Internal::Transport::PooledNetRequester::request request
|
|
29
|
-
) {
|
|
30
|
-
(String arg0) -> void
|
|
31
|
-
} -> [top, (^-> void)]
|
|
32
|
-
|
|
33
|
-
private def with_pool: (
|
|
34
|
-
URI::Generic url,
|
|
35
|
-
deadline: Float
|
|
36
|
-
) {
|
|
37
|
-
(top arg0) -> void
|
|
38
|
-
} -> void
|
|
39
|
-
|
|
40
|
-
def execute: (
|
|
41
|
-
OpenAI::Internal::Transport::PooledNetRequester::request request
|
|
42
|
-
) -> [Integer, top, Enumerable[String]]
|
|
43
|
-
|
|
44
|
-
def initialize: (?size: Integer) -> void
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|