Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace importing the wf with ast parsing #516

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ayushkamat
Copy link
Contributor

  • workflows that use dockerfile-per-task need to now have the dockerfile be a string literal so that we can pull it out of the AST directly, probably not a big issue bc no one uses this feature anyway
  • not removing _import_flyte_objects bc that is used elsewhere and i dont have the time to fix those places right now



def is_task_decorator(decorator_name: str) -> bool:
return decorator_name in {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id just store the set as a global constant and do the in inline


elif isinstance(decorator, ast.Call):
func = decorator.func
assert isinstance(func, ast.Name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might want to handle ast.Attribute here if people import qualified e.g.

from latch import tasks

@tasks.small_task
def f():
	....

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally we would also try to resolve to a fully qualified name (i.e. only match latch.tasks.small_task vs any decorator that happens to share that name)

I'd leave a todo

continue

if func.id == "workflow":
self.flyte_objects.append(FlyteObject("workflow", node.name))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you probably want to store a qualified name? i.e. including the module names? flyte uses that iirc e.g. a workflow might be named src.main.wf because def wf() is in src/main.py

continue

dockerfile: Optional[Path] = None
for kw in decorator.keywords:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double-check that dockerfile is a keyword-only argument?

id leave a note here

continue

try:
dockerfile = Path(ast.literal_eval(kw.value)).resolve()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

careful with the working directory here

if the path is relative you need to resolve it relative to project root probably? or the file that is being parsed? unclear rn



def get_flyte_objects(file: Path) -> list[FlyteObject]:
res = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add explicit type

try:
parsed = ast.parse(file.read_text(), filename=file)
except SyntaxError as e:
click.secho(f"There is a syntax error in {file}: {e}", fg="red")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
click.secho(f"There is a syntax error in {file}: {e}", fg="red")
traceback.print_exc()
click.secho(f"\nRegistration failed due to a syntax error (see above)", fg="red")

self.file = file
self.flyte_objects: list[FlyteObject] = []

def visit_FunctionDef(self, node: ast.FunctionDef):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might want to skip functions that are not at the top level? what does flyte do with e.g. class methods?

res = []
if file.is_dir():
for child in file.iterdir():
res.extend(get_flyte_objects(child))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might want to use a queue instead of recursing
the file tree might be very deep for some stupid reason

also might want to avoid recursing into directories that don't have a __init__.py since those cannot contain importable python files anyway

return res

assert file.is_file()
if file.suffix != ".py":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a great heuristic tbh
would be better to follow the import graph i think

leave a todo at least

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants