pydocket 0.6.1__py3-none-any.whl → 0.6.3__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 pydocket might be problematic. Click here for more details.
- docket/__init__.py +11 -9
- docket/__main__.py +1 -1
- docket/cli.py +8 -0
- docket/dependencies.py +48 -1
- docket/docket.py +2 -2
- docket/execution.py +48 -4
- docket/worker.py +63 -35
- {pydocket-0.6.1.dist-info → pydocket-0.6.3.dist-info}/METADATA +2 -1
- pydocket-0.6.3.dist-info/RECORD +16 -0
- pydocket-0.6.1.dist-info/RECORD +0 -16
- {pydocket-0.6.1.dist-info → pydocket-0.6.3.dist-info}/WHEEL +0 -0
- {pydocket-0.6.1.dist-info → pydocket-0.6.3.dist-info}/entry_points.txt +0 -0
- {pydocket-0.6.1.dist-info → pydocket-0.6.3.dist-info}/licenses/LICENSE +0 -0
docket/__init__.py
CHANGED
|
@@ -17,6 +17,7 @@ from .dependencies import (
|
|
|
17
17
|
ExponentialRetry,
|
|
18
18
|
Perpetual,
|
|
19
19
|
Retry,
|
|
20
|
+
TaskArgument,
|
|
20
21
|
TaskKey,
|
|
21
22
|
TaskLogger,
|
|
22
23
|
Timeout,
|
|
@@ -26,19 +27,20 @@ from .execution import Execution
|
|
|
26
27
|
from .worker import Worker
|
|
27
28
|
|
|
28
29
|
__all__ = [
|
|
29
|
-
"
|
|
30
|
-
"Worker",
|
|
31
|
-
"Execution",
|
|
30
|
+
"__version__",
|
|
32
31
|
"CurrentDocket",
|
|
33
|
-
"CurrentWorker",
|
|
34
32
|
"CurrentExecution",
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
33
|
+
"CurrentWorker",
|
|
34
|
+
"Depends",
|
|
35
|
+
"Docket",
|
|
36
|
+
"Execution",
|
|
38
37
|
"ExponentialRetry",
|
|
39
38
|
"Logged",
|
|
40
39
|
"Perpetual",
|
|
40
|
+
"Retry",
|
|
41
|
+
"TaskArgument",
|
|
42
|
+
"TaskKey",
|
|
43
|
+
"TaskLogger",
|
|
41
44
|
"Timeout",
|
|
42
|
-
"
|
|
43
|
-
"__version__",
|
|
45
|
+
"Worker",
|
|
44
46
|
]
|
docket/__main__.py
CHANGED
docket/cli.py
CHANGED
|
@@ -245,6 +245,13 @@ def worker(
|
|
|
245
245
|
envvar="DOCKET_WORKER_SCHEDULING_RESOLUTION",
|
|
246
246
|
),
|
|
247
247
|
] = timedelta(milliseconds=250),
|
|
248
|
+
schedule_automatic_tasks: Annotated[
|
|
249
|
+
bool,
|
|
250
|
+
typer.Option(
|
|
251
|
+
"--schedule-automatic-tasks",
|
|
252
|
+
help="Schedule automatic tasks",
|
|
253
|
+
),
|
|
254
|
+
] = True,
|
|
248
255
|
until_finished: Annotated[
|
|
249
256
|
bool,
|
|
250
257
|
typer.Option(
|
|
@@ -270,6 +277,7 @@ def worker(
|
|
|
270
277
|
reconnection_delay=reconnection_delay,
|
|
271
278
|
minimum_check_interval=minimum_check_interval,
|
|
272
279
|
scheduling_resolution=scheduling_resolution,
|
|
280
|
+
schedule_automatic_tasks=schedule_automatic_tasks,
|
|
273
281
|
until_finished=until_finished,
|
|
274
282
|
metrics_port=metrics_port,
|
|
275
283
|
tasks=tasks,
|
docket/dependencies.py
CHANGED
|
@@ -79,6 +79,29 @@ def TaskKey() -> str:
|
|
|
79
79
|
return cast(str, _TaskKey())
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
class _TaskArgument(Dependency):
|
|
83
|
+
parameter: str | None
|
|
84
|
+
optional: bool
|
|
85
|
+
|
|
86
|
+
def __init__(self, parameter: str | None = None, optional: bool = False) -> None:
|
|
87
|
+
self.parameter = parameter
|
|
88
|
+
self.optional = optional
|
|
89
|
+
|
|
90
|
+
async def __aenter__(self) -> Any:
|
|
91
|
+
assert self.parameter is not None
|
|
92
|
+
execution = self.execution.get()
|
|
93
|
+
try:
|
|
94
|
+
return execution.get_argument(self.parameter)
|
|
95
|
+
except KeyError:
|
|
96
|
+
if self.optional:
|
|
97
|
+
return None
|
|
98
|
+
raise
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def TaskArgument(parameter: str | None = None, optional: bool = False) -> Any:
|
|
102
|
+
return cast(Any, _TaskArgument(parameter, optional))
|
|
103
|
+
|
|
104
|
+
|
|
82
105
|
class _TaskLogger(Dependency):
|
|
83
106
|
async def __aenter__(self) -> logging.LoggerAdapter[logging.Logger]:
|
|
84
107
|
execution = self.execution.get()
|
|
@@ -275,6 +298,11 @@ class _Depends(Dependency, Generic[R]):
|
|
|
275
298
|
parameters = get_dependency_parameters(function)
|
|
276
299
|
|
|
277
300
|
for parameter, dependency in parameters.items():
|
|
301
|
+
# Special case for TaskArguments, they are "magical" and infer the parameter
|
|
302
|
+
# they refer to from the parameter name (unless otherwise specified)
|
|
303
|
+
if isinstance(dependency, _TaskArgument) and not dependency.parameter:
|
|
304
|
+
dependency.parameter = parameter
|
|
305
|
+
|
|
278
306
|
arguments[parameter] = await stack.enter_async_context(dependency)
|
|
279
307
|
|
|
280
308
|
return arguments
|
|
@@ -338,6 +366,12 @@ def validate_dependencies(function: TaskFunction) -> None:
|
|
|
338
366
|
)
|
|
339
367
|
|
|
340
368
|
|
|
369
|
+
class FailedDependency:
|
|
370
|
+
def __init__(self, parameter: str, error: Exception) -> None:
|
|
371
|
+
self.parameter = parameter
|
|
372
|
+
self.error = error
|
|
373
|
+
|
|
374
|
+
|
|
341
375
|
@asynccontextmanager
|
|
342
376
|
async def resolved_dependencies(
|
|
343
377
|
worker: "Worker", execution: Execution
|
|
@@ -361,6 +395,19 @@ async def resolved_dependencies(
|
|
|
361
395
|
arguments[parameter] = kwargs[parameter]
|
|
362
396
|
continue
|
|
363
397
|
|
|
364
|
-
|
|
398
|
+
# Special case for TaskArguments, they are "magical" and infer the parameter
|
|
399
|
+
# they refer to from the parameter name (unless otherwise specified). At
|
|
400
|
+
# the top-level task function call, it doesn't make sense to specify one
|
|
401
|
+
# _without_ a parameter name, so we'll call that a failed dependency.
|
|
402
|
+
if isinstance(dependency, _TaskArgument) and not dependency.parameter:
|
|
403
|
+
arguments[parameter] = FailedDependency(
|
|
404
|
+
parameter, ValueError("No parameter name specified")
|
|
405
|
+
)
|
|
406
|
+
continue
|
|
407
|
+
|
|
408
|
+
try:
|
|
409
|
+
arguments[parameter] = await stack.enter_async_context(dependency)
|
|
410
|
+
except Exception as error:
|
|
411
|
+
arguments[parameter] = FailedDependency(parameter, error)
|
|
365
412
|
|
|
366
413
|
yield arguments
|
docket/docket.py
CHANGED
|
@@ -23,12 +23,12 @@ from typing import (
|
|
|
23
23
|
cast,
|
|
24
24
|
overload,
|
|
25
25
|
)
|
|
26
|
-
from uuid import uuid4
|
|
27
26
|
|
|
28
27
|
import redis.exceptions
|
|
29
28
|
from opentelemetry import propagate, trace
|
|
30
29
|
from redis.asyncio import ConnectionPool, Redis
|
|
31
30
|
from redis.asyncio.client import Pipeline
|
|
31
|
+
from uuid_extensions import uuid7
|
|
32
32
|
|
|
33
33
|
from .execution import (
|
|
34
34
|
Execution,
|
|
@@ -254,7 +254,7 @@ class Docket:
|
|
|
254
254
|
when = datetime.now(timezone.utc)
|
|
255
255
|
|
|
256
256
|
if key is None:
|
|
257
|
-
key =
|
|
257
|
+
key = str(uuid7())
|
|
258
258
|
|
|
259
259
|
async def scheduler(*args: P.args, **kwargs: P.kwargs) -> Execution:
|
|
260
260
|
execution = Execution(function, args, kwargs, when, key, attempt=1)
|
docket/execution.py
CHANGED
|
@@ -3,15 +3,23 @@ import enum
|
|
|
3
3
|
import inspect
|
|
4
4
|
import logging
|
|
5
5
|
from datetime import datetime
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import (
|
|
7
|
+
Any,
|
|
8
|
+
Awaitable,
|
|
9
|
+
Callable,
|
|
10
|
+
Hashable,
|
|
11
|
+
Literal,
|
|
12
|
+
Mapping,
|
|
13
|
+
Self,
|
|
14
|
+
cast,
|
|
15
|
+
)
|
|
7
16
|
|
|
8
17
|
import cloudpickle # type: ignore[import]
|
|
9
|
-
|
|
10
|
-
from opentelemetry import trace, propagate
|
|
11
18
|
import opentelemetry.context
|
|
19
|
+
from opentelemetry import propagate, trace
|
|
12
20
|
|
|
13
21
|
from .annotations import Logged
|
|
14
|
-
from
|
|
22
|
+
from .instrumentation import message_getter
|
|
15
23
|
|
|
16
24
|
logger: logging.Logger = logging.getLogger(__name__)
|
|
17
25
|
|
|
@@ -83,6 +91,11 @@ class Execution:
|
|
|
83
91
|
"docket.attempt": self.attempt,
|
|
84
92
|
}
|
|
85
93
|
|
|
94
|
+
def get_argument(self, parameter: str) -> Any:
|
|
95
|
+
signature = get_signature(self.function)
|
|
96
|
+
bound_args = signature.bind(*self.args, **self.kwargs)
|
|
97
|
+
return bound_args.arguments[parameter]
|
|
98
|
+
|
|
86
99
|
def call_repr(self) -> str:
|
|
87
100
|
arguments: list[str] = []
|
|
88
101
|
function_name = self.function.__name__
|
|
@@ -112,6 +125,37 @@ class Execution:
|
|
|
112
125
|
return [trace.Link(initiating_context)] if initiating_context.is_valid else []
|
|
113
126
|
|
|
114
127
|
|
|
128
|
+
def compact_signature(signature: inspect.Signature) -> str:
|
|
129
|
+
from .dependencies import Dependency
|
|
130
|
+
|
|
131
|
+
parameters: list[str] = []
|
|
132
|
+
dependencies: int = 0
|
|
133
|
+
|
|
134
|
+
for parameter in signature.parameters.values():
|
|
135
|
+
if isinstance(parameter.default, Dependency):
|
|
136
|
+
dependencies += 1
|
|
137
|
+
continue
|
|
138
|
+
|
|
139
|
+
parameter_definition = parameter.name
|
|
140
|
+
if parameter.annotation is not parameter.empty:
|
|
141
|
+
annotation = parameter.annotation
|
|
142
|
+
if hasattr(annotation, "__origin__"):
|
|
143
|
+
annotation = annotation.__args__[0]
|
|
144
|
+
|
|
145
|
+
type_name = getattr(annotation, "__name__", str(annotation))
|
|
146
|
+
parameter_definition = f"{parameter.name}: {type_name}"
|
|
147
|
+
|
|
148
|
+
if parameter.default is not parameter.empty:
|
|
149
|
+
parameter_definition = f"{parameter_definition} = {parameter.default!r}"
|
|
150
|
+
|
|
151
|
+
parameters.append(parameter_definition)
|
|
152
|
+
|
|
153
|
+
if dependencies > 0:
|
|
154
|
+
parameters.append("...")
|
|
155
|
+
|
|
156
|
+
return ", ".join(parameters)
|
|
157
|
+
|
|
158
|
+
|
|
115
159
|
class Operator(enum.StrEnum):
|
|
116
160
|
EQUAL = "=="
|
|
117
161
|
NOT_EQUAL = "!="
|
docket/worker.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import logging
|
|
3
|
+
import os
|
|
4
|
+
import socket
|
|
3
5
|
import sys
|
|
4
6
|
import time
|
|
5
7
|
from datetime import datetime, timedelta, timezone
|
|
@@ -11,17 +13,15 @@ from typing import (
|
|
|
11
13
|
Self,
|
|
12
14
|
cast,
|
|
13
15
|
)
|
|
14
|
-
from uuid import uuid4
|
|
15
16
|
|
|
16
17
|
from opentelemetry import trace
|
|
17
18
|
from opentelemetry.trace import Tracer
|
|
18
19
|
from redis.asyncio import Redis
|
|
19
20
|
from redis.exceptions import ConnectionError, LockError
|
|
20
21
|
|
|
21
|
-
from docket.execution import get_signature
|
|
22
|
-
|
|
23
22
|
from .dependencies import (
|
|
24
23
|
Dependency,
|
|
24
|
+
FailedDependency,
|
|
25
25
|
Perpetual,
|
|
26
26
|
Retry,
|
|
27
27
|
Timeout,
|
|
@@ -36,6 +36,7 @@ from .docket import (
|
|
|
36
36
|
RedisMessageID,
|
|
37
37
|
RedisReadGroupResponse,
|
|
38
38
|
)
|
|
39
|
+
from .execution import compact_signature, get_signature
|
|
39
40
|
from .instrumentation import (
|
|
40
41
|
QUEUE_DEPTH,
|
|
41
42
|
REDIS_DISRUPTIONS,
|
|
@@ -71,6 +72,7 @@ class Worker:
|
|
|
71
72
|
reconnection_delay: timedelta
|
|
72
73
|
minimum_check_interval: timedelta
|
|
73
74
|
scheduling_resolution: timedelta
|
|
75
|
+
schedule_automatic_tasks: bool
|
|
74
76
|
|
|
75
77
|
def __init__(
|
|
76
78
|
self,
|
|
@@ -81,14 +83,16 @@ class Worker:
|
|
|
81
83
|
reconnection_delay: timedelta = timedelta(seconds=5),
|
|
82
84
|
minimum_check_interval: timedelta = timedelta(milliseconds=250),
|
|
83
85
|
scheduling_resolution: timedelta = timedelta(milliseconds=250),
|
|
86
|
+
schedule_automatic_tasks: bool = True,
|
|
84
87
|
) -> None:
|
|
85
88
|
self.docket = docket
|
|
86
|
-
self.name = name or f"
|
|
89
|
+
self.name = name or f"{socket.gethostname()}#{os.getpid()}"
|
|
87
90
|
self.concurrency = concurrency
|
|
88
91
|
self.redelivery_timeout = redelivery_timeout
|
|
89
92
|
self.reconnection_delay = reconnection_delay
|
|
90
93
|
self.minimum_check_interval = minimum_check_interval
|
|
91
94
|
self.scheduling_resolution = scheduling_resolution
|
|
95
|
+
self.schedule_automatic_tasks = schedule_automatic_tasks
|
|
92
96
|
|
|
93
97
|
async def __aenter__(self) -> Self:
|
|
94
98
|
self._heartbeat_task = asyncio.create_task(self._heartbeat())
|
|
@@ -134,6 +138,7 @@ class Worker:
|
|
|
134
138
|
reconnection_delay: timedelta = timedelta(seconds=5),
|
|
135
139
|
minimum_check_interval: timedelta = timedelta(milliseconds=100),
|
|
136
140
|
scheduling_resolution: timedelta = timedelta(milliseconds=250),
|
|
141
|
+
schedule_automatic_tasks: bool = True,
|
|
137
142
|
until_finished: bool = False,
|
|
138
143
|
metrics_port: int | None = None,
|
|
139
144
|
tasks: list[str] = ["docket.tasks:standard_tasks"],
|
|
@@ -151,6 +156,7 @@ class Worker:
|
|
|
151
156
|
reconnection_delay=reconnection_delay,
|
|
152
157
|
minimum_check_interval=minimum_check_interval,
|
|
153
158
|
scheduling_resolution=scheduling_resolution,
|
|
159
|
+
schedule_automatic_tasks=schedule_automatic_tasks,
|
|
154
160
|
) as worker:
|
|
155
161
|
if until_finished:
|
|
156
162
|
await worker.run_until_finished()
|
|
@@ -199,10 +205,7 @@ class Worker:
|
|
|
199
205
|
self._execution_counts = {}
|
|
200
206
|
|
|
201
207
|
async def _run(self, forever: bool = False) -> None:
|
|
202
|
-
|
|
203
|
-
for task_name, task in self.docket.tasks.items():
|
|
204
|
-
signature = get_signature(task)
|
|
205
|
-
logger.info("* %s%s", task_name, signature)
|
|
208
|
+
self._startup_log()
|
|
206
209
|
|
|
207
210
|
while True:
|
|
208
211
|
try:
|
|
@@ -220,7 +223,8 @@ class Worker:
|
|
|
220
223
|
async def _worker_loop(self, redis: Redis, forever: bool = False):
|
|
221
224
|
worker_stopping = asyncio.Event()
|
|
222
225
|
|
|
223
|
-
|
|
226
|
+
if self.schedule_automatic_tasks:
|
|
227
|
+
await self._schedule_all_automatic_perpetual_tasks()
|
|
224
228
|
|
|
225
229
|
scheduler_task = asyncio.create_task(
|
|
226
230
|
self._scheduler_loop(redis, worker_stopping)
|
|
@@ -499,6 +503,8 @@ class Worker:
|
|
|
499
503
|
arrow = "↬" if execution.attempt > 1 else "↪"
|
|
500
504
|
logger.info("%s [%s] %s", arrow, ms(punctuality), call, extra=log_context)
|
|
501
505
|
|
|
506
|
+
dependencies: dict[str, Dependency] = {}
|
|
507
|
+
|
|
502
508
|
with tracer.start_as_current_span(
|
|
503
509
|
execution.function.__name__,
|
|
504
510
|
kind=trace.SpanKind.CONSUMER,
|
|
@@ -509,17 +515,34 @@ class Worker:
|
|
|
509
515
|
},
|
|
510
516
|
links=execution.incoming_span_links(),
|
|
511
517
|
):
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
518
|
+
try:
|
|
519
|
+
async with resolved_dependencies(self, execution) as dependencies:
|
|
520
|
+
# Preemptively reschedule the perpetual task for the future, or clear
|
|
521
|
+
# the known task key for this task
|
|
522
|
+
rescheduled = await self._perpetuate_if_requested(
|
|
523
|
+
execution, dependencies
|
|
524
|
+
)
|
|
525
|
+
if not rescheduled:
|
|
526
|
+
async with self.docket.redis() as redis:
|
|
527
|
+
await self._delete_known_task(redis, execution)
|
|
528
|
+
|
|
529
|
+
dependency_failures = {
|
|
530
|
+
k: v
|
|
531
|
+
for k, v in dependencies.items()
|
|
532
|
+
if isinstance(v, FailedDependency)
|
|
533
|
+
}
|
|
534
|
+
if dependency_failures:
|
|
535
|
+
raise ExceptionGroup(
|
|
536
|
+
(
|
|
537
|
+
"Failed to resolve dependencies for parameter(s): "
|
|
538
|
+
+ ", ".join(dependency_failures.keys())
|
|
539
|
+
),
|
|
540
|
+
[
|
|
541
|
+
dependency.error
|
|
542
|
+
for dependency in dependency_failures.values()
|
|
543
|
+
],
|
|
544
|
+
)
|
|
521
545
|
|
|
522
|
-
try:
|
|
523
546
|
if timeout := get_single_dependency_of_type(dependencies, Timeout):
|
|
524
547
|
await self._run_function_with_timeout(
|
|
525
548
|
execution, dependencies, timeout
|
|
@@ -544,24 +567,24 @@ class Worker:
|
|
|
544
567
|
logger.info(
|
|
545
568
|
"%s [%s] %s", arrow, ms(duration), call, extra=log_context
|
|
546
569
|
)
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
retried = await self._retry_if_requested(execution, dependencies)
|
|
552
|
-
if not retried:
|
|
553
|
-
retried = await self._perpetuate_if_requested(
|
|
554
|
-
execution, dependencies, timedelta(seconds=duration)
|
|
555
|
-
)
|
|
570
|
+
except Exception:
|
|
571
|
+
duration = log_context["duration"] = time.time() - start
|
|
572
|
+
TASKS_FAILED.add(1, counter_labels)
|
|
556
573
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
574
|
+
retried = await self._retry_if_requested(execution, dependencies)
|
|
575
|
+
if not retried:
|
|
576
|
+
retried = await self._perpetuate_if_requested(
|
|
577
|
+
execution, dependencies, timedelta(seconds=duration)
|
|
560
578
|
)
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
579
|
+
|
|
580
|
+
arrow = "↫" if retried else "↩"
|
|
581
|
+
logger.exception(
|
|
582
|
+
"%s [%s] %s", arrow, ms(duration), call, extra=log_context
|
|
583
|
+
)
|
|
584
|
+
finally:
|
|
585
|
+
TASKS_RUNNING.add(-1, counter_labels)
|
|
586
|
+
TASKS_COMPLETED.add(1, counter_labels)
|
|
587
|
+
TASK_DURATION.record(duration, counter_labels)
|
|
565
588
|
|
|
566
589
|
async def _run_function_with_timeout(
|
|
567
590
|
self,
|
|
@@ -641,6 +664,11 @@ class Worker:
|
|
|
641
664
|
|
|
642
665
|
return True
|
|
643
666
|
|
|
667
|
+
def _startup_log(self) -> None:
|
|
668
|
+
logger.info("Starting worker %r with the following tasks:", self.name)
|
|
669
|
+
for task_name, task in self.docket.tasks.items():
|
|
670
|
+
logger.info("* %s(%s)", task_name, compact_signature(get_signature(task)))
|
|
671
|
+
|
|
644
672
|
@property
|
|
645
673
|
def workers_set(self) -> str:
|
|
646
674
|
return self.docket.workers_set
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pydocket
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.3
|
|
4
4
|
Summary: A distributed background task system for Python functions
|
|
5
5
|
Project-URL: Homepage, https://github.com/chrisguidry/docket
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/chrisguidry/docket/issues
|
|
@@ -31,6 +31,7 @@ Requires-Dist: python-json-logger>=3.2.1
|
|
|
31
31
|
Requires-Dist: redis>=4.6
|
|
32
32
|
Requires-Dist: rich>=13.9.4
|
|
33
33
|
Requires-Dist: typer>=0.15.1
|
|
34
|
+
Requires-Dist: uuid7>=0.1.0
|
|
34
35
|
Description-Content-Type: text/markdown
|
|
35
36
|
|
|
36
37
|
Docket is a distributed background task system for Python functions with a focus
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
docket/__init__.py,sha256=sY1T_NVsXQNOmOhOnfYmZ95dcE_52Ov6DSIVIMZp-1w,869
|
|
2
|
+
docket/__main__.py,sha256=wcCrL4PjG51r5wVKqJhcoJPTLfHW0wNbD31DrUN0MWI,28
|
|
3
|
+
docket/annotations.py,sha256=6sCgQxsgOjBN6ithFdXulXq4CPNSdyFocwyJ1gK9v2Q,1688
|
|
4
|
+
docket/cli.py,sha256=znHN7eqaD_PFpSFn7iXa_uZlKzVWDrKkrmOd1CNuZRk,20561
|
|
5
|
+
docket/dependencies.py,sha256=-gruEho5jf07Jx9fEh2YBFg4gDSJFm7X5qhQjArVXjU,11910
|
|
6
|
+
docket/docket.py,sha256=r5TNcGmaQuxST56OVKNjFXDsrU5-Ioz3Y_I38PkLqRM,21411
|
|
7
|
+
docket/execution.py,sha256=6KozjnS96byvyCMTQ2-IkcIrPsqaPIVu2HZU0U4Be9E,14813
|
|
8
|
+
docket/instrumentation.py,sha256=bZlGA02JoJcY0J1WGm5_qXDfY0AXKr0ZLAYu67wkeKY,4611
|
|
9
|
+
docket/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
docket/tasks.py,sha256=RIlSM2omh-YDwVnCz6M5MtmK8T_m_s1w2OlRRxDUs6A,1437
|
|
11
|
+
docket/worker.py,sha256=Xf6_7GyrIUNq1jG8YjbJk5KkRQdvxs0CniF9XW8kdJg,27450
|
|
12
|
+
pydocket-0.6.3.dist-info/METADATA,sha256=LRtykRFP2dcauKjzQDoNpC_xe6aVjvleAN1xS5cSIUY,13120
|
|
13
|
+
pydocket-0.6.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
14
|
+
pydocket-0.6.3.dist-info/entry_points.txt,sha256=4WOk1nUlBsUT5O3RyMci2ImuC5XFswuopElYcLHtD5k,47
|
|
15
|
+
pydocket-0.6.3.dist-info/licenses/LICENSE,sha256=YuVWU_ZXO0K_k2FG8xWKe5RGxV24AhJKTvQmKfqXuyk,1087
|
|
16
|
+
pydocket-0.6.3.dist-info/RECORD,,
|
pydocket-0.6.1.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
docket/__init__.py,sha256=124XWbyQQHO1lhCoLQ-oheZnu4vNDHIaq4Whb7z3ogI,831
|
|
2
|
-
docket/__main__.py,sha256=Vkuh7aJ-Bl7QVpVbbkUksAd_hn05FiLmWbc-8kbhZQ4,34
|
|
3
|
-
docket/annotations.py,sha256=6sCgQxsgOjBN6ithFdXulXq4CPNSdyFocwyJ1gK9v2Q,1688
|
|
4
|
-
docket/cli.py,sha256=OWql6QFthSbvRCGkIg-ufo26F48z0eCmzRXJYOdyAEc,20309
|
|
5
|
-
docket/dependencies.py,sha256=pkjseBZjdSpgW9g2H4cZ_RXIRZ2ZfdngBCXJGUcbmao,10052
|
|
6
|
-
docket/docket.py,sha256=KJxgiyOskEHsRQOmfgLpJCYDNNleHI-vEKK3uBPL_K8,21420
|
|
7
|
-
docket/execution.py,sha256=f3LLt9bC7ExEZhgde5OBo1faKLYv-8ryfNLXSswo318,13579
|
|
8
|
-
docket/instrumentation.py,sha256=bZlGA02JoJcY0J1WGm5_qXDfY0AXKr0ZLAYu67wkeKY,4611
|
|
9
|
-
docket/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
docket/tasks.py,sha256=RIlSM2omh-YDwVnCz6M5MtmK8T_m_s1w2OlRRxDUs6A,1437
|
|
11
|
-
docket/worker.py,sha256=NrzmfpjHjQaGS8CoTOiKM5Bn88tPh_q2hz9f4hFegSk,26280
|
|
12
|
-
pydocket-0.6.1.dist-info/METADATA,sha256=mxI1OHWe9W9bAyi8QiH69eMSsSk1Dm2oDvh301BJFgo,13092
|
|
13
|
-
pydocket-0.6.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
14
|
-
pydocket-0.6.1.dist-info/entry_points.txt,sha256=4WOk1nUlBsUT5O3RyMci2ImuC5XFswuopElYcLHtD5k,47
|
|
15
|
-
pydocket-0.6.1.dist-info/licenses/LICENSE,sha256=YuVWU_ZXO0K_k2FG8xWKe5RGxV24AhJKTvQmKfqXuyk,1087
|
|
16
|
-
pydocket-0.6.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|