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

Fix patch behavior for trusses using python DX #1337

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

nnarayen
Copy link
Contributor

@nnarayen nnarayen commented Jan 23, 2025

🚀 What

This PR fixes the truss watch behavior for traditional trusses using the new chains DX. Use:

$ truss watch --remote baseten-staging my_model.py

💻 How

🔬 Testing

Tested by manually applying patches to a development model, confirmed that both changes to the model file and import files are reflected.

def patch(
# TODO(nikhil): inspect source code rather than assume that watching an individual
# file indicates standalone models using the chains code gen framework
def _watch_path_requires_code_gen(self, watch_path: Path):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's now 3 places where we have this magic to switch between traditional truss code and chains truss code. For V0 it's probably still ok, but I wonder if there's something better we can do via:

  • scanning source code
  • explicit command line flag propagated around

Copy link
Contributor

Choose a reason for hiding this comment

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

Have you looked how watch for chains works? Can we somehow in the CLI branch of to using this instead of "hacking" this into here?

Copy link
Contributor Author

@nnarayen nnarayen Jan 27, 2025

Choose a reason for hiding this comment

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

I did poke around a bit to see if that would be possible, but decided against it for a couple small reasons:

  • The existing Watcher understandably has lots of chains specific stuff, and I think it would be some work to try and refactor what's not applicable to standalone models, fix error messages, etc
  • On the cli side we could try and branch between existing logic and new logic around here, but then we'd likely have to duplicate some logic or introduce a decent amount of refactors to Watcher so the code can work for both cases

I think it might unfortunately be cleanest for now to drop this directly into the remote provider, how do you feel about that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The second commit has a slightly different approach, lmk if you prefer that

# These imports are delayed, to handle pydantic v1 envs gracefully.
from truss_chains.deployment import code_gen

gen_truss_path = code_gen.gen_truss_model_from_source(patch_path)
Copy link
Contributor

Choose a reason for hiding this comment

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

What if it's a traditional truss model?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah that's a different path on L414 above, but after discussing offline this will likely go away!

@nnarayen nnarayen force-pushed the nikhil/fix-truss-watch-python-dx branch from 98c86e3 to 18d9e4a Compare January 27, 2025 19:28
def _handle_intercepted_logs(logs: list[str], console: "rich_console.Console"):
if logs:
formatted_logs = textwrap.indent("\n".join(logs), " " * 4)
console.print(f"Intercepted logs from importing source code:\n{formatted_logs}")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This message (and in _handle_import_error below) are basically the same as before, but removed any explicit mention of chains. I don't think it detracts from the usefulness of the message, and otherwise we'd have to introduce another param to differentiate

patcher = _ModelWatcher(
source=source,
model_name=model_name,
remote_provider=cast(b10_remote.BasetenRemote, remote_provider),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't love the explicit cast, but the interface method sync_truss_to_dev_version_by_name doesn't quite work for our use case with different directories for source / generated truss. Therefore, we need to do something similar to chainlets and peek into more low level patch API

@@ -542,7 +542,7 @@ def do_patch():
),
)

def patch(
def patch_model(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Small naming change, since path_for_chainlet is explicit below

@nnarayen nnarayen force-pushed the nikhil/fix-truss-watch-python-dx branch from 18d9e4a to 3598133 Compare January 27, 2025 19:36
@@ -29,6 +29,7 @@
from truss.remote.baseten import custom_types as b10_types
from truss.remote.baseten import remote as b10_remote
from truss.remote.baseten import service as b10_service
from truss.remote.baseten.error import RemoteError
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: please follow the convetion in this file of importing modules (see also: https://google.github.io/styleguide/pyguide.html#22-imports)

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