Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Initial implementation #1

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

Merged
merged 178 commits into from
Jul 2, 2025
Merged

Initial implementation #1

merged 178 commits into from
Jul 2, 2025

Conversation

dandavison
Copy link
Contributor

@dandavison dandavison commented Apr 2, 2025

Nexus Python SDK initial content.

For an overview of the user experience of implementing and calling Nexus handlers, see the Temporal sample, and tests in this PR.

@dandavison dandavison force-pushed the v0 branch 2 times, most recently from a0db8c4 to 2733044 Compare April 22, 2025 20:52
@dandavison dandavison changed the title Initial prototyping Initial implementation May 8, 2025
@dandavison dandavison force-pushed the v0 branch 3 times, most recently from 4c284df to 9bdf24d Compare May 27, 2025 20:13
@dandavison dandavison force-pushed the v0 branch 4 times, most recently from fbb91b0 to 659557b Compare May 30, 2025 01:42
@dandavison dandavison requested a review from Copilot May 30, 2025 01:44
Copilot

This comment was marked as off-topic.

@nexus-rpc nexus-rpc deleted a comment from Copilot AI May 30, 2025
@dandavison dandavison force-pushed the v0 branch 6 times, most recently from 96f9be3 to 9711999 Compare June 9, 2025 20:58
@dandavison dandavison marked this pull request as ready for review June 9, 2025 21:00
@dandavison dandavison force-pushed the v0 branch 6 times, most recently from fa76eac to 706b354 Compare June 9, 2025 22:27
...


class LazyValueT(Protocol):
Copy link

Choose a reason for hiding this comment

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

But I thought we were removing sync form? At which point is there value here?

"""Request or response data."""


class Serializer(Protocol):
Copy link

Choose a reason for hiding this comment

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

It's not incorrect, it's just too limiting and not common for these use cases. I think we should revisit this since it makes sense for serializer to be a base class one extends instead of duck-typed.

...


class LazyValueT(Protocol):
Copy link

Choose a reason for hiding this comment

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

Yeah, I think my main problem was that this didn't make sense as a protocol

)
return defn

def _validation_errors(self) -> list[str]:
Copy link

Choose a reason for hiding this comment

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

Can we get a general decision on operation-less Nexus service contracts and whether we generally believe they are valid? A dataclass with no fields may be valid, but a service with no calls may not be.

from nexusrpc.handler._operation_handler import OperationHandler


def get_service_definition(
Copy link

Choose a reason for hiding this comment

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

Concern about the name is different than concern about the placement. I think there's not a need to clutter the top-level API with a top-level function here. Whether we call this from_class or get_from_class or whatever I think is a secondary question (I don't see a from_whatever to be a constructor, but can be documented away).



@dataclass(frozen=True)
class OperationContext:
Copy link

Choose a reason for hiding this comment

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

I think it's also a signal of intent as well (i.e. "this is always used as a base class")

...


class BaseServiceCollectionHandler(AbstractHandler):
Copy link

Choose a reason for hiding this comment

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

👍 Would definitely like to reduce class/abstraction count if we can

)
self.service_handlers[sh.service.name] = sh

async def start_operation(
Copy link

Choose a reason for hiding this comment

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

👍 I trust the removal of the unused syncio stuff is being tracked

def service_handler(cls: Type[ServiceHandlerT]) -> Type[ServiceHandlerT]: ...


# TODO(preview): allow service to be provided as positional argument?
Copy link

Choose a reason for hiding this comment

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

I guess what I mean is why is service before * in the impl but after the * here?

self.headers = headers
self.stream = stream

def consume(self, as_type: Optional[Type[Any]] = None) -> Any:
Copy link

Choose a reason for hiding this comment

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

A thought while we're here - arguably a sync implementation should allow async operations and provide an event loop to run them on via run_coroutine_threadsafe similar to how an executor is provided to go from async to sync.

Copy link

@cretz cretz left a comment

Choose a reason for hiding this comment

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

Approving with the understanding that things mentioned here will be revisited soon

@dandavison dandavison force-pushed the v0 branch 3 times, most recently from f1c5988 to 0673817 Compare July 2, 2025 16:02
@dandavison dandavison merged commit 94a1267 into main Jul 2, 2025
10 checks passed
@dandavison
Copy link
Contributor Author

Thanks for all the code review @cretz and @bergundy.

@dandavison dandavison deleted the v0 branch July 2, 2025 16:06
@dandavison dandavison mentioned this pull request Jul 4, 2025
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.

5 participants