tgzr.cuisine 0.0.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.
- tgzr/cuisine/__init__.py +0 -0
- tgzr/cuisine/_version.py +34 -0
- tgzr/cuisine/basics/__init__.py +35 -0
- tgzr/cuisine/basics/buildable.py +38 -0
- tgzr/cuisine/basics/builder.py +72 -0
- tgzr/cuisine/basics/computable.py +33 -0
- tgzr/cuisine/basics/editable.py +28 -0
- tgzr/cuisine/basics/editor.py +29 -0
- tgzr/cuisine/basics/env.py +216 -0
- tgzr/cuisine/basics/files_recipes/__init__.py +18 -0
- tgzr/cuisine/basics/panels/__init__.py +0 -0
- tgzr/cuisine/basics/panels/params_panel.py +540 -0
- tgzr/cuisine/basics/product.py +32 -0
- tgzr/cuisine/basics/recipe_contexts.py +10 -0
- tgzr/cuisine/basics/recipe_with_params.py +119 -0
- tgzr/cuisine/basics/viewable.py +33 -0
- tgzr/cuisine/basics/viewer.py +30 -0
- tgzr/cuisine/basics/workscene.py +5 -0
- tgzr/cuisine/chef.py +339 -0
- tgzr/cuisine/cli/__init__.py +232 -0
- tgzr/cuisine/cli/main.py +7 -0
- tgzr/cuisine/cli/utils.py +31 -0
- tgzr/cuisine/plugin.py +27 -0
- tgzr/cuisine/recipe.py +361 -0
- tgzr/cuisine/workbench.py +455 -0
- tgzr_cuisine-0.0.1.dist-info/METADATA +34 -0
- tgzr_cuisine-0.0.1.dist-info/RECORD +30 -0
- tgzr_cuisine-0.0.1.dist-info/WHEEL +4 -0
- tgzr_cuisine-0.0.1.dist-info/entry_points.txt +8 -0
- tgzr_cuisine-0.0.1.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
Naming:
|
|
4
|
+
user_workspaces -> cuisine
|
|
5
|
+
workspace -> workbench
|
|
6
|
+
requirement -> input
|
|
7
|
+
asset -> recipe
|
|
8
|
+
repo -> catalog
|
|
9
|
+
inputs -> N/A (managed by uv)
|
|
10
|
+
outputs -> editables
|
|
11
|
+
|
|
12
|
+
uv config:
|
|
13
|
+
|
|
14
|
+
# add from a remote catalog:
|
|
15
|
+
uv add recipe==1.0.3 --index blessed=https://path/to/blessed_catalog
|
|
16
|
+
# add from a path:
|
|
17
|
+
uv add recipe /path/to/blessed_catalog
|
|
18
|
+
# add from editables:
|
|
19
|
+
uv add --editable ./editable/recipe
|
|
20
|
+
|
|
21
|
+
->
|
|
22
|
+
[tool.uv.sources]
|
|
23
|
+
torch = { index = "blessed" }
|
|
24
|
+
|
|
25
|
+
[[tool.uv.index]]
|
|
26
|
+
name = "blessed"
|
|
27
|
+
url = "https://path/to/blessed_catalog"
|
|
28
|
+
explicit = true #<-- see if this is better and if it can be set by uv cli
|
|
29
|
+
|
|
30
|
+
# add a requirement in a specific group
|
|
31
|
+
uv add builder_recipe --optional build
|
|
32
|
+
|
|
33
|
+
NOTE: environment marker on dependencies can use [extra] to select the catalog to install from:
|
|
34
|
+
https://docs.astral.sh/uv/concepts/projects/dependencies/#multiple-sources
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
from __future__ import annotations
|
|
39
|
+
from typing import Any
|
|
40
|
+
|
|
41
|
+
from pathlib import Path
|
|
42
|
+
import subprocess
|
|
43
|
+
import dataclasses
|
|
44
|
+
from importlib_metadata import Distribution
|
|
45
|
+
from ast import literal_eval
|
|
46
|
+
import os
|
|
47
|
+
|
|
48
|
+
import uv as external_uv
|
|
49
|
+
import pydantic
|
|
50
|
+
|
|
51
|
+
from tgzr.package_management.workspace import Workspace
|
|
52
|
+
|
|
53
|
+
from .recipe import RecipeTypeInfo
|
|
54
|
+
from .chef import Chef
|
|
55
|
+
from .plugin import cuisine_plugin_manager
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class WorkbenchSettings(pydantic.BaseModel):
|
|
59
|
+
main_entity: str | None = (
|
|
60
|
+
None # optional main entity FIXME: should be auto installed
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclasses.dataclass
|
|
65
|
+
class RecipeDistInfo:
|
|
66
|
+
"""
|
|
67
|
+
Recipe related information extracted from
|
|
68
|
+
a `importlib.metadata.Distribution()`.
|
|
69
|
+
|
|
70
|
+
These are created by Workbench.get_dist_info
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
dist: Distribution
|
|
74
|
+
is_recipe: bool
|
|
75
|
+
recipe_name: str
|
|
76
|
+
recipe_type: str | None
|
|
77
|
+
tags: set[str]
|
|
78
|
+
is_editable: bool
|
|
79
|
+
editable_path: Path | None
|
|
80
|
+
nice_panel_names: list[str]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class Workbench:
|
|
84
|
+
def __init__(self, path: Path | str | None) -> None:
|
|
85
|
+
if path is None:
|
|
86
|
+
path = "."
|
|
87
|
+
path = Path(path).resolve()
|
|
88
|
+
self._workspace = Workspace(path)
|
|
89
|
+
|
|
90
|
+
# self._name = self.path.name
|
|
91
|
+
|
|
92
|
+
# self._venv_name = ".venv"
|
|
93
|
+
# self._venv_path = self.path / self._venv_name
|
|
94
|
+
|
|
95
|
+
# exe_dir = "bin"
|
|
96
|
+
# self._exe_suffix = ""
|
|
97
|
+
# if platform.system() != "Linux":
|
|
98
|
+
# exe_dir = "Scripts"
|
|
99
|
+
# self._exe_suffix = ".exe"
|
|
100
|
+
# self._exe_path = self._venv_path / exe_dir
|
|
101
|
+
|
|
102
|
+
# self._external_packages_path = self.path / "external_packages"
|
|
103
|
+
# self._output_path = self.path / "outputs"
|
|
104
|
+
# self._uv_workspace_pyproject = self.path / "pyproject.toml"
|
|
105
|
+
self._editable_path = self.path / "editables"
|
|
106
|
+
self._build_path = self.path / "build"
|
|
107
|
+
|
|
108
|
+
venv_name = ".venv" # imposed by uv
|
|
109
|
+
self._venv_path = self.path / venv_name
|
|
110
|
+
self._chef = Chef(self._venv_path)
|
|
111
|
+
for plugin in cuisine_plugin_manager.get_plugins():
|
|
112
|
+
self._chef.register_recipe_types(*plugin.get_recipe_types())
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def path(self) -> Path:
|
|
116
|
+
"""The path of the Workbench, including its name."""
|
|
117
|
+
return self._workspace.path
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def name(self) -> str:
|
|
121
|
+
"""The name of the Workbench, deducted from its path."""
|
|
122
|
+
return self._workspace.name
|
|
123
|
+
|
|
124
|
+
# @property
|
|
125
|
+
# def venv_path(self) -> Path:
|
|
126
|
+
# """The path to the Workspace's venv."""
|
|
127
|
+
# return self._venv_path
|
|
128
|
+
|
|
129
|
+
def exists(self) -> bool:
|
|
130
|
+
return self._workspace.exists()
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
def chef(self) -> Chef:
|
|
134
|
+
return self._chef
|
|
135
|
+
|
|
136
|
+
def get_recipe_types_info(self) -> dict[str, RecipeTypeInfo]:
|
|
137
|
+
recipe_types = self.chef.get_recipe_types()
|
|
138
|
+
|
|
139
|
+
ret = dict()
|
|
140
|
+
for RecipeType in recipe_types:
|
|
141
|
+
recipe_type_info = RecipeType.RECIPE_TYPE_INFO
|
|
142
|
+
ret[recipe_type_info.type_name] = recipe_type_info
|
|
143
|
+
return ret
|
|
144
|
+
|
|
145
|
+
def ensure_exists(
|
|
146
|
+
self,
|
|
147
|
+
force_build: bool = False,
|
|
148
|
+
description: str | None = None,
|
|
149
|
+
python_version: str | None = None,
|
|
150
|
+
):
|
|
151
|
+
if self.exists():
|
|
152
|
+
if force_build:
|
|
153
|
+
# Not sure it's needed, and not sure how to do it ^_^', so:
|
|
154
|
+
raise ValueError("Workspace Rebuild not yet implemented!")
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
self._workspace.create(
|
|
158
|
+
description=description, python_version=python_version, vcs="none"
|
|
159
|
+
)
|
|
160
|
+
# Make all editable
|
|
161
|
+
self._workspace.add_member("editables/*")
|
|
162
|
+
# Seed the workspace with mandatory dependencies:
|
|
163
|
+
self._workspace.add_dependencies("", "uv", "hatch", "tgzr.cuisine")
|
|
164
|
+
self._workspace.ensure_index("pypi", "https://pypi.org/simple")
|
|
165
|
+
# self._workspace.set_source("uv", index_name="pypi")
|
|
166
|
+
# self._workspace.set_source("hatch", index_name="pypi")
|
|
167
|
+
|
|
168
|
+
# TODO: install from pypi:
|
|
169
|
+
self._workspace.set_source(
|
|
170
|
+
"tgzr.cuisine", path="/home/dee/DEV/_OPEN-TGZR_/tgzr.cuisine", editable=True
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
self._editable_path.mkdir(parents=False, exist_ok=True)
|
|
174
|
+
self._build_path.mkdir(parents=False, exist_ok=True)
|
|
175
|
+
|
|
176
|
+
def create_recipe(
|
|
177
|
+
self,
|
|
178
|
+
recipe_type_name: str,
|
|
179
|
+
recipe_name: str,
|
|
180
|
+
):
|
|
181
|
+
"""
|
|
182
|
+
Create an editable recipe on this workbench.
|
|
183
|
+
"""
|
|
184
|
+
recipe_id = self.chef.create_recipe(
|
|
185
|
+
folder=self._editable_path,
|
|
186
|
+
recipe_name=recipe_name,
|
|
187
|
+
recipe_metadata=None,
|
|
188
|
+
version=None,
|
|
189
|
+
recipe_type_name=recipe_type_name,
|
|
190
|
+
)
|
|
191
|
+
# TODO: repace these 3 line with a subprocess `uv add {recipe_name}` ?
|
|
192
|
+
self._workspace.set_source(recipe_name, workspace=True)
|
|
193
|
+
self._workspace.add_dependencies("", recipe_name)
|
|
194
|
+
self.sync()
|
|
195
|
+
# self._workspace.sync(allow_upgrade=True, allow_custom_classifiers=True)
|
|
196
|
+
# self._install_editable(recipe_id)
|
|
197
|
+
|
|
198
|
+
def rebuid_pyproject(self, recipe_name: str):
|
|
199
|
+
"""
|
|
200
|
+
Rebuild the pyproject.toml file, bump and install (editable)
|
|
201
|
+
Usefull when the content of the pyproject file need to be updated/conformed
|
|
202
|
+
"""
|
|
203
|
+
self.chef.rebuild_pyproject(self._editable_path, recipe_name)
|
|
204
|
+
self.bump_recipe(recipe_name, "micro")
|
|
205
|
+
|
|
206
|
+
def rebuid_dinit(self, recipe_name: str):
|
|
207
|
+
"""
|
|
208
|
+
Rebuild the __init__.py file, bump and install (editable)
|
|
209
|
+
Usefull when the content of the __init__ file need to be updated/conformed
|
|
210
|
+
after modifying what the base class puts in it.
|
|
211
|
+
"""
|
|
212
|
+
self.chef.rebuild_dinit(self._editable_path, recipe_name)
|
|
213
|
+
self.bump_recipe(recipe_name, "micro")
|
|
214
|
+
|
|
215
|
+
def get_recipe_names(self) -> list[str]:
|
|
216
|
+
venv = self._workspace.venv()
|
|
217
|
+
dists = venv.get_packages()
|
|
218
|
+
recipe_dist_infos = [self.get_dist_info(dist) for dist in dists]
|
|
219
|
+
return [dist.recipe_name for dist in recipe_dist_infos if dist.is_recipe]
|
|
220
|
+
|
|
221
|
+
def get_editable_recipe_names(self) -> list[str]:
|
|
222
|
+
names = []
|
|
223
|
+
for path in self._editable_path.iterdir():
|
|
224
|
+
if (path / "pyproject.toml").exists:
|
|
225
|
+
names.append(path.name)
|
|
226
|
+
return sorted(names)
|
|
227
|
+
|
|
228
|
+
# def _install_editable(self, recipe_requirement: str):
|
|
229
|
+
# print("WS Install editable", recipe_requirement)
|
|
230
|
+
|
|
231
|
+
# find_links = []
|
|
232
|
+
# # TODO: implement management of uv's workspace index + use in them here
|
|
233
|
+
|
|
234
|
+
# self.chef.install_editable(
|
|
235
|
+
# self._editable_path,
|
|
236
|
+
# recipe_name,
|
|
237
|
+
# *find_links,
|
|
238
|
+
# )
|
|
239
|
+
|
|
240
|
+
def sync(self) -> None:
|
|
241
|
+
"""
|
|
242
|
+
Install all editables an update all versions.
|
|
243
|
+
"""
|
|
244
|
+
self._workspace.sync(allow_upgrade=True, allow_custom_classifiers=True)
|
|
245
|
+
|
|
246
|
+
def tag_recipe(self, recipe_name: str, *tags: str):
|
|
247
|
+
self.chef.add_tags(self._editable_path, recipe_name, set(tags))
|
|
248
|
+
self.sync()
|
|
249
|
+
# self._workspace.sync(allow_upgrade=True, allow_custom_classifiers=True)
|
|
250
|
+
# self._install_editable(recipe_name)
|
|
251
|
+
|
|
252
|
+
def add_inputs(self, recipe_name: str, group: str = "", *input_requirements: str):
|
|
253
|
+
"""
|
|
254
|
+
Make this recipe dependent of given input_requirements.
|
|
255
|
+
Each input_requirement can be like:
|
|
256
|
+
- recipe-name
|
|
257
|
+
- recipe-name==1.2.3
|
|
258
|
+
- recipe-anme>=2.3.4
|
|
259
|
+
- recipe-name>=3.4.5<4.0
|
|
260
|
+
etc...
|
|
261
|
+
"""
|
|
262
|
+
if not self.has_editable_recipe(recipe_name):
|
|
263
|
+
raise ValueError(f"Cannot add inputs to non-editable asset {recipe_name!r}")
|
|
264
|
+
self.chef.add_inputs(
|
|
265
|
+
self._editable_path, recipe_name, group, *input_requirements
|
|
266
|
+
)
|
|
267
|
+
self.sync()
|
|
268
|
+
# self._workspace.sync(allow_upgrade=True, allow_custom_classifiers=True)
|
|
269
|
+
# self._install_editable(recipe_name)
|
|
270
|
+
|
|
271
|
+
def bump_recipe(self, recipe_name: str, bump: str = "minor"):
|
|
272
|
+
"""
|
|
273
|
+
Bumpt the part of the version specified with bump, like:"
|
|
274
|
+
major
|
|
275
|
+
minor
|
|
276
|
+
micro / patch / fix
|
|
277
|
+
a / alpha
|
|
278
|
+
b / alpha
|
|
279
|
+
c / rc / pre / preview
|
|
280
|
+
r / rev / post
|
|
281
|
+
dev
|
|
282
|
+
|
|
283
|
+
or a combination like:
|
|
284
|
+
minor,rc
|
|
285
|
+
patch,a
|
|
286
|
+
major,alpha,dev
|
|
287
|
+
|
|
288
|
+
Defaults is to bump minor."
|
|
289
|
+
"""
|
|
290
|
+
self.chef.bump_recipe(self._editable_path, recipe_name, bump=bump)
|
|
291
|
+
self.sync()
|
|
292
|
+
# self._workspace.sync(allow_upgrade=True, allow_custom_classifiers=True)
|
|
293
|
+
# self._install_editable(recipe_name)
|
|
294
|
+
|
|
295
|
+
def build_recipe(self, recipe_name: str, bump: str = "minor"):
|
|
296
|
+
self.chef.bump_recipe(self._editable_path, recipe_name, bump=bump)
|
|
297
|
+
self.chef.build_recipe(self._editable_path, recipe_name, self._build_path)
|
|
298
|
+
|
|
299
|
+
def publish_recipe(self, recipe_name: str, index_name: str):
|
|
300
|
+
index = self._workspace.get_index(index_name)
|
|
301
|
+
if index is None:
|
|
302
|
+
raise ValueError(
|
|
303
|
+
f"Undefined index {index_name!r} in workbench {str(self.path)!r}."
|
|
304
|
+
)
|
|
305
|
+
self.chef.publish_recipe(
|
|
306
|
+
self._editable_path,
|
|
307
|
+
recipe_name,
|
|
308
|
+
self._build_path,
|
|
309
|
+
index.url,
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
def install_recipe(
|
|
313
|
+
self,
|
|
314
|
+
from_index_name: str,
|
|
315
|
+
requirement,
|
|
316
|
+
):
|
|
317
|
+
self._workspace.set_source(requirement, index_name=from_index_name)
|
|
318
|
+
self.sync()
|
|
319
|
+
# self._workspace.sync(allow_upgrade=True, allow_custom_classifiers=True)
|
|
320
|
+
|
|
321
|
+
def has_editable_recipe(self, recipe_name: str):
|
|
322
|
+
return (self._editable_path / recipe_name).exists()
|
|
323
|
+
|
|
324
|
+
def turn_recipe_editable(self, recipe_name: str, force: bool = False):
|
|
325
|
+
"""
|
|
326
|
+
Turn an installed recipe into an editable recipe.
|
|
327
|
+
"""
|
|
328
|
+
if self.has_editable_recipe(recipe_name):
|
|
329
|
+
if not force:
|
|
330
|
+
raise ValueError(
|
|
331
|
+
f"The recipe {recipe_name!r} is already editable in the worksbench {self.path!r}."
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
command = f"import {recipe_name} as package; package.recipe._CONTROLER.create_editable(package.recipe, workbench_path='{self.path}', force={force})"
|
|
335
|
+
try:
|
|
336
|
+
self._workspace.run_python_command(command)
|
|
337
|
+
except:
|
|
338
|
+
print("Oopsy, runing python command returned non-zero !")
|
|
339
|
+
else:
|
|
340
|
+
self.chef.bump_recipe(self._editable_path, recipe_name, bump="micro")
|
|
341
|
+
self._workspace.set_source(recipe_name, workspace=True)
|
|
342
|
+
self.sync()
|
|
343
|
+
# self._workspace.sync(allow_upgrade=True, allow_custom_classifiers=True)
|
|
344
|
+
|
|
345
|
+
def get_dist_info(self, dist: Distribution) -> RecipeDistInfo:
|
|
346
|
+
is_editable = False
|
|
347
|
+
editable_path = None
|
|
348
|
+
if (
|
|
349
|
+
hasattr(dist, "origin")
|
|
350
|
+
and dist.origin is not None
|
|
351
|
+
and hasattr(dist.origin, "dir_info")
|
|
352
|
+
and dist.origin.dir_info.editable
|
|
353
|
+
):
|
|
354
|
+
# TODO: verify if the editable path in in our output dir?
|
|
355
|
+
is_editable = True
|
|
356
|
+
url = dist.origin.url
|
|
357
|
+
editable_path = Path(url.split("file://", 1)[-1])
|
|
358
|
+
|
|
359
|
+
dist_info = RecipeDistInfo(
|
|
360
|
+
dist=dist,
|
|
361
|
+
is_recipe="tgzr.pipeline.asset_info_trick" in dist.entry_points.groups,
|
|
362
|
+
recipe_name=dist.name,
|
|
363
|
+
recipe_type=None,
|
|
364
|
+
tags=set(),
|
|
365
|
+
is_editable=is_editable,
|
|
366
|
+
editable_path=editable_path,
|
|
367
|
+
nice_panel_names=[],
|
|
368
|
+
)
|
|
369
|
+
if dist_info.is_recipe:
|
|
370
|
+
for ep in dist.entry_points.select(group="tgzr.pipeline.recipe_info_trick"):
|
|
371
|
+
if ep.name == "recipe_name":
|
|
372
|
+
dist_info.recipe_name = ep.value
|
|
373
|
+
elif ep.name == "recipe_type":
|
|
374
|
+
dist_info.recipe_type = ep.value
|
|
375
|
+
# TODO: read tags from keywords
|
|
376
|
+
# elif ep.name == "tags":
|
|
377
|
+
# try:
|
|
378
|
+
# dist_info.tags = literal_eval(ep.value)
|
|
379
|
+
# print(
|
|
380
|
+
# f"Error evaluating asset tags for {dist.name}: {ep.value}"
|
|
381
|
+
# )
|
|
382
|
+
# except:
|
|
383
|
+
# dist_info.tags = set()
|
|
384
|
+
|
|
385
|
+
for ep in dist.entry_points.select(group="tgzr.pipeline.asset.nice_panel"):
|
|
386
|
+
dist_info.nice_panel_names.append(ep.name)
|
|
387
|
+
|
|
388
|
+
return dist_info
|
|
389
|
+
|
|
390
|
+
def get_dist_infos(
|
|
391
|
+
self, editable_only: bool = False, include_non_recipe: bool = False
|
|
392
|
+
) -> list[RecipeDistInfo]:
|
|
393
|
+
venv = self._workspace.venv()
|
|
394
|
+
|
|
395
|
+
def match(dist):
|
|
396
|
+
if editable_only and not dist.is_editable:
|
|
397
|
+
return False
|
|
398
|
+
if not include_non_recipe and not dist.is_recipe:
|
|
399
|
+
return False
|
|
400
|
+
return True
|
|
401
|
+
|
|
402
|
+
dists = venv.get_packages()
|
|
403
|
+
dist_infos = [self.get_dist_info(dist) for dist in dists]
|
|
404
|
+
return [di for di in dist_infos if match(di)]
|
|
405
|
+
|
|
406
|
+
def run(self, console_script_name: str):
|
|
407
|
+
extra_env = {"tgzr.pipeline.current_workspace.path": str(self.path)}
|
|
408
|
+
self._workspace.run(console_script_name, **extra_env)
|
|
409
|
+
|
|
410
|
+
# self._venv_path
|
|
411
|
+
# uv = self._venv_bin_path / "uv"
|
|
412
|
+
# python = self._venv_bin_path / "python"
|
|
413
|
+
# cmd = [
|
|
414
|
+
# str(uv),
|
|
415
|
+
# "run",
|
|
416
|
+
# "--python",
|
|
417
|
+
# str(python),
|
|
418
|
+
# "--directory",
|
|
419
|
+
# str(self._venv_bin_path),
|
|
420
|
+
# console_script_name,
|
|
421
|
+
# ]
|
|
422
|
+
# # print(cmd)
|
|
423
|
+
# env = os.environ.copy()
|
|
424
|
+
# env["tgzr.pipeline.current_workspace.path"] = str(self.path)
|
|
425
|
+
# # print(env)
|
|
426
|
+
# err_code = subprocess.call(cmd, env=env)
|
|
427
|
+
# if err_code:
|
|
428
|
+
# print(
|
|
429
|
+
# f"Oops, 'uv run {console_script_name}' returned error code: {err_code}."
|
|
430
|
+
# )
|
|
431
|
+
|
|
432
|
+
def run_recipe_method(
|
|
433
|
+
self, recipe_name: str, method_name: str, *args, **kwargs
|
|
434
|
+
) -> Any:
|
|
435
|
+
"""
|
|
436
|
+
Execute that Recipe's method in the current thread.
|
|
437
|
+
|
|
438
|
+
This is probably dangerous. Doing things like modifying the
|
|
439
|
+
asset in that method would be quite a bad ides I guess...
|
|
440
|
+
"""
|
|
441
|
+
return self.chef.run_recipe_method(
|
|
442
|
+
self._editable_path, recipe_name, method_name, *args, **kwargs
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
def render_nice_panel(self, recipe_name: str, panel_name: str) -> Any:
|
|
446
|
+
"""
|
|
447
|
+
Assets can implement GUI panels (see Asset.nice_panel_names())
|
|
448
|
+
When they do so, their DistInfo.nice_panel_names contains the
|
|
449
|
+
name of the panel they can render.
|
|
450
|
+
You can call this method under a nicegui.ui element context
|
|
451
|
+
to render the asset's panel.
|
|
452
|
+
"""
|
|
453
|
+
return self.run_recipe_method(
|
|
454
|
+
recipe_name, method_name=panel_name, workspace=self
|
|
455
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tgzr.cuisine
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: tgzr cuisine engine
|
|
5
|
+
Project-URL: Documentation, https://github.com/open-tgzr/tgzr.cuisine#readme
|
|
6
|
+
Project-URL: Issues, https://github.com/open-tgzr/tgzr.cuisine/issues
|
|
7
|
+
Project-URL: Source, https://github.com/open-tgzr/tgzr.cuisine
|
|
8
|
+
Author-email: Dee <dee.sometech@gmail.com>
|
|
9
|
+
License-Expression: GPL-3.0-or-later
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
19
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Requires-Dist: click
|
|
22
|
+
Requires-Dist: eval-type-backport
|
|
23
|
+
Requires-Dist: hatch
|
|
24
|
+
Requires-Dist: importlib-metadata
|
|
25
|
+
Requires-Dist: pydantic
|
|
26
|
+
Requires-Dist: rich
|
|
27
|
+
Requires-Dist: tgzr-context
|
|
28
|
+
Requires-Dist: tgzr-package-management
|
|
29
|
+
Requires-Dist: toml
|
|
30
|
+
Requires-Dist: uv
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# tgzr.cuisine
|
|
34
|
+
Cusine let your perform your tasks by crafting and cooking recipes.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
tgzr/cuisine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
tgzr/cuisine/_version.py,sha256=qf6R-J7-UyuABBo8c0HgaquJ8bejVbf07HodXgwAwgQ,704
|
|
3
|
+
tgzr/cuisine/chef.py,sha256=6vifcXhq9UUmucfHssp_EHMgfI2W5-vdxZN7U1bxTpQ,11957
|
|
4
|
+
tgzr/cuisine/plugin.py,sha256=rF3lTwyFlWv9tEEUAr3os92THK4R5sk723qMPLMbXzM,634
|
|
5
|
+
tgzr/cuisine/recipe.py,sha256=C1mDsU_Kd1E29GmKRLNrnOaCArFBWJqq4z4JDj4D6rI,12817
|
|
6
|
+
tgzr/cuisine/workbench.py,sha256=XlQDHU4AaA190VYRYvA4CIXq55y242RjqxL-upZdi8I,15630
|
|
7
|
+
tgzr/cuisine/basics/__init__.py,sha256=EPN3Km7k6cfT0dx2dYBzaSkt2a0qF9V1ZFN21vmbcS8,829
|
|
8
|
+
tgzr/cuisine/basics/buildable.py,sha256=TYutAmB9e7T1AjhftuzUyL_FK2qOVvcAYvwYfkUQEeo,967
|
|
9
|
+
tgzr/cuisine/basics/builder.py,sha256=P1HhjDtjkL6wapRhKY-tUFy92yWV56X5GFm-yV5rXqU,2608
|
|
10
|
+
tgzr/cuisine/basics/computable.py,sha256=SjAqfkcV9R9wbQ1t0aQIdYroJKea7wIKQWGxxQcJxd4,917
|
|
11
|
+
tgzr/cuisine/basics/editable.py,sha256=J6k_1Qiblqxt5DUiRhdVFPt8DyGmD7WXSkeZY7uXiaM,718
|
|
12
|
+
tgzr/cuisine/basics/editor.py,sha256=IwcgNl_djrukQv-nWP7cwS4erde3R6f5MgPKiJRBdLw,854
|
|
13
|
+
tgzr/cuisine/basics/env.py,sha256=mSNqDK3RM6D6Em4Ba0Ok86z7aRvryLhRRyexhuEbGD4,6251
|
|
14
|
+
tgzr/cuisine/basics/product.py,sha256=bkDHSNVumNYg4q-5O-Lb9Am9h9qlbGwKWkR_YEgv0OY,989
|
|
15
|
+
tgzr/cuisine/basics/recipe_contexts.py,sha256=GEt9SkmnIRRaiFZ-CYZ_15zwUWr8wbCaRg2qc50r3FI,319
|
|
16
|
+
tgzr/cuisine/basics/recipe_with_params.py,sha256=CAhMnOPvhEN7lX8HzkUCsO13TW_g7wLnHpQxCiL4G3w,3727
|
|
17
|
+
tgzr/cuisine/basics/viewable.py,sha256=0ee8Tljwd_N4GbYiEwjAkVe1v38jATDKA2_q7e3xn-U,865
|
|
18
|
+
tgzr/cuisine/basics/viewer.py,sha256=jYQhRUpDCGqnil26wD47U27SdsrOpJ770HqHJZWpdj8,901
|
|
19
|
+
tgzr/cuisine/basics/workscene.py,sha256=YryFFIAaL9jd-5v5XYrZVKyknuLnne8Enn7egcwGREg,88
|
|
20
|
+
tgzr/cuisine/basics/files_recipes/__init__.py,sha256=lYi2lwJlgTktwDJ7z4-uZf49sBXNHFz-0SpFO9pm61A,480
|
|
21
|
+
tgzr/cuisine/basics/panels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
tgzr/cuisine/basics/panels/params_panel.py,sha256=AWg5T62PiAViLeViKBtvTFf0ChtsH1jG3gBVS_Vmqrg,18118
|
|
23
|
+
tgzr/cuisine/cli/__init__.py,sha256=bD8gnm_IH-SaflfpL5YTKXhdUHxTNpcHB6UFMBaVr38,5810
|
|
24
|
+
tgzr/cuisine/cli/main.py,sha256=_dV9wqpoU5PMQeNKZiUGdt18xZUj4r2qkD7CYR9ii3Y,80
|
|
25
|
+
tgzr/cuisine/cli/utils.py,sha256=dafT-pQuV2Fnkq5od2jv31Ghu-ZtvoHzsCgo2zT8iGI,1034
|
|
26
|
+
tgzr_cuisine-0.0.1.dist-info/METADATA,sha256=8I-dhdZ358DaVUvSM0E43ZN5okZLhriDHr4BdY58mMw,1283
|
|
27
|
+
tgzr_cuisine-0.0.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
28
|
+
tgzr_cuisine-0.0.1.dist-info/entry_points.txt,sha256=WP7UXVs6sZVYsb3Xx0BluJ2WFLfusdnLiWX4BB5zhU4,203
|
|
29
|
+
tgzr_cuisine-0.0.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
30
|
+
tgzr_cuisine-0.0.1.dist-info/RECORD,,
|