labtasker-client 2.0.0__tar.gz → 2.0.1__tar.gz
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.
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/PKG-INFO +1 -1
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/pyproject.toml +1 -1
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/__init__.py +1 -1
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/binding.py +6 -2
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/cli.py +5 -5
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/command_worker.py +10 -2
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/config.py +6 -0
- labtasker_client-2.0.1/src/labtasker/py.typed +0 -0
- labtasker_client-2.0.0/src/labtasker/py.typed +0 -1
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/.gitignore +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/LICENSE +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/__main__.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/api.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/client.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/command_template.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/errors.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/execution.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/journal.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/local.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/models.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/paths.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/tee.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/types.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/validation.py +0 -0
- {labtasker_client-2.0.0 → labtasker_client-2.0.1}/src/labtasker/worker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: labtasker-client
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: A small task queue for parallel model inference and evaluation
|
|
5
5
|
Project-URL: Homepage, https://github.com/luocfprime/labtasker
|
|
6
6
|
Project-URL: Repository, https://github.com/luocfprime/labtasker.git
|
|
@@ -35,7 +35,7 @@ from labtasker.models import BulkUpdateResult, LastError, Queue, Task, TaskInfo,
|
|
|
35
35
|
from labtasker.types import JSONValue, TaskOrderField, TaskStatus, TaskUpdate
|
|
36
36
|
from labtasker.worker import loop
|
|
37
37
|
|
|
38
|
-
__version__ = "2.0.
|
|
38
|
+
__version__ = "2.0.1"
|
|
39
39
|
|
|
40
40
|
__all__ = [
|
|
41
41
|
"APIError",
|
|
@@ -119,7 +119,7 @@ class CompiledBinding:
|
|
|
119
119
|
|
|
120
120
|
|
|
121
121
|
def compile_binding(function: Callable[..., Any]) -> CompiledBinding:
|
|
122
|
-
if
|
|
122
|
+
if _is_async_callable(function):
|
|
123
123
|
raise TypeError("Labtasker v2 Worker handlers must be synchronous functions.")
|
|
124
124
|
signature = inspect.signature(function)
|
|
125
125
|
try:
|
|
@@ -170,7 +170,7 @@ def compile_binding(function: Callable[..., Any]) -> CompiledBinding:
|
|
|
170
170
|
def _validate_resolver(resolver: object, name: str) -> None:
|
|
171
171
|
if not callable(resolver):
|
|
172
172
|
raise TypeError(f"TaskArg resolver for {name!r} must be callable.")
|
|
173
|
-
if
|
|
173
|
+
if _is_async_callable(resolver):
|
|
174
174
|
raise TypeError(f"TaskArg resolver for {name!r} must be synchronous.")
|
|
175
175
|
try:
|
|
176
176
|
signature = inspect.signature(resolver)
|
|
@@ -182,3 +182,7 @@ def _validate_resolver(resolver: object, name: str) -> None:
|
|
|
182
182
|
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
|
183
183
|
}:
|
|
184
184
|
raise TypeError(f"TaskArg resolver for {name!r} must accept exactly one value.")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _is_async_callable(value: object) -> bool:
|
|
188
|
+
return inspect.iscoroutinefunction(value) or inspect.iscoroutinefunction(type(value).__call__)
|
|
@@ -98,7 +98,7 @@ def worker_loop(
|
|
|
98
98
|
|
|
99
99
|
Example:
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
\b
|
|
102
102
|
labtasker loop --route train -- \\
|
|
103
103
|
python train.py --seed '%{seed}' --lr '%{optimizer.lr}'
|
|
104
104
|
"""
|
|
@@ -174,7 +174,7 @@ def task_submit(
|
|
|
174
174
|
|
|
175
175
|
Example:
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
\b
|
|
178
178
|
labtasker task submit --name baseline \\
|
|
179
179
|
--args '{"seed":1,"enabled":true}' \\
|
|
180
180
|
--metadata '{"group":"paper"}' --route train
|
|
@@ -250,7 +250,7 @@ def task_list(
|
|
|
250
250
|
|
|
251
251
|
Example:
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
\b
|
|
254
254
|
labtasker task list --status pending \\
|
|
255
255
|
--filter 'priority >= 10 and metadata.group == "paper"' \\
|
|
256
256
|
--order-by priority --descending --limit 100
|
|
@@ -295,7 +295,7 @@ def task_count(
|
|
|
295
295
|
|
|
296
296
|
Example:
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
\b
|
|
299
299
|
labtasker task count --status failed \\
|
|
300
300
|
--filter 'last_error.type == "ValueError"'
|
|
301
301
|
"""
|
|
@@ -339,7 +339,7 @@ def task_update(
|
|
|
339
339
|
|
|
340
340
|
Examples:
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
\b
|
|
343
343
|
labtasker task update t_ABCDEFGHIJKL \\
|
|
344
344
|
--changes '{"priority":20}'
|
|
345
345
|
labtasker task update --filter 'status == "pending"' \\
|
|
@@ -244,13 +244,21 @@ def _start_drain(
|
|
|
244
244
|
name: str,
|
|
245
245
|
) -> threading.Thread:
|
|
246
246
|
def drain() -> None:
|
|
247
|
+
relay = True
|
|
247
248
|
while True:
|
|
248
|
-
chunk =
|
|
249
|
+
chunk = os.read(source.fileno(), 65536)
|
|
249
250
|
if not chunk:
|
|
250
251
|
return
|
|
251
252
|
with lock:
|
|
252
253
|
log.write(chunk)
|
|
253
|
-
|
|
254
|
+
if relay:
|
|
255
|
+
try:
|
|
256
|
+
_write_bytes(destination, chunk)
|
|
257
|
+
except Exception:
|
|
258
|
+
# The child must never block on a full pipe merely because the
|
|
259
|
+
# caller closed or replaced its output stream. Keep draining and
|
|
260
|
+
# journaling after live relay becomes unavailable.
|
|
261
|
+
relay = False
|
|
254
262
|
|
|
255
263
|
thread = threading.Thread(target=drain, name=f"labtasker-command-{name}", daemon=True)
|
|
256
264
|
thread.start()
|
|
@@ -190,4 +190,10 @@ def _validate_token(value: str | None, *, source: str) -> str | None:
|
|
|
190
190
|
return None
|
|
191
191
|
if not isinstance(value, str) or not value:
|
|
192
192
|
raise invalid_config("Token must be a non-empty string.", source=source, field="token")
|
|
193
|
+
if any(not 0x21 <= ord(character) <= 0x7E for character in value):
|
|
194
|
+
raise invalid_config(
|
|
195
|
+
"Token must contain only visible ASCII characters.",
|
|
196
|
+
source=source,
|
|
197
|
+
field="token",
|
|
198
|
+
)
|
|
193
199
|
return value
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|