modal-rb 0.0.0 → 0.0.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/lib/modal/api_client.rb +18 -18
- data/lib/modal/cls.rb +10 -10
- data/lib/modal/config.rb +13 -13
- data/lib/modal/errors.rb +8 -0
- data/lib/modal/function.rb +14 -16
- data/lib/modal/function_call.rb +1 -1
- data/lib/modal/image.rb +0 -1
- data/lib/modal/invocation.rb +8 -7
- data/lib/modal/pickle.rb +22 -30
- data/lib/modal/sandbox.rb +5 -12
- data/lib/modal/sandbox_filesystem.rb +9 -16
- data/lib/modal/streams.rb +4 -5
- data/lib/modal/version.rb +1 -1
- data/lib/modal.rb +12 -12
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 781ff33d3fee6b9f00220da4fcbff5c993bc51b2ddd062b7f6e741706a9d4dfb
|
4
|
+
data.tar.gz: 073f29b57cda9ff253d1e191deff71011766442e3e9408f2a8da10fd9e6e776b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 710918e25cbcafdb5c4eb2c99eb25716aea16ba695b86f0c4b488b236683151eb1af80416746993492e2495040b5118ffe5be1d428b31d67f5fc94f0e93113d9
|
7
|
+
data.tar.gz: fc32dbf25698ce7f798d874df1a0180e221299fbe811b911fff4467a41736675fd19ef605960da0708e1b06ef679fceaccada16401d427fcf879837bb2162ead
|
data/lib/modal/api_client.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "grpc"
|
2
|
+
require "securerandom"
|
3
3
|
|
4
4
|
module Modal
|
5
5
|
class ApiClient
|
@@ -8,7 +8,7 @@ module Modal
|
|
8
8
|
GRPC::Core::StatusCodes::UNAVAILABLE,
|
9
9
|
GRPC::Core::StatusCodes::CANCELLED,
|
10
10
|
GRPC::Core::StatusCodes::INTERNAL,
|
11
|
-
GRPC::Core::StatusCodes::UNKNOWN
|
11
|
+
GRPC::Core::StatusCodes::UNKNOWN
|
12
12
|
])
|
13
13
|
|
14
14
|
def initialize
|
@@ -19,8 +19,8 @@ module Modal
|
|
19
19
|
target,
|
20
20
|
credentials,
|
21
21
|
channel_args: {
|
22
|
-
|
23
|
-
|
22
|
+
"grpc.max_receive_message_length" => 100 * 1024 * 1024, # 100 MiB
|
23
|
+
"grpc.max_send_message_length" => 100 * 1024 * 1024 # 100 MiB
|
24
24
|
}
|
25
25
|
)
|
26
26
|
end
|
@@ -37,16 +37,16 @@ module Modal
|
|
37
37
|
|
38
38
|
loop do
|
39
39
|
metadata = {
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
"x-modal-client-type" => Modal::Client::ClientType::CLIENT_TYPE_LIBMODAL.to_s, # TODO: libmodal_rb!!!
|
41
|
+
"x-modal-client-version" => "1.0.0",
|
42
|
+
"x-modal-token-id" => @profile[:token_id],
|
43
|
+
"x-modal-token-secret" => @profile[:token_secret],
|
44
|
+
"x-idempotency-key" => idempotency_key,
|
45
|
+
"x-retry-attempt" => attempt.to_s
|
46
46
|
}
|
47
|
-
metadata[
|
47
|
+
metadata["x-retry-delay"] = base_delay.to_s if attempt > 0
|
48
48
|
|
49
|
-
call_options = {
|
49
|
+
call_options = {metadata: metadata}
|
50
50
|
call_options[:deadline] = Time.now + timeout / 1000.0 if timeout
|
51
51
|
|
52
52
|
begin
|
@@ -61,7 +61,7 @@ module Modal
|
|
61
61
|
else
|
62
62
|
raise convert_grpc_error(e)
|
63
63
|
end
|
64
|
-
rescue
|
64
|
+
rescue => e
|
65
65
|
raise e
|
66
66
|
end
|
67
67
|
end
|
@@ -70,11 +70,11 @@ module Modal
|
|
70
70
|
private
|
71
71
|
|
72
72
|
def parse_server_url(server_url)
|
73
|
-
if server_url.start_with?(
|
74
|
-
target = server_url.sub(
|
73
|
+
if server_url.start_with?("https://")
|
74
|
+
target = server_url.sub("https://", "")
|
75
75
|
credentials = GRPC::Core::ChannelCredentials.new
|
76
|
-
elsif server_url.start_with?(
|
77
|
-
target = server_url.sub(
|
76
|
+
elsif server_url.start_with?("http://")
|
77
|
+
target = server_url.sub("http://", "")
|
78
78
|
credentials = :this_channel_is_insecure
|
79
79
|
else
|
80
80
|
target = server_url
|
data/lib/modal/cls.rb
CHANGED
@@ -25,22 +25,22 @@ module Modal
|
|
25
25
|
end
|
26
26
|
|
27
27
|
method_names = if service_function.handle_metadata&.method_handle_metadata
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
service_function.handle_metadata.method_handle_metadata.keys
|
29
|
+
else
|
30
|
+
raise "Cls requires Modal deployments using client v0.67 or later."
|
31
|
+
end
|
32
32
|
|
33
33
|
new(service_function.function_id, schema, method_names)
|
34
|
-
rescue NotFoundError
|
34
|
+
rescue NotFoundError
|
35
35
|
raise NotFoundError.new("Class '#{app_name}/#{name}' not found")
|
36
36
|
end
|
37
37
|
|
38
38
|
def instance(params = {})
|
39
39
|
function_id = if @schema.empty?
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
@service_function_id
|
41
|
+
else
|
42
|
+
bind_parameters(params)
|
43
|
+
end
|
44
44
|
|
45
45
|
methods = {}
|
46
46
|
@method_names.each do |name|
|
@@ -107,7 +107,7 @@ module Modal
|
|
107
107
|
unless value.is_a?(String)
|
108
108
|
raise "Parameter '#{name}' must be a byte array (String in Ruby)"
|
109
109
|
end
|
110
|
-
param_value.bytes_value = value.bytes.pack(
|
110
|
+
param_value.bytes_value = value.bytes.pack("C*")
|
111
111
|
else
|
112
112
|
raise "Unsupported parameter type: #{param_type}"
|
113
113
|
end
|
data/lib/modal/config.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "toml-rb"
|
2
|
+
require "fileutils"
|
3
3
|
|
4
4
|
module Modal
|
5
5
|
module Config
|
6
|
-
CONFIG_FILE = File.join(Dir.home,
|
6
|
+
CONFIG_FILE = File.join(Dir.home, ".modal.toml")
|
7
7
|
|
8
8
|
def self.read_config_file
|
9
9
|
if File.exist?(CONFIG_FILE)
|
@@ -11,17 +11,17 @@ module Modal
|
|
11
11
|
else
|
12
12
|
{}
|
13
13
|
end
|
14
|
-
rescue
|
14
|
+
rescue => e
|
15
15
|
raise "Failed to read or parse .modal.toml: #{e.message}"
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.get_profile(profile_name = nil)
|
19
19
|
config = read_config_file
|
20
20
|
|
21
|
-
profile_name ||= ENV[
|
21
|
+
profile_name ||= ENV["MODAL_PROFILE"]
|
22
22
|
unless profile_name
|
23
23
|
config.each do |name, data|
|
24
|
-
if data[
|
24
|
+
if data["active"]
|
25
25
|
profile_name = name
|
26
26
|
break
|
27
27
|
end
|
@@ -29,16 +29,16 @@ module Modal
|
|
29
29
|
end
|
30
30
|
|
31
31
|
if profile_name && !config.key?(profile_name)
|
32
|
-
raise "Profile \"#{profile_name}\" not found in .modal.toml. Please set the MODAL_PROFILE environment variable or specify a valid profile."
|
32
|
+
raise "Profile \"#{profile_name}\" not found in .modal.toml. Please set the MODAL_PROFILE environment variable or specify a valid profile." unless config.empty?
|
33
33
|
end
|
34
34
|
|
35
|
-
profile_data = profile_name ? config[profile_name] : {}
|
35
|
+
profile_data = profile_name ? (config[profile_name] || {}) : {}
|
36
36
|
|
37
|
-
server_url = ENV[
|
38
|
-
token_id = ENV[
|
39
|
-
token_secret = ENV[
|
40
|
-
environment = ENV[
|
41
|
-
image_builder_version = ENV[
|
37
|
+
server_url = ENV["MODAL_SERVER_URL"] || profile_data["server_url"] || "https://api.modal.com"
|
38
|
+
token_id = ENV["MODAL_TOKEN_ID"] || profile_data["token_id"]
|
39
|
+
token_secret = ENV["MODAL_TOKEN_SECRET"] || profile_data["token_secret"]
|
40
|
+
environment = ENV["MODAL_ENVIRONMENT"] || profile_data["environment"]
|
41
|
+
image_builder_version = ENV["MODAL_IMAGE_BUILDER_VERSION"] || profile_data["image_builder_version"] || "2024.10"
|
42
42
|
|
43
43
|
unless token_id && token_secret
|
44
44
|
raise "Profile \"#{profile_name}\" is missing token_id or token_secret. Please set them in .modal.toml or as environment variables."
|
data/lib/modal/errors.rb
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
module Modal
|
2
2
|
class ModalError < StandardError; end
|
3
|
+
|
3
4
|
class FunctionTimeoutError < ModalError; end
|
5
|
+
|
4
6
|
class RemoteError < ModalError; end
|
7
|
+
|
5
8
|
class InternalFailure < ModalError; end
|
9
|
+
|
6
10
|
class NotFoundError < ModalError; end
|
11
|
+
|
7
12
|
class InvalidError < ModalError; end
|
13
|
+
|
8
14
|
class QueueEmptyError < ModalError; end
|
15
|
+
|
9
16
|
class QueueFullError < ModalError; end
|
17
|
+
|
10
18
|
class SandboxFilesystemError < ModalError; end
|
11
19
|
end
|
data/lib/modal/function.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require_relative
|
1
|
+
require "digest"
|
2
|
+
require_relative "pickle"
|
3
3
|
|
4
4
|
module Modal
|
5
5
|
class Function_
|
@@ -32,15 +32,13 @@ module Modal
|
|
32
32
|
|
33
33
|
retry_count = 0
|
34
34
|
loop do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
raise e
|
43
|
-
end
|
35
|
+
return invocation.await_output
|
36
|
+
rescue InternalFailure => e
|
37
|
+
if retry_count <= MAX_SYSTEM_RETRIES
|
38
|
+
invocation.retry(retry_count)
|
39
|
+
retry_count += 1
|
40
|
+
else
|
41
|
+
raise e
|
44
42
|
end
|
45
43
|
end
|
46
44
|
end
|
@@ -96,16 +94,16 @@ module Modal
|
|
96
94
|
if resp.multipart
|
97
95
|
raise "Function input size exceeds multipart upload threshold, unsupported by this SDK version"
|
98
96
|
elsif resp.upload_url
|
99
|
-
require
|
100
|
-
require
|
97
|
+
require "net/http"
|
98
|
+
require "uri"
|
101
99
|
|
102
100
|
uri = URI.parse(resp.upload_url)
|
103
101
|
http = Net::HTTP.new(uri.host, uri.port)
|
104
|
-
http.use_ssl = uri.scheme ==
|
102
|
+
http.use_ssl = uri.scheme == "https"
|
105
103
|
|
106
104
|
req = Net::HTTP::Put.new(uri.request_uri)
|
107
|
-
req[
|
108
|
-
req[
|
105
|
+
req["Content-Type"] = "application/octet-stream"
|
106
|
+
req["Content-MD5"] = content_md5
|
109
107
|
req.body = data
|
110
108
|
|
111
109
|
upload_resp = http.request(req)
|
data/lib/modal/function_call.rb
CHANGED
data/lib/modal/image.rb
CHANGED
data/lib/modal/invocation.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "pickle"
|
2
2
|
|
3
3
|
module Modal
|
4
4
|
module Invocation
|
5
|
-
def await_output(timeout = nil)
|
6
|
-
|
5
|
+
def await_output(timeout = nil)
|
6
|
+
end
|
7
|
+
|
8
|
+
def retry(retry_count)
|
9
|
+
end
|
7
10
|
end
|
8
11
|
|
9
12
|
class ControlPlaneInvocation
|
@@ -115,11 +118,9 @@ module Modal
|
|
115
118
|
case status
|
116
119
|
when :GENERIC_STATUS_SUCCESS
|
117
120
|
if result.data && !result.data.empty?
|
118
|
-
|
121
|
+
Pickle.load(result.data)
|
119
122
|
elsif result.data_blob_id && !result.data_blob_id.empty?
|
120
|
-
|
121
|
-
else
|
122
|
-
return nil
|
123
|
+
nil
|
123
124
|
end
|
124
125
|
when :GENERIC_STATUS_TIMEOUT
|
125
126
|
raise FunctionTimeoutError.new(result.exception || "Function timed out")
|
data/lib/modal/pickle.rb
CHANGED
@@ -1,50 +1,42 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "pycall"
|
2
|
+
require "json"
|
3
3
|
|
4
4
|
module Pickle
|
5
5
|
class PickleError < StandardError; end
|
6
6
|
|
7
7
|
def self.pickle_module
|
8
|
-
@pickle_module ||= PyCall.import_module(
|
8
|
+
@pickle_module ||= PyCall.import_module("pickle")
|
9
9
|
end
|
10
10
|
|
11
11
|
def self.json_module
|
12
|
-
@json_module ||= PyCall.import_module(
|
12
|
+
@json_module ||= PyCall.import_module("json")
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.load(data)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
raise PickleError, "Failed to load pickle data: #{e.message}"
|
23
|
-
end
|
16
|
+
pickle_data = data.respond_to?(:read) ? data.read : data
|
17
|
+
python_obj = pickle_module.loads(pickle_data)
|
18
|
+
json_str = json_module.dumps(python_obj)
|
19
|
+
JSON.parse(json_str.to_s)
|
20
|
+
rescue => e
|
21
|
+
raise PickleError, "Failed to load pickle data: #{e.message}"
|
24
22
|
end
|
25
23
|
|
26
24
|
def self.dumps(obj)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
raise PickleError, "Failed to dump object to pickle: #{e.message}"
|
33
|
-
end
|
25
|
+
json_str = JSON.generate(obj)
|
26
|
+
python_obj = json_module.loads(json_str)
|
27
|
+
pickle_module.dumps(python_obj).to_s
|
28
|
+
rescue => e
|
29
|
+
raise PickleError, "Failed to dump object to pickle: #{e.message}"
|
34
30
|
end
|
35
31
|
|
36
32
|
def self.dump(obj, file)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
File.open(file, 'wb') do |f|
|
43
|
-
f.write(pickled_data)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
rescue => e
|
47
|
-
raise PickleError, "Failed to dump object to file: #{e.message}"
|
33
|
+
pickled_data = dumps(obj)
|
34
|
+
if file.respond_to?(:write)
|
35
|
+
file.write(pickled_data)
|
36
|
+
else
|
37
|
+
File.binwrite(file, pickled_data)
|
48
38
|
end
|
39
|
+
rescue => e
|
40
|
+
raise PickleError, "Failed to dump object to file: #{e.message}"
|
49
41
|
end
|
50
42
|
end
|
data/lib/modal/sandbox.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require
|
1
|
+
require_relative "sandbox_filesystem"
|
2
|
+
require_relative "streams"
|
3
|
+
require "ostruct"
|
4
4
|
|
5
5
|
module Modal
|
6
6
|
class Sandbox
|
@@ -105,7 +105,6 @@ module Modal
|
|
105
105
|
|
106
106
|
retries -= 1
|
107
107
|
sleep(0.1)
|
108
|
-
|
109
108
|
rescue GRPC::BadStatus => e
|
110
109
|
if e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
|
111
110
|
retries -= 1
|
@@ -176,7 +175,7 @@ module Modal
|
|
176
175
|
def write(chunk)
|
177
176
|
request = Modal::Client::SandboxStdinWriteRequest.new(
|
178
177
|
sandbox_id: @sandbox_id,
|
179
|
-
input: chunk.bytes.pack(
|
178
|
+
input: chunk.bytes.pack("C*"), # Convert to bytes
|
180
179
|
index: @index
|
181
180
|
)
|
182
181
|
Modal.client.call(:sandbox_stdin_write, request)
|
@@ -207,7 +206,6 @@ module Modal
|
|
207
206
|
|
208
207
|
return if @finished
|
209
208
|
|
210
|
-
|
211
209
|
# make one call and collect all data until EOF
|
212
210
|
request = Modal::Client::SandboxGetLogsRequest.new(
|
213
211
|
sandbox_id: @sandbox_id,
|
@@ -221,7 +219,6 @@ module Modal
|
|
221
219
|
|
222
220
|
# Process the entire streaming response
|
223
221
|
resp.each do |batch|
|
224
|
-
|
225
222
|
# Update last_entry_id
|
226
223
|
if batch.respond_to?(:entry_id) && batch.entry_id && !batch.entry_id.empty?
|
227
224
|
@last_entry_id = batch.entry_id
|
@@ -242,7 +239,6 @@ module Modal
|
|
242
239
|
break
|
243
240
|
end
|
244
241
|
end
|
245
|
-
|
246
242
|
rescue GRPC::BadStatus => e
|
247
243
|
if e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
|
248
244
|
@finished = true
|
@@ -253,7 +249,6 @@ module Modal
|
|
253
249
|
|
254
250
|
# Yield all collected data
|
255
251
|
@data_collected.each { |data| yield data }
|
256
|
-
|
257
252
|
end
|
258
253
|
end
|
259
254
|
|
@@ -267,7 +262,7 @@ module Modal
|
|
267
262
|
request = Modal::Client::ContainerExecPutInputRequest.new(
|
268
263
|
exec_id: @exec_id,
|
269
264
|
input: Modal::Client::ContainerExecInput.new(
|
270
|
-
message: chunk.bytes.pack(
|
265
|
+
message: chunk.bytes.pack("C*"), # Convert to bytes
|
271
266
|
message_index: @message_index
|
272
267
|
)
|
273
268
|
)
|
@@ -300,7 +295,6 @@ module Modal
|
|
300
295
|
return enum_for(:each) unless block_given?
|
301
296
|
return if @finished
|
302
297
|
|
303
|
-
|
304
298
|
begin
|
305
299
|
request = Modal::Client::ContainerExecGetOutputRequest.new(
|
306
300
|
exec_id: @exec_id,
|
@@ -326,7 +320,6 @@ module Modal
|
|
326
320
|
break
|
327
321
|
end
|
328
322
|
end
|
329
|
-
|
330
323
|
rescue GRPC::BadStatus => e
|
331
324
|
if e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
|
332
325
|
else
|
@@ -32,17 +32,16 @@ module Modal
|
|
32
32
|
stream = Modal.client.call(:container_filesystem_exec_get_output, output_request)
|
33
33
|
|
34
34
|
stream.each do |batch|
|
35
|
-
|
36
35
|
if batch.respond_to?(:output) && batch.output && batch.output.any?
|
37
|
-
if batch.output.first.is_a?(String)
|
38
|
-
|
36
|
+
chunk = if batch.output.first.is_a?(String)
|
37
|
+
batch.output.join("")
|
39
38
|
elsif batch.output.first.is_a?(Integer)
|
40
|
-
|
39
|
+
batch.output.pack("C*")
|
41
40
|
else
|
42
|
-
|
41
|
+
batch.output.map(&:to_s).join("")
|
43
42
|
end
|
44
43
|
|
45
|
-
data += chunk.force_encoding(
|
44
|
+
data += chunk.force_encoding("UTF-8")
|
46
45
|
end
|
47
46
|
|
48
47
|
if batch.respond_to?(:error) && batch.error
|
@@ -59,7 +58,6 @@ module Modal
|
|
59
58
|
retries -= 1
|
60
59
|
sleep(0.1)
|
61
60
|
end
|
62
|
-
|
63
61
|
rescue GRPC::BadStatus => e
|
64
62
|
if e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
|
65
63
|
retries -= 1
|
@@ -76,10 +74,10 @@ module Modal
|
|
76
74
|
|
77
75
|
def write(data)
|
78
76
|
binary_data = if data.is_a?(String)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
77
|
+
data.force_encoding("BINARY")
|
78
|
+
else
|
79
|
+
data.to_s.force_encoding("BINARY")
|
80
|
+
end
|
83
81
|
|
84
82
|
request = Modal::Client::ContainerFilesystemExecRequest.new(
|
85
83
|
file_write_request: Modal::Client::ContainerFileWriteRequest.new(
|
@@ -89,11 +87,9 @@ module Modal
|
|
89
87
|
task_id: @task_id
|
90
88
|
)
|
91
89
|
|
92
|
-
|
93
90
|
resp = Modal.client.call(:container_filesystem_exec, request)
|
94
91
|
exec_id = resp.exec_id
|
95
92
|
|
96
|
-
|
97
93
|
completed = false
|
98
94
|
retries = 20
|
99
95
|
|
@@ -120,7 +116,6 @@ module Modal
|
|
120
116
|
retries -= 1
|
121
117
|
sleep(0.1)
|
122
118
|
end
|
123
|
-
|
124
119
|
rescue GRPC::BadStatus => e
|
125
120
|
if e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
|
126
121
|
retries -= 1
|
@@ -170,7 +165,6 @@ module Modal
|
|
170
165
|
|
171
166
|
retries -= 1
|
172
167
|
sleep(0.1)
|
173
|
-
|
174
168
|
rescue GRPC::BadStatus => e
|
175
169
|
if e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
|
176
170
|
retries -= 1
|
@@ -214,7 +208,6 @@ module Modal
|
|
214
208
|
|
215
209
|
retries -= 1
|
216
210
|
sleep(0.1)
|
217
|
-
|
218
211
|
rescue GRPC::BadStatus => e
|
219
212
|
if e.code == GRPC::Core::StatusCodes::DEADLINE_EXCEEDED
|
220
213
|
retries -= 1
|
data/lib/modal/streams.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "stringio"
|
2
2
|
|
3
3
|
module Modal
|
4
4
|
class ModalReadStream
|
@@ -13,9 +13,9 @@ module Modal
|
|
13
13
|
def read_text
|
14
14
|
chunks = []
|
15
15
|
@source_iterable.each do |bytes|
|
16
|
-
chunks << bytes.dup.force_encoding(
|
16
|
+
chunks << bytes.dup.force_encoding("UTF-8")
|
17
17
|
end
|
18
|
-
chunks.join(
|
18
|
+
chunks.join("")
|
19
19
|
end
|
20
20
|
|
21
21
|
def read_bytes
|
@@ -23,7 +23,7 @@ module Modal
|
|
23
23
|
@source_iterable.each do |bytes|
|
24
24
|
chunks << bytes.dup
|
25
25
|
end
|
26
|
-
chunks.join(
|
26
|
+
chunks.join("").bytes.pack("C*")
|
27
27
|
end
|
28
28
|
|
29
29
|
def each(&block)
|
@@ -40,7 +40,6 @@ module Modal
|
|
40
40
|
@sink_writable = sink_writable
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
43
|
def write(data)
|
45
44
|
if data.is_a?(String)
|
46
45
|
if data.encoding == Encoding::BINARY
|
data/lib/modal/version.rb
CHANGED
data/lib/modal.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module Modal
|
2
|
-
require
|
2
|
+
require "modal_proto/api_services_pb"
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
4
|
+
require "modal/version"
|
5
|
+
require "modal/errors"
|
6
|
+
require "modal/config"
|
7
|
+
require "modal/api_client"
|
8
|
+
require "modal/app"
|
9
|
+
require "modal/cls"
|
10
|
+
require "modal/image"
|
11
|
+
require "modal/function"
|
12
|
+
require "modal/function_call"
|
13
|
+
require "modal/sandbox"
|
14
|
+
require "modal/streams"
|
15
15
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: modal-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Corletti
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: A gem to interact with Modal from your Ruby, Rails, or Sinatra applications
|
13
13
|
email:
|
@@ -36,7 +36,7 @@ files:
|
|
36
36
|
- lib/modal_proto/options_pb.rb
|
37
37
|
homepage: https://rubygems.org/gems/modal_rb
|
38
38
|
licenses:
|
39
|
-
-
|
39
|
+
- MIT
|
40
40
|
metadata: {}
|
41
41
|
rdoc_options: []
|
42
42
|
require_paths:
|
@@ -45,14 +45,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
45
45
|
requirements:
|
46
46
|
- - ">="
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
48
|
+
version: 3.4.0
|
49
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '0'
|
54
54
|
requirements: []
|
55
|
-
rubygems_version: 3.6.
|
55
|
+
rubygems_version: 3.6.9
|
56
56
|
specification_version: 4
|
57
57
|
summary: Interact with modal from your Ruby code
|
58
58
|
test_files: []
|