isolate 0.13.10__py3-none-any.whl → 0.14.1__py3-none-any.whl

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.

Potentially problematic release.


This version of isolate might be problematic. Click here for more details.

@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.13.10'
16
- __version_tuple__ = version_tuple = (0, 13, 10)
15
+ __version__ = version = '0.14.1'
16
+ __version_tuple__ = version_tuple = (0, 14, 1)
@@ -2,16 +2,20 @@
2
2
  @generated by mypy-protobuf. Do not edit manually!
3
3
  isort:skip_file
4
4
  """
5
-
6
5
  import builtins
7
6
  from isolate.connections.grpc.definitions import common_pb2
8
7
  import google.protobuf.descriptor
9
8
  import google.protobuf.message
10
- import typing
9
+ import sys
10
+
11
+ if sys.version_info >= (3, 8):
12
+ import typing as typing_extensions
13
+ else:
14
+ import typing_extensions
11
15
 
12
16
  DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
13
17
 
14
- @typing.final
18
+ @typing_extensions.final
15
19
  class FunctionCall(google.protobuf.message.Message):
16
20
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
17
21
 
@@ -20,7 +24,6 @@ class FunctionCall(google.protobuf.message.Message):
20
24
  @property
21
25
  def function(self) -> common_pb2.SerializedObject:
22
26
  """The function to execute and return the results to."""
23
-
24
27
  @property
25
28
  def setup_func(self) -> common_pb2.SerializedObject:
26
29
  """Optionally the setup function which will be passed
@@ -28,15 +31,14 @@ class FunctionCall(google.protobuf.message.Message):
28
31
  has to be an idempotent step since the result for
29
32
  this executable will be cached.
30
33
  """
31
-
32
34
  def __init__(
33
35
  self,
34
36
  *,
35
37
  function: common_pb2.SerializedObject | None = ...,
36
38
  setup_func: common_pb2.SerializedObject | None = ...,
37
39
  ) -> None: ...
38
- def HasField(self, field_name: typing.Literal["_setup_func", b"_setup_func", "function", b"function", "setup_func", b"setup_func"]) -> builtins.bool: ...
39
- def ClearField(self, field_name: typing.Literal["_setup_func", b"_setup_func", "function", b"function", "setup_func", b"setup_func"]) -> None: ...
40
- def WhichOneof(self, oneof_group: typing.Literal["_setup_func", b"_setup_func"]) -> typing.Literal["setup_func"] | None: ...
40
+ def HasField(self, field_name: typing_extensions.Literal["_setup_func", b"_setup_func", "function", b"function", "setup_func", b"setup_func"]) -> builtins.bool: ...
41
+ def ClearField(self, field_name: typing_extensions.Literal["_setup_func", b"_setup_func", "function", b"function", "setup_func", b"setup_func"]) -> None: ...
42
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_setup_func", b"_setup_func"]) -> typing_extensions.Literal["setup_func"] | None: ...
41
43
 
42
44
  global___FunctionCall = FunctionCall
@@ -2,7 +2,6 @@
2
2
  @generated by mypy-protobuf. Do not edit manually!
3
3
  isort:skip_file
4
4
  """
5
-
6
5
  import builtins
7
6
  import collections.abc
8
7
  import google.protobuf.descriptor
@@ -62,7 +61,7 @@ STDOUT: LogLevel.ValueType # 5
62
61
  STDERR: LogLevel.ValueType # 6
63
62
  global___LogLevel = LogLevel
64
63
 
65
- @typing.final
64
+ @typing_extensions.final
66
65
  class SerializedObject(google.protobuf.message.Message):
67
66
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
68
67
 
@@ -90,13 +89,13 @@ class SerializedObject(google.protobuf.message.Message):
90
89
  was_it_raised: builtins.bool = ...,
91
90
  stringized_traceback: builtins.str | None = ...,
92
91
  ) -> None: ...
93
- def HasField(self, field_name: typing.Literal["_stringized_traceback", b"_stringized_traceback", "stringized_traceback", b"stringized_traceback"]) -> builtins.bool: ...
94
- def ClearField(self, field_name: typing.Literal["_stringized_traceback", b"_stringized_traceback", "definition", b"definition", "method", b"method", "stringized_traceback", b"stringized_traceback", "was_it_raised", b"was_it_raised"]) -> None: ...
95
- def WhichOneof(self, oneof_group: typing.Literal["_stringized_traceback", b"_stringized_traceback"]) -> typing.Literal["stringized_traceback"] | None: ...
92
+ def HasField(self, field_name: typing_extensions.Literal["_stringized_traceback", b"_stringized_traceback", "stringized_traceback", b"stringized_traceback"]) -> builtins.bool: ...
93
+ def ClearField(self, field_name: typing_extensions.Literal["_stringized_traceback", b"_stringized_traceback", "definition", b"definition", "method", b"method", "stringized_traceback", b"stringized_traceback", "was_it_raised", b"was_it_raised"]) -> None: ...
94
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_stringized_traceback", b"_stringized_traceback"]) -> typing_extensions.Literal["stringized_traceback"] | None: ...
96
95
 
97
96
  global___SerializedObject = SerializedObject
98
97
 
99
- @typing.final
98
+ @typing_extensions.final
100
99
  class PartialRunResult(google.protobuf.message.Message):
101
100
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
102
101
 
@@ -110,11 +109,9 @@ class PartialRunResult(google.protobuf.message.Message):
110
109
  """A list of logs collected during this partial execution. It does
111
110
  not include old logs.
112
111
  """
113
-
114
112
  @property
115
113
  def result(self) -> global___SerializedObject:
116
114
  """The result of the run, if it is complete."""
117
-
118
115
  def __init__(
119
116
  self,
120
117
  *,
@@ -122,13 +119,13 @@ class PartialRunResult(google.protobuf.message.Message):
122
119
  logs: collections.abc.Iterable[global___Log] | None = ...,
123
120
  result: global___SerializedObject | None = ...,
124
121
  ) -> None: ...
125
- def HasField(self, field_name: typing.Literal["_result", b"_result", "result", b"result"]) -> builtins.bool: ...
126
- def ClearField(self, field_name: typing.Literal["_result", b"_result", "is_complete", b"is_complete", "logs", b"logs", "result", b"result"]) -> None: ...
127
- def WhichOneof(self, oneof_group: typing.Literal["_result", b"_result"]) -> typing.Literal["result"] | None: ...
122
+ def HasField(self, field_name: typing_extensions.Literal["_result", b"_result", "result", b"result"]) -> builtins.bool: ...
123
+ def ClearField(self, field_name: typing_extensions.Literal["_result", b"_result", "is_complete", b"is_complete", "logs", b"logs", "result", b"result"]) -> None: ...
124
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_result", b"_result"]) -> typing_extensions.Literal["result"] | None: ...
128
125
 
129
126
  global___PartialRunResult = PartialRunResult
130
127
 
131
- @typing.final
128
+ @typing_extensions.final
132
129
  class Log(google.protobuf.message.Message):
133
130
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
134
131
 
@@ -149,7 +146,7 @@ class Log(google.protobuf.message.Message):
149
146
  level: global___LogLevel.ValueType = ...,
150
147
  timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ...,
151
148
  ) -> None: ...
152
- def HasField(self, field_name: typing.Literal["timestamp", b"timestamp"]) -> builtins.bool: ...
153
- def ClearField(self, field_name: typing.Literal["level", b"level", "message", b"message", "source", b"source", "timestamp", b"timestamp"]) -> None: ...
149
+ def HasField(self, field_name: typing_extensions.Literal["timestamp", b"timestamp"]) -> builtins.bool: ...
150
+ def ClearField(self, field_name: typing_extensions.Literal["level", b"level", "message", b"message", "source", b"source", "timestamp", b"timestamp"]) -> None: ...
154
151
 
155
152
  global___Log = Log
isolate/logger.py CHANGED
@@ -1,24 +1,18 @@
1
1
  import json
2
2
  import os
3
+ from typing import Dict
4
+
5
+ from isolate.logs import LogLevel, LogSource
3
6
 
4
7
 
5
8
  # NOTE: we probably should've created a proper `logging.getLogger` here,
6
9
  # but it handling `source` would be not trivial, so we are better off
7
10
  # just keeping it simple for now.
8
11
  class IsolateLogger:
9
- def __init__(self):
10
- self.log_labels = {}
11
- raw = os.getenv("ISOLATE_LOG_LABELS")
12
- if raw:
13
- labels = json.loads(raw)
14
- for key, value in labels.items():
15
- if value.startswith("$"):
16
- expanded = os.getenv(value[1:])
17
- else:
18
- expanded = value
19
- self.log_labels[key] = expanded
20
-
21
- def log(self, level, message, source):
12
+ def __init__(self, log_labels: Dict[str, str]):
13
+ self.log_labels = log_labels
14
+
15
+ def log(self, level: LogLevel, message: str, source: LogSource) -> None:
22
16
  record = {
23
17
  "isolate_source": source.name,
24
18
  "level": level.name,
@@ -27,5 +21,29 @@ class IsolateLogger:
27
21
  }
28
22
  print(json.dumps(record))
29
23
 
24
+ @classmethod
25
+ def with_env_expanded(cls, labels: Dict[str, str]) -> "IsolateLogger":
26
+ for key, value in labels.items():
27
+ if value.startswith("$"):
28
+ expanded = os.getenv(value[1:])
29
+ else:
30
+ expanded = value
31
+ if expanded is not None:
32
+ labels[key] = expanded
33
+
34
+ return cls(labels)
35
+
36
+ @classmethod
37
+ def from_env(cls) -> "IsolateLogger":
38
+ _labels: Dict[str, str] = {}
39
+ raw = os.getenv("ISOLATE_LOG_LABELS")
40
+ if raw:
41
+ try:
42
+ _labels = json.loads(raw)
43
+ except json.JSONDecodeError:
44
+ print("Failed to parse ISOLATE_LOG_LABELS")
45
+
46
+ return cls.with_env_expanded(labels=_labels)
47
+
30
48
 
31
- logger = IsolateLogger()
49
+ ENV_LOGGER = IsolateLogger.from_env()
@@ -11,6 +11,9 @@ service Isolate {
11
11
  // Submit a function to be run without waiting for results.
12
12
  rpc Submit (SubmitRequest) returns (SubmitResponse) {}
13
13
 
14
+ // Set the metadata for a task.
15
+ rpc SetMetadata (SetMetadataRequest) returns (SetMetadataResponse) {}
16
+
14
17
  // List running tasks
15
18
  rpc List (ListRequest) returns (ListResponse) {}
16
19
 
@@ -36,12 +39,27 @@ message EnvironmentDefinition {
36
39
  message SubmitRequest {
37
40
  // The function to run.
38
41
  BoundFunction function = 1;
42
+ // Task metadata.
43
+ TaskMetadata metadata = 2;
44
+ }
45
+
46
+ message TaskMetadata {
47
+ // Labels to attach to the logs.
48
+ map<string, string> logger_labels = 1;
39
49
  }
40
50
 
41
51
  message SubmitResponse {
42
52
  string task_id = 1;
43
53
  }
44
54
 
55
+ message SetMetadataRequest{
56
+ string task_id = 1;
57
+ TaskMetadata metadata = 2;
58
+ }
59
+
60
+ message SetMetadataResponse {
61
+ }
62
+
45
63
  message ListRequest {
46
64
  }
47
65
 
@@ -16,31 +16,41 @@ from isolate.connections.grpc.definitions import common_pb2 as common__pb2
16
16
  from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
17
17
 
18
18
 
19
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cserver.proto\x1a\x0c\x63ommon.proto\x1a\x1cgoogle/protobuf/struct.proto\"\x9d\x01\n\rBoundFunction\x12,\n\x0c\x65nvironments\x18\x01 \x03(\x0b\x32\x16.EnvironmentDefinition\x12#\n\x08\x66unction\x18\x02 \x01(\x0b\x32\x11.SerializedObject\x12*\n\nsetup_func\x18\x03 \x01(\x0b\x32\x11.SerializedObjectH\x00\x88\x01\x01\x42\r\n\x0b_setup_func\"d\n\x15\x45nvironmentDefinition\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12.\n\rconfiguration\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\r\n\x05\x66orce\x18\x03 \x01(\x08\"1\n\rSubmitRequest\x12 \n\x08\x66unction\x18\x01 \x01(\x0b\x32\x0e.BoundFunction\"!\n\x0eSubmitResponse\x12\x0f\n\x07task_id\x18\x01 \x01(\t\"\r\n\x0bListRequest\"\x1b\n\x08TaskInfo\x12\x0f\n\x07task_id\x18\x01 \x01(\t\"(\n\x0cListResponse\x12\x18\n\x05tasks\x18\x01 \x03(\x0b\x32\t.TaskInfo\" \n\rCancelRequest\x12\x0f\n\x07task_id\x18\x01 \x01(\t\"\x10\n\x0e\x43\x61ncelResponse2\xb8\x01\n\x07Isolate\x12,\n\x03Run\x12\x0e.BoundFunction\x1a\x11.PartialRunResult\"\x00\x30\x01\x12+\n\x06Submit\x12\x0e.SubmitRequest\x1a\x0f.SubmitResponse\"\x00\x12%\n\x04List\x12\x0c.ListRequest\x1a\r.ListResponse\"\x00\x12+\n\x06\x43\x61ncel\x12\x0e.CancelRequest\x1a\x0f.CancelResponse\"\x00\x62\x06proto3')
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cserver.proto\x1a\x0c\x63ommon.proto\x1a\x1cgoogle/protobuf/struct.proto\"\x9d\x01\n\rBoundFunction\x12,\n\x0c\x65nvironments\x18\x01 \x03(\x0b\x32\x16.EnvironmentDefinition\x12#\n\x08\x66unction\x18\x02 \x01(\x0b\x32\x11.SerializedObject\x12*\n\nsetup_func\x18\x03 \x01(\x0b\x32\x11.SerializedObjectH\x00\x88\x01\x01\x42\r\n\x0b_setup_func\"d\n\x15\x45nvironmentDefinition\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12.\n\rconfiguration\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\r\n\x05\x66orce\x18\x03 \x01(\x08\"R\n\rSubmitRequest\x12 \n\x08\x66unction\x18\x01 \x01(\x0b\x32\x0e.BoundFunction\x12\x1f\n\x08metadata\x18\x02 \x01(\x0b\x32\r.TaskMetadata\"{\n\x0cTaskMetadata\x12\x36\n\rlogger_labels\x18\x01 \x03(\x0b\x32\x1f.TaskMetadata.LoggerLabelsEntry\x1a\x33\n\x11LoggerLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"!\n\x0eSubmitResponse\x12\x0f\n\x07task_id\x18\x01 \x01(\t\"F\n\x12SetMetadataRequest\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x1f\n\x08metadata\x18\x02 \x01(\x0b\x32\r.TaskMetadata\"\x15\n\x13SetMetadataResponse\"\r\n\x0bListRequest\"\x1b\n\x08TaskInfo\x12\x0f\n\x07task_id\x18\x01 \x01(\t\"(\n\x0cListResponse\x12\x18\n\x05tasks\x18\x01 \x03(\x0b\x32\t.TaskInfo\" \n\rCancelRequest\x12\x0f\n\x07task_id\x18\x01 \x01(\t\"\x10\n\x0e\x43\x61ncelResponse2\xf4\x01\n\x07Isolate\x12,\n\x03Run\x12\x0e.BoundFunction\x1a\x11.PartialRunResult\"\x00\x30\x01\x12+\n\x06Submit\x12\x0e.SubmitRequest\x1a\x0f.SubmitResponse\"\x00\x12:\n\x0bSetMetadata\x12\x13.SetMetadataRequest\x1a\x14.SetMetadataResponse\"\x00\x12%\n\x04List\x12\x0c.ListRequest\x1a\r.ListResponse\"\x00\x12+\n\x06\x43\x61ncel\x12\x0e.CancelRequest\x1a\x0f.CancelResponse\"\x00\x62\x06proto3')
20
20
 
21
21
  _globals = globals()
22
22
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
23
23
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'server_pb2', _globals)
24
24
  if not _descriptor._USE_C_DESCRIPTORS:
25
25
  DESCRIPTOR._loaded_options = None
26
+ _globals['_TASKMETADATA_LOGGERLABELSENTRY']._loaded_options = None
27
+ _globals['_TASKMETADATA_LOGGERLABELSENTRY']._serialized_options = b'8\001'
26
28
  _globals['_BOUNDFUNCTION']._serialized_start=61
27
29
  _globals['_BOUNDFUNCTION']._serialized_end=218
28
30
  _globals['_ENVIRONMENTDEFINITION']._serialized_start=220
29
31
  _globals['_ENVIRONMENTDEFINITION']._serialized_end=320
30
32
  _globals['_SUBMITREQUEST']._serialized_start=322
31
- _globals['_SUBMITREQUEST']._serialized_end=371
32
- _globals['_SUBMITRESPONSE']._serialized_start=373
33
- _globals['_SUBMITRESPONSE']._serialized_end=406
34
- _globals['_LISTREQUEST']._serialized_start=408
35
- _globals['_LISTREQUEST']._serialized_end=421
36
- _globals['_TASKINFO']._serialized_start=423
37
- _globals['_TASKINFO']._serialized_end=450
38
- _globals['_LISTRESPONSE']._serialized_start=452
39
- _globals['_LISTRESPONSE']._serialized_end=492
40
- _globals['_CANCELREQUEST']._serialized_start=494
41
- _globals['_CANCELREQUEST']._serialized_end=526
42
- _globals['_CANCELRESPONSE']._serialized_start=528
43
- _globals['_CANCELRESPONSE']._serialized_end=544
44
- _globals['_ISOLATE']._serialized_start=547
45
- _globals['_ISOLATE']._serialized_end=731
33
+ _globals['_SUBMITREQUEST']._serialized_end=404
34
+ _globals['_TASKMETADATA']._serialized_start=406
35
+ _globals['_TASKMETADATA']._serialized_end=529
36
+ _globals['_TASKMETADATA_LOGGERLABELSENTRY']._serialized_start=478
37
+ _globals['_TASKMETADATA_LOGGERLABELSENTRY']._serialized_end=529
38
+ _globals['_SUBMITRESPONSE']._serialized_start=531
39
+ _globals['_SUBMITRESPONSE']._serialized_end=564
40
+ _globals['_SETMETADATAREQUEST']._serialized_start=566
41
+ _globals['_SETMETADATAREQUEST']._serialized_end=636
42
+ _globals['_SETMETADATARESPONSE']._serialized_start=638
43
+ _globals['_SETMETADATARESPONSE']._serialized_end=659
44
+ _globals['_LISTREQUEST']._serialized_start=661
45
+ _globals['_LISTREQUEST']._serialized_end=674
46
+ _globals['_TASKINFO']._serialized_start=676
47
+ _globals['_TASKINFO']._serialized_end=703
48
+ _globals['_LISTRESPONSE']._serialized_start=705
49
+ _globals['_LISTRESPONSE']._serialized_end=745
50
+ _globals['_CANCELREQUEST']._serialized_start=747
51
+ _globals['_CANCELREQUEST']._serialized_end=779
52
+ _globals['_CANCELRESPONSE']._serialized_start=781
53
+ _globals['_CANCELRESPONSE']._serialized_end=797
54
+ _globals['_ISOLATE']._serialized_start=800
55
+ _globals['_ISOLATE']._serialized_end=1044
46
56
  # @@protoc_insertion_point(module_scope)
@@ -2,7 +2,6 @@
2
2
  @generated by mypy-protobuf. Do not edit manually!
3
3
  isort:skip_file
4
4
  """
5
-
6
5
  import builtins
7
6
  import collections.abc
8
7
  from isolate.connections.grpc.definitions import common_pb2
@@ -10,11 +9,16 @@ import google.protobuf.descriptor
10
9
  import google.protobuf.internal.containers
11
10
  import google.protobuf.message
12
11
  import google.protobuf.struct_pb2
13
- import typing
12
+ import sys
13
+
14
+ if sys.version_info >= (3, 8):
15
+ import typing as typing_extensions
16
+ else:
17
+ import typing_extensions
14
18
 
15
19
  DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
16
20
 
17
- @typing.final
21
+ @typing_extensions.final
18
22
  class BoundFunction(google.protobuf.message.Message):
19
23
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
20
24
 
@@ -34,13 +38,13 @@ class BoundFunction(google.protobuf.message.Message):
34
38
  function: common_pb2.SerializedObject | None = ...,
35
39
  setup_func: common_pb2.SerializedObject | None = ...,
36
40
  ) -> None: ...
37
- def HasField(self, field_name: typing.Literal["_setup_func", b"_setup_func", "function", b"function", "setup_func", b"setup_func"]) -> builtins.bool: ...
38
- def ClearField(self, field_name: typing.Literal["_setup_func", b"_setup_func", "environments", b"environments", "function", b"function", "setup_func", b"setup_func"]) -> None: ...
39
- def WhichOneof(self, oneof_group: typing.Literal["_setup_func", b"_setup_func"]) -> typing.Literal["setup_func"] | None: ...
41
+ def HasField(self, field_name: typing_extensions.Literal["_setup_func", b"_setup_func", "function", b"function", "setup_func", b"setup_func"]) -> builtins.bool: ...
42
+ def ClearField(self, field_name: typing_extensions.Literal["_setup_func", b"_setup_func", "environments", b"environments", "function", b"function", "setup_func", b"setup_func"]) -> None: ...
43
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_setup_func", b"_setup_func"]) -> typing_extensions.Literal["setup_func"] | None: ...
40
44
 
41
45
  global___BoundFunction = BoundFunction
42
46
 
43
- @typing.final
47
+ @typing_extensions.final
44
48
  class EnvironmentDefinition(google.protobuf.message.Message):
45
49
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
46
50
 
@@ -49,12 +53,11 @@ class EnvironmentDefinition(google.protobuf.message.Message):
49
53
  FORCE_FIELD_NUMBER: builtins.int
50
54
  kind: builtins.str
51
55
  """Kind of the isolate environment."""
52
- force: builtins.bool
53
- """Whether to force-create this environment or not."""
54
56
  @property
55
57
  def configuration(self) -> google.protobuf.struct_pb2.Struct:
56
58
  """A free-form definition of environment properties."""
57
-
59
+ force: builtins.bool
60
+ """Whether to force-create this environment or not."""
58
61
  def __init__(
59
62
  self,
60
63
  *,
@@ -62,31 +65,68 @@ class EnvironmentDefinition(google.protobuf.message.Message):
62
65
  configuration: google.protobuf.struct_pb2.Struct | None = ...,
63
66
  force: builtins.bool = ...,
64
67
  ) -> None: ...
65
- def HasField(self, field_name: typing.Literal["configuration", b"configuration"]) -> builtins.bool: ...
66
- def ClearField(self, field_name: typing.Literal["configuration", b"configuration", "force", b"force", "kind", b"kind"]) -> None: ...
68
+ def HasField(self, field_name: typing_extensions.Literal["configuration", b"configuration"]) -> builtins.bool: ...
69
+ def ClearField(self, field_name: typing_extensions.Literal["configuration", b"configuration", "force", b"force", "kind", b"kind"]) -> None: ...
67
70
 
68
71
  global___EnvironmentDefinition = EnvironmentDefinition
69
72
 
70
- @typing.final
73
+ @typing_extensions.final
71
74
  class SubmitRequest(google.protobuf.message.Message):
72
75
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
73
76
 
74
77
  FUNCTION_FIELD_NUMBER: builtins.int
78
+ METADATA_FIELD_NUMBER: builtins.int
75
79
  @property
76
80
  def function(self) -> global___BoundFunction:
77
81
  """The function to run."""
78
-
82
+ @property
83
+ def metadata(self) -> global___TaskMetadata:
84
+ """Task metadata."""
79
85
  def __init__(
80
86
  self,
81
87
  *,
82
88
  function: global___BoundFunction | None = ...,
89
+ metadata: global___TaskMetadata | None = ...,
83
90
  ) -> None: ...
84
- def HasField(self, field_name: typing.Literal["function", b"function"]) -> builtins.bool: ...
85
- def ClearField(self, field_name: typing.Literal["function", b"function"]) -> None: ...
91
+ def HasField(self, field_name: typing_extensions.Literal["function", b"function", "metadata", b"metadata"]) -> builtins.bool: ...
92
+ def ClearField(self, field_name: typing_extensions.Literal["function", b"function", "metadata", b"metadata"]) -> None: ...
86
93
 
87
94
  global___SubmitRequest = SubmitRequest
88
95
 
89
- @typing.final
96
+ @typing_extensions.final
97
+ class TaskMetadata(google.protobuf.message.Message):
98
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
99
+
100
+ @typing_extensions.final
101
+ class LoggerLabelsEntry(google.protobuf.message.Message):
102
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
103
+
104
+ KEY_FIELD_NUMBER: builtins.int
105
+ VALUE_FIELD_NUMBER: builtins.int
106
+ key: builtins.str
107
+ value: builtins.str
108
+ def __init__(
109
+ self,
110
+ *,
111
+ key: builtins.str = ...,
112
+ value: builtins.str = ...,
113
+ ) -> None: ...
114
+ def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "value", b"value"]) -> None: ...
115
+
116
+ LOGGER_LABELS_FIELD_NUMBER: builtins.int
117
+ @property
118
+ def logger_labels(self) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]:
119
+ """Labels to attach to the logs."""
120
+ def __init__(
121
+ self,
122
+ *,
123
+ logger_labels: collections.abc.Mapping[builtins.str, builtins.str] | None = ...,
124
+ ) -> None: ...
125
+ def ClearField(self, field_name: typing_extensions.Literal["logger_labels", b"logger_labels"]) -> None: ...
126
+
127
+ global___TaskMetadata = TaskMetadata
128
+
129
+ @typing_extensions.final
90
130
  class SubmitResponse(google.protobuf.message.Message):
91
131
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
92
132
 
@@ -97,11 +137,41 @@ class SubmitResponse(google.protobuf.message.Message):
97
137
  *,
98
138
  task_id: builtins.str = ...,
99
139
  ) -> None: ...
100
- def ClearField(self, field_name: typing.Literal["task_id", b"task_id"]) -> None: ...
140
+ def ClearField(self, field_name: typing_extensions.Literal["task_id", b"task_id"]) -> None: ...
101
141
 
102
142
  global___SubmitResponse = SubmitResponse
103
143
 
104
- @typing.final
144
+ @typing_extensions.final
145
+ class SetMetadataRequest(google.protobuf.message.Message):
146
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
147
+
148
+ TASK_ID_FIELD_NUMBER: builtins.int
149
+ METADATA_FIELD_NUMBER: builtins.int
150
+ task_id: builtins.str
151
+ @property
152
+ def metadata(self) -> global___TaskMetadata: ...
153
+ def __init__(
154
+ self,
155
+ *,
156
+ task_id: builtins.str = ...,
157
+ metadata: global___TaskMetadata | None = ...,
158
+ ) -> None: ...
159
+ def HasField(self, field_name: typing_extensions.Literal["metadata", b"metadata"]) -> builtins.bool: ...
160
+ def ClearField(self, field_name: typing_extensions.Literal["metadata", b"metadata", "task_id", b"task_id"]) -> None: ...
161
+
162
+ global___SetMetadataRequest = SetMetadataRequest
163
+
164
+ @typing_extensions.final
165
+ class SetMetadataResponse(google.protobuf.message.Message):
166
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
167
+
168
+ def __init__(
169
+ self,
170
+ ) -> None: ...
171
+
172
+ global___SetMetadataResponse = SetMetadataResponse
173
+
174
+ @typing_extensions.final
105
175
  class ListRequest(google.protobuf.message.Message):
106
176
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
107
177
 
@@ -111,7 +181,7 @@ class ListRequest(google.protobuf.message.Message):
111
181
 
112
182
  global___ListRequest = ListRequest
113
183
 
114
- @typing.final
184
+ @typing_extensions.final
115
185
  class TaskInfo(google.protobuf.message.Message):
116
186
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
117
187
 
@@ -122,11 +192,11 @@ class TaskInfo(google.protobuf.message.Message):
122
192
  *,
123
193
  task_id: builtins.str = ...,
124
194
  ) -> None: ...
125
- def ClearField(self, field_name: typing.Literal["task_id", b"task_id"]) -> None: ...
195
+ def ClearField(self, field_name: typing_extensions.Literal["task_id", b"task_id"]) -> None: ...
126
196
 
127
197
  global___TaskInfo = TaskInfo
128
198
 
129
- @typing.final
199
+ @typing_extensions.final
130
200
  class ListResponse(google.protobuf.message.Message):
131
201
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
132
202
 
@@ -138,11 +208,11 @@ class ListResponse(google.protobuf.message.Message):
138
208
  *,
139
209
  tasks: collections.abc.Iterable[global___TaskInfo] | None = ...,
140
210
  ) -> None: ...
141
- def ClearField(self, field_name: typing.Literal["tasks", b"tasks"]) -> None: ...
211
+ def ClearField(self, field_name: typing_extensions.Literal["tasks", b"tasks"]) -> None: ...
142
212
 
143
213
  global___ListResponse = ListResponse
144
214
 
145
- @typing.final
215
+ @typing_extensions.final
146
216
  class CancelRequest(google.protobuf.message.Message):
147
217
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
148
218
 
@@ -153,11 +223,11 @@ class CancelRequest(google.protobuf.message.Message):
153
223
  *,
154
224
  task_id: builtins.str = ...,
155
225
  ) -> None: ...
156
- def ClearField(self, field_name: typing.Literal["task_id", b"task_id"]) -> None: ...
226
+ def ClearField(self, field_name: typing_extensions.Literal["task_id", b"task_id"]) -> None: ...
157
227
 
158
228
  global___CancelRequest = CancelRequest
159
229
 
160
- @typing.final
230
+ @typing_extensions.final
161
231
  class CancelResponse(google.protobuf.message.Message):
162
232
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
163
233
 
@@ -50,6 +50,11 @@ class IsolateStub(object):
50
50
  request_serializer=server__pb2.SubmitRequest.SerializeToString,
51
51
  response_deserializer=server__pb2.SubmitResponse.FromString,
52
52
  _registered_method=True)
53
+ self.SetMetadata = channel.unary_unary(
54
+ '/Isolate/SetMetadata',
55
+ request_serializer=server__pb2.SetMetadataRequest.SerializeToString,
56
+ response_deserializer=server__pb2.SetMetadataResponse.FromString,
57
+ _registered_method=True)
53
58
  self.List = channel.unary_unary(
54
59
  '/Isolate/List',
55
60
  request_serializer=server__pb2.ListRequest.SerializeToString,
@@ -80,6 +85,13 @@ class IsolateServicer(object):
80
85
  context.set_details('Method not implemented!')
81
86
  raise NotImplementedError('Method not implemented!')
82
87
 
88
+ def SetMetadata(self, request, context):
89
+ """Set the metadata for a task.
90
+ """
91
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
92
+ context.set_details('Method not implemented!')
93
+ raise NotImplementedError('Method not implemented!')
94
+
83
95
  def List(self, request, context):
84
96
  """List running tasks
85
97
  """
@@ -107,6 +119,11 @@ def add_IsolateServicer_to_server(servicer, server):
107
119
  request_deserializer=server__pb2.SubmitRequest.FromString,
108
120
  response_serializer=server__pb2.SubmitResponse.SerializeToString,
109
121
  ),
122
+ 'SetMetadata': grpc.unary_unary_rpc_method_handler(
123
+ servicer.SetMetadata,
124
+ request_deserializer=server__pb2.SetMetadataRequest.FromString,
125
+ response_serializer=server__pb2.SetMetadataResponse.SerializeToString,
126
+ ),
110
127
  'List': grpc.unary_unary_rpc_method_handler(
111
128
  servicer.List,
112
129
  request_deserializer=server__pb2.ListRequest.FromString,
@@ -182,6 +199,33 @@ class Isolate(object):
182
199
  metadata,
183
200
  _registered_method=True)
184
201
 
202
+ @staticmethod
203
+ def SetMetadata(request,
204
+ target,
205
+ options=(),
206
+ channel_credentials=None,
207
+ call_credentials=None,
208
+ insecure=False,
209
+ compression=None,
210
+ wait_for_ready=None,
211
+ timeout=None,
212
+ metadata=None):
213
+ return grpc.experimental.unary_unary(
214
+ request,
215
+ target,
216
+ '/Isolate/SetMetadata',
217
+ server__pb2.SetMetadataRequest.SerializeToString,
218
+ server__pb2.SetMetadataResponse.FromString,
219
+ options,
220
+ channel_credentials,
221
+ insecure,
222
+ call_credentials,
223
+ compression,
224
+ wait_for_ready,
225
+ timeout,
226
+ metadata,
227
+ _registered_method=True)
228
+
185
229
  @staticmethod
186
230
  def List(request,
187
231
  target,
@@ -2,7 +2,6 @@
2
2
  @generated by mypy-protobuf. Do not edit manually!
3
3
  isort:skip_file
4
4
  """
5
-
6
5
  import builtins
7
6
  import google.protobuf.descriptor
8
7
  import google.protobuf.internal.enum_type_wrapper
@@ -17,7 +16,7 @@ else:
17
16
 
18
17
  DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
19
18
 
20
- @typing.final
19
+ @typing_extensions.final
21
20
  class HealthCheckRequest(google.protobuf.message.Message):
22
21
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
23
22
 
@@ -28,11 +27,11 @@ class HealthCheckRequest(google.protobuf.message.Message):
28
27
  *,
29
28
  service: builtins.str = ...,
30
29
  ) -> None: ...
31
- def ClearField(self, field_name: typing.Literal["service", b"service"]) -> None: ...
30
+ def ClearField(self, field_name: typing_extensions.Literal["service", b"service"]) -> None: ...
32
31
 
33
32
  global___HealthCheckRequest = HealthCheckRequest
34
33
 
35
- @typing.final
34
+ @typing_extensions.final
36
35
  class HealthCheckResponse(google.protobuf.message.Message):
37
36
  DESCRIPTOR: google.protobuf.descriptor.Descriptor
38
37
 
@@ -62,6 +61,6 @@ class HealthCheckResponse(google.protobuf.message.Message):
62
61
  *,
63
62
  status: global___HealthCheckResponse.ServingStatus.ValueType = ...,
64
63
  ) -> None: ...
65
- def ClearField(self, field_name: typing.Literal["status", b"status"]) -> None: ...
64
+ def ClearField(self, field_name: typing_extensions.Literal["status", b"status"]) -> None: ...
66
65
 
67
66
  global___HealthCheckResponse = HealthCheckResponse
isolate/server/server.py CHANGED
@@ -29,13 +29,14 @@ from isolate.backends.local import LocalPythonEnvironment
29
29
  from isolate.backends.virtualenv import VirtualPythonEnvironment
30
30
  from isolate.connections.grpc import AgentError, LocalPythonGRPC
31
31
  from isolate.connections.grpc.configuration import get_default_options
32
- from isolate.logger import logger
32
+ from isolate.logger import ENV_LOGGER, IsolateLogger
33
33
  from isolate.logs import Log, LogLevel, LogSource
34
34
  from isolate.server import definitions, health
35
35
  from isolate.server.health_server import HealthServicer
36
36
  from isolate.server.interface import from_grpc, to_grpc
37
37
 
38
38
  EMPTY_MESSAGE_INTERVAL = float(os.getenv("ISOLATE_EMPTY_MESSAGE_INTERVAL", "600"))
39
+ SKIP_EMPTY_LOGS = os.getenv("ISOLATE_SKIP_EMPTY_LOGS") == "1"
39
40
  MAX_GRPC_WAIT_TIMEOUT = float(os.getenv("ISOLATE_MAX_GRPC_WAIT_TIMEOUT", "10.0"))
40
41
 
41
42
  # Whether to inherit all the packages from the current environment or not.
@@ -174,6 +175,7 @@ class RunTask:
174
175
  request: definitions.BoundFunction
175
176
  future: futures.Future | None = None
176
177
  agent: RunnerAgent | None = None
178
+ logger: IsolateLogger = ENV_LOGGER
177
179
 
178
180
  def cancel(self):
179
181
  while True:
@@ -210,7 +212,8 @@ class IsolateServicer(definitions.IsolateServicer):
210
212
  StatusCode.INVALID_ARGUMENT,
211
213
  )
212
214
 
213
- log_handler = LogHandler(messages)
215
+ log_handler = LogHandler(messages, task=task)
216
+
214
217
  run_settings = replace(
215
218
  self.default_settings,
216
219
  log_hook=log_handler.handle,
@@ -321,11 +324,17 @@ class IsolateServicer(definitions.IsolateServicer):
321
324
  request: definitions.SubmitRequest,
322
325
  context: ServicerContext,
323
326
  ) -> definitions.SubmitResponse:
324
- task = RunTask(request=request.function)
325
- task.future = RUNNER_THREAD_POOL.submit(
326
- self._run_task_in_background,
327
- task,
328
- )
327
+ logger = ENV_LOGGER
328
+ if request.metadata.logger_labels:
329
+ logger_labels_dict = dict(request.metadata.logger_labels)
330
+ try:
331
+ logger = IsolateLogger.with_env_expanded(logger_labels_dict)
332
+ except BaseException:
333
+ # Ignore the error if the logger couldn't be created.
334
+ pass
335
+
336
+ task = RunTask(request=request.function, logger=logger)
337
+ task.future = RUNNER_THREAD_POOL.submit(self._run_task_in_background, task)
329
338
  task_id = str(uuid.uuid4())
330
339
 
331
340
  print(f"Submitted a task {task_id}")
@@ -345,6 +354,25 @@ class IsolateServicer(definitions.IsolateServicer):
345
354
 
346
355
  return definitions.SubmitResponse(task_id=task_id)
347
356
 
357
+ def SetMetadata(
358
+ self,
359
+ request: definitions.SetMetadataRequest,
360
+ context: ServicerContext,
361
+ ) -> definitions.SetMetadataResponse:
362
+ if request.task_id not in self.background_tasks:
363
+ raise GRPCException(
364
+ f"Task {request.task_id} not found.",
365
+ StatusCode.NOT_FOUND,
366
+ )
367
+
368
+ task = self.background_tasks[request.task_id]
369
+
370
+ task.logger = IsolateLogger.with_env_expanded(
371
+ dict(request.metadata.logger_labels)
372
+ )
373
+
374
+ return definitions.SetMetadataResponse()
375
+
348
376
  def Run(
349
377
  self,
350
378
  request: definitions.BoundFunction,
@@ -437,7 +465,8 @@ class IsolateServicer(definitions.IsolateServicer):
437
465
  return None
438
466
 
439
467
  def cancel_tasks(self):
440
- for task in self.background_tasks.values():
468
+ tasks_copy = self.background_tasks.copy()
469
+ for task in tasks_copy.values():
441
470
  task.cancel()
442
471
 
443
472
 
@@ -453,10 +482,13 @@ def _proxy_to_queue(
453
482
  @dataclass
454
483
  class LogHandler:
455
484
  messages: Queue
485
+ # Reference to the task so we can change the logger
486
+ task: RunTask
456
487
 
457
488
  def handle(self, log: Log) -> None:
458
- logger.log(log.level, log.message, source=log.source)
459
- self._add_log_to_queue(log)
489
+ if not SKIP_EMPTY_LOGS or log.message.strip():
490
+ self.task.logger.log(log.level, log.message, source=log.source)
491
+ self._add_log_to_queue(log)
460
492
 
461
493
  def _add_log_to_queue(self, log: Log) -> None:
462
494
  grpc_log = cast(definitions.Log, to_grpc(log))
@@ -505,6 +537,16 @@ class SingleTaskInterceptor(ServerBoundInterceptor):
505
537
  """Sets server to terminate after the first Submit/Run task."""
506
538
 
507
539
  _done: bool = False
540
+ _task_id: str | None = None
541
+
542
+ def __init__(self):
543
+ def terminate(request: Any, context: grpc.ServicerContext) -> Any:
544
+ context.abort(
545
+ grpc.StatusCode.RESOURCE_EXHAUSTED,
546
+ "Server has already served one Run/Submit task.",
547
+ )
548
+
549
+ self._terminator = grpc.unary_unary_rpc_method_handler(terminate)
508
550
 
509
551
  def intercept_service(self, continuation, handler_call_details):
510
552
  handler = continuation(handler_call_details)
@@ -513,29 +555,62 @@ class SingleTaskInterceptor(ServerBoundInterceptor):
513
555
  is_run = handler_call_details.method == "/Isolate/Run"
514
556
  is_new_task = is_submit or is_run
515
557
 
516
- if is_new_task and self._done:
517
- raise grpc.RpcError(
518
- grpc.StatusCode.UNAVAILABLE,
519
- "Server has already served one Run/Submit task.",
520
- )
521
- elif is_new_task:
522
- self._done = True
523
- else:
558
+ if not is_new_task:
524
559
  # Let other requests like List/Cancel/etc pass through
525
- return continuation(handler_call_details)
560
+ return handler
561
+
562
+ if self._done:
563
+ # Fail the request if the server has already served or is serving
564
+ # a Run/Submit task.
565
+ return self._terminator
566
+
567
+ self._done = True
526
568
 
527
569
  def wrapper(method_impl):
528
570
  @functools.wraps(method_impl)
529
- def _wrapper(request, context):
530
- def _stop():
531
- if is_submit:
532
- # Wait for the task to finish
533
- while self.server.servicer.background_tasks:
571
+ def _wrapper(request: Any, context: grpc.ServicerContext) -> Any:
572
+ def termination() -> None:
573
+ if is_run:
574
+ print("Stopping server since run is finished")
575
+ # Stop the server after the Run task is finished
576
+ self.server.stop(grace=0.1)
577
+
578
+ elif is_submit:
579
+ # Wait until the task_id is assigned
580
+ while self._task_id is None:
534
581
  time.sleep(0.1)
535
- self.server.stop(grace=0.1)
536
582
 
537
- context.add_callback(_stop)
538
- return method_impl(request, context)
583
+ # Get the task from the background tasks
584
+ task = self.servicer.background_tasks.get(self._task_id)
585
+
586
+ if task is not None:
587
+ # Wait until the task future is assigned
588
+ tries = 0
589
+ while task.future is None:
590
+ time.sleep(0.1)
591
+ tries += 1
592
+ if tries > 100:
593
+ raise RuntimeError(
594
+ "Task future was not assigned in time."
595
+ )
596
+
597
+ def _stop(*args):
598
+ # Small sleep to make sure the cancellation is processed
599
+ time.sleep(0.1)
600
+ print("Stopping server since the task is finished")
601
+ self.server.stop(grace=0.1)
602
+
603
+ # Add a callback which will stop the server
604
+ # after the task is finished
605
+ task.future.add_done_callback(_stop)
606
+
607
+ context.add_callback(termination)
608
+ res = method_impl(request, context)
609
+
610
+ if is_submit:
611
+ self._task_id = cast(definitions.SubmitResponse, res).task_id
612
+
613
+ return res
539
614
 
540
615
  return _wrapper
541
616
 
@@ -569,7 +644,7 @@ def main(argv: list[str] | None = None) -> None:
569
644
  server = grpc.server(
570
645
  futures.ThreadPoolExecutor(max_workers=options.num_workers),
571
646
  options=get_default_options(),
572
- interceptors=interceptors,
647
+ interceptors=interceptors, # type: ignore
573
648
  )
574
649
 
575
650
  for interceptor in interceptors:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: isolate
3
- Version: 0.13.10
3
+ Version: 0.14.1
4
4
  Summary: Managed isolated environments for Python
5
5
  Author-email: Features & Labels <hello@fal.ai>
6
6
  Project-URL: Issues, https://github.com/fal-ai/isolate/issues
@@ -1,7 +1,7 @@
1
1
  isolate/__init__.py,sha256=uXOKnONs7sXgARNgElwr4_A1sKoA6ACHVEvs3IDiX1M,127
2
- isolate/_isolate_version.py,sha256=B_BL6eQ9yadF9gaiiJ3EqZhMaaHCCNUTzs-755F92es,415
2
+ isolate/_isolate_version.py,sha256=2Ctgubb5b_lxFG2ixV07ZYKw5eto45wRlKsBIObkGsg,413
3
3
  isolate/_version.py,sha256=05pXvy-yr5t3I1m9JMn42Ilzpg7fa8IB2J8a3G7t1cU,274
4
- isolate/logger.py,sha256=Pr-P1UVDIHJkel3ZA3pkAOwXgnGiGjTw-KsxTVc5Y6E,894
4
+ isolate/logger.py,sha256=d9mZyTOtplMZeQSNgRNiXhOPwJ0be2B1nGGaQx09C3g,1450
5
5
  isolate/logs.py,sha256=R_AHUVYD18z_PhtK_mDWi9Gch79CxmwHY09hUDShtwg,2079
6
6
  isolate/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  isolate/registry.py,sha256=hpzv4HI7iihG5I7i5r8Pb257ibhEKY18xQcG-w1-BgI,1590
@@ -30,11 +30,11 @@ isolate/connections/grpc/interface.py,sha256=yt63kytgXRXrTnjePGJVdXz4LJJVSSrNkJC
30
30
  isolate/connections/grpc/definitions/__init__.py,sha256=Z0453Bbjoq-Oxm2Wfi9fae-BFf8YsZwmuh88strmvxo,459
31
31
  isolate/connections/grpc/definitions/agent.proto,sha256=Hx11hHc8PKwhWzyasViLeq7JL33KsRex2-iibfWruTw,568
32
32
  isolate/connections/grpc/definitions/agent_pb2.py,sha256=F8KVIE1CK542c7_EJKJ40LY8mPZwEqvdmgBPntAMqE0,1424
33
- isolate/connections/grpc/definitions/agent_pb2.pyi,sha256=kZsyy2PJX21J6n-hPN_bZPMl8UKNXGTNErdqKkmenes,1589
33
+ isolate/connections/grpc/definitions/agent_pb2.pyi,sha256=IKJHEq01DZRIy4xrtpHalJmM56IQCZRxFEOZEs7hCUw,1744
34
34
  isolate/connections/grpc/definitions/agent_pb2_grpc.py,sha256=7tm-RB4CTu_YmqvI7QGRll1Z1NmkMWY2Vm-4AHr57X8,3632
35
35
  isolate/connections/grpc/definitions/common.proto,sha256=4W1upvDIPezNj-Ab6FVNa-7cA9_N-2xJMJpwytRhpCw,1260
36
36
  isolate/connections/grpc/definitions/common_pb2.py,sha256=lkpvpARZbPDrzrVkKJ-4WZWISN2kzrzJPNBUczmvkHU,2464
37
- isolate/connections/grpc/definitions/common_pb2.pyi,sha256=R-den8f1m7Lv2EnMXb3do3UjpO0Ncp3zSLtnKdW895c,6082
37
+ isolate/connections/grpc/definitions/common_pb2.pyi,sha256=J3av86ZHoHR28_5zshqCJ0I7v9WCxuQsvOAin-zig9w,6222
38
38
  isolate/connections/grpc/definitions/common_pb2_grpc.py,sha256=EvGJ0LYaWTflBesxg0P1nh_EeWKYKqUVRf0_plMISTs,1123
39
39
  isolate/connections/ipc/__init__.py,sha256=j2Mbsph2mRhAWmkMyrtPOz0VG-e75h1OOZLwzs6pXUo,131
40
40
  isolate/connections/ipc/_base.py,sha256=Jk715XK2ei3yBpFcwUnFZ0owQMMf5jekZFNh2WlKRT4,8009
@@ -42,20 +42,20 @@ isolate/connections/ipc/agent.py,sha256=hGlL4x78FhRvMZ4DkVh3dk-EmWQqxHW4LIipgyOk
42
42
  isolate/server/__init__.py,sha256=7R3GuWmxuqe0q28rVqETJN9OCrP_-Svjv9h0NR1GFL0,79
43
43
  isolate/server/health_server.py,sha256=yN7F1Q28DdX8-Zk3gef7XcQEE25XwlHwzV5GBM75aQM,1249
44
44
  isolate/server/interface.py,sha256=nGbjdxrN0p9m1LNdeds8NIoJOwPYW2NM6ktmbhfG4_s,687
45
- isolate/server/server.py,sha256=9abptODXQIdswNBQqEYY3yRGz6Jr4NFVs15FiftfRdw,20125
45
+ isolate/server/server.py,sha256=q0g0dL8hOosogGWpZMpXOOohTV55itp6f4K5yenvtBg,23233
46
46
  isolate/server/definitions/__init__.py,sha256=f_Q3pdjMuZrjgNlbM60btFKiB1Vg8cnVyKEbp0RmU0A,572
47
- isolate/server/definitions/server.proto,sha256=GIou0c_RP4sVDxjdYQzUtSptOfJtvbgsU4MGhL9hsMQ,1372
48
- isolate/server/definitions/server_pb2.py,sha256=SdbigRwRd1pU1yFwvyrA4vkmwQHPelPkQT7dtggKUlk,3194
49
- isolate/server/definitions/server_pb2.pyi,sha256=kEo781qnfiYpR9ok7CDdn4kaqdkEgB_66wT4qLMk3M4,5594
50
- isolate/server/definitions/server_pb2_grpc.py,sha256=lSGH6BeQf9cbdESlteNfMlDkFXIFjeVR7PVo-b0k3HM,8455
47
+ isolate/server/definitions/server.proto,sha256=UihlFbYG8fbwm0IUfKDRH1vNkopzP3C-wplXXcAO1c8,1761
48
+ isolate/server/definitions/server_pb2.py,sha256=TYBJC_z_dNf2J6FgHukY9mDyc3WBt9EPQOVFd_ayQNc,4304
49
+ isolate/server/definitions/server_pb2.pyi,sha256=bGDzwxvYJEq_N7R4mvE86t_GhBfUx8eXRYbrvOzFhqc,8352
50
+ isolate/server/definitions/server_pb2_grpc.py,sha256=TUKXKlT-6oOpZ2zg8EhJ-XFvjKGX90ze4iY0f5R6ZHU,10107
51
51
  isolate/server/health/__init__.py,sha256=sy349GRK2YGX9KFKqDxM-jdYtBpMXjZu1QwBkjn0SsM,337
52
52
  isolate/server/health/health.proto,sha256=wE2_QD0OQAblKkEBG7sALLXEOj1mOLKG-FbC4tFopWE,455
53
53
  isolate/server/health/health_pb2.py,sha256=onOdP3M4Tpqhqs2PlGcyfoKe2VVKUEDx5ALeRcObb9A,1899
54
- isolate/server/health/health_pb2.pyi,sha256=CPyvxvDzra-1d-mBsukaJnscMUDBaqSACvo9LiXlFzo,2416
54
+ isolate/server/health/health_pb2.pyi,sha256=AK-DPCpJzoYhU6DydD856c0Ywx84x6k-Cs4m6HpNv5A,2459
55
55
  isolate/server/health/health_pb2_grpc.py,sha256=XgsULrnRBmYIqvKr8eI7bqs6NIea5A0kkqdOOc2JHBY,5303
56
- isolate-0.13.10.dist-info/LICENSE,sha256=427vuyirL5scgBLqA9UWcdnxKrtSGc0u_JfUupk6lAA,11359
57
- isolate-0.13.10.dist-info/METADATA,sha256=EbD9rw4Ys3Z9DcN0pI5ak-aHndo9zGuqOgAjypuK-uw,3192
58
- isolate-0.13.10.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
59
- isolate-0.13.10.dist-info/entry_points.txt,sha256=s3prh2EERaVCbL8R45tfY5WFPZ1TsYOsz305YR7s-Pc,360
60
- isolate-0.13.10.dist-info/top_level.txt,sha256=W9QJBHcq5WXRkbOXf25bvftzFsOZZN4n1DAatdroZrs,8
61
- isolate-0.13.10.dist-info/RECORD,,
56
+ isolate-0.14.1.dist-info/LICENSE,sha256=427vuyirL5scgBLqA9UWcdnxKrtSGc0u_JfUupk6lAA,11359
57
+ isolate-0.14.1.dist-info/METADATA,sha256=_B69rNK-IJtBqsUjNwPXijhI_uLVcBTSLJ3jcbfl8Dk,3191
58
+ isolate-0.14.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
59
+ isolate-0.14.1.dist-info/entry_points.txt,sha256=s3prh2EERaVCbL8R45tfY5WFPZ1TsYOsz305YR7s-Pc,360
60
+ isolate-0.14.1.dist-info/top_level.txt,sha256=W9QJBHcq5WXRkbOXf25bvftzFsOZZN4n1DAatdroZrs,8
61
+ isolate-0.14.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (73.0.1)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5