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

Make CLI import logic consistent between listings and runnability #2787

Merged
merged 21 commits into from
Jan 24, 2025

Conversation

freider
Copy link
Contributor

@freider freider commented Jan 21, 2025

Changes the CLI import logic to use an exhaustive list of commands + filters instead of getattr() navigation.

This ensures that the listed modal "runnables" in the CLI error output will always be runnable by the command that you've run, which wasn't previously the case.

While this was a lot of code, I think it's mostly a simplification of the previous code.
The tests are still a bit of a mess since I mostly ported the old tests, and they now overlap quite a lot, but they are quick so it doesn't matter too much.

Note that this does remove a few of the helpful commands for special cases that we had before in favor of a more general error message that always lists the runnable commands if the user passes something that can't resolve to a single "runnable" (function, entrypoint, method)

Also fixes CLI-293


Check these boxes or delete any item (or this section) if not relevant for this PR.

  • Client+Server: this change is compatible with old servers
  • Client forward compatibility: this change ensures client can accept data intended for later versions of itself

Note on protobuf: protobuf message changes in one place may have impact to
multiple entities (client, server, worker, database). See points above.


Changelog

  • Fixes a CLI bug where you couldn't reference functions via a qualified app, e.g. mymodule::{app_variable}.{function_name}.
  • The modal run, modal serve and modal shell commands get more consistent error messages in cases where the passed app or function reference isn't resolvable to something that the current command expects.
  • Removes the deprecated __getattr__, __setattr__, __getitem__ and __setitem__ methods from modal.App

@freider freider requested a review from mwaskom January 21, 2025 12:54
@mwaskom
Copy link
Contributor

mwaskom commented Jan 21, 2025

Is there a typo in the first changelog bullet? I am having trouble parsing it.

@freider
Copy link
Contributor Author

freider commented Jan 21, 2025

Is there a typo in the first changelog bullet? I am having trouble parsing it.

Yup, fixed

Copy link
Contributor

@mwaskom mwaskom left a comment

Choose a reason for hiding this comment

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

Definitely a lot here ... had a few questions but overall lgtm; thanks for cleaning this up.

Does this PR also fix https://linear.app/modal-labs/issue/CLI-293/regression-modal-run-against-class-w-lifecycle-methods-doesnt-auto-run?

app: App, module, accept_local_entrypoint: bool, accept_webhook: bool
) -> Union[Function, LocalEntrypoint, MethodReference]:
"""Using only an app - automatically infer a single "runnable" for a `modal run` invocation
Runnables includes all Functions, (class) Methods and Local Entrypoints, including web endpoints.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are web endpoints considered "runnable"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

modal shell can "run" them - happy to consider other names (but I'm only using this internally at the moment)

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah interesting, yeah I guess that makes sense.

]
apps = cast(list[tuple[str, App]], inspect.getmembers(module, lambda x: isinstance(x, App)))

all_runnables: dict[Runnable, list[str]] = {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would using defaultdict make some of the updates marginally simpler?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

Comment on lines 231 to 232
f"Expected to find an app variable named **`{DEFAULT_APP_NAME}`** (the default app name). "
"If your `modal.App` is named differently, "
Copy link
Contributor

Choose a reason for hiding this comment

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

Something I'm a little confused by: is this guiding users to to the App name (e.g. App("my-app")) or to the variable name that points at the App?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's supposed to be the variable name, not the name of the app (this is unchanged from before, it's just that any references via the app has been broken since we deprecated App.__getattr__ 😬 )

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe could rephrase (e.g. "If your modal.App is assigned to a different variable name") to reduce the chance of confusion 🤷‍♂️

@freider
Copy link
Contributor Author

freider commented Jan 22, 2025

Definitely a lot here ... had a few questions but overall lgtm; thanks for cleaning this up.

Does this PR also fix https://linear.app/modal-labs/issue/CLI-293/regression-modal-run-against-class-w-lifecycle-methods-doesnt-auto-run?

Oooh, good question. Not intentionally, but seems very relevant so I should make it so if I haven't! (It would be a bug if it listed/could run the lifecycle methods)

@freider
Copy link
Contributor Author

freider commented Jan 22, 2025

Definitely a lot here ... had a few questions but overall lgtm; thanks for cleaning this up.
Does this PR also fix https://linear.app/modal-labs/issue/CLI-293/regression-modal-run-against-class-w-lifecycle-methods-doesnt-auto-run?

Oooh, good question. Not intentionally, but seems very relevant so I should make it so if I haven't! (It would be a bug if it listed/could run the lifecycle methods)

Seems like this patch fixed it, since it extracts the method names using the method metadata on the class. I made sure to add a lifecycle method now to one of the tests to keep this from regressing!

@freider freider merged commit 0f0beb7 into main Jan 24, 2025
23 checks passed
@freider freider deleted the freider/cli-runnable-consistency branch January 24, 2025 07:41
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