diffusers-workflow 0.4.0__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.
- diffusers_workflow-0.4.0.dist-info/METADATA +318 -0
- diffusers_workflow-0.4.0.dist-info/RECORD +260 -0
- diffusers_workflow-0.4.0.dist-info/WHEEL +5 -0
- diffusers_workflow-0.4.0.dist-info/entry_points.txt +7 -0
- diffusers_workflow-0.4.0.dist-info/licenses/LICENSE +201 -0
- diffusers_workflow-0.4.0.dist-info/top_level.txt +2 -0
- dw/__init__.py +440 -0
- dw/adapter_compatibility.py +226 -0
- dw/arguments.py +1231 -0
- dw/assessment_rules.py +159 -0
- dw/assets.py +130 -0
- dw/cache_blocks.json +16 -0
- dw/cache_blocks.py +146 -0
- dw/community_pipelines/pipeline_flux_rf_inversion.py +1184 -0
- dw/content_types.py +150 -0
- dw/dissolve_frame_errors.py +121 -0
- dw/docs/ACCELERATION.md +352 -0
- dw/docs/AGENT_LOOP.md +95 -0
- dw/docs/DEPENDENCIES.md +91 -0
- dw/docs/IP_ADAPTER.md +109 -0
- dw/docs/LORAS.md +131 -0
- dw/docs/MCP.md +517 -0
- dw/docs/PROMPT_WEIGHTING.md +78 -0
- dw/docs/QUANTIZATION.md +230 -0
- dw/docs/RECIPES_24GB.md +201 -0
- dw/docs/RELEASING.md +195 -0
- dw/docs/REMOTE.md +140 -0
- dw/docs/REPL_COMMANDS.md +121 -0
- dw/docs/REPL_WORKER_GUIDE.md +51 -0
- dw/docs/SECURITY.md +272 -0
- dw/docs/SECURITY_QUICKREF.md +112 -0
- dw/docs/SERVER.md +679 -0
- dw/docs/TASKS.md +1741 -0
- dw/docs/TESTING.md +71 -0
- dw/docs/WORKFLOW_GUIDE.md +2038 -0
- dw/docs/WORKSPACES.md +316 -0
- dw/download_watch.py +335 -0
- dw/elision.py +306 -0
- dw/events.py +275 -0
- dw/for_each.py +409 -0
- dw/host_memory.py +258 -0
- dw/host_memory_projection.py +230 -0
- dw/hub_cache.py +432 -0
- dw/introspection.py +1228 -0
- dw/kernel_availability.py +208 -0
- dw/locations.py +599 -0
- dw/log_setup.py +45 -0
- dw/loudness.py +82 -0
- dw/media_audio.py +217 -0
- dw/media_frames.py +367 -0
- dw/media_info.py +297 -0
- dw/pipeline_processors/chain.py +821 -0
- dw/pipeline_processors/config_objects.py +237 -0
- dw/pipeline_processors/pipeline.py +2297 -0
- dw/pipeline_processors/remote.py +46 -0
- dw/plan.py +920 -0
- dw/previous_results.py +411 -0
- dw/probe_paths.py +59 -0
- dw/prompt_schema.json +48 -0
- dw/prompt_weighting.py +378 -0
- dw/prompts.py +159 -0
- dw/realize.py +250 -0
- dw/reference_limits.py +215 -0
- dw/reference_names.py +125 -0
- dw/repl.py +338 -0
- dw/repl_commands.py +836 -0
- dw/repl_worker.py +159 -0
- dw/result.py +1720 -0
- dw/result_fps.py +82 -0
- dw/run.py +162 -0
- dw/runs.py +768 -0
- dw/scalar_result_validation.py +97 -0
- dw/schema.py +283 -0
- dw/security.py +1038 -0
- dw/select_validation.py +115 -0
- dw/serve.py +277 -0
- dw/server/__init__.py +2 -0
- dw/server/app.py +4586 -0
- dw/server/assess.py +132 -0
- dw/server/catalog_shape.py +487 -0
- dw/server/enhancers.py +129 -0
- dw/server/exports.py +480 -0
- dw/server/guides.py +257 -0
- dw/server/jobs.py +1561 -0
- dw/server/mcp_mount.py +95 -0
- dw/server/netinfo.py +124 -0
- dw/server/observed_cost.py +379 -0
- dw/server/sysinfo.py +71 -0
- dw/server/ui/assets/abap-08VXUWAP.js +1 -0
- dw/server/ui/assets/apex-BWPQTe0t.js +1 -0
- dw/server/ui/assets/azcli-Bc_sGQ0U.js +1 -0
- dw/server/ui/assets/bat-i0X4ZdIN.js +1 -0
- dw/server/ui/assets/bicep-B5-_aFwp.js +2 -0
- dw/server/ui/assets/cameligo-DMUM7wLl.js +1 -0
- dw/server/ui/assets/clojure-Cm7r79vr.js +1 -0
- dw/server/ui/assets/codicon-Brq4_Ui5.ttf +0 -0
- dw/server/ui/assets/coffee-Ba7i2nA0.js +1 -0
- dw/server/ui/assets/cpp-C7h46wYY.js +1 -0
- dw/server/ui/assets/csharp-BKxtCVv1.js +1 -0
- dw/server/ui/assets/csp-bTuwJoIa.js +1 -0
- dw/server/ui/assets/css-DIMkf-bt.js +3 -0
- dw/server/ui/assets/css.worker-B3ciXF_0.js +93 -0
- dw/server/ui/assets/cssMode-CPznxfY8.js +1 -0
- dw/server/ui/assets/cypher-CVaqCwHa.js +1 -0
- dw/server/ui/assets/dart-onAF5SnQ.js +1 -0
- dw/server/ui/assets/dockerfile-DZFCIeNp.js +1 -0
- dw/server/ui/assets/ecl-D05T4iGw.js +1 -0
- dw/server/ui/assets/editor-jjEx9u7D.css +1 -0
- dw/server/ui/assets/editor.api-CpWcotrd.js +847 -0
- dw/server/ui/assets/editor.worker-q-txB4vs.js +30 -0
- dw/server/ui/assets/elixir-6RTg0lbw.js +1 -0
- dw/server/ui/assets/flow9-C5_-GSwl.js +1 -0
- dw/server/ui/assets/freemarker2-CXtRM8N4.js +3 -0
- dw/server/ui/assets/fsharp-C8Ef5oNN.js +1 -0
- dw/server/ui/assets/go-C-y9NEjX.js +1 -0
- dw/server/ui/assets/graphql-fmXr3nnJ.js +1 -0
- dw/server/ui/assets/handlebars-N7x-6NMY.js +1 -0
- dw/server/ui/assets/hcl-CpzslTdj.js +1 -0
- dw/server/ui/assets/html-PhsdjHSr.js +1 -0
- dw/server/ui/assets/html.worker-C93Ht9o9.js +506 -0
- dw/server/ui/assets/htmlMode-Dgj0SEok.js +1 -0
- dw/server/ui/assets/index-3Vw6WAPW.css +1 -0
- dw/server/ui/assets/index-DgrYhQd9.js +43 -0
- dw/server/ui/assets/ini-sBoK_t0W.js +1 -0
- dw/server/ui/assets/java-BEtHBSE6.js +1 -0
- dw/server/ui/assets/javascript-BJqN9Qhv.js +1 -0
- dw/server/ui/assets/json.worker-B2V3pomh.js +62 -0
- dw/server/ui/assets/jsonMode-DbM4SWSv.js +7 -0
- dw/server/ui/assets/julia-Bri6UV-V.js +1 -0
- dw/server/ui/assets/kotlin-BOotOW0E.js +1 -0
- dw/server/ui/assets/less-B9JPFI3C.js +2 -0
- dw/server/ui/assets/lexon-CfSJPG6W.js +1 -0
- dw/server/ui/assets/liquid-BWr8lEc4.js +1 -0
- dw/server/ui/assets/lspLanguageFeatures-C1iGuDyZ.js +4 -0
- dw/server/ui/assets/lua-CsQS60Ue.js +1 -0
- dw/server/ui/assets/m3-D-oSqn_W.js +1 -0
- dw/server/ui/assets/markdown-Cimd5fb3.js +1 -0
- dw/server/ui/assets/mdx-DAdMi_0p.js +1 -0
- dw/server/ui/assets/mips-CIPQ_RoX.js +1 -0
- dw/server/ui/assets/monaco--ixms01u.css +1 -0
- dw/server/ui/assets/monaco-BGCeEqaw.js +56 -0
- dw/server/ui/assets/msdax-DauUninz.js +1 -0
- dw/server/ui/assets/mysql-SOo6toE5.js +1 -0
- dw/server/ui/assets/objective-c-FvmIjYaQ.js +1 -0
- dw/server/ui/assets/pascal-DrH0SRf2.js +1 -0
- dw/server/ui/assets/pascaligo-D-ptJ9y-.js +1 -0
- dw/server/ui/assets/perl-oz_6vUea.js +1 -0
- dw/server/ui/assets/pgsql-DTj74zXo.js +1 -0
- dw/server/ui/assets/php-nr791fC2.js +1 -0
- dw/server/ui/assets/pla-CopQ2nXW.js +1 -0
- dw/server/ui/assets/postiats-43DmfD33.js +1 -0
- dw/server/ui/assets/powerquery-D3hlyOfw.js +1 -0
- dw/server/ui/assets/powershell-DmHpPYUd.js +1 -0
- dw/server/ui/assets/protobuf-C531GsRP.js +2 -0
- dw/server/ui/assets/pug-Z5eAx3Zn.js +1 -0
- dw/server/ui/assets/python-Bcn70HdC.js +1 -0
- dw/server/ui/assets/qsharp-DkqhCAOL.js +1 -0
- dw/server/ui/assets/r-BwWrilGY.js +1 -0
- dw/server/ui/assets/razor-D1HmNnby.js +1 -0
- dw/server/ui/assets/redis-ClamHrr6.js +1 -0
- dw/server/ui/assets/redshift-DT7zqm-g.js +1 -0
- dw/server/ui/assets/restructuredtext-BYgofb2h.js +1 -0
- dw/server/ui/assets/ruby-DezsRK8O.js +1 -0
- dw/server/ui/assets/rust-DdL9SqIa.js +1 -0
- dw/server/ui/assets/sb-CcwsVR0C.js +1 -0
- dw/server/ui/assets/scala-DHpiXF5c.js +1 -0
- dw/server/ui/assets/scheme-BeGwcela.js +1 -0
- dw/server/ui/assets/scss-gp-XZpBa.js +3 -0
- dw/server/ui/assets/shell-CC2rA5mh.js +1 -0
- dw/server/ui/assets/solidity-BEEn4gHE.js +1 -0
- dw/server/ui/assets/sophia-CRfGWb83.js +1 -0
- dw/server/ui/assets/sparql-D_Lu-MrJ.js +1 -0
- dw/server/ui/assets/sql-NEE52Syq.js +1 -0
- dw/server/ui/assets/st-DbInun42.js +1 -0
- dw/server/ui/assets/swift-Bxkupp3x.js +1 -0
- dw/server/ui/assets/systemverilog-Bz4Y3fRF.js +1 -0
- dw/server/ui/assets/tcl-DISqw1ZD.js +1 -0
- dw/server/ui/assets/ts.worker-D7T1-Ig5.js +67738 -0
- dw/server/ui/assets/tsMode-D6u0XmOW.js +11 -0
- dw/server/ui/assets/twig-De2hgUGE.js +1 -0
- dw/server/ui/assets/typescript-BU6v-LMV.js +1 -0
- dw/server/ui/assets/typespec-B8J7ngcE.js +1 -0
- dw/server/ui/assets/vb-DV3o63ZY.js +1 -0
- dw/server/ui/assets/wgsl-DpFanUEy.js +298 -0
- dw/server/ui/assets/workers-Cn7cTUKr.js +1 -0
- dw/server/ui/assets/xml--0LP2Lwk.js +1 -0
- dw/server/ui/assets/yaml-mpBg9jnt.js +1 -0
- dw/server/ui/index.html +17 -0
- dw/server/updater.py +192 -0
- dw/settings.py +98 -0
- dw/shot_span_preflight.py +116 -0
- dw/shots.py +359 -0
- dw/slice_preflight.py +148 -0
- dw/step.py +187 -0
- dw/step_cache.py +442 -0
- dw/subfolders.py +107 -0
- dw/task_domains.py +307 -0
- dw/tasks/assess.py +826 -0
- dw/tasks/audio_transcription.py +88 -0
- dw/tasks/audio_utils.py +1862 -0
- dw/tasks/background_remover.py +43 -0
- dw/tasks/borders.py +113 -0
- dw/tasks/compose_text.py +74 -0
- dw/tasks/concat_videos.py +300 -0
- dw/tasks/depth_estimator.py +54 -0
- dw/tasks/diffusion_upscale.py +109 -0
- dw/tasks/dissolve_videos.py +342 -0
- dw/tasks/format_messages.py +24 -0
- dw/tasks/gather.py +173 -0
- dw/tasks/grade.py +97 -0
- dw/tasks/image_to_text.py +43 -0
- dw/tasks/image_utils.py +764 -0
- dw/tasks/interpolate_frames.py +252 -0
- dw/tasks/judge.py +68 -0
- dw/tasks/model_cache.py +55 -0
- dw/tasks/pair_audio.py +268 -0
- dw/tasks/qr_code.py +19 -0
- dw/tasks/restore_faces.py +175 -0
- dw/tasks/rife_model.py +192 -0
- dw/tasks/segment.py +121 -0
- dw/tasks/select.py +111 -0
- dw/tasks/speech_generation.py +228 -0
- dw/tasks/stabilize.py +129 -0
- dw/tasks/task.py +920 -0
- dw/tasks/tensor_image.py +57 -0
- dw/tasks/text_generation.py +169 -0
- dw/tasks/text_sections.py +80 -0
- dw/tasks/upscale.py +203 -0
- dw/tasks/video_utils.py +624 -0
- dw/tasks/zoe_depth.py +71 -0
- dw/teacache.py +381 -0
- dw/teacache_models.json +99 -0
- dw/test.py +29 -0
- dw/type_helpers.py +231 -0
- dw/validate.py +68 -0
- dw/variable_constraints.py +444 -0
- dw/variables.py +443 -0
- dw/video_extensions.py +141 -0
- dw/vram_estimate.py +116 -0
- dw/worker.py +764 -0
- dw/workflow.py +2007 -0
- dw/workflow_schema.json +1346 -0
- dw/workflow_sources.py +383 -0
- dw/workflows/h3_context_ir.json +57 -0
- dw/workflows/test.json +31 -0
- dw/workspace.py +730 -0
- dw_mcp/__init__.py +6 -0
- dw_mcp/__main__.py +133 -0
- dw_mcp/assets.py +336 -0
- dw_mcp/authoring.py +114 -0
- dw_mcp/catalog.py +360 -0
- dw_mcp/client.py +486 -0
- dw_mcp/diagnose.py +371 -0
- dw_mcp/exports.py +84 -0
- dw_mcp/guides.py +35 -0
- dw_mcp/media.py +638 -0
- dw_mcp/models.py +97 -0
- dw_mcp/prompts.py +104 -0
- dw_mcp/server.py +1343 -0
- dw_mcp/workspaces.py +212 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""An 'attn_processor_type' backed by a Hub kernel that this box cannot run.
|
|
2
|
+
|
|
3
|
+
`LTX2VideoVaeNeighborhoodNattenProcessor` (LTX-2.5's diffusion decoder)
|
|
4
|
+
fetches its `na3d` kernel from `shi-labs/natten` through the `kernels`
|
|
5
|
+
package in `__init__` - no forward pass, no `__call__`, just construction.
|
|
6
|
+
When the installed torch is newer than every published natten build variant
|
|
7
|
+
(torch 2.14, natten's newest wheel built for 2.13), that `__init__` raises
|
|
8
|
+
`FileNotFoundError` - and by the time anything constructs the processor, the
|
|
9
|
+
pipeline has already loaded its transformer and text encoder onto the GPU.
|
|
10
|
+
`validate_workflow` reported this workflow clean and `run_workflow` paid
|
|
11
|
+
~88s of loading to learn what construction alone would have said in under
|
|
12
|
+
two seconds (#178).
|
|
13
|
+
|
|
14
|
+
The processor class is resolved exactly as `dw/pipeline_processors/pipeline.py`
|
|
15
|
+
resolves it at run time - `load_type_from_name`, then a zero-argument
|
|
16
|
+
construction, since every 'attn_processor_type' site (the top-level
|
|
17
|
+
`unet`/`transformer` blocks and the generic per-component
|
|
18
|
+
`set_attn_processor`) constructs it that way. Not every attention processor
|
|
19
|
+
depends on a Hub kernel, so this only probes ones whose `__init__` calls
|
|
20
|
+
`kernels.get_kernel` - a source-level check rather than a natten-specific
|
|
21
|
+
name, so a future diffusers processor with the same Hub-fetch shape is
|
|
22
|
+
caught without a new entry here. A processor that constructs cleanly, or
|
|
23
|
+
whose source can't be inspected, is left alone: this check exists to move a
|
|
24
|
+
real, cheap, side-effect-free construction failure earlier, not to guess at
|
|
25
|
+
one.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
import functools
|
|
29
|
+
import inspect
|
|
30
|
+
|
|
31
|
+
from .for_each import MEMBER_SEPARATOR, render_path
|
|
32
|
+
from .type_helpers import load_type_from_name
|
|
33
|
+
|
|
34
|
+
ATTN_PROCESSOR_KEY = "attn_processor_type"
|
|
35
|
+
_UNRESOLVED_PREFIXES = ("variable:", "item:")
|
|
36
|
+
KERNEL_FAULT_MARKER = "cannot be used on this machine"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def is_kernel_availability_fault(message):
|
|
40
|
+
"""Whether a validation error's text is this check's, not the author's.
|
|
41
|
+
|
|
42
|
+
A template naming a Hub-kernel-backed processor is only ever as valid as
|
|
43
|
+
the box running the check - one box's torch build satisfies natten and
|
|
44
|
+
another's doesn't, so a failure here says nothing about the workflow
|
|
45
|
+
itself (dw/kernel_availability.py, #178). Callers that need to tell "this
|
|
46
|
+
box can't satisfy a real dependency" apart from "the workflow is wrong"
|
|
47
|
+
- such as tests/test_examples.py, which otherwise expects every shipped
|
|
48
|
+
template to validate on whatever machine runs the suite - match on this
|
|
49
|
+
rather than re-deriving the message.
|
|
50
|
+
"""
|
|
51
|
+
return KERNEL_FAULT_MARKER in message
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _attn_processor_locations(configuration):
|
|
55
|
+
"""Yield (path_suffix, value) for every 'attn_processor_type' string in
|
|
56
|
+
one step's pipeline configuration - the top-level 'unet'/'transformer'
|
|
57
|
+
blocks and any 'components' entry, matching every site
|
|
58
|
+
dw/pipeline_processors/pipeline.py constructs one from.
|
|
59
|
+
"""
|
|
60
|
+
if not isinstance(configuration, dict):
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
for block_name in ("unet", "transformer"):
|
|
64
|
+
block = configuration.get(block_name)
|
|
65
|
+
if isinstance(block, dict) and ATTN_PROCESSOR_KEY in block:
|
|
66
|
+
yield (block_name, ATTN_PROCESSOR_KEY), block[ATTN_PROCESSOR_KEY]
|
|
67
|
+
|
|
68
|
+
components = configuration.get("components")
|
|
69
|
+
if isinstance(components, dict):
|
|
70
|
+
for component_name, component_configuration in components.items():
|
|
71
|
+
if (
|
|
72
|
+
isinstance(component_configuration, dict)
|
|
73
|
+
and ATTN_PROCESSOR_KEY in component_configuration
|
|
74
|
+
):
|
|
75
|
+
yield (
|
|
76
|
+
("components", component_name, ATTN_PROCESSOR_KEY),
|
|
77
|
+
component_configuration[ATTN_PROCESSOR_KEY],
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _requires_remote_kernel(attn_processor_class):
|
|
82
|
+
"""Whether constructing this class fetches a kernel from the Hub -
|
|
83
|
+
a source-level check so a future processor with the same shape as
|
|
84
|
+
natten's is caught without naming it here.
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
source = inspect.getsource(attn_processor_class.__init__)
|
|
88
|
+
except (OSError, TypeError):
|
|
89
|
+
return False
|
|
90
|
+
return "get_kernel(" in source
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class _KernelFault(Exception):
|
|
94
|
+
"""Carries a fault message out of `_fault_for_name` without letting
|
|
95
|
+
`lru_cache` memoize it - see that function's docstring."""
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@functools.lru_cache(maxsize=None)
|
|
99
|
+
def _fault_for_name(value):
|
|
100
|
+
"""The answer for one type name, memoized - except a fault.
|
|
101
|
+
|
|
102
|
+
Which class a name resolves to, and whether that class *requires* a
|
|
103
|
+
remote kernel, are per-process constants, so a clean `None` answer is
|
|
104
|
+
cached. Whether *this* construction attempt succeeds is not: the
|
|
105
|
+
construction is a Hub kernel fetch, which can fail transiently (network,
|
|
106
|
+
rate limit, cold cache), and caching that failure would pin every
|
|
107
|
+
validate/submit/rerun in the process to "broken" until the process
|
|
108
|
+
restarts, even once the transient condition clears. `lru_cache` never
|
|
109
|
+
memoizes a call that raises, so a fault is raised as `_KernelFault`
|
|
110
|
+
rather than returned - `kernel_availability_fault` catches it. The cost
|
|
111
|
+
of not caching a fault is one more fetch on the next call, which is
|
|
112
|
+
cheap next to being wrong for a process's whole lifetime.
|
|
113
|
+
"""
|
|
114
|
+
try:
|
|
115
|
+
attn_processor_class = load_type_from_name(value)
|
|
116
|
+
except Exception:
|
|
117
|
+
return None
|
|
118
|
+
|
|
119
|
+
if not _requires_remote_kernel(attn_processor_class):
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
attn_processor_class()
|
|
124
|
+
except Exception as e:
|
|
125
|
+
raise _KernelFault(f"'{value}' {KERNEL_FAULT_MARKER}: {e}") from e
|
|
126
|
+
return None
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def kernel_availability_fault(value):
|
|
130
|
+
"""Why constructing this 'attn_processor_type' value will fail, or None.
|
|
131
|
+
|
|
132
|
+
`value` is the dotted or bare type name as written in the workflow.
|
|
133
|
+
A name that fails to resolve at all is not this check's job - that is
|
|
134
|
+
an ordinary '_type' load failure at run time. A processor that doesn't
|
|
135
|
+
depend on a remote kernel is never constructed here, since a processor
|
|
136
|
+
with real side effects in `__init__` should not be instantiated just to
|
|
137
|
+
validate it.
|
|
138
|
+
|
|
139
|
+
A clean answer is memoized once per process per name: validate, submit
|
|
140
|
+
and rerun all ask, and a for_each asks once per member (`_fault_for_name`).
|
|
141
|
+
A fault is not memoized, and so is re-probed on every call - see
|
|
142
|
+
`_fault_for_name`.
|
|
143
|
+
"""
|
|
144
|
+
if not isinstance(value, str) or value.startswith(_UNRESOLVED_PREFIXES):
|
|
145
|
+
return None
|
|
146
|
+
try:
|
|
147
|
+
return _fault_for_name(value)
|
|
148
|
+
except _KernelFault as fault:
|
|
149
|
+
return str(fault)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def kernel_availability_errors(workflow_definition, source_indices=None):
|
|
153
|
+
"""Every 'attn_processor_type' whose Hub kernel this machine can't
|
|
154
|
+
satisfy, as [{path, message}] - reported before any model loads rather
|
|
155
|
+
than discovered inside one (#178).
|
|
156
|
+
|
|
157
|
+
The definition handed here has already been substituted and expanded,
|
|
158
|
+
so every value in it is literal; a 'variable:' or 'item:' still spelled
|
|
159
|
+
out is left alone. `source_indices`, when given, is the source step
|
|
160
|
+
index of each step - a 'for_each' group turns one written step into
|
|
161
|
+
several, and the path an error carries has to be one the author can
|
|
162
|
+
find in the file they wrote; the member is named in the message.
|
|
163
|
+
"""
|
|
164
|
+
steps = workflow_definition.get("steps")
|
|
165
|
+
if not isinstance(steps, list):
|
|
166
|
+
return []
|
|
167
|
+
|
|
168
|
+
errors = []
|
|
169
|
+
for index, step in enumerate(steps):
|
|
170
|
+
if not isinstance(step, dict):
|
|
171
|
+
continue
|
|
172
|
+
pipeline = step.get("pipeline")
|
|
173
|
+
if not isinstance(pipeline, dict):
|
|
174
|
+
continue
|
|
175
|
+
configuration = pipeline.get("configuration")
|
|
176
|
+
|
|
177
|
+
for path_suffix, value in _attn_processor_locations(configuration):
|
|
178
|
+
fault = kernel_availability_fault(value)
|
|
179
|
+
if fault is None:
|
|
180
|
+
continue
|
|
181
|
+
|
|
182
|
+
source = (
|
|
183
|
+
source_indices[index]
|
|
184
|
+
if source_indices is not None and index < len(source_indices)
|
|
185
|
+
else index
|
|
186
|
+
)
|
|
187
|
+
name = step.get("name")
|
|
188
|
+
where = (
|
|
189
|
+
f" in member '{name}'"
|
|
190
|
+
if isinstance(name, str) and MEMBER_SEPARATOR in name
|
|
191
|
+
else ""
|
|
192
|
+
)
|
|
193
|
+
errors.append(
|
|
194
|
+
{
|
|
195
|
+
"path": render_path(
|
|
196
|
+
("steps", source, "pipeline", "configuration") + path_suffix
|
|
197
|
+
),
|
|
198
|
+
"message": f"{fault}{where}",
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
return errors
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
__all__ = [
|
|
205
|
+
"is_kernel_availability_fault",
|
|
206
|
+
"kernel_availability_errors",
|
|
207
|
+
"kernel_availability_fault",
|
|
208
|
+
]
|