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
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
178 commits
Select commit Hold shift + click to select a range
fb231a0
Initial content
dandavison Jan 30, 2025
6e6a28a
Generate API docs
dandavison Jun 9, 2025
c4c9740
Changes based on review comments
dandavison Jun 9, 2025
89fd030
Move types
dandavison Jun 9, 2025
4c6bdc8
Eliminate Operation.key
dandavison Jun 10, 2025
6367411
Use Mapping for headers
dandavison Jun 10, 2025
a94f181
s/status/state/
dandavison Jun 10, 2025
29a5504
Delete ServiceHandlerDefinition
dandavison Jun 10, 2025
a5cc3b4
Add failing test
dandavison Jun 10, 2025
26f5522
Bug fix
dandavison Jun 10, 2025
e67dbef
Remove MISSING_TYPE
dandavison Jun 11, 2025
696da1b
Use None as the sentinel value
dandavison Jun 11, 2025
a75c8ee
Test output covariance
dandavison Jun 11, 2025
a029d06
Make output covariance tests pass
dandavison Jun 11, 2025
090edff
Test input contravariance
dandavison Jun 11, 2025
ec039c1
Make input contravariance tests pass
dandavison Jun 11, 2025
201ab95
Fix bugs found by Cursor BugBot
dandavison Jun 11, 2025
1d65a51
Minor fixups
dandavison Jun 12, 2025
c71f0f0
Move http client to Temporal SDK
dandavison Jun 13, 2025
48ad60e
Do not require cause for HandlerError
dandavison Jun 14, 2025
87c4adb
Clean-up AI-authored test
dandavison Jun 15, 2025
79eb6a1
Failg test for service definition inheritance
dandavison Jun 15, 2025
91855da
Add tests of service defn inheritance
dandavison Jun 15, 2025
dbcc009
Clean up test
dandavison Jun 15, 2025
79d73e0
Clean up test
dandavison Jun 15, 2025
ce33dd4
service decorator: refactor
dandavison Jun 15, 2025
a63024a
service decorator: refactor
dandavison Jun 15, 2025
c92d4c2
Cleanup
dandavison Jun 16, 2025
abb05cc
Use default Operation constructor
dandavison Jun 15, 2025
23b3fa6
Use get_annotations shim
dandavison Jun 15, 2025
45c076a
Refactor
dandavison Jun 15, 2025
810d0cb
Refactor
dandavison Jun 15, 2025
4371d45
Refactor: ServiceDefinition.from_user_clas
dandavison Jun 15, 2025
3548e04
Use ServiceDefinition if already computed
dandavison Jun 15, 2025
d604a66
Use first operation encountered in mro
dandavison Jun 15, 2025
8fd0f06
Refactor: recursion
dandavison Jun 16, 2025
d86d67e
Test: use different input and output types
dandavison Jun 16, 2025
38e5a91
Validate service definition on creation
dandavison Jun 16, 2025
e48eb12
Support sync and async users
dandavison Jun 16, 2025
d443b29
Evolve collection of operations
dandavison Jun 17, 2025
8c06955
Collect operations from attributes as well as annotations
dandavison Jun 17, 2025
e93c4c0
Refactor
dandavison Jun 17, 2025
1b6fd90
Fixups
dandavison Jun 17, 2025
7280381
Use keys throughout; map to name overrides at end
dandavison Jun 17, 2025
a063676
Fix operation merge edge case
dandavison Jun 17, 2025
ef55dad
Move Link and OperationInfo to top-level
dandavison Jun 17, 2025
b632074
Reorganize directory structure
dandavison Jun 17, 2025
1df5c7e
Revert handler rename
dandavison Jun 18, 2025
cefb8fd
Import order
dandavison Jun 19, 2025
311eda4
Rename: SyncExecutor -> Executor
dandavison Jun 19, 2025
0bd864b
TODO: Executor
dandavison Jun 19, 2025
ca7af9a
Do not require Executor wrapper
dandavison Jun 19, 2025
e4652de
Rename with Sync/Async suffixes
dandavison Jun 19, 2025
5b659d9
Reorganize
dandavison Jun 19, 2025
449f28a
Upgrade ruff
dandavison Jun 19, 2025
bbd6bff
combine-as-imports formatter config
dandavison Jun 20, 2025
1e4d8fe
Backport inspect.get_annotations from 3.13.5
dandavison Jun 21, 2025
996da25
Unskip test
dandavison Jun 21, 2025
7255c49
Docstring
dandavison Jun 22, 2025
05fc6fe
Cleanup
dandavison Jun 22, 2025
ba86bdd
Default to async
dandavison Jun 23, 2025
96e1618
Refactor types
dandavison Jun 23, 2025
af99478
Switch to SyncOperationHandler
dandavison Jun 23, 2025
3aaa53a
s/start_method/start/
dandavison Jun 23, 2025
f5a1cae
Implement fetch_operation_info and fetch_operation_result on Handler
dandavison Jun 24, 2025
043f4af
Update get_start_method_input_and_output_types_annotations
dandavison Jun 24, 2025
95f7874
Delete unused get_start_method types utility
dandavison Jun 24, 2025
8c3be18
Switch to SyncOperationHandler.from_callable
dandavison Jun 25, 2025
721f3d1
Rename test
dandavison Jun 25, 2025
770ffbc
Move OperationInfo to top level
dandavison Jun 25, 2025
5a88b85
Cleanup
dandavison Jun 25, 2025
a60cb3a
Test all operation methods
dandavison Jun 25, 2025
964a99a
Cleanup
dandavison Jun 25, 2025
69c501d
Cleanup
dandavison Jun 25, 2025
b6e792c
Revert "Delete unused get_start_method types utility"
dandavison Jun 25, 2025
a938cfd
New version of sync_operation decorator
dandavison Jun 25, 2025
ef3aeb9
Support name override, add overloads
dandavison Jun 25, 2025
41f1008
Make sync_operation_handler support sync start methods
dandavison Jun 26, 2025
92a4a14
Fix callable instances
dandavison Jun 26, 2025
cb5774b
rename: @sync_operation
dandavison Jun 26, 2025
4bfd25d
Clean up imports in tests
dandavison Jun 26, 2025
68fcac8
Remove @operation_handler from public API for now
dandavison Jun 26, 2025
4a2d19a
CI test on 3.9, 3.13, 3.14
dandavison Jun 26, 2025
ad9791f
Activate vercel publishing of apidocs
dandavison Jun 26, 2025
be8fba2
Start adding README content
dandavison Jun 26, 2025
f4a2f42
uv remove --group dev httpx
dandavison Jun 26, 2025
833a4c6
Make Content.data required
dandavison Jun 26, 2025
549b81f
Rename method: from_user_class -> from_class
dandavison Jun 26, 2025
5f24e15
Relocate OperationError
dandavison Jun 26, 2025
e2cf7fe
Make dataclasses `frozen`
dandavison Jun 26, 2025
cc43cdd
Make OperationContext non-instantiatable
dandavison Jun 26, 2025
3b6500b
Make dataclasses frozen=True
dandavison Jun 26, 2025
e514cdf
Make request ID required
dandavison Jun 26, 2025
2d90830
Eliminate types.module
dandavison Jun 26, 2025
8d875cc
Add FetchOperationResultContext timeout with stub implementation
dandavison Jun 27, 2025
657602e
Cleanup
dandavison Jun 28, 2025
1b3f7d0
Cleanup
dandavison Jun 28, 2025
f98a884
Move DummySerializer
dandavison Jun 28, 2025
60c2c9e
Work around lack of proper subtype compatibility check for parameteri…
dandavison Jun 28, 2025
b3bb2d3
get_service_definition cleanup
dandavison Jun 28, 2025
eaf5913
Make get_service_definition public
dandavison Jun 28, 2025
8b1b1a9
Don't raise in get_service_definition
dandavison Jun 28, 2025
4f22822
Move get_operation_factory
dandavison Jun 28, 2025
1d63015
Fixup operation getters/setters
dandavison Jun 28, 2025
7d466ac
test_request_routing
dandavison Jun 28, 2025
7f3c6e0
Refactor
dandavison Jun 28, 2025
e1f4405
Cleanup
dandavison Jun 28, 2025
4f24094
Failing test
dandavison Jun 28, 2025
6753fc5
Documentation
dandavison Jun 28, 2025
69a88e0
Bug fix: take op name from Operation in service definition
dandavison Jun 28, 2025
02e6010
Bug fix 2
dandavison Jun 28, 2025
b8fe8f6
Test request routing without service definition
dandavison Jun 28, 2025
fcad5b8
Fix tests
dandavison Jun 28, 2025
68f1d0d
Cleanup: collect_operation_handler_factories_by_method_name
dandavison Jun 29, 2025
8776f9d
Cleanups from code review
dandavison Jun 29, 2025
97f22e0
Move HandlerError to root module
dandavison Jun 29, 2025
d5a94b6
Create syncio version of @sync_operation, in syncio module
dandavison Jun 29, 2025
a607809
Cleanup
dandavison Jun 29, 2025
f474c03
Service definition: only inherit operations from decorated classes
dandavison Jun 29, 2025
62193e6
pydoctor
dandavison Jun 29, 2025
5bec150
make pyright pass
dandavison Jun 29, 2025
4b475d3
Make mypy pass
dandavison Jun 29, 2025
42c0f75
Add poe tasks
dandavison Jun 29, 2025
914f507
CI os/python matrix
dandavison Jun 29, 2025
3c6f318
Cleanup
dandavison Jun 29, 2025
bf51ca1
AbstractHandler base class
dandavison Jun 29, 2025
3e736ee
Don't leak operation names on NOT_FOUND
dandavison Jun 29, 2025
b977ba5
Tweak error message
dandavison Jun 29, 2025
f74d2ab
RuntimeError -> ValueError
dandavison Jun 29, 2025
5ace993
Test invalid usage
dandavison Jun 29, 2025
fb2eb4a
Cleanup
dandavison Jun 29, 2025
56306b1
Bug fix: get error when operation definition lacks type params
dandavison Jun 29, 2025
5b255ef
Create parallel syncio tree
dandavison Jun 29, 2025
2675366
HandlerError docstrings and properties
dandavison Jun 29, 2025
2d1ff81
Delete cause
dandavison Jun 29, 2025
62ebe96
poe commands
dandavison Jun 29, 2025
8384e5d
Deploy API docs to GH pages
dandavison Jun 29, 2025
25af294
Docstrings
dandavison Jun 29, 2025
e83999b
TEMP: reduce GHA matrix
dandavison Jun 29, 2025
ec0d892
Don't skip deploy docs
dandavison Jun 29, 2025
903dcfe
Move utils
dandavison Jun 29, 2025
8838a25
Import-time validation of def/async def methods used with sync_operation
dandavison Jun 29, 2025
4bffd37
Remove TODOs
dandavison Jun 30, 2025
a364208
Differentiate syncio/asyncio handlers
dandavison Jun 29, 2025
f2e4ede
Test type checking
dandavison Jun 30, 2025
68ee1db
Docstrings
dandavison Jun 30, 2025
aa35a07
Reorder
dandavison Jun 30, 2025
75dd11c
Add __all__s
dandavison Jun 30, 2025
61b62d8
Examples
dandavison Jun 30, 2025
4ff9844
Add examples
dandavison Jun 30, 2025
812eb59
Only expose intended syncio.handler components
dandavison Jun 30, 2025
829e43a
Update CONTRIBUTING.md
dandavison Jun 30, 2025
95d821e
Revert "TEMP: reduce GHA matrix"
dandavison Jun 30, 2025
375c1f4
ServiceDefinitionT -> ServiceT
dandavison Jun 30, 2025
717bdbe
Docstrings
dandavison Jun 30, 2025
c439b88
Do not expose get_operation_factory
dandavison Jun 30, 2025
c9629c4
Stope doing `as` imports
dandavison Jun 30, 2025
84388d1
Docstring
dandavison Jun 30, 2025
a48958c
Make Content.data non-nullable
dandavison Jun 30, 2025
ba528f0
Move content out of __init__.py
dandavison Jun 30, 2025
963d9c3
Import handler in nexusrpc
dandavison Jun 30, 2025
065faee
Delete spurious check
dandavison Jun 30, 2025
5430973
Failing test of enforcement of method name uniqueness
dandavison Jun 30, 2025
3ea58ff
Enforce method name uniqueness and 1:1 between op_handler and op_defn
dandavison Jun 30, 2025
5fa431a
Remove accidentally exposed utility function
dandavison Jun 30, 2025
56b0c6a
Cleanup
dandavison Jun 30, 2025
72daeab
Add is_callable utility
dandavison Jun 30, 2025
6f6e01a
Support callable instances as operation methods
dandavison Jun 30, 2025
79e08a1
Cleanup
dandavison Jun 30, 2025
e6e2b95
Fix test assertion
dandavison Jun 30, 2025
901ac9b
Skip test
dandavison Jun 30, 2025
d2db821
Add no type annotations invalid usage test
dandavison Jun 30, 2025
112c242
Fix CI test matrix
dandavison Jul 1, 2025
84b288a
Make OperationContext an ABC
dandavison Jul 1, 2025
00b7afa
Fix position of * in signature
dandavison Jul 1, 2025
37e8630
Bump version with explanatory note
dandavison Jul 2, 2025
406e0a9
Capture and assert on warnings in tests
dandavison Jul 2, 2025
d5411e3
Add README note regarding versions
dandavison Jul 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: CI

on:
pull_request:
push:
branches: [ main ]

jobs:
lint-test-docs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ['3.9', '3.13', '3.14']
os: [ubuntu-latest, macos-latest, windows-latest]

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v6
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
uv sync

- name: Lint and type check
run: uv run poe lint

- name: Run tests
run: |
uv run pytest --cov=src --cov-report=html:coverage_html_report

- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-html-report-${{ matrix.os }}-${{ matrix.python-version }}
path: coverage_html_report/

deploy-docs:
runs-on: ubuntu-latest
needs: lint-test-docs
# TODO(preview): deploy on releases only
permissions:
contents: read
pages: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v6
with:
python-version: '3.9'

- name: Install dependencies
run: uv sync

- name: Build API docs
run: uv run poe docs

- name: Upload docs to GitHub Pages
uses: actions/upload-pages-artifact@v3
with:
path: apidocs

- name: Deploy to GitHub Pages
uses: actions/deploy-pages@v4
13 changes: 4 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info

# Virtual environments
__pycache__
.venv
apidocs
dist
docs
1 change: 0 additions & 1 deletion .python-version

This file was deleted.

22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
We will welcome contributions once the SDK has reached a stable release.

### Type-check and lint

```sh
uv run poe lint
```

### Format
```
uv run poe format
```

### Test
```
uv run pytest
```

### API docs
```
uv run poe docs
```
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Temporal Technologies Inc. All Rights Reserved

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Nexus Python SDK

⚠️ **This SDK is currently at an experimental release stage. Backwards-incompatible changes are anticipated until a stable release is announced.** ⚠️

## What is Nexus?

[Nexus](https://github.com/nexus-rpc/) is a synchronous RPC protocol. Arbitrary duration operations are modeled on top of
a set of pre-defined synchronous RPCs.

A Nexus caller calls a handler. The handler may respond inline (synchronous response) or
return a token referencing the ongoing operation (asynchronous response). The caller can
cancel an asynchronous operation, check for its outcome, or fetch its current state. The
caller can also specify a callback URL, which the handler uses to deliver the result of
an asynchronous operation when it is ready.

## Installation

```
uv add nexus-rpc
```
or
```
pip install nexus-rpc
```

## Usage

The SDK currently supports two use cases:

1. As an end user, defining Nexus services and operations.

2. Implementing a Nexus handler that can accept and respond to incoming Nexus requests, dispatching to the corresponding user-defined Nexus operation.

The handler in (2) would form part of a server or worker that processes Nexus requests; the SDK does not yet provide reference implementations of these, or of a Nexus client.

### Defining Nexus services and operations

```python
from dataclasses import dataclass

import nexusrpc
from nexusrpc.handler import StartOperationContext, service_handler, sync_operation
Comment on lines +41 to +42

Choose a reason for hiding this comment

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

Why do you only sometimes import from?

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 hesitate to recommend from nexusrpc import service since it's a common variable name.

Choose a reason for hiding this comment

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

See my suggestion above to export handler from nexusrpc, then you can use nexusrpc.handler.service_handler here without requiring another import statement and this mixed pattern.

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 think we want all our docs and samples to use long names such as @nexusrpc.handler.service_handler and ctx: nexusrpc.handler.StartOperationContext

I have imported handler in nexusrpc for occasions when people want that.



@dataclass
class MyInput:
name: str


@dataclass
class MyOutput:
message: str


@nexusrpc.service
class MyNexusService:
my_sync_operation: nexusrpc.Operation[MyInput, MyOutput]


@service_handler(service=MyNexusService)
class MyNexusServiceHandler:
# You can create an __init__ method accepting what is needed by your operation
# handlers to handle requests. You will typically instantiate your service handler class
# when starting your Nexus server/worker.

# This is a Nexus operation that responds synchronously to all requests. That means
# that the `start` method returns the final operation result.
#
# Sync operations are free to make arbitrary network calls.
@sync_operation
async def my_sync_operation(
self, ctx: StartOperationContext, input: MyInput
) -> MyOutput:
return MyOutput(message=f"Hello {input.name}!")
```


## Note regarding version number
The nexus-rpc name in PyPi was originally held by an unrelated project. Despite the
version being at `v1.x` it is currently at an experimental release stage.
61 changes: 57 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,67 @@
[project]
name = "nexus-rpc"
version = "0.1.0"
# The nexus-rpc name in PyPi was originally held by an unrelated project that reached
# 1.0.1 and was abandoned in 2018. The name was inherited by the Python Nexus SDK in
# 2025 and version numbering started from 1.1.0. Despite the version number, this is an
# experimental release and backwards-incompatible changes are anticipated until a GA
# release is announced.
version = "1.1.0"
description = "Nexus Python SDK"
readme = "README.md"
authors = [
{ name = "Dan Davison", email = "dandavison7@gmail.com" }
{ name = "Temporal Technologies", email = "sdk@temporal.io" }
]
requires-python = ">=3.9"
dependencies = [
"typing-extensions>=4.12.2",
]

[dependency-groups]
dev = [
"mypy>=1.15.0",
"poethepoet>=0.35.0",
"pydoctor>=25.4.0",
"pyright>=1.1.402",
"pytest>=8.3.5",
"pytest-asyncio>=0.26.0",
"pytest-cov>=6.1.1",
"pytest-pretty>=1.3.0",
"ruff>=0.12.0",
]
requires-python = ">=3.13"
dependencies = []

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/nexusrpc"]

[tool.poe.tasks]
lint = [
{cmd = "uv run pyright src"},
{cmd = "uv run mypy --check-untyped-defs src"},
{cmd = "uv run ruff check --select I"},
{cmd = "uv run ruff format --check"},
]
format = [
{cmd = "uv run ruff check --select I --fix"},
{cmd = "uv run ruff format"},
]
docs = [
{cmd = "uv run pydoctor src/nexusrpc"},
]

[tool.pyright]
include = ["src", "tests"]

Choose a reason for hiding this comment

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

Python packages don't typically put code in src, instead they use the name of the package directly (nexusrpc should be in the root folder).

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 is the structure created by uv init --lib and seen in recently created libraries such as https://github.com/anthropics/anthropic-sdk-python
https://github.com/openai/openai-agents-python
https://github.com/openai/openai-python

I'm not expert on the pros and cons, but I guess it leaves open the possibility of supporting multiple roots more cleanly.

Less recently created ones such as pydantic do as you describe.

Copy link

Choose a reason for hiding this comment

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

Yeah I've seen it both ways. I like nexusrpc top-level myself but no strong opinion.

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 have a strong opinion either, so won't change now. It should be a backwards compatible change, of course.

Choose a reason for hiding this comment

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

Hmm... maybe this pattern started being adopted more, I have typically seen Python project not have an src directory.


[tool.mypy]
disable_error_code = ["empty-body"]

[tool.ruff]
target-version = "py39"

[tool.ruff.lint.isort]
combine-as-imports = true

[tool.pydoctor]
docformat = "google"
2 changes: 0 additions & 2 deletions src/nexus_rpc/__init__.py

This file was deleted.

57 changes: 57 additions & 0 deletions src/nexusrpc/__init__.py

Choose a reason for hiding this comment

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

Wonder if we should be exporting handler here too so users can use nexusrpc.handler.service_handler directly without having to import handler separately.

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 was thinking the same. I've done it.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
nexusrpc is a library for building Nexus handlers.

See https://github.com/nexus-rpc and https://github.com/nexus-rpc/api/blob/main/SPEC.md.

Nexus is a synchronous RPC protocol. Arbitrary duration operations are modeled on top of
a set of pre-defined synchronous RPCs.

A Nexus caller calls a handler. The handler may respond inline (synchronous response) or
return a token referencing the ongoing operation (asynchronous response). The caller can
cancel an asynchronous operation, check for its outcome, or fetch its current state. The
caller can also specify a callback URL, which the handler uses to deliver the result of
an asynchronous operation when it is ready.
"""

from __future__ import annotations

from . import handler
from ._common import (
HandlerError,
HandlerErrorType,
InputT,
Link,
OperationError,
OperationErrorState,
OperationInfo,
OperationState,
OutputT,
)
from ._serializer import Content, LazyValue
from ._service import Operation, ServiceDefinition, service
from ._util import (
get_operation_definition,
get_service_definition,
set_operation_definition,
)

__all__ = [
Copy link

Choose a reason for hiding this comment

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

Do users need to be able to access the Serializer and LazyValueT classes?

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 think we're aware of a need for them to: they are just protocols, so structural typing.

"Content",
"get_operation_definition",
"get_service_definition",
"handler",
"HandlerError",
"HandlerErrorType",
"InputT",
"LazyValue",
"Link",
"Operation",
"OperationError",
"OperationErrorState",
"OperationInfo",
"OperationState",
"OutputT",
"service",
"ServiceDefinition",
"set_operation_definition",
]
Loading