Skip to content

Commit 147d1e1

Browse files
committed
fixies
Signed-off-by: Ayush Kamat <[email protected]>
1 parent ff1aabe commit 147d1e1

File tree

4 files changed

+52
-38
lines changed

4 files changed

+52
-38
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ include = ["src/**/*.py", "src/latch_cli/services/init/*"]
1212

1313
[project]
1414
name = "latch"
15-
version = "2.56.10"
15+
version = "2.57.0"
1616
description = "The Latch SDK"
1717
authors = [{ name = "Kenny Workman", email = "[email protected]" }]
1818
maintainers = [

src/latch_cli/centromere/ast_parsing.py

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,29 @@ class FlyteObject:
2323

2424

2525
class Visitor(ast.NodeVisitor):
26-
def __init__(self, file: Path):
26+
def __init__(self, file: Path, module_name: str):
2727
self.file = file
28-
self.module_name = str(file.with_suffix("")).replace(os.pathsep, ".")
28+
self.module_name = module_name
2929
self.flyte_objects: list[FlyteObject] = []
3030

3131
# todo(ayush): skip defs that arent run on import
3232
def visit_FunctionDef(self, node: ast.FunctionDef): # noqa: N802
3333
if len(node.decorator_list) == 0:
3434
return self.generic_visit(node)
3535

36-
name = f"{self.module_name}.{node.name}"
36+
fqn = f"{self.module_name}.{node.name}"
37+
# fqn = node.name
3738

3839
# todo(ayush): |
3940
# 1. support ast.Attribute (@latch.tasks.small_task)
4041
# 2. normalize to fqn before checking whether or not its a task decorator
42+
# 3. save fully qualified name for tasks (need to parse based on import graph)
4143
for decorator in node.decorator_list:
4244
if isinstance(decorator, ast.Name):
4345
if decorator.id == "workflow":
44-
self.flyte_objects.append(FlyteObject("workflow", name))
46+
self.flyte_objects.append(FlyteObject("workflow", fqn))
4547
elif decorator.id in task_decorators:
46-
self.flyte_objects.append(FlyteObject("task", name))
48+
self.flyte_objects.append(FlyteObject("task", fqn))
4749

4850
elif isinstance(decorator, ast.Call):
4951
func = decorator.func
@@ -53,7 +55,7 @@ def visit_FunctionDef(self, node: ast.FunctionDef): # noqa: N802
5355
continue
5456

5557
if func.id == "workflow":
56-
self.flyte_objects.append(FlyteObject("workflow", name))
58+
self.flyte_objects.append(FlyteObject("workflow", fqn))
5759
continue
5860

5961
# note(ayush): this only works if `dockerfile` is a keyword arg - if someone
@@ -65,40 +67,27 @@ def visit_FunctionDef(self, node: ast.FunctionDef): # noqa: N802
6567
continue
6668

6769
try:
68-
provided: str = ast.literal_eval(kw.value)
70+
dockerfile = Path(ast.literal_eval(kw.value))
6971
except ValueError as e:
7072
click.secho(
7173
dedent(f"""\
72-
There was an issue parsing the `dockerfile` argument for task `{name}` in {self.file}.
74+
There was an issue parsing the `dockerfile` argument for task `{fqn}` in {self.file}.
7375
Note that values passed to `dockerfile` must be string literals.
7476
"""),
7577
fg="red",
7678
)
7779

7880
raise click.exceptions.Exit(1) from e
7981

80-
dockerfile = self.file.parent / provided
81-
82-
if not dockerfile.exists():
83-
click.secho(
84-
f"""\
85-
The `dockerfile` value (provided {provided}, resolved to {dockerfile}) for task `{name}` in {self.file} does not exist.
86-
Note that relative paths are resolved with respect to the parent directory of the file.\
87-
""",
88-
fg="red",
89-
)
90-
91-
raise click.exceptions.Exit(1)
92-
93-
self.flyte_objects.append(FlyteObject("task", name, dockerfile))
82+
self.flyte_objects.append(FlyteObject("task", fqn, dockerfile))
9483

9584
return self.generic_visit(node)
9685

9786

98-
def get_flyte_objects(p: Path) -> list[FlyteObject]:
87+
def get_flyte_objects(module: Path) -> list[FlyteObject]:
9988
res: list[FlyteObject] = []
10089
queue: Queue[Path] = Queue()
101-
queue.put(p)
90+
queue.put(module)
10291

10392
while not queue.empty():
10493
file = queue.get()
@@ -114,7 +103,11 @@ def get_flyte_objects(p: Path) -> list[FlyteObject]:
114103
if file.suffix != ".py":
115104
continue
116105

117-
v = Visitor(file)
106+
module_name = str(file.with_suffix("").relative_to(module.parent)).replace(
107+
os.sep, "."
108+
)
109+
110+
v = Visitor(file, module_name)
118111

119112
try:
120113
parsed = ast.parse(file.read_text(), filename=file)

src/latch_cli/centromere/ctx.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
WorkflowType,
2727
generate_temporary_ssh_credentials,
2828
hash_directory,
29+
identifier_suffix_from_str,
2930
)
3031
from latch_sdk_config.latch import config
3132

@@ -36,6 +37,9 @@ class _Container:
3637
pkg_dir: Path
3738
image_name: str
3839

40+
def __post_init__(self):
41+
print(self)
42+
3943

4044
# todo(ayush): cleanse this
4145
class _CentromereCtx:
@@ -217,6 +221,19 @@ def __init__(
217221
if obj.type != "task" or obj.dockerfile is None:
218222
continue
219223

224+
dockerfile = self.pkg_root / obj.dockerfile
225+
226+
if not dockerfile.exists():
227+
click.secho(
228+
f"""\
229+
The `dockerfile` value (provided {obj.dockerfile}, resolved to {dockerfile}) for task `{obj.name}` does not exist.
230+
Note that relative paths are resolved with respect to the parent directory of the file.\
231+
""",
232+
fg="red",
233+
)
234+
235+
raise click.exceptions.Exit(1)
236+
220237
self.container_map[obj.name] = _Container(
221238
dockerfile=obj.dockerfile,
222239
image_name=self.task_image_name(obj.name),
@@ -440,8 +457,6 @@ def image(self):
440457
else:
441458
account_id = self.account_id
442459

443-
from ..utils import identifier_suffix_from_str
444-
445460
wf_name = identifier_suffix_from_str(self.workflow_name).lower()
446461
wf_name = docker_image_name_illegal_pat.sub("_", wf_name)
447462

@@ -481,6 +496,9 @@ def image_tagged(self):
481496
return f"{self.image}:{self.version}"
482497

483498
def task_image_name(self, task_name: str) -> str:
499+
task_name = identifier_suffix_from_str(task_name).lower()
500+
task_name = docker_image_name_illegal_pat.sub("_", task_name)
501+
484502
return f"{self.image}:{task_name}-{self.version}"
485503

486504
@property

src/latch_cli/services/register/register.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -359,9 +359,10 @@ def register(
359359

360360
# todo(maximsmol): we really want the workflow display name here
361361
click.echo(
362-
" ".join(
363-
[click.style("Workflow name:", fg="bright_blue"), ctx.workflow_name]
364-
)
362+
" ".join([
363+
click.style("Workflow name:", fg="bright_blue"),
364+
ctx.workflow_name,
365+
])
365366
)
366367
click.echo(" ".join([click.style("Version:", fg="bright_blue"), ctx.version]))
367368

@@ -392,15 +393,17 @@ def register(
392393
)
393394
if ctx.workflow_type == WorkflowType.snakemake:
394395
click.echo(
395-
" ".join(
396-
[click.style("Snakefile:", fg="bright_blue"), str(ctx.snakefile)]
397-
)
396+
" ".join([
397+
click.style("Snakefile:", fg="bright_blue"),
398+
str(ctx.snakefile),
399+
])
398400
)
399401
elif ctx.workflow_type == WorkflowType.nextflow:
400402
click.echo(
401-
" ".join(
402-
[click.style("NF script:", fg="bright_blue"), str(ctx.nf_script)]
403-
)
403+
" ".join([
404+
click.style("NF script:", fg="bright_blue"),
405+
str(ctx.nf_script),
406+
])
404407
)
405408

406409
if use_new_centromere:
@@ -532,7 +535,7 @@ def register(
532535
try:
533536
split_task_name = task_name.split(".")
534537
task_name = ".".join(
535-
split_task_name[split_task_name.index("wf") :]
538+
split_task_name[split_task_name.index(ctx.wf_module) :]
536539
)
537540
for new_proto in new_protos:
538541
if task_name in new_proto.name:

0 commit comments

Comments
 (0)