From 0771ede354d16e4bf43147be6af1824890a0e610 Mon Sep 17 00:00:00 2001 From: Robert-Jan Huijsman <22160949+rjhuijsman@users.noreply.github.com> Date: Tue, 21 Jul 2026 22:57:29 +0000 Subject: [PATCH 1/3] Codegen: namespace constructors under `factory` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change, constructors lived directly on the state class: a user-defined constructor named `ref` silently collided with the built-in `MyType.ref()`, and the framework could never add a new factory method without risking a clash with an existing user constructor — which a customer could not rename or delete, leaving them permanently unable to upgrade. This commit namespaces every state type's constructor (a.k.a. factory) methods under a `factory` attribute, so `await MyType.create(context)` becomes `await MyType.factory.create(context)`. That frees the top level of the generated state class for framework methods we may want to add later (e.g. a future `MyType.query(...)`), and prevents naming collisions with built-in methods. The way a constructor is declared (`factory=True`, or the `constructor` proto option) is unchanged; only the call surface moved. IMPORTANT REVIEWER HINT: the GitHub diff of the `*.j2` files is big, but very little actually changed: a bunch of methods got indented inside a new `_Factory` class, that's it. For Python that's literally just 4 spaces added to everything, for TS some code had to move to be contiguous but still remains unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_011xyvD8vLQ9dTwtFMexovJo --- reboot/templates/reboot.py.j2 | 473 +++++++-------- reboot/templates/reboot.ts.j2 | 172 +++--- reboot/templates/reboot_web.ts.j2 | 28 +- tests/reboot/echo_rbt.golden.py | 89 +-- tests/reboot/greeter_rbt.golden.js | 73 +-- tests/reboot/greeter_rbt.golden.py | 385 ++++++------ tests/reboot/greeter_rbt_web.golden.js | 11 +- tests/reboot/ping_api_rbt.golden.py | 796 +++++++++++++------------ 8 files changed, 1033 insertions(+), 994 deletions(-) diff --git a/reboot/templates/reboot.py.j2 b/reboot/templates/reboot.py.j2 index 2acaeb46..100577b1 100644 --- a/reboot/templates/reboot.py.j2 +++ b/reboot/templates/reboot.py.j2 @@ -3113,7 +3113,7 @@ class {{ state.proto.name }}BaseServicer(IMPORT_reboot_aio_servicers.Servicer): f"urn:dev.reboot:auto-construct:{{ state.proto.name }}:{state_id}", ) try: - await {{ state.proto.name }}.idempotently( + await {{ state.proto.name }}.factory.idempotently( key=idempotency_key, ).{{ AUTO_CONSTRUCT_METHOD }}(context, state_id) except {{ state.proto.name }}.{{ AUTO_CONSTRUCT_PROTO_METHOD }}Aborted as aborted: @@ -7116,268 +7116,271 @@ class {{ client.proto.state_name }}: bearer_token=bearer_token, ) - {% for service in client.services %} - {% for method in service.methods %} - {%- if method.options.proto.kind == 'workflow' %} - {# TODO(benh): support constructor "tasks" and workflows. #} - {%- else %} - {% if method.options.proto.constructor %} - {# If there are no 'input_type_fields', we will have the same function signature, - so no overloads are needed. If there is 'None', 'input_type_fields' will be - already empty.#} - {% if method.input_type_fields | length > 0 %} - @IMPORT_typing.overload - @classmethod - async def {{ method.proto.name }}( - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | {{ client.proto.state_name }}.{{ method.proto.name }}Request] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[{{ client.proto.state_name }}.{{ method.proto.name }}Request | IMPORT_reboot_aio_call.Options] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - ) -> tuple[{{ client.proto.state_name }}.WeakReference, {% if method.has_non_none_response %}{{ client.proto.state_name }}.{{ method.proto.name }}Response{% else %}None{% endif %}]: - ... - - @IMPORT_typing.overload - @classmethod - async def {{ method.proto.name }}( - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | IMPORT_reboot_aio_call.Options] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - {% for name, type in method.input_type_fields.items() %} - {% if loop.first %} - *, - {% endif %} - {% if options.proto.pydantic %} - {{ name }}: {{ type }} | Unset = UNSET, - {% else %} - {{ name }}: IMPORT_typing.Optional[{{ type }}] | Unset = UNSET, - {% endif %} - {% endfor %} - ) -> tuple[{{ client.proto.state_name }}.WeakReference, {% if method.has_non_none_response %}{{ client.proto.state_name }}.{{ method.proto.name }}Response{% else %}None{% endif %}]: - ... - {% endif %} + class _Factory: + {% for service in client.services %} + {% for method in service.methods %} + {%- if method.options.proto.kind == 'workflow' %} + {# TODO(benh): support constructor "tasks" and workflows. #} + {%- else %} + {% if method.options.proto.constructor %} + {# If there are no 'input_type_fields', we will have the same function signature, + so no overloads are needed. If there is 'None', 'input_type_fields' will be + already empty.#} + {% if method.input_type_fields | length > 0 %} + @IMPORT_typing.overload + @classmethod + async def {{ method.proto.name }}( + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | {{ client.proto.state_name }}.{{ method.proto.name }}Request] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[{{ client.proto.state_name }}.{{ method.proto.name }}Request | IMPORT_reboot_aio_call.Options] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + ) -> tuple[{{ client.proto.state_name }}.WeakReference, {% if method.has_non_none_response %}{{ client.proto.state_name }}.{{ method.proto.name }}Response{% else %}None{% endif %}]: + ... - @classmethod - async def {{ method.proto.name }}( # type: ignore[misc] - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - {% if method.has_non_none_request %} - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | {{ client.proto.state_name }}.{{ method.proto.name }}Request | IMPORT_reboot_aio_call.Options] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[{{ client.proto.state_name }}.{{ method.proto.name }}Request | IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - {% for name, type in method.input_type_fields.items() %} - {% if loop.first %} - *, - {% endif %} - {% if options.proto.pydantic %} - {{ name }}: {{ type }} | Unset = UNSET, - {% else %} - {{ name }}: IMPORT_typing.Optional[{{ type }}] | Unset = UNSET, - {% endif %} - {% endfor %} - {% else %} - __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None, - __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None, - __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + @IMPORT_typing.overload + @classmethod + async def {{ method.proto.name }}( + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | IMPORT_reboot_aio_call.Options] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + {% for name, type in method.input_type_fields.items() %} + {% if loop.first %} + *, + {% endif %} + {% if options.proto.pydantic %} + {{ name }}: {{ type }} | Unset = UNSET, + {% else %} + {{ name }}: IMPORT_typing.Optional[{{ type }}] | Unset = UNSET, + {% endif %} + {% endfor %} + ) -> tuple[{{ client.proto.state_name }}.WeakReference, {% if method.has_non_none_response %}{{ client.proto.state_name }}.{{ method.proto.name }}Response{% else %}None{% endif %}]: + ... {% endif %} - ) -> tuple[{{ client.proto.state_name }}.WeakReference, {% if method.has_non_none_response %}{{ client.proto.state_name }}.{{ method.proto.name }}Response{% else %}None{% endif %}]: - # Within a `workflow`, all "bare" calls are - # `per_workflow()` calls, unless we're within a control - # loop, in which case they are syntactic sugar for - # `per_iteration()`. - # - # Unless we are "within until" in which case all "bare" - # calls are `.always()`. - {% if method.has_non_none_request %} - __request__: IMPORT_typing.Optional[{{ client.proto.state_name }}.{{ method.proto.name }}Request] = None - __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None - __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None - - if isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_types.StateId): - __state_id__ = __state_id_or_request_or_options__ - if isinstance(__request_or_options_or_idempotency__, {{ client.proto.state_name }}.{{ method.proto.name }}Request): - __request__ = __request_or_options_or_idempotency__ - assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_call.Options) - __options__ = __options_or_idempotency__ - assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + @classmethod + async def {{ method.proto.name }}( # type: ignore[misc] + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + {% if method.has_non_none_request %} + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | {{ client.proto.state_name }}.{{ method.proto.name }}Request | IMPORT_reboot_aio_call.Options] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[{{ client.proto.state_name }}.{{ method.proto.name }}Request | IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + {% for name, type in method.input_type_fields.items() %} + {% if loop.first %} + *, + {% endif %} + {% if options.proto.pydantic %} + {{ name }}: {{ type }} | Unset = UNSET, + {% else %} + {{ name }}: IMPORT_typing.Optional[{{ type }}] | Unset = UNSET, + {% endif %} + {% endfor %} + {% else %} + __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None, + __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None, + __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + {% endif %} + ) -> tuple[{{ client.proto.state_name }}.WeakReference, {% if method.has_non_none_response %}{{ client.proto.state_name }}.{{ method.proto.name }}Response{% else %}None{% endif %}]: + # Within a `workflow`, all "bare" calls are + # `per_workflow()` calls, unless we're within a control + # loop, in which case they are syntactic sugar for + # `per_iteration()`. + # + # Unless we are "within until" in which case all "bare" + # calls are `.always()`. - {# When specifying __request__ directly, we need to ensure that all other input fields are 'UNSET'. #} - {% for name in method.input_type_fields %} - assert {{ name }} is UNSET - {% endfor %} - else: + {% if method.has_non_none_request %} + __request__: IMPORT_typing.Optional[{{ client.proto.state_name }}.{{ method.proto.name }}Request] = None + __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None + __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None + + if isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_types.StateId): + __state_id__ = __state_id_or_request_or_options__ + if isinstance(__request_or_options_or_idempotency__, {{ client.proto.state_name }}.{{ method.proto.name }}Request): + __request__ = __request_or_options_or_idempotency__ + assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_call.Options) + __options__ = __options_or_idempotency__ + assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + + {# When specifying __request__ directly, we need to ensure that all other input fields are 'UNSET'. #} + {% for name in method.input_type_fields %} + assert {{ name }} is UNSET + {% endfor %} + else: + assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) + __options__ = __request_or_options_or_idempotency__ + assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + __idempotency__ = __options_or_idempotency__ + + __request__ = {{ client.proto.state_name }}{{ method.proto.name }}RequestFromInputFields( + {% for name in method.input_type_fields %} + {{ name }}={{ name }}, + {% endfor %} + ) + elif isinstance(__state_id_or_request_or_options__, {{ client.proto.state_name }}.{{ method.proto.name }}Request): + __request__ = __state_id_or_request_or_options__ assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) __options__ = __request_or_options_or_idempotency__ assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) __idempotency__ = __options_or_idempotency__ + else: + assert ( + __state_id_or_request_or_options__ is None + or isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_call.Options) + ), "Invalid argument type. Did you pass:\n" \ + " - A 'state_id' that is not of type 'reboot.aio.types.StateId'?\n" \ + " - 'options' that are not of type 'reboot.aio.call.Options'?" + __options__ = __state_id_or_request_or_options__ + assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + __idempotency__ = __request_or_options_or_idempotency__ __request__ = {{ client.proto.state_name }}{{ method.proto.name }}RequestFromInputFields( {% for name in method.input_type_fields %} {{ name }}={{ name }}, {% endfor %} ) - elif isinstance(__state_id_or_request_or_options__, {{ client.proto.state_name }}.{{ method.proto.name }}Request): - __request__ = __state_id_or_request_or_options__ - assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) - __options__ = __request_or_options_or_idempotency__ - assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - __idempotency__ = __options_or_idempotency__ - else: - assert ( - __state_id_or_request_or_options__ is None - or isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_call.Options) - ), "Invalid argument type. Did you pass:\n" \ - " - A 'state_id' that is not of type 'reboot.aio.types.StateId'?\n" \ - " - 'options' that are not of type 'reboot.aio.call.Options'?" - __options__ = __state_id_or_request_or_options__ - assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - __idempotency__ = __request_or_options_or_idempotency__ - - __request__ = {{ client.proto.state_name }}{{ method.proto.name }}RequestFromInputFields( - {% for name in method.input_type_fields %} - {{ name }}={{ name }}, - {% endfor %} - ) - {% else %} - assert __state_id__ is None or isinstance(__state_id__, IMPORT_reboot_aio_types.StateId) - assert __options__ is None or isinstance(__options__, IMPORT_reboot_aio_call.Options) - assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - {% endif %} + {% else %} + assert __state_id__ is None or isinstance(__state_id__, IMPORT_reboot_aio_types.StateId) + assert __options__ is None or isinstance(__options__, IMPORT_reboot_aio_call.Options) + assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + {% endif %} - if __idempotency__ is None: - __args__: tuple[IMPORT_typing.Any, ...] = ( - __context__, - ) - if __state_id__ is not None: - # Don't include `state_id` if it is `None`, so that - # we won't break the positional argument deduction. - __args__ += (__state_id__,) - __args__ += ( - {% if method.has_non_none_request %} - __request__, - {% endif %} - __options__, - ) - if isinstance(__context__, IMPORT_reboot_aio_contexts.WorkflowContext): - return await ( - __cls__.always() if __context__.within_until() - else ( - __cls__.per_iteration() if __context__.within_loop() - else __cls__.per_workflow() - ) - ).{{ method.proto.name }}( - *__args__ + if __idempotency__ is None: + __args__: tuple[IMPORT_typing.Any, ...] = ( + __context__, ) - elif isinstance(__context__, IMPORT_reboot_aio_external.InitializeContext): - return await __cls__.idempotently().{{ method.proto.name }}( - *__args__ + if __state_id__ is not None: + # Don't include `state_id` if it is `None`, so that + # we won't break the positional argument deduction. + __args__ += (__state_id__,) + __args__ += ( + {% if method.has_non_none_request %} + __request__, + {% endif %} + __options__, ) + if isinstance(__context__, IMPORT_reboot_aio_contexts.WorkflowContext): + return await ( + __cls__.always() if __context__.within_until() + else ( + __cls__.per_iteration() if __context__.within_loop() + else __cls__.per_workflow() + ) + ).{{ method.proto.name }}( + *__args__ + ) + elif isinstance(__context__, IMPORT_reboot_aio_external.InitializeContext): + return await __cls__.idempotently().{{ method.proto.name }}( + *__args__ + ) + + __metadata__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.GrpcMetadata] = None + __bearer_token__: IMPORT_typing.Optional[str] = None - __metadata__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.GrpcMetadata] = None - __bearer_token__: IMPORT_typing.Optional[str] = None + if __options__ is not None: + IMPORT_reboot_aio_types.assert_type(__options__, [IMPORT_reboot_aio_call.Options]) + if __options__.metadata is not None: + __metadata__ = __options__.metadata + if __options__.bearer_token is not None: + __bearer_token__ = __options__.bearer_token - if __options__ is not None: - IMPORT_reboot_aio_types.assert_type(__options__, [IMPORT_reboot_aio_call.Options]) - if __options__.metadata is not None: - __metadata__ = __options__.metadata - if __options__.bearer_token is not None: - __bearer_token__ = __options__.bearer_token + if __state_id__ is None: + if __idempotency__ is None: + __state_id__ = str(IMPORT_uuid.uuid4()) + else: + __state_id__ = __context__.generate_idempotent_state_id( + state_type_name={{ client.proto.state_name }}.__state_type_name__, + service_name=IMPORT_reboot_aio_types.ServiceName('{{ service.proto.full_name }}'), + method='{{ method.proto.name }}', + idempotency=__idempotency__, + ) - if __state_id__ is None: - if __idempotency__ is None: - __state_id__ = str(IMPORT_uuid.uuid4()) - else: - __state_id__ = __context__.generate_idempotent_state_id( - state_type_name=__cls__.__state_type_name__, - service_name=IMPORT_reboot_aio_types.ServiceName('{{ service.proto.full_name }}'), - method='{{ method.proto.name }}', - idempotency=__idempotency__, - ) + __reference__ = {{ client.proto.state_name }}.ref( + __state_id__, bearer_token=__bearer_token__ + ) + {% if method.options.proto.kind == 'writer' %} + __stub__ = __reference__._writer(__context__) + {% elif method.options.proto.kind == 'transaction' %} + __stub__ = __reference__._workflow(__context__) + {% endif %} + return ( + __reference__, + {{ client.proto.state_name }}{{ method.proto.name }}ResponseFromProto( + await __stub__.{{ method.proto.name }}( + {% if method.has_non_none_request %} + __request__, + {% endif %} + idempotency=__idempotency__, + metadata=__metadata__, + bearer_token=__bearer_token__, + ) + ), + ) - __reference__ = {{ client.proto.state_name }}.ref( - __state_id__, bearer_token=__bearer_token__ - ) - {% if method.options.proto.kind == 'writer' %} - __stub__ = __reference__._writer(__context__) - {% elif method.options.proto.kind == 'transaction' %} - __stub__ = __reference__._workflow(__context__) + # Keep the original functions on the client, so old code will + # continue to work, but use the new 'snake_case' method in + # the new code. + {{ method.proto.name | to_snake }} = {{ method.proto.name }} {% endif %} - return ( - __reference__, - {{ client.proto.state_name }}{{ method.proto.name }}ResponseFromProto( - await __stub__.{{ method.proto.name }}( - {% if method.has_non_none_request %} - __request__, - {% endif %} - idempotency=__idempotency__, - metadata=__metadata__, - bearer_token=__bearer_token__, - ) - ), - ) + {% endif %} + {% endfor %} + {% endfor %} - # Keep the original functions on the client, so old code will - # continue to work, but use the new 'snake_case' method in - # the new code. - {{ method.proto.name | to_snake }} = {{ method.proto.name }} - {% endif %} - {% endif %} - {% endfor %} - {% endfor %} + @IMPORT_typing.overload + @classmethod + def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> {{ client.proto.state_name }}._ConstructIdempotently: + ... - @IMPORT_typing.overload - @classmethod - def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> {{ client.proto.state_name }}._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> {{ client.proto.state_name }}._ConstructIdempotently: + ... - @IMPORT_typing.overload - @classmethod - def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> {{ client.proto.state_name }}._ConstructIdempotently: - ... + @classmethod + def idempotently( + cls, + alias: IMPORT_typing.Optional[str] = None, + *, + key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, + how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, + ) -> {{ client.proto.state_name }}._ConstructIdempotently: + return {{ client.proto.state_name }}._ConstructIdempotently( + _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( + alias=alias, + key=key, + how=how, + ), + ) - @classmethod - def idempotently( - cls, - alias: IMPORT_typing.Optional[str] = None, - *, - key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, - how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, - ) -> {{ client.proto.state_name }}._ConstructIdempotently: - return {{ client.proto.state_name }}._ConstructIdempotently( - _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( - alias=alias, - key=key, - how=how, - ), - ) + @classmethod + def per_workflow( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently(alias) - @classmethod - def per_workflow( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently(alias) + @classmethod + def per_iteration( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently( + alias, + how=IMPORT_reboot_aio_idempotency.PER_ITERATION, + ) - @classmethod - def per_iteration( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently( - alias, - how=IMPORT_reboot_aio_idempotency.PER_ITERATION, - ) + @classmethod + def always(cls): + return cls.idempotently( + how=IMPORT_reboot_aio_idempotency.ALWAYS, + ) - @classmethod - def always(cls): - return cls.idempotently( - how=IMPORT_reboot_aio_idempotency.ALWAYS, - ) + factory = _Factory @IMPORT_dataclasses.dataclass(frozen=True) class _ConstructIdempotently: @@ -7522,7 +7525,7 @@ class {{ client.proto.state_name }}: __this__._idempotency, ) - return await {{ client.proto.state_name }}.{{ method.proto.name }}( + return await {{ client.proto.state_name }}.factory.{{ method.proto.name }}( *__args__, ) diff --git a/reboot/templates/reboot.ts.j2 b/reboot/templates/reboot.ts.j2 index 193b2104..a407abba 100644 --- a/reboot/templates/reboot.ts.j2 +++ b/reboot/templates/reboot.ts.j2 @@ -2200,62 +2200,7 @@ export class {{ client.proto.state_name }}WeakReference { } } -export class {{ client.proto.state_name }} { - - {% if client.state is not none %} - static singleton = { Servicer: {{ client.proto.state_name }}SingletonServicer }; - static Servicer = {{ client.proto.state_name }}Servicer; - static servicer = {{ client.proto.state_name }}BaseServicer.servicer; - static State = {{ client.proto.state_name }}State; - static Authorizer = {{ client.proto.state_name }}Authorizer; - {% endif %} - static WeakReference = {{ client.proto.state_name }}WeakReference; - - {% for service in client.services %} - {% for method in service.methods %} - - static {{ method.proto.name }}Aborted = {{ client.proto.state_name }}{{ method.proto.name }}Aborted; - - static {{ method.proto.name }}Task = {{ client.proto.state_name }}{{ method.proto.name }}Task; - - {% endfor %} - {% endfor %} - - public static ref( - idOrOptions?: string | { bearerToken?: string | null }, - options?: { bearerToken?: string | null } - ) { - if (idOrOptions === undefined || typeof idOrOptions === "object") { - const context = reboot.getContext(); - if (context instanceof WorkflowContext) { - // We support calling `{{ client.proto.state_name }}.ref()` with - // no `id` __only__ inside a workflow to be able to call an - // inline writer, inline reader or other method call, since - // workflow is a `static` and therefor we can't get a - // reference to outselves as `this.ref()`. - const servicer = {{ client.proto.state_name }}BaseServicer.__servicer__.getStore()?.servicer; - - {# We temporary don't assert that servicer is not undefined - because we still support old style workflow methods, when we - complete the migration we should remove this check. #} - if (servicer !== undefined) { - return new {{ client.proto.state_name }}.WeakReference( - context.stateId, - idOrOptions?.bearerToken, - servicer, - ); - } - } - return new {{ client.proto.state_name }}.WeakReference(context.stateId, idOrOptions?.bearerToken); - } - if (typeof idOrOptions !== "string") { - throw new TypeError( - `Expecting first argument to be a 'string' "id", ` + - `got '${typeof idOrOptions}'` - ); - } - return new {{ client.proto.state_name }}.WeakReference(idOrOptions, options?.bearerToken); - } +export class {{ client.proto.state_name }}Factory { {% for service in client.services %} {% for method in service.methods %} @@ -2263,7 +2208,7 @@ export class {{ client.proto.state_name }} { {# TODO(benh): support constructor "tasks" and workflows. #} {%- else %} {% if method.options.proto.constructor %} - public async {{ method.proto.name | to_lower_camel }}( + static async {{ method.proto.name | to_lower_camel }}( context: reboot.TransactionContext | reboot.WorkflowContext | reboot.ExternalContext, partialRequest?: {{ client.proto.state_name }}.Partial{{ method.proto.name }}Request, options?: { bearerToken?: string | null } @@ -2276,7 +2221,7 @@ export class {{ client.proto.state_name }} { {% endif %} ]>; - public async {{ method.proto.name | to_lower_camel }}( + static async {{ method.proto.name | to_lower_camel }}( context: reboot.TransactionContext | reboot.WorkflowContext | reboot.ExternalContext, id: string, partialRequest?: {{ client.proto.state_name }}.Partial{{ method.proto.name }}Request, @@ -2290,7 +2235,7 @@ export class {{ client.proto.state_name }} { {% endif %} ]>; - public static async {{ method.proto.name | to_lower_camel }}( + static async {{ method.proto.name | to_lower_camel }}( context: reboot.TransactionContext | reboot.WorkflowContext | reboot.ExternalContext, idOrPartialRequest?: string | {{ client.proto.state_name }}.Partial{{ method.proto.name }}Request, partialRequestOrOptions?: {{ client.proto.state_name }}.Partial{{ method.proto.name }}Request | { bearerToken?: string | null }, @@ -2316,7 +2261,7 @@ export class {{ client.proto.state_name }} { options = partialRequestOrOptions; if (optionsOrUndefined !== undefined) { throw new Error( - `Invalid arguments passed to '{{ client.proto.state_name }}.{{ method.proto.name | to_lower_camel }}'` + `Invalid arguments passed to '{{ client.proto.state_name }}.factory.{{ method.proto.name | to_lower_camel }}'` ); } } @@ -2325,8 +2270,8 @@ export class {{ client.proto.state_name }} { if (context instanceof WorkflowContext) { return await ( reboot.isWithinLoop() - ? {{ client.proto.state_name }}.perIteration() - : {{ client.proto.state_name }}.perWorkflow() + ? {{ client.proto.state_name }}.factory.perIteration() + : {{ client.proto.state_name }}.factory.perWorkflow() ).{{ method.proto.name | to_lower_camel }}( context, idOrPartialRequest, @@ -2334,7 +2279,7 @@ export class {{ client.proto.state_name }} { optionsOrUndefined ); } else if (context instanceof InitializeContext) { - return await {{ client.proto.state_name }}.idempotently() + return await {{ client.proto.state_name }}.factory.idempotently() .{{ method.proto.name | to_lower_camel }}( context, idOrPartialRequest, @@ -2366,6 +2311,86 @@ export class {{ client.proto.state_name }} { {% endif %} {% endfor %} {% endfor %} + static idempotently(aliasOrOptions: string | reboot_api.IdempotencyOptions = {} as reboot_api.IdempotencyOptions) { + const idempotency = (typeof aliasOrOptions === "string" || aliasOrOptions instanceof String) ? { alias: aliasOrOptions as string } : aliasOrOptions; + return new {{ client.proto.state_name }}._ConstructIdempotently(idempotency); + } + + static perWorkflow(alias?: string) { + return {{ client.proto.state_name }}.factory + .idempotently({ alias }); + } + + static perIteration(alias?: string) { + return {{ client.proto.state_name }}.factory + .idempotently({ alias, perIteration: true }); + } + + static always() { + return {{ client.proto.state_name }}.factory + .idempotently({ always: true }); + } +} + +export class {{ client.proto.state_name }} { + + {% if client.state is not none %} + static singleton = { Servicer: {{ client.proto.state_name }}SingletonServicer }; + static Servicer = {{ client.proto.state_name }}Servicer; + static servicer = {{ client.proto.state_name }}BaseServicer.servicer; + static State = {{ client.proto.state_name }}State; + static Authorizer = {{ client.proto.state_name }}Authorizer; + {% endif %} + static WeakReference = {{ client.proto.state_name }}WeakReference; + + {% for service in client.services %} + {% for method in service.methods %} + + static {{ method.proto.name }}Aborted = {{ client.proto.state_name }}{{ method.proto.name }}Aborted; + + static {{ method.proto.name }}Task = {{ client.proto.state_name }}{{ method.proto.name }}Task; + + {% endfor %} + {% endfor %} + + static factory = {{ client.proto.state_name }}Factory; + + public static ref( + idOrOptions?: string | { bearerToken?: string | null }, + options?: { bearerToken?: string | null } + ) { + if (idOrOptions === undefined || typeof idOrOptions === "object") { + const context = reboot.getContext(); + if (context instanceof WorkflowContext) { + // We support calling `{{ client.proto.state_name }}.ref()` with + // no `id` __only__ inside a workflow to be able to call an + // inline writer, inline reader or other method call, since + // workflow is a `static` and therefor we can't get a + // reference to outselves as `this.ref()`. + const servicer = {{ client.proto.state_name }}BaseServicer.__servicer__.getStore()?.servicer; + + {# We temporary don't assert that servicer is not undefined + because we still support old style workflow methods, when we + complete the migration we should remove this check. #} + if (servicer !== undefined) { + return new {{ client.proto.state_name }}.WeakReference( + context.stateId, + idOrOptions?.bearerToken, + servicer, + ); + } + } + return new {{ client.proto.state_name }}.WeakReference(context.stateId, idOrOptions?.bearerToken); + } + if (typeof idOrOptions !== "string") { + throw new TypeError( + `Expecting first argument to be a 'string' "id", ` + + `got '${typeof idOrOptions}'` + ); + } + return new {{ client.proto.state_name }}.WeakReference(idOrOptions, options?.bearerToken); + } + static _Forall = class { #ids: string[]; @@ -2410,25 +2435,6 @@ export class {{ client.proto.state_name }} { return new {{ client.proto.state_name }}._Forall(ids); } - public static idempotently(aliasOrOptions: string | reboot_api.IdempotencyOptions = {} as reboot_api.IdempotencyOptions) { - const idempotency = (typeof aliasOrOptions === "string" || aliasOrOptions instanceof String) ? { alias: aliasOrOptions as string } : aliasOrOptions; - return new {{ client.proto.state_name }}._ConstructIdempotently(idempotency); - } - - public static perWorkflow(alias?: string) { - return {{ client.proto.state_name }} - .idempotently({ alias }); - } - - public static perIteration(alias?: string) { - return {{ client.proto.state_name }} - .idempotently({ alias, perIteration: true }); - } - - public static always() { - return {{ client.proto.state_name }} - .idempotently({ always: true }); - } static _ConstructIdempotently = class { #idempotency: reboot_api.IdempotencyOptions; @@ -2510,7 +2516,7 @@ export class {{ client.proto.state_name }} { ) as string; } - return await {{ client.proto.state_name }}.{{ method.proto.name | to_lower_camel }}( + return await {{ client.proto.state_name }}.factory.{{ method.proto.name | to_lower_camel }}( context, id, partialRequest, diff --git a/reboot/templates/reboot_web.ts.j2 b/reboot/templates/reboot_web.ts.j2 index ee651f66..dd60fcc1 100644 --- a/reboot/templates/reboot_web.ts.j2 +++ b/reboot/templates/reboot_web.ts.j2 @@ -592,23 +592,14 @@ export class {{ client.proto.state_name }}WeakReference { {% endfor %} } -export class {{ client.proto.state_name }} { - - static WeakReference = {{ client.proto.state_name }}WeakReference; - - public static ref( - id: string, - options?: { bearerToken?: string } - ) { - return new {{ client.proto.state_name }}.WeakReference(id, options?.bearerToken); - } +export class {{ client.proto.state_name }}Factory { {% for service in client.services %} {% for method in service.methods %} {%- if method.options.proto.kind == 'workflow' %} {# TODO(benh): support "tasks" and workflows. #} {% elif method.options.proto.constructor %} - public static async {{ method.proto.name | to_lower_camel }}( + static async {{ method.proto.name | to_lower_camel }}( context: reboot_web.WebContext, idOrPartialRequest?: string | {{ client.proto.state_name }}.Partial{{ method.proto.name }}Request, inputPartialRequest?: {{ client.proto.state_name }}.Partial{{ method.proto.name }}Request, @@ -649,6 +640,21 @@ export class {{ client.proto.state_name }} { {% endif %} {% endfor %} {% endfor %} +} + +export class {{ client.proto.state_name }} { + + static WeakReference = {{ client.proto.state_name }}WeakReference; + + static factory = {{ client.proto.state_name }}Factory; + + public static ref( + id: string, + options?: { bearerToken?: string } + ) { + return new {{ client.proto.state_name }}.WeakReference(id, options?.bearerToken); + } + } diff --git a/tests/reboot/echo_rbt.golden.py b/tests/reboot/echo_rbt.golden.py index 58d0ad54..fad1f614 100755 --- a/tests/reboot/echo_rbt.golden.py +++ b/tests/reboot/echo_rbt.golden.py @@ -28727,55 +28727,58 @@ def ref( bearer_token=bearer_token, ) + class _Factory: - @IMPORT_typing.overload - @classmethod - def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Echo._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Echo._ConstructIdempotently: + ... - @IMPORT_typing.overload - @classmethod - def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Echo._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Echo._ConstructIdempotently: + ... - @classmethod - def idempotently( - cls, - alias: IMPORT_typing.Optional[str] = None, - *, - key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, - how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, - ) -> Echo._ConstructIdempotently: - return Echo._ConstructIdempotently( - _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( - alias=alias, - key=key, - how=how, - ), - ) + @classmethod + def idempotently( + cls, + alias: IMPORT_typing.Optional[str] = None, + *, + key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, + how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, + ) -> Echo._ConstructIdempotently: + return Echo._ConstructIdempotently( + _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( + alias=alias, + key=key, + how=how, + ), + ) - @classmethod - def per_workflow( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently(alias) + @classmethod + def per_workflow( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently(alias) - @classmethod - def per_iteration( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently( - alias, - how=IMPORT_reboot_aio_idempotency.PER_ITERATION, - ) + @classmethod + def per_iteration( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently( + alias, + how=IMPORT_reboot_aio_idempotency.PER_ITERATION, + ) - @classmethod - def always(cls): - return cls.idempotently( - how=IMPORT_reboot_aio_idempotency.ALWAYS, - ) + @classmethod + def always(cls): + return cls.idempotently( + how=IMPORT_reboot_aio_idempotency.ALWAYS, + ) + + factory = _Factory @IMPORT_dataclasses.dataclass(frozen=True) class _ConstructIdempotently: diff --git a/tests/reboot/greeter_rbt.golden.js b/tests/reboot/greeter_rbt.golden.js index 0a69e314..51f37ce4 100755 --- a/tests/reboot/greeter_rbt.golden.js +++ b/tests/reboot/greeter_rbt.golden.js @@ -5298,29 +5298,7 @@ GreeterWeakReference._Spawn = (_g = class { _weakReference_2 = new WeakMap(), _options_2 = new WeakMap(), _g); -export class Greeter { - static ref(idOrOptions, options) { - if (idOrOptions === undefined || typeof idOrOptions === "object") { - const context = reboot.getContext(); - if (context instanceof WorkflowContext) { - // We support calling `Greeter.ref()` with - // no `id` __only__ inside a workflow to be able to call an - // inline writer, inline reader or other method call, since - // workflow is a `static` and therefor we can't get a - // reference to outselves as `this.ref()`. - const servicer = GreeterBaseServicer.__servicer__.getStore()?.servicer; - if (servicer !== undefined) { - return new Greeter.WeakReference(context.stateId, idOrOptions?.bearerToken, servicer); - } - } - return new Greeter.WeakReference(context.stateId, idOrOptions?.bearerToken); - } - if (typeof idOrOptions !== "string") { - throw new TypeError(`Expecting first argument to be a 'string' "id", ` + - `got '${typeof idOrOptions}'`); - } - return new Greeter.WeakReference(idOrOptions, options?.bearerToken); - } +export class GreeterFactory { static async create(context, idOrPartialRequest, partialRequestOrOptions, optionsOrUndefined) { let id = undefined; let partialRequest = undefined; @@ -5334,17 +5312,17 @@ export class Greeter { partialRequest = idOrPartialRequest; options = partialRequestOrOptions; if (optionsOrUndefined !== undefined) { - throw new Error(`Invalid arguments passed to 'Greeter.create'`); + throw new Error(`Invalid arguments passed to 'Greeter.factory.create'`); } } if (options === undefined || !("idempotency" in options)) { if (context instanceof WorkflowContext) { return await (reboot.isWithinLoop() - ? Greeter.perIteration() - : Greeter.perWorkflow()).create(context, idOrPartialRequest, partialRequestOrOptions, optionsOrUndefined); + ? Greeter.factory.perIteration() + : Greeter.factory.perWorkflow()).create(context, idOrPartialRequest, partialRequestOrOptions, optionsOrUndefined); } else if (context instanceof InitializeContext) { - return await Greeter.idempotently() + return await Greeter.factory.idempotently() .create(context, idOrPartialRequest, partialRequestOrOptions, optionsOrUndefined); } } @@ -5358,26 +5336,50 @@ export class Greeter { response, ]; } - static forall(ids) { - return new Greeter._Forall(ids); - } static idempotently(aliasOrOptions = {}) { const idempotency = (typeof aliasOrOptions === "string" || aliasOrOptions instanceof String) ? { alias: aliasOrOptions } : aliasOrOptions; return new Greeter._ConstructIdempotently(idempotency); } static perWorkflow(alias) { - return Greeter + return Greeter.factory .idempotently({ alias }); } static perIteration(alias) { - return Greeter + return Greeter.factory .idempotently({ alias, perIteration: true }); } static always() { - return Greeter + return Greeter.factory .idempotently({ always: true }); } } +export class Greeter { + static ref(idOrOptions, options) { + if (idOrOptions === undefined || typeof idOrOptions === "object") { + const context = reboot.getContext(); + if (context instanceof WorkflowContext) { + // We support calling `Greeter.ref()` with + // no `id` __only__ inside a workflow to be able to call an + // inline writer, inline reader or other method call, since + // workflow is a `static` and therefor we can't get a + // reference to outselves as `this.ref()`. + const servicer = GreeterBaseServicer.__servicer__.getStore()?.servicer; + if (servicer !== undefined) { + return new Greeter.WeakReference(context.stateId, idOrOptions?.bearerToken, servicer); + } + } + return new Greeter.WeakReference(context.stateId, idOrOptions?.bearerToken); + } + if (typeof idOrOptions !== "string") { + throw new TypeError(`Expecting first argument to be a 'string' "id", ` + + `got '${typeof idOrOptions}'`); + } + return new Greeter.WeakReference(idOrOptions, options?.bearerToken); + } + static forall(ids) { + return new Greeter._Forall(ids); + } +} Greeter.singleton = { Servicer: GreeterSingletonServicer }; Greeter.Servicer = GreeterServicer; Greeter.servicer = GreeterBaseServicer.servicer; @@ -5416,6 +5418,7 @@ Greeter.ReadRecursiveMessageAborted = GreeterReadRecursiveMessageAborted; Greeter.ReadRecursiveMessageTask = GreeterReadRecursiveMessageTask; Greeter.ConstructAndStoreRecursiveMessageAborted = GreeterConstructAndStoreRecursiveMessageAborted; Greeter.ConstructAndStoreRecursiveMessageTask = GreeterConstructAndStoreRecursiveMessageTask; +Greeter.factory = GreeterFactory; Greeter._Forall = (_h = class { constructor(ids) { _ids.set(this, void 0); @@ -5490,7 +5493,7 @@ Greeter._ConstructIdempotently = (_j = class { if (id === undefined) { id = await context.generateIdempotentStateId("tests.reboot.Greeter", "tests.reboot.GreeterMethods", "Create", __classPrivateFieldGet(this, _idempotency_1, "f")); } - return await Greeter.create(context, id, partialRequest, { + return await Greeter.factory.create(context, id, partialRequest, { ...options, idempotency: __classPrivateFieldGet(this, _idempotency_1, "f"), }); @@ -5501,6 +5504,6 @@ Greeter._ConstructIdempotently = (_j = class { export function importPys() { reboot_native.importPy("tests.reboot.greeter_pb2", "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"); reboot_native.importPy("tests.reboot.greeter_pb2_grpc", "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"); - reboot_native.importPy("tests.reboot.greeter_rbt", "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"); + reboot_native.importPy("tests.reboot.greeter_rbt", "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"); } importPys(); diff --git a/tests/reboot/greeter_rbt.golden.py b/tests/reboot/greeter_rbt.golden.py index 08db96dd..9417a931 100755 --- a/tests/reboot/greeter_rbt.golden.py +++ b/tests/reboot/greeter_rbt.golden.py @@ -31713,220 +31713,223 @@ def ref( bearer_token=bearer_token, ) - @IMPORT_typing.overload - @classmethod - async def Create( - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | Greeter.CreateRequest] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[Greeter.CreateRequest | IMPORT_reboot_aio_call.Options] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - ) -> tuple[Greeter.WeakReference, Greeter.CreateResponse]: - ... - - @IMPORT_typing.overload - @classmethod - async def Create( - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | IMPORT_reboot_aio_call.Options] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - *, - title: IMPORT_typing.Optional[str] | Unset = UNSET, - name: IMPORT_typing.Optional[str] | Unset = UNSET, - adjective: IMPORT_typing.Optional[str] | Unset = UNSET, - ) -> tuple[Greeter.WeakReference, Greeter.CreateResponse]: - ... + class _Factory: + @IMPORT_typing.overload + @classmethod + async def Create( + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | Greeter.CreateRequest] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[Greeter.CreateRequest | IMPORT_reboot_aio_call.Options] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + ) -> tuple[Greeter.WeakReference, Greeter.CreateResponse]: + ... - @classmethod - async def Create( # type: ignore[misc] - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | Greeter.CreateRequest | IMPORT_reboot_aio_call.Options] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[Greeter.CreateRequest | IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - *, - title: IMPORT_typing.Optional[str] | Unset = UNSET, - name: IMPORT_typing.Optional[str] | Unset = UNSET, - adjective: IMPORT_typing.Optional[str] | Unset = UNSET, - ) -> tuple[Greeter.WeakReference, Greeter.CreateResponse]: - # Within a `workflow`, all "bare" calls are - # `per_workflow()` calls, unless we're within a control - # loop, in which case they are syntactic sugar for - # `per_iteration()`. - # - # Unless we are "within until" in which case all "bare" - # calls are `.always()`. - - __request__: IMPORT_typing.Optional[Greeter.CreateRequest] = None - __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None - __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None - - if isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_types.StateId): - __state_id__ = __state_id_or_request_or_options__ - if isinstance(__request_or_options_or_idempotency__, Greeter.CreateRequest): - __request__ = __request_or_options_or_idempotency__ - assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_call.Options) - __options__ = __options_or_idempotency__ - assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - - assert title is UNSET - assert name is UNSET - assert adjective is UNSET - else: + @IMPORT_typing.overload + @classmethod + async def Create( + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | IMPORT_reboot_aio_call.Options] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + *, + title: IMPORT_typing.Optional[str] | Unset = UNSET, + name: IMPORT_typing.Optional[str] | Unset = UNSET, + adjective: IMPORT_typing.Optional[str] | Unset = UNSET, + ) -> tuple[Greeter.WeakReference, Greeter.CreateResponse]: + ... + + @classmethod + async def Create( # type: ignore[misc] + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | Greeter.CreateRequest | IMPORT_reboot_aio_call.Options] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[Greeter.CreateRequest | IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + *, + title: IMPORT_typing.Optional[str] | Unset = UNSET, + name: IMPORT_typing.Optional[str] | Unset = UNSET, + adjective: IMPORT_typing.Optional[str] | Unset = UNSET, + ) -> tuple[Greeter.WeakReference, Greeter.CreateResponse]: + # Within a `workflow`, all "bare" calls are + # `per_workflow()` calls, unless we're within a control + # loop, in which case they are syntactic sugar for + # `per_iteration()`. + # + # Unless we are "within until" in which case all "bare" + # calls are `.always()`. + + __request__: IMPORT_typing.Optional[Greeter.CreateRequest] = None + __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None + __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None + + if isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_types.StateId): + __state_id__ = __state_id_or_request_or_options__ + if isinstance(__request_or_options_or_idempotency__, Greeter.CreateRequest): + __request__ = __request_or_options_or_idempotency__ + assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_call.Options) + __options__ = __options_or_idempotency__ + assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + + assert title is UNSET + assert name is UNSET + assert adjective is UNSET + else: + assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) + __options__ = __request_or_options_or_idempotency__ + assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + __idempotency__ = __options_or_idempotency__ + + __request__ = GreeterCreateRequestFromInputFields( + title=title, + name=name, + adjective=adjective, + ) + elif isinstance(__state_id_or_request_or_options__, Greeter.CreateRequest): + __request__ = __state_id_or_request_or_options__ assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) __options__ = __request_or_options_or_idempotency__ assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) __idempotency__ = __options_or_idempotency__ + else: + assert ( + __state_id_or_request_or_options__ is None + or isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_call.Options) + ), "Invalid argument type. Did you pass:\n" \ + " - A 'state_id' that is not of type 'reboot.aio.types.StateId'?\n" \ + " - 'options' that are not of type 'reboot.aio.call.Options'?" + __options__ = __state_id_or_request_or_options__ + assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + __idempotency__ = __request_or_options_or_idempotency__ __request__ = GreeterCreateRequestFromInputFields( title=title, name=name, adjective=adjective, ) - elif isinstance(__state_id_or_request_or_options__, Greeter.CreateRequest): - __request__ = __state_id_or_request_or_options__ - assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) - __options__ = __request_or_options_or_idempotency__ - assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - __idempotency__ = __options_or_idempotency__ - else: - assert ( - __state_id_or_request_or_options__ is None - or isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_call.Options) - ), "Invalid argument type. Did you pass:\n" \ - " - A 'state_id' that is not of type 'reboot.aio.types.StateId'?\n" \ - " - 'options' that are not of type 'reboot.aio.call.Options'?" - __options__ = __state_id_or_request_or_options__ - assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - __idempotency__ = __request_or_options_or_idempotency__ - - __request__ = GreeterCreateRequestFromInputFields( - title=title, - name=name, - adjective=adjective, - ) - - if __idempotency__ is None: - __args__: tuple[IMPORT_typing.Any, ...] = ( - __context__, - ) - if __state_id__ is not None: - # Don't include `state_id` if it is `None`, so that - # we won't break the positional argument deduction. - __args__ += (__state_id__,) - __args__ += ( - __request__, - __options__, - ) - if isinstance(__context__, IMPORT_reboot_aio_contexts.WorkflowContext): - return await ( - __cls__.always() if __context__.within_until() - else ( - __cls__.per_iteration() if __context__.within_loop() - else __cls__.per_workflow() - ) - ).Create( - *__args__ + + if __idempotency__ is None: + __args__: tuple[IMPORT_typing.Any, ...] = ( + __context__, ) - elif isinstance(__context__, IMPORT_reboot_aio_external.InitializeContext): - return await __cls__.idempotently().Create( - *__args__ + if __state_id__ is not None: + # Don't include `state_id` if it is `None`, so that + # we won't break the positional argument deduction. + __args__ += (__state_id__,) + __args__ += ( + __request__, + __options__, ) + if isinstance(__context__, IMPORT_reboot_aio_contexts.WorkflowContext): + return await ( + __cls__.always() if __context__.within_until() + else ( + __cls__.per_iteration() if __context__.within_loop() + else __cls__.per_workflow() + ) + ).Create( + *__args__ + ) + elif isinstance(__context__, IMPORT_reboot_aio_external.InitializeContext): + return await __cls__.idempotently().Create( + *__args__ + ) - __metadata__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.GrpcMetadata] = None - __bearer_token__: IMPORT_typing.Optional[str] = None + __metadata__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.GrpcMetadata] = None + __bearer_token__: IMPORT_typing.Optional[str] = None - if __options__ is not None: - IMPORT_reboot_aio_types.assert_type(__options__, [IMPORT_reboot_aio_call.Options]) - if __options__.metadata is not None: - __metadata__ = __options__.metadata - if __options__.bearer_token is not None: - __bearer_token__ = __options__.bearer_token + if __options__ is not None: + IMPORT_reboot_aio_types.assert_type(__options__, [IMPORT_reboot_aio_call.Options]) + if __options__.metadata is not None: + __metadata__ = __options__.metadata + if __options__.bearer_token is not None: + __bearer_token__ = __options__.bearer_token - if __state_id__ is None: - if __idempotency__ is None: - __state_id__ = str(IMPORT_uuid.uuid4()) - else: - __state_id__ = __context__.generate_idempotent_state_id( - state_type_name=__cls__.__state_type_name__, - service_name=IMPORT_reboot_aio_types.ServiceName('tests.reboot.GreeterMethods'), - method='Create', - idempotency=__idempotency__, - ) + if __state_id__ is None: + if __idempotency__ is None: + __state_id__ = str(IMPORT_uuid.uuid4()) + else: + __state_id__ = __context__.generate_idempotent_state_id( + state_type_name=Greeter.__state_type_name__, + service_name=IMPORT_reboot_aio_types.ServiceName('tests.reboot.GreeterMethods'), + method='Create', + idempotency=__idempotency__, + ) - __reference__ = Greeter.ref( - __state_id__, bearer_token=__bearer_token__ - ) - __stub__ = __reference__._writer(__context__) - return ( - __reference__, - GreeterCreateResponseFromProto( - await __stub__.Create( - __request__, - idempotency=__idempotency__, - metadata=__metadata__, - bearer_token=__bearer_token__, - ) - ), - ) + __reference__ = Greeter.ref( + __state_id__, bearer_token=__bearer_token__ + ) + __stub__ = __reference__._writer(__context__) + return ( + __reference__, + GreeterCreateResponseFromProto( + await __stub__.Create( + __request__, + idempotency=__idempotency__, + metadata=__metadata__, + bearer_token=__bearer_token__, + ) + ), + ) - # Keep the original functions on the client, so old code will - # continue to work, but use the new 'snake_case' method in - # the new code. - create = Create + # Keep the original functions on the client, so old code will + # continue to work, but use the new 'snake_case' method in + # the new code. + create = Create - @IMPORT_typing.overload - @classmethod - def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Greeter._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Greeter._ConstructIdempotently: + ... - @IMPORT_typing.overload - @classmethod - def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Greeter._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Greeter._ConstructIdempotently: + ... - @classmethod - def idempotently( - cls, - alias: IMPORT_typing.Optional[str] = None, - *, - key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, - how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, - ) -> Greeter._ConstructIdempotently: - return Greeter._ConstructIdempotently( - _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( - alias=alias, - key=key, - how=how, - ), - ) + @classmethod + def idempotently( + cls, + alias: IMPORT_typing.Optional[str] = None, + *, + key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, + how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, + ) -> Greeter._ConstructIdempotently: + return Greeter._ConstructIdempotently( + _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( + alias=alias, + key=key, + how=how, + ), + ) - @classmethod - def per_workflow( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently(alias) + @classmethod + def per_workflow( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently(alias) - @classmethod - def per_iteration( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently( - alias, - how=IMPORT_reboot_aio_idempotency.PER_ITERATION, - ) + @classmethod + def per_iteration( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently( + alias, + how=IMPORT_reboot_aio_idempotency.PER_ITERATION, + ) - @classmethod - def always(cls): - return cls.idempotently( - how=IMPORT_reboot_aio_idempotency.ALWAYS, - ) + @classmethod + def always(cls): + return cls.idempotently( + how=IMPORT_reboot_aio_idempotency.ALWAYS, + ) + + factory = _Factory @IMPORT_dataclasses.dataclass(frozen=True) class _ConstructIdempotently: @@ -32031,7 +32034,7 @@ async def Create( # type: ignore[misc] __this__._idempotency, ) - return await Greeter.Create( + return await Greeter.factory.Create( *__args__, ) diff --git a/tests/reboot/greeter_rbt_web.golden.js b/tests/reboot/greeter_rbt_web.golden.js index 554dc375..cd57a696 100755 --- a/tests/reboot/greeter_rbt_web.golden.js +++ b/tests/reboot/greeter_rbt_web.golden.js @@ -2306,10 +2306,7 @@ export class GreeterWeakReference { } } _GreeterWeakReference_id = new WeakMap(), _GreeterWeakReference_options = new WeakMap(); -export class Greeter { - static ref(id, options) { - return new Greeter.WeakReference(id, options === null || options === void 0 ? void 0 : options.bearerToken); - } +export class GreeterFactory { static async create(context, idOrPartialRequest, inputPartialRequest, options) { let id = undefined; let partialRequest = undefined; @@ -2332,4 +2329,10 @@ export class Greeter { return [weakReference, response]; } } +export class Greeter { + static ref(id, options) { + return new Greeter.WeakReference(id, options === null || options === void 0 ? void 0 : options.bearerToken); + } +} Greeter.WeakReference = GreeterWeakReference; +Greeter.factory = GreeterFactory; diff --git a/tests/reboot/ping_api_rbt.golden.py b/tests/reboot/ping_api_rbt.golden.py index 6d4b9c5c..81f94d81 100755 --- a/tests/reboot/ping_api_rbt.golden.py +++ b/tests/reboot/ping_api_rbt.golden.py @@ -17360,7 +17360,7 @@ async def _authenticated( f"urn:dev.reboot:auto-construct:User:{state_id}", ) try: - await User.idempotently( + await User.factory.idempotently( key=idempotency_key, ).create(context, state_id) except User.CreateAborted as aborted: @@ -23229,55 +23229,58 @@ def ref( bearer_token=bearer_token, ) + class _Factory: - @IMPORT_typing.overload - @classmethod - def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Ping._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Ping._ConstructIdempotently: + ... - @IMPORT_typing.overload - @classmethod - def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Ping._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Ping._ConstructIdempotently: + ... - @classmethod - def idempotently( - cls, - alias: IMPORT_typing.Optional[str] = None, - *, - key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, - how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, - ) -> Ping._ConstructIdempotently: - return Ping._ConstructIdempotently( - _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( - alias=alias, - key=key, - how=how, - ), - ) + @classmethod + def idempotently( + cls, + alias: IMPORT_typing.Optional[str] = None, + *, + key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, + how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, + ) -> Ping._ConstructIdempotently: + return Ping._ConstructIdempotently( + _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( + alias=alias, + key=key, + how=how, + ), + ) - @classmethod - def per_workflow( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently(alias) + @classmethod + def per_workflow( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently(alias) - @classmethod - def per_iteration( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently( - alias, - how=IMPORT_reboot_aio_idempotency.PER_ITERATION, - ) + @classmethod + def per_iteration( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently( + alias, + how=IMPORT_reboot_aio_idempotency.PER_ITERATION, + ) - @classmethod - def always(cls): - return cls.idempotently( - how=IMPORT_reboot_aio_idempotency.ALWAYS, - ) + @classmethod + def always(cls): + return cls.idempotently( + how=IMPORT_reboot_aio_idempotency.ALWAYS, + ) + + factory = _Factory @IMPORT_dataclasses.dataclass(frozen=True) class _ConstructIdempotently: @@ -25090,55 +25093,58 @@ def ref( bearer_token=bearer_token, ) + class _Factory: - @IMPORT_typing.overload - @classmethod - def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Pong._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Pong._ConstructIdempotently: + ... - @IMPORT_typing.overload - @classmethod - def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Pong._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Pong._ConstructIdempotently: + ... - @classmethod - def idempotently( - cls, - alias: IMPORT_typing.Optional[str] = None, - *, - key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, - how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, - ) -> Pong._ConstructIdempotently: - return Pong._ConstructIdempotently( - _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( - alias=alias, - key=key, - how=how, - ), - ) + @classmethod + def idempotently( + cls, + alias: IMPORT_typing.Optional[str] = None, + *, + key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, + how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, + ) -> Pong._ConstructIdempotently: + return Pong._ConstructIdempotently( + _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( + alias=alias, + key=key, + how=how, + ), + ) - @classmethod - def per_workflow( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently(alias) + @classmethod + def per_workflow( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently(alias) - @classmethod - def per_iteration( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently( - alias, - how=IMPORT_reboot_aio_idempotency.PER_ITERATION, - ) + @classmethod + def per_iteration( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently( + alias, + how=IMPORT_reboot_aio_idempotency.PER_ITERATION, + ) - @classmethod - def always(cls): - return cls.idempotently( - how=IMPORT_reboot_aio_idempotency.ALWAYS, - ) + @classmethod + def always(cls): + return cls.idempotently( + how=IMPORT_reboot_aio_idempotency.ALWAYS, + ) + + factory = _Factory @IMPORT_dataclasses.dataclass(frozen=True) class _ConstructIdempotently: @@ -28985,142 +28991,145 @@ def ref( bearer_token=bearer_token, ) + class _Factory: - @classmethod - async def Create( # type: ignore[misc] - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None, - __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None, - __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - ) -> tuple[User.WeakReference, None]: - # Within a `workflow`, all "bare" calls are - # `per_workflow()` calls, unless we're within a control - # loop, in which case they are syntactic sugar for - # `per_iteration()`. - # - # Unless we are "within until" in which case all "bare" - # calls are `.always()`. + @classmethod + async def Create( # type: ignore[misc] + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None, + __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None, + __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + ) -> tuple[User.WeakReference, None]: + # Within a `workflow`, all "bare" calls are + # `per_workflow()` calls, unless we're within a control + # loop, in which case they are syntactic sugar for + # `per_iteration()`. + # + # Unless we are "within until" in which case all "bare" + # calls are `.always()`. - assert __state_id__ is None or isinstance(__state_id__, IMPORT_reboot_aio_types.StateId) - assert __options__ is None or isinstance(__options__, IMPORT_reboot_aio_call.Options) - assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + assert __state_id__ is None or isinstance(__state_id__, IMPORT_reboot_aio_types.StateId) + assert __options__ is None or isinstance(__options__, IMPORT_reboot_aio_call.Options) + assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - if __idempotency__ is None: - __args__: tuple[IMPORT_typing.Any, ...] = ( - __context__, - ) - if __state_id__ is not None: - # Don't include `state_id` if it is `None`, so that - # we won't break the positional argument deduction. - __args__ += (__state_id__,) - __args__ += ( - __options__, - ) - if isinstance(__context__, IMPORT_reboot_aio_contexts.WorkflowContext): - return await ( - __cls__.always() if __context__.within_until() - else ( - __cls__.per_iteration() if __context__.within_loop() - else __cls__.per_workflow() - ) - ).Create( - *__args__ + if __idempotency__ is None: + __args__: tuple[IMPORT_typing.Any, ...] = ( + __context__, ) - elif isinstance(__context__, IMPORT_reboot_aio_external.InitializeContext): - return await __cls__.idempotently().Create( - *__args__ + if __state_id__ is not None: + # Don't include `state_id` if it is `None`, so that + # we won't break the positional argument deduction. + __args__ += (__state_id__,) + __args__ += ( + __options__, ) + if isinstance(__context__, IMPORT_reboot_aio_contexts.WorkflowContext): + return await ( + __cls__.always() if __context__.within_until() + else ( + __cls__.per_iteration() if __context__.within_loop() + else __cls__.per_workflow() + ) + ).Create( + *__args__ + ) + elif isinstance(__context__, IMPORT_reboot_aio_external.InitializeContext): + return await __cls__.idempotently().Create( + *__args__ + ) - __metadata__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.GrpcMetadata] = None - __bearer_token__: IMPORT_typing.Optional[str] = None + __metadata__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.GrpcMetadata] = None + __bearer_token__: IMPORT_typing.Optional[str] = None - if __options__ is not None: - IMPORT_reboot_aio_types.assert_type(__options__, [IMPORT_reboot_aio_call.Options]) - if __options__.metadata is not None: - __metadata__ = __options__.metadata - if __options__.bearer_token is not None: - __bearer_token__ = __options__.bearer_token + if __options__ is not None: + IMPORT_reboot_aio_types.assert_type(__options__, [IMPORT_reboot_aio_call.Options]) + if __options__.metadata is not None: + __metadata__ = __options__.metadata + if __options__.bearer_token is not None: + __bearer_token__ = __options__.bearer_token - if __state_id__ is None: - if __idempotency__ is None: - __state_id__ = str(IMPORT_uuid.uuid4()) - else: - __state_id__ = __context__.generate_idempotent_state_id( - state_type_name=__cls__.__state_type_name__, - service_name=IMPORT_reboot_aio_types.ServiceName('reboot.ping.UserMethods'), - method='Create', - idempotency=__idempotency__, - ) + if __state_id__ is None: + if __idempotency__ is None: + __state_id__ = str(IMPORT_uuid.uuid4()) + else: + __state_id__ = __context__.generate_idempotent_state_id( + state_type_name=User.__state_type_name__, + service_name=IMPORT_reboot_aio_types.ServiceName('reboot.ping.UserMethods'), + method='Create', + idempotency=__idempotency__, + ) - __reference__ = User.ref( - __state_id__, bearer_token=__bearer_token__ - ) - __stub__ = __reference__._workflow(__context__) - return ( - __reference__, - UserCreateResponseFromProto( - await __stub__.Create( - idempotency=__idempotency__, - metadata=__metadata__, - bearer_token=__bearer_token__, - ) - ), - ) + __reference__ = User.ref( + __state_id__, bearer_token=__bearer_token__ + ) + __stub__ = __reference__._workflow(__context__) + return ( + __reference__, + UserCreateResponseFromProto( + await __stub__.Create( + idempotency=__idempotency__, + metadata=__metadata__, + bearer_token=__bearer_token__, + ) + ), + ) - # Keep the original functions on the client, so old code will - # continue to work, but use the new 'snake_case' method in - # the new code. - create = Create + # Keep the original functions on the client, so old code will + # continue to work, but use the new 'snake_case' method in + # the new code. + create = Create - @IMPORT_typing.overload - @classmethod - def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> User._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> User._ConstructIdempotently: + ... - @IMPORT_typing.overload - @classmethod - def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> User._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> User._ConstructIdempotently: + ... - @classmethod - def idempotently( - cls, - alias: IMPORT_typing.Optional[str] = None, - *, - key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, - how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, - ) -> User._ConstructIdempotently: - return User._ConstructIdempotently( - _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( - alias=alias, - key=key, - how=how, - ), - ) + @classmethod + def idempotently( + cls, + alias: IMPORT_typing.Optional[str] = None, + *, + key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, + how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, + ) -> User._ConstructIdempotently: + return User._ConstructIdempotently( + _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( + alias=alias, + key=key, + how=how, + ), + ) - @classmethod - def per_workflow( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently(alias) + @classmethod + def per_workflow( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently(alias) - @classmethod - def per_iteration( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently( - alias, - how=IMPORT_reboot_aio_idempotency.PER_ITERATION, - ) + @classmethod + def per_iteration( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently( + alias, + how=IMPORT_reboot_aio_idempotency.PER_ITERATION, + ) - @classmethod - def always(cls): - return cls.idempotently( - how=IMPORT_reboot_aio_idempotency.ALWAYS, - ) + @classmethod + def always(cls): + return cls.idempotently( + how=IMPORT_reboot_aio_idempotency.ALWAYS, + ) + + factory = _Factory @IMPORT_dataclasses.dataclass(frozen=True) class _ConstructIdempotently: @@ -29154,7 +29163,7 @@ async def Create( # type: ignore[misc] __this__._idempotency, ) - return await User.Create( + return await User.factory.Create( *__args__, ) @@ -31952,215 +31961,218 @@ def ref( bearer_token=bearer_token, ) - @IMPORT_typing.overload - @classmethod - async def Create( - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | Counter.CreateRequest] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[Counter.CreateRequest | IMPORT_reboot_aio_call.Options] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - ) -> tuple[Counter.WeakReference, None]: - ... - - @IMPORT_typing.overload - @classmethod - async def Create( - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | IMPORT_reboot_aio_call.Options] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - *, - description: str | Unset = UNSET, - owner_id: str | Unset = UNSET, - ) -> tuple[Counter.WeakReference, None]: - ... + class _Factory: + @IMPORT_typing.overload + @classmethod + async def Create( + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | Counter.CreateRequest] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[Counter.CreateRequest | IMPORT_reboot_aio_call.Options] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + ) -> tuple[Counter.WeakReference, None]: + ... - @classmethod - async def Create( # type: ignore[misc] - __cls__, - __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, - __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | Counter.CreateRequest | IMPORT_reboot_aio_call.Options] = None, - __request_or_options_or_idempotency__: IMPORT_typing.Optional[Counter.CreateRequest | IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, - __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, - *, - description: str | Unset = UNSET, - owner_id: str | Unset = UNSET, - ) -> tuple[Counter.WeakReference, None]: - # Within a `workflow`, all "bare" calls are - # `per_workflow()` calls, unless we're within a control - # loop, in which case they are syntactic sugar for - # `per_iteration()`. - # - # Unless we are "within until" in which case all "bare" - # calls are `.always()`. + @IMPORT_typing.overload + @classmethod + async def Create( + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | IMPORT_reboot_aio_call.Options] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + *, + description: str | Unset = UNSET, + owner_id: str | Unset = UNSET, + ) -> tuple[Counter.WeakReference, None]: + ... - __request__: IMPORT_typing.Optional[Counter.CreateRequest] = None - __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None - __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None + @classmethod + async def Create( # type: ignore[misc] + __cls__, + __context__: IMPORT_reboot_aio_contexts.TransactionContext | IMPORT_reboot_aio_contexts.WorkflowContext | IMPORT_reboot_aio_external.ExternalContext, + __state_id_or_request_or_options__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId | Counter.CreateRequest | IMPORT_reboot_aio_call.Options] = None, + __request_or_options_or_idempotency__: IMPORT_typing.Optional[Counter.CreateRequest | IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __options_or_idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options | IMPORT_reboot_aio_idempotency.Idempotency] = None, + __idempotency__: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.Idempotency] = None, + *, + description: str | Unset = UNSET, + owner_id: str | Unset = UNSET, + ) -> tuple[Counter.WeakReference, None]: + # Within a `workflow`, all "bare" calls are + # `per_workflow()` calls, unless we're within a control + # loop, in which case they are syntactic sugar for + # `per_iteration()`. + # + # Unless we are "within until" in which case all "bare" + # calls are `.always()`. - if isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_types.StateId): - __state_id__ = __state_id_or_request_or_options__ - if isinstance(__request_or_options_or_idempotency__, Counter.CreateRequest): - __request__ = __request_or_options_or_idempotency__ - assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_call.Options) - __options__ = __options_or_idempotency__ - assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + __request__: IMPORT_typing.Optional[Counter.CreateRequest] = None + __state_id__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.StateId] = None + __options__: IMPORT_typing.Optional[IMPORT_reboot_aio_call.Options] = None - assert description is UNSET - assert owner_id is UNSET - else: + if isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_types.StateId): + __state_id__ = __state_id_or_request_or_options__ + if isinstance(__request_or_options_or_idempotency__, Counter.CreateRequest): + __request__ = __request_or_options_or_idempotency__ + assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_call.Options) + __options__ = __options_or_idempotency__ + assert __idempotency__ is None or isinstance(__idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + + assert description is UNSET + assert owner_id is UNSET + else: + assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) + __options__ = __request_or_options_or_idempotency__ + assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + __idempotency__ = __options_or_idempotency__ + + __request__ = CounterCreateRequestFromInputFields( + description=description, + owner_id=owner_id, + ) + elif isinstance(__state_id_or_request_or_options__, Counter.CreateRequest): + __request__ = __state_id_or_request_or_options__ assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) __options__ = __request_or_options_or_idempotency__ assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) __idempotency__ = __options_or_idempotency__ + else: + assert ( + __state_id_or_request_or_options__ is None + or isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_call.Options) + ), "Invalid argument type. Did you pass:\n" \ + " - A 'state_id' that is not of type 'reboot.aio.types.StateId'?\n" \ + " - 'options' that are not of type 'reboot.aio.call.Options'?" + __options__ = __state_id_or_request_or_options__ + assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) + __idempotency__ = __request_or_options_or_idempotency__ __request__ = CounterCreateRequestFromInputFields( description=description, owner_id=owner_id, ) - elif isinstance(__state_id_or_request_or_options__, Counter.CreateRequest): - __request__ = __state_id_or_request_or_options__ - assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_call.Options) - __options__ = __request_or_options_or_idempotency__ - assert __options_or_idempotency__ is None or isinstance(__options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - __idempotency__ = __options_or_idempotency__ - else: - assert ( - __state_id_or_request_or_options__ is None - or isinstance(__state_id_or_request_or_options__, IMPORT_reboot_aio_call.Options) - ), "Invalid argument type. Did you pass:\n" \ - " - A 'state_id' that is not of type 'reboot.aio.types.StateId'?\n" \ - " - 'options' that are not of type 'reboot.aio.call.Options'?" - __options__ = __state_id_or_request_or_options__ - assert __request_or_options_or_idempotency__ is None or isinstance(__request_or_options_or_idempotency__, IMPORT_reboot_aio_idempotency.Idempotency) - __idempotency__ = __request_or_options_or_idempotency__ - - __request__ = CounterCreateRequestFromInputFields( - description=description, - owner_id=owner_id, - ) - - if __idempotency__ is None: - __args__: tuple[IMPORT_typing.Any, ...] = ( - __context__, - ) - if __state_id__ is not None: - # Don't include `state_id` if it is `None`, so that - # we won't break the positional argument deduction. - __args__ += (__state_id__,) - __args__ += ( - __request__, - __options__, - ) - if isinstance(__context__, IMPORT_reboot_aio_contexts.WorkflowContext): - return await ( - __cls__.always() if __context__.within_until() - else ( - __cls__.per_iteration() if __context__.within_loop() - else __cls__.per_workflow() - ) - ).Create( - *__args__ + + if __idempotency__ is None: + __args__: tuple[IMPORT_typing.Any, ...] = ( + __context__, ) - elif isinstance(__context__, IMPORT_reboot_aio_external.InitializeContext): - return await __cls__.idempotently().Create( - *__args__ + if __state_id__ is not None: + # Don't include `state_id` if it is `None`, so that + # we won't break the positional argument deduction. + __args__ += (__state_id__,) + __args__ += ( + __request__, + __options__, ) + if isinstance(__context__, IMPORT_reboot_aio_contexts.WorkflowContext): + return await ( + __cls__.always() if __context__.within_until() + else ( + __cls__.per_iteration() if __context__.within_loop() + else __cls__.per_workflow() + ) + ).Create( + *__args__ + ) + elif isinstance(__context__, IMPORT_reboot_aio_external.InitializeContext): + return await __cls__.idempotently().Create( + *__args__ + ) - __metadata__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.GrpcMetadata] = None - __bearer_token__: IMPORT_typing.Optional[str] = None + __metadata__: IMPORT_typing.Optional[IMPORT_reboot_aio_types.GrpcMetadata] = None + __bearer_token__: IMPORT_typing.Optional[str] = None - if __options__ is not None: - IMPORT_reboot_aio_types.assert_type(__options__, [IMPORT_reboot_aio_call.Options]) - if __options__.metadata is not None: - __metadata__ = __options__.metadata - if __options__.bearer_token is not None: - __bearer_token__ = __options__.bearer_token + if __options__ is not None: + IMPORT_reboot_aio_types.assert_type(__options__, [IMPORT_reboot_aio_call.Options]) + if __options__.metadata is not None: + __metadata__ = __options__.metadata + if __options__.bearer_token is not None: + __bearer_token__ = __options__.bearer_token - if __state_id__ is None: - if __idempotency__ is None: - __state_id__ = str(IMPORT_uuid.uuid4()) - else: - __state_id__ = __context__.generate_idempotent_state_id( - state_type_name=__cls__.__state_type_name__, - service_name=IMPORT_reboot_aio_types.ServiceName('reboot.ping.CounterMethods'), - method='Create', - idempotency=__idempotency__, - ) + if __state_id__ is None: + if __idempotency__ is None: + __state_id__ = str(IMPORT_uuid.uuid4()) + else: + __state_id__ = __context__.generate_idempotent_state_id( + state_type_name=Counter.__state_type_name__, + service_name=IMPORT_reboot_aio_types.ServiceName('reboot.ping.CounterMethods'), + method='Create', + idempotency=__idempotency__, + ) - __reference__ = Counter.ref( - __state_id__, bearer_token=__bearer_token__ - ) - __stub__ = __reference__._writer(__context__) - return ( - __reference__, - CounterCreateResponseFromProto( - await __stub__.Create( - __request__, - idempotency=__idempotency__, - metadata=__metadata__, - bearer_token=__bearer_token__, - ) - ), - ) + __reference__ = Counter.ref( + __state_id__, bearer_token=__bearer_token__ + ) + __stub__ = __reference__._writer(__context__) + return ( + __reference__, + CounterCreateResponseFromProto( + await __stub__.Create( + __request__, + idempotency=__idempotency__, + metadata=__metadata__, + bearer_token=__bearer_token__, + ) + ), + ) - # Keep the original functions on the client, so old code will - # continue to work, but use the new 'snake_case' method in - # the new code. - create = Create + # Keep the original functions on the client, so old code will + # continue to work, but use the new 'snake_case' method in + # the new code. + create = Create - @IMPORT_typing.overload - @classmethod - def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Counter._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, alias: IMPORT_typing.Optional[str] = None, *, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Counter._ConstructIdempotently: + ... - @IMPORT_typing.overload - @classmethod - def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Counter._ConstructIdempotently: - ... + @IMPORT_typing.overload + @classmethod + def idempotently(cls, *, key: IMPORT_uuid.UUID, how: IMPORT_reboot_aio_idempotency.How = IMPORT_reboot_aio_idempotency.PER_WORKFLOW) -> Counter._ConstructIdempotently: + ... - @classmethod - def idempotently( - cls, - alias: IMPORT_typing.Optional[str] = None, - *, - key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, - how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, - ) -> Counter._ConstructIdempotently: - return Counter._ConstructIdempotently( - _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( - alias=alias, - key=key, - how=how, - ), - ) + @classmethod + def idempotently( + cls, + alias: IMPORT_typing.Optional[str] = None, + *, + key: IMPORT_typing.Optional[IMPORT_uuid.UUID] = None, + how: IMPORT_typing.Optional[IMPORT_reboot_aio_idempotency.How] = None, + ) -> Counter._ConstructIdempotently: + return Counter._ConstructIdempotently( + _idempotency=IMPORT_reboot_aio_contexts.Context.idempotency( + alias=alias, + key=key, + how=how, + ), + ) - @classmethod - def per_workflow( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently(alias) + @classmethod + def per_workflow( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently(alias) - @classmethod - def per_iteration( - cls, - alias: IMPORT_typing.Optional[str] = None, - ): - return cls.idempotently( - alias, - how=IMPORT_reboot_aio_idempotency.PER_ITERATION, - ) + @classmethod + def per_iteration( + cls, + alias: IMPORT_typing.Optional[str] = None, + ): + return cls.idempotently( + alias, + how=IMPORT_reboot_aio_idempotency.PER_ITERATION, + ) - @classmethod - def always(cls): - return cls.idempotently( - how=IMPORT_reboot_aio_idempotency.ALWAYS, - ) + @classmethod + def always(cls): + return cls.idempotently( + how=IMPORT_reboot_aio_idempotency.ALWAYS, + ) + + factory = _Factory @IMPORT_dataclasses.dataclass(frozen=True) class _ConstructIdempotently: @@ -32260,7 +32272,7 @@ async def Create( # type: ignore[misc] __this__._idempotency, ) - return await Counter.Create( + return await Counter.factory.Create( *__args__, ) From 234c8ff70b868dece60787e2a940edb2363b9ba6 Mon Sep 17 00:00:00 2001 From: Robert-Jan Huijsman <22160949+rjhuijsman@users.noreply.github.com> Date: Tue, 21 Jul 2026 22:57:43 +0000 Subject: [PATCH 2/3] Migration: note the `factory` namespace move for upgrades The `upgrade` skill rolls fragments from `skills/upgrade/migrations/next/` into each release's migration notes. This adds the fragment for the constructor-namespacing change so an app upgrading past it knows to move its constructor calls: it gives grep-able before/after patterns for `Foo.create(context, ...)` -> `Foo.factory.create(context, ...)`, plus the idempotency-scope and custom-constructor variants. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_011xyvD8vLQ9dTwtFMexovJo --- .../next/factory-namespaced-constructors.md | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 reboot/plugin/skills/upgrade/migrations/next/factory-namespaced-constructors.md diff --git a/reboot/plugin/skills/upgrade/migrations/next/factory-namespaced-constructors.md b/reboot/plugin/skills/upgrade/migrations/next/factory-namespaced-constructors.md new file mode 100644 index 00000000..946a3ea5 --- /dev/null +++ b/reboot/plugin/skills/upgrade/migrations/next/factory-namespaced-constructors.md @@ -0,0 +1,40 @@ +## Constructors moved under a `factory` namespace + +Constructor (a.k.a. factory) methods are no longer exposed directly on +a state type. They now live under a `factory` namespace on the type, +so the top-level namespace is free for framework methods like `ref()`. +This only changes how constructors are **called** — the way you +**declare** one (`factory=True` on a writer/transaction, or the +`constructor` proto option) is unchanged. + +For every call that invokes a constructor **directly on a state type** +(i.e. on the class itself, not on a `.ref(...)` handle), insert +`.factory` between the type and the method: + +- `await Foo.create(context, ...)` → `await Foo.factory.create(context, ...)` +- Custom-named constructors too, e.g. `await Account.open(context, ...)` + → `await Account.factory.open(context, ...)`. +- Class-level idempotency-scoped construction moves under `factory` as + well: `Foo.idempotently(...)`, `Foo.per_workflow(...)`, + `Foo.per_iteration(...)`, `Foo.always(...)` (TypeScript: + `Foo.perWorkflow(...)`, `Foo.perIteration(...)`) when invoked on the + **class** to construct → `Foo.factory.idempotently(...)`, etc. So + `await Foo.idempotently("alias").create(context)` becomes + `await Foo.factory.idempotently("alias").create(context)`. + +How to find them: a method invoked directly on a state-type class is +_necessarily_ a constructor — every other method requires a `.ref(...)` +handle. So in `backend/` (Python and TypeScript), search for +`.(` calls where `` is a generated state +type imported from a `*_rbt`/`*_reboot` module and the call is made on +the bare class (the first argument is a `context`). Rewrite each as +`.factory.(`. + +Leave these unchanged: + +- Calls on a `.ref(...)` handle, including the reference-construction + form `Foo.ref(id).create(context)` and inline writers like + `Foo.ref().per_workflow("a").write(context, fn)`. +- `Foo.ref(...)` and `Foo.forall(...)` themselves. +- `factory=True` declarations and the `constructor` proto option. +- Implicit construction on first write (no explicit constructor call). From 5e1d25986010045c451ebf92fea24d53f0004cfb Mon Sep 17 00:00:00 2001 From: Robert-Jan Huijsman <22160949+rjhuijsman@users.noreply.github.com> Date: Tue, 21 Jul 2026 23:07:29 +0000 Subject: [PATCH 3/3] Callers: call constructors via `factory` The previous commit changed where constructor/factory methods live; this commit changes all the callers to use the new syntax. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_011xyvD8vLQ9dTwtFMexovJo --- .../docs/ai_chat_apps/get_started.mdx | 2 +- .../docs/learn_more/applications.mdx | 4 +- documentation/docs/learn_more/auth.mdx | 4 +- .../learn_more/call/from_within_your_app.mdx | 5 +- .../docs/learn_more/call/overview.mdx | 24 +++--- documentation/docs/learn_more/idempotency.mdx | 5 +- .../learn_more/identity_and_external_apis.mdx | 2 +- .../learn_more/implement/transactions.mdx | 2 +- .../docs/library_services/ciphertext.mdx | 8 +- .../docs/library_services/mailgun.md | 6 +- rbt/thirdparty/mailgun/v1/mailgun.proto | 3 +- reboot/cli/commands/cloud/up.py | 2 +- reboot/demos/fig/backend/src/main.ts | 4 +- reboot/demos/fig/backend/src/user_servicer.ts | 2 +- .../agent-wiki/backend/src/servicers/wiki.py | 6 +- .../agent-wiki/backend/tests/wiki_test.py | 4 +- .../backend/src/servicers/counter.py | 2 +- .../backend/src/servicers/counter.py | 2 +- .../bank-nodejs/backend/src/bank_servicer.ts | 10 ++- .../bank-nodejs/backend/tests/test.ts | 2 +- .../backend/src/bank_servicer.py | 2 +- .../backend/src/customer_servicer.py | 2 +- .../bank-pydantic/backend/src/main.py | 2 +- .../backend/tests/full_bank_test.py | 10 +-- reboot/examples/bank-zod/backend/src/bank.ts | 2 +- .../examples/bank-zod/backend/src/customer.ts | 2 +- reboot/examples/bank-zod/backend/src/main.ts | 2 +- .../examples/bank-zod/backend/tests/test.ts | 6 +- reboot/examples/bank/backend/src/main.py | 6 +- .../boutique/backend/src/checkout/servicer.py | 2 +- reboot/examples/boutique/backend/src/main.py | 6 +- .../chick-potle/backend/src/servicers/food.py | 2 +- reboot/examples/docubot/backend/src/main.ts | 2 +- reboot/examples/kcdc-2025/backend/src/main.py | 4 +- .../backend/src/servicers/channel.py | 2 +- .../backend/src/servicers/chatbot.py | 2 +- .../kcdc-2025/backend/src/servicers/user.py | 4 +- .../bank/backend/src/bank_servicer.py | 2 +- .../backend/tests/account_servicer_test.py | 4 +- .../hello-constructors/backend/src/main.py | 2 +- .../backend/tests/hello_servicer_test.py | 4 +- .../reboot-swag-store/backend/src/main.py | 2 +- .../backend/src/servicers/store.py | 4 +- .../backend/tests/store_servicer_test.py | 40 +++++++--- reboot/ping/ping.py | 2 +- reboot/plugin/skills/chat-app/SKILL.md | 8 +- .../skills/chat-app/references/gotchas.md | 2 +- .../chat-app/references/servicer-patterns.md | 14 ++-- reboot/plugin/skills/python/SKILL.md | 5 +- .../skills/python/references/_sections.md | 2 +- .../skills/python/references/api-pydantic.md | 4 +- .../references/auth-external-api-calls.md | 4 +- .../references/lifecycle-initialize-hook.md | 17 +++-- .../references/patterns-common-gotchas.md | 12 +-- .../python/references/patterns-idempotency.md | 6 +- .../skills/python/references/rpc-calls.md | 2 +- .../references/rpc-constructor-calls.md | 35 +++++---- .../python/references/servicer-constructor.md | 19 ++--- .../python/references/servicer-transaction.md | 16 ++-- .../references/state-actor-decomposition.md | 4 +- .../python/references/state-collections.md | 2 +- .../python/references/state-scalar-fields.md | 2 +- .../python/references/stdlib-ciphertext.md | 16 ++-- .../python/references/stdlib-ordered-map.md | 2 +- .../python/references/stdlib-presence.md | 2 +- .../python/references/testing-harness.md | 2 +- reboot/plugin/skills/web-app/SKILL.md | 2 +- reboot/std/oauth/v1/oauth.py | 2 +- .../reboot/agents/pydantic_ai/agent_tests.py | 4 +- .../aio/internals/tasks_servicer_tests.py | 4 +- tests/reboot/auth_bank_main.py | 2 +- tests/reboot/auth_tests.py | 6 +- tests/reboot/bank.py | 24 +++--- tests/reboot/bank_main.py | 2 +- tests/reboot/benchmark.py | 2 +- tests/reboot/cancellation_tests.py | 2 +- tests/reboot/context_tests.py | 4 +- .../backend/src/servicers/counter.py | 2 +- tests/reboot/documentation/task.py | 2 +- tests/reboot/documentation/task.ts | 4 +- tests/reboot/documentation/test_http.py | 2 +- tests/reboot/documentation/test_http.ts | 2 +- tests/reboot/documentation/transactions.ts | 6 +- tests/reboot/effect_validation_tests.py | 10 +-- tests/reboot/errors_tests.py | 12 +-- tests/reboot/external_context_tests.py | 2 +- tests/reboot/idempotency_seeds_tests.py | 8 +- tests/reboot/idempotency_tests.py | 32 ++++---- tests/reboot/invalid_header_tests.py | 24 +++--- tests/reboot/nodejs/app_internal_test/test.ts | 6 +- tests/reboot/nodejs/auth_test/test.ts | 6 +- tests/reboot/nodejs/greeter.ts | 2 +- tests/reboot/nodejs/greeter_test/test.ts | 34 ++++----- tests/reboot/nodejs/reboot_down_test/test.ts | 2 +- tests/reboot/nodejs/reboot_test/test.ts | 6 +- tests/reboot/nodejs/reboot_web_test/test.ts | 12 +-- tests/reboot/nodejs/tasks_test/test.ts | 6 +- .../nodejs/yarn_zod_test/backend/src/bank.ts | 2 +- .../nodejs/yarn_zod_test/backend/src/main.ts | 2 +- .../yarn_zod_test/backend/tests/test.ts | 2 +- tests/reboot/ping/ping_test.py | 2 +- tests/reboot/preload_tests.py | 10 +-- tests/reboot/protoc_gen_reboot_tests.py | 3 +- .../pydantic/auto_construct_user/servicer.py | 2 +- .../pydantic/auto_construct_user/test.py | 4 +- .../pydantic/discriminated_union/test.py | 12 +-- tests/reboot/pydantic/methods/servicer.py | 4 +- tests/reboot/pydantic/methods/test.py | 24 +++--- .../test_against_local_envoy.py | 2 +- .../test_auth/test_against_local_envoy.py | 2 +- .../react/test_cache/greeter_cache.test.tsx | 4 +- .../test_errors/test_against_local_envoy.py | 2 +- tests/reboot/react/test_http_fallback/test.py | 2 +- .../react/test_idempotent_writer/test.py | 2 +- .../react/test_long_running_fetches/test.py | 2 +- tests/reboot/react/test_mutations/test.py | 2 +- .../test.py | 2 +- .../test_reader/test_against_local_envoy.py | 2 +- .../state_id_change.test.tsx | 4 +- .../test_suspense/test_against_local_envoy.py | 2 +- .../test_against_local_envoy.py | 2 +- .../test_against_local_envoy.py | 2 +- .../test.py | 2 +- tests/reboot/reactivity_test.py | 2 +- tests/reboot/reboot_tests.py | 2 +- tests/reboot/server/local_envoy_test.py | 20 +++-- .../std/ciphertext/v1/ciphertext_tests.py | 2 +- .../std/collections/sorted_map_tests.py | 4 +- tests/reboot/tasks_tests.py | 34 ++++----- tests/reboot/thirdparty/mailgun/tests.py | 4 +- tests/reboot/transaction_tests.py | 74 ++++++++++--------- tests/reboot/zod/methods/test.ts | 2 +- 132 files changed, 465 insertions(+), 407 deletions(-) diff --git a/documentation/docs/ai_chat_apps/get_started.mdx b/documentation/docs/ai_chat_apps/get_started.mdx index 16e9b581..3b6ee8e4 100644 --- a/documentation/docs/ai_chat_apps/get_started.mdx +++ b/documentation/docs/ai_chat_apps/get_started.mdx @@ -296,7 +296,7 @@ class UserServicer(User.Servicer): request: CreateCounterRequest, ) -> CreateCounterResponse: """Create a new Counter and return its ID.""" - counter, _ = await Counter.create( + counter, _ = await Counter.factory.create( context, description=request.description, owner_id=context.state_id, diff --git a/documentation/docs/learn_more/applications.mdx b/documentation/docs/learn_more/applications.mdx index 62e2df63..eafd6331 100644 --- a/documentation/docs/learn_more/applications.mdx +++ b/documentation/docs/learn_more/applications.mdx @@ -205,7 +205,7 @@ async def hello_greeter( context: ExternalContext = InjectExternalContext, ): body = await request.json() - greeter, _ = await Greeter.create( + greeter, _ = await Greeter.factory.create( context, title=body['title'], name=body['name'], @@ -234,7 +234,7 @@ application.http.post("/hello_greeter", async (context, req, res) => { name: string; adjective: string; }; - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title, name, adjective, diff --git a/documentation/docs/learn_more/auth.mdx b/documentation/docs/learn_more/auth.mdx index 01844ea8..301d0d31 100644 --- a/documentation/docs/learn_more/auth.mdx +++ b/documentation/docs/learn_more/auth.mdx @@ -56,7 +56,7 @@ construction](/learn_more/call/overview#explicit-construction): ```py -bank, _ = await Bank.create( +bank, _ = await Bank.factory.create( context, SINGLETON_BANK_ID, Options(bearer_token=VALID_JWT), @@ -68,7 +68,7 @@ bank, _ = await Bank.create( ```ts -const [bank] = await Bank.create( +const [bank] = await Bank.factory.create( context, SINGLETON_BANK_ID, {}, diff --git a/documentation/docs/learn_more/call/from_within_your_app.mdx b/documentation/docs/learn_more/call/from_within_your_app.mdx index 5bc9da7a..4fb8b109 100644 --- a/documentation/docs/learn_more/call/from_within_your_app.mdx +++ b/documentation/docs/learn_more/call/from_within_your_app.mdx @@ -49,7 +49,7 @@ async def transfer( +(CODE:src=../../../../reboot/examples/bank-nodejs/backend/src/bank_servicer.ts&lines=50-61) --> ```ts @@ -62,6 +62,9 @@ async transfer( await fromAccount.withdraw(context, { amount: request.amount }); await toAccount.deposit(context, { amount: request.amount }); + + return {}; +} ``` diff --git a/documentation/docs/learn_more/call/overview.mdx b/documentation/docs/learn_more/call/overview.mdx index 008c048e..4dd281c1 100644 --- a/documentation/docs/learn_more/call/overview.mdx +++ b/documentation/docs/learn_more/call/overview.mdx @@ -24,7 +24,7 @@ from_account = Account.ref(request.from_account_id) +(CODE:src=../../../../reboot/examples/bank-nodejs/backend/src/bank_servicer.ts&lines=54-54) --> ```ts @@ -193,7 +193,7 @@ example: ```python -account, response = await Account.open( +account, response = await Account.factory.open( context, customer_name=request.customer_name, ) @@ -202,7 +202,7 @@ account, response = await Account.open( ```typescript -const [account, response] = await Account.open(context, { +const [account, response] = await Account.factory.open(context, { customerName: request.customerName, }); ``` @@ -232,7 +232,7 @@ an example of constructing an `Account` with an explicit ID using the ```python -account, _ = await Account.open( +account, _ = await Account.factory.open( context, new_account_id, customer_name=request.customer_name, @@ -242,13 +242,17 @@ account, _ = await Account.open( - + ```typescript -const [account, response] = await Account.open(context, newAccountId, { - customerName: request.customerName, -}); +const [account, response] = await Account.factory.open( + context, + newAccountId, + { + customerName: request.customerName, + } +); ``` @@ -266,7 +270,7 @@ application (i.e., using an ```python -account, response = await Account.idempotently().open( +account, response = await Account.factory.idempotently().open( context, customer_name=request.customer_name, ) @@ -275,7 +279,7 @@ account, response = await Account.idempotently().open( ```typescript -const [account, response] = await Account.idempotently().open(context, { +const [account, response] = await Account.factory.idempotently().open(context, { customerName: request.customerName, }); ``` diff --git a/documentation/docs/learn_more/idempotency.mdx b/documentation/docs/learn_more/idempotency.mdx index 8995f131..b5b6a351 100644 --- a/documentation/docs/learn_more/idempotency.mdx +++ b/documentation/docs/learn_more/idempotency.mdx @@ -23,10 +23,11 @@ distinguish each call, for example: +(CODE:src=../../../tests/reboot/idempotency_tests.py&lines=371-375) --> ```py +# First call: sign up the account idempotently. await bank.idempotently('sign up jonathan').SignUp( context, account_id='jonathan', @@ -41,7 +42,7 @@ await bank.idempotently('sign up jonathan').SignUp( ```ts -await Greeter.idempotently("generated").create(context, { +await Greeter.factory.idempotently("generated").create(context, { title: "Mr", name: "John", adjective: "Dangerous", diff --git a/documentation/docs/learn_more/identity_and_external_apis.mdx b/documentation/docs/learn_more/identity_and_external_apis.mdx index 81fdd6b4..5a903841 100644 --- a/documentation/docs/learn_more/identity_and_external_apis.mdx +++ b/documentation/docs/learn_more/identity_and_external_apis.mdx @@ -273,7 +273,7 @@ key is still a secret at rest, so encrypt it with reference to the encrypted value: ```py -ciphertext, _ = await Ciphertext.encrypt( +ciphertext, _ = await Ciphertext.factory.encrypt( context, plaintext=request.api_key.encode(), associated_data=make_associated_data( diff --git a/documentation/docs/learn_more/implement/transactions.mdx b/documentation/docs/learn_more/implement/transactions.mdx index a222f989..1773f048 100644 --- a/documentation/docs/learn_more/implement/transactions.mdx +++ b/documentation/docs/learn_more/implement/transactions.mdx @@ -73,7 +73,7 @@ transfer: async ( +(CODE:src=../../../../reboot/examples/bank-nodejs/backend/src/bank_servicer.ts&lines=50-61) --> ```ts diff --git a/documentation/docs/library_services/ciphertext.mdx b/documentation/docs/library_services/ciphertext.mdx index c229bdfd..05487fb2 100644 --- a/documentation/docs/library_services/ciphertext.mdx +++ b/documentation/docs/library_services/ciphertext.mdx @@ -112,7 +112,7 @@ from reboot.std.ciphertext.v1.ciphertext import APP_SHARED_KEY_MANAGER_ID from uuid import uuid4 ciphertext_id = str(uuid4()) -ciphertext, _ = await Ciphertext.encrypt( +ciphertext, _ = await Ciphertext.factory.encrypt( context, ciphertext_id, plaintext=b"123-45-6789", @@ -132,7 +132,7 @@ import { } from "@reboot-dev/reboot-std/ciphertext/v1"; const ciphertextId = crypto.randomUUID(); -const [ciphertext] = await Ciphertext.encrypt(context, ciphertextId, { +const [ciphertext] = await Ciphertext.factory.encrypt(context, ciphertextId, { plaintext: new TextEncoder().encode("123-45-6789"), associatedData: makeAssociatedData({ user_id: "42", purpose: "ssn" }), scope: "user_id:42", @@ -199,7 +199,7 @@ other's ciphertexts (`shred` operates per manager). ```py # Encrypt under a named manager. -await Ciphertext.encrypt( +await Ciphertext.factory.encrypt( context, ciphertext_id, plaintext=b"123-45-6789", @@ -217,7 +217,7 @@ await KeyManager.ref("tenant:acme").shred(context, scope="user_id:42") ```ts // Encrypt under a named manager. -await Ciphertext.encrypt(context, ciphertextId, { +await Ciphertext.factory.encrypt(context, ciphertextId, { plaintext: new TextEncoder().encode("123-45-6789"), associatedData: makeAssociatedData({ user_id: "42", purpose: "ssn" }), scope: "user_id:42", diff --git a/documentation/docs/library_services/mailgun.md b/documentation/docs/library_services/mailgun.md index 22b75be7..8edfc46c 100644 --- a/documentation/docs/library_services/mailgun.md +++ b/documentation/docs/library_services/mailgun.md @@ -28,12 +28,12 @@ Calls to the integration must also authenticate using that same API key as the bearer token: the integration only accepts calls whose bearer token matches `MAILGUN_API_KEY`, and rejects all other calls as unauthenticated. Pass the key using `Options` when calling -`Message.send`: +`Message.factory.send`: ```python from reboot.aio.call import Options -await Message.send( +await Message.factory.send( context, Options(bearer_token=mailgun_api_key), recipient="alice@example.com", @@ -47,7 +47,7 @@ await Message.send( ## Message {#rbtthirdpartymailgunv1message} A single message sent using the integration. -Created and scheduled using its constructor: `await Message.send(...)`. +Created and scheduled using its constructor: `await Message.factory.send(...)`. ### Send diff --git a/rbt/thirdparty/mailgun/v1/mailgun.proto b/rbt/thirdparty/mailgun/v1/mailgun.proto index c08753e1..4004768a 100644 --- a/rbt/thirdparty/mailgun/v1/mailgun.proto +++ b/rbt/thirdparty/mailgun/v1/mailgun.proto @@ -19,7 +19,8 @@ import "google/protobuf/timestamp.proto"; /** * A single message sent using the integration. * - * Created and scheduled using its constructor: `await Message.Send(...)`. + * Created and scheduled using its constructor: + * `await Message.factory.Send(...)`. */ service MessageMethods { /** diff --git a/reboot/cli/commands/cloud/up.py b/reboot/cli/commands/cloud/up.py index 0624b4b1..3c3dc8cf 100644 --- a/reboot/cli/commands/cloud/up.py +++ b/reboot/cli/commands/cloud/up.py @@ -87,7 +87,7 @@ async def _maybe_create_application( bearer_token=api_key, ) try: - await Application.Create(context, qualified_application_name) + await Application.factory.Create(context, qualified_application_name) except Aborted as aborted: match aborted.error: case StateAlreadyConstructed(): # type: ignore[misc] diff --git a/reboot/demos/fig/backend/src/main.ts b/reboot/demos/fig/backend/src/main.ts index 9f4de37a..33f18b9d 100644 --- a/reboot/demos/fig/backend/src/main.ts +++ b/reboot/demos/fig/backend/src/main.ts @@ -7,9 +7,9 @@ import { FigBoardServicer, FigServicer } from "./fig_servicer.js"; import { UserServicer, UsersServicer } from "./user_servicer.js"; const initialize = async (context) => { - await FigBoard.create(context, FIG_BOARD_ID); + await FigBoard.factory.create(context, FIG_BOARD_ID); - await Users.create(context, USERS_ID); + await Users.factory.create(context, USERS_ID); }; new Application({ diff --git a/reboot/demos/fig/backend/src/user_servicer.ts b/reboot/demos/fig/backend/src/user_servicer.ts index 0ad66355..cd898af6 100644 --- a/reboot/demos/fig/backend/src/user_servicer.ts +++ b/reboot/demos/fig/backend/src/user_servicer.ts @@ -52,7 +52,7 @@ export class UsersServicer extends Users.Servicer { this.state.userIds.push(request.userId); - await User.create(context, request.userId); + await User.factory.create(context, request.userId); return {}; } diff --git a/reboot/examples/agent-wiki/backend/src/servicers/wiki.py b/reboot/examples/agent-wiki/backend/src/servicers/wiki.py index 7df45abf..30e7582f 100644 --- a/reboot/examples/agent-wiki/backend/src/servicers/wiki.py +++ b/reboot/examples/agent-wiki/backend/src/servicers/wiki.py @@ -264,7 +264,7 @@ async def create_page( content. Returns the new page's state ID, which you should link to from the wiki's markdown as `Page:`.""" - page, _ = await Page.create( + page, _ = await Page.factory.create( context, title=title, content=content, @@ -288,7 +288,7 @@ async def create_wiki( context.auth.user_id if context.auth is not None and context.auth.user_id is not None else "" ) - wiki, _ = await Wiki.create( + wiki, _ = await Wiki.factory.create( context, name=request.name, description=request.description, @@ -363,7 +363,7 @@ async def add_transcript( ) -> WikiAddTranscriptResponse: """Create a new Transcript belonging to this Wiki and record it as pending ingestion on the Wiki.""" - transcript, _ = await Transcript.create( + transcript, _ = await Transcript.factory.create( context, messages=list(request.messages), owner_id=self.state.owner_id, diff --git a/reboot/examples/agent-wiki/backend/tests/wiki_test.py b/reboot/examples/agent-wiki/backend/tests/wiki_test.py index 655f6c39..804b71f9 100644 --- a/reboot/examples/agent-wiki/backend/tests/wiki_test.py +++ b/reboot/examples/agent-wiki/backend/tests/wiki_test.py @@ -162,7 +162,7 @@ async def test_wiki_get_and_update(self) -> None: async def test_page_crud(self) -> None: """`Page.create` / `get` / `update` round-trip the title and markdown body.""" - page, _ = await Page.create( + page, _ = await Page.factory.create( self.context, title="My Page", content="Initial body.", @@ -188,7 +188,7 @@ async def test_transcript_crud(self) -> None: TranscriptMessage(role="user", content="Hello"), TranscriptMessage(role="assistant", content="Hi!"), ] - transcript, _ = await Transcript.create( + transcript, _ = await Transcript.factory.create( self.context, messages=messages, owner_id=self.user_id, diff --git a/reboot/examples/ai-chat-counter-dashboard/backend/src/servicers/counter.py b/reboot/examples/ai-chat-counter-dashboard/backend/src/servicers/counter.py index 9c5cb8f7..9eeb8429 100644 --- a/reboot/examples/ai-chat-counter-dashboard/backend/src/servicers/counter.py +++ b/reboot/examples/ai-chat-counter-dashboard/backend/src/servicers/counter.py @@ -22,7 +22,7 @@ async def create_counter( request: CreateCounterRequest, ) -> CreateCounterResponse: """Create a new Counter and return its ID.""" - counter, _ = await Counter.create( + counter, _ = await Counter.factory.create( context, description=request.description ) self.state.counter_ids.append(counter.state_id) diff --git a/reboot/examples/ai-chat-counter/backend/src/servicers/counter.py b/reboot/examples/ai-chat-counter/backend/src/servicers/counter.py index ba6952e8..59bfe4c9 100644 --- a/reboot/examples/ai-chat-counter/backend/src/servicers/counter.py +++ b/reboot/examples/ai-chat-counter/backend/src/servicers/counter.py @@ -42,7 +42,7 @@ async def create_counter( request: CreateCounterRequest, ) -> CreateCounterResponse: """Create a new Counter and return its ID.""" - counter, _ = await Counter.create( + counter, _ = await Counter.factory.create( context, description=request.description, owner_id=context.state_id, diff --git a/reboot/examples/bank-nodejs/backend/src/bank_servicer.ts b/reboot/examples/bank-nodejs/backend/src/bank_servicer.ts index 32cfefce..c9fad9a7 100644 --- a/reboot/examples/bank-nodejs/backend/src/bank_servicer.ts +++ b/reboot/examples/bank-nodejs/backend/src/bank_servicer.ts @@ -36,9 +36,13 @@ export class BankServicer extends Bank.Servicer { this.state.accountIds.push(newAccountId); // Let's go create the account. - const [account, response] = await Account.open(context, newAccountId, { - customerName: request.customerName, - }); + const [account, response] = await Account.factory.open( + context, + newAccountId, + { + customerName: request.customerName, + } + ); return { accountId: newAccountId }; } diff --git a/reboot/examples/bank-nodejs/backend/tests/test.ts b/reboot/examples/bank-nodejs/backend/tests/test.ts index c45ad476..83511724 100644 --- a/reboot/examples/bank-nodejs/backend/tests/test.ts +++ b/reboot/examples/bank-nodejs/backend/tests/test.ts @@ -14,7 +14,7 @@ function reportErrorToUser(errorMessage: string): void { async function performErroringWithdrawal(context: any): Promise { const accountId = "account-nodejs"; - const [account] = await Account.open(context, accountId, { + const [account] = await Account.factory.open(context, accountId, { customerName: "Tony", }); diff --git a/reboot/examples/bank-pydantic/backend/src/bank_servicer.py b/reboot/examples/bank-pydantic/backend/src/bank_servicer.py index eddaba5b..79f5d847 100644 --- a/reboot/examples/bank-pydantic/backend/src/bank_servicer.py +++ b/reboot/examples/bank-pydantic/backend/src/bank_servicer.py @@ -31,7 +31,7 @@ async def sign_up( context: TransactionContext, request: Bank.SignUpRequest, ) -> None: - await Customer.sign_up(context, request.customer_id) + await Customer.factory.sign_up(context, request.customer_id) await SortedMap.ref(self.state.customer_ids_map_id).insert( context, diff --git a/reboot/examples/bank-pydantic/backend/src/customer_servicer.py b/reboot/examples/bank-pydantic/backend/src/customer_servicer.py index 32443812..596bcc87 100644 --- a/reboot/examples/bank-pydantic/backend/src/customer_servicer.py +++ b/reboot/examples/bank-pydantic/backend/src/customer_servicer.py @@ -29,7 +29,7 @@ async def open_account( account_id = str(uuid.uuid4()) self.state.account_ids.append(account_id) - account, _ = await Account.open( + account, _ = await Account.factory.open( context, account_id, ) diff --git a/reboot/examples/bank-pydantic/backend/src/main.py b/reboot/examples/bank-pydantic/backend/src/main.py index 70a385dd..e430875a 100644 --- a/reboot/examples/bank-pydantic/backend/src/main.py +++ b/reboot/examples/bank-pydantic/backend/src/main.py @@ -16,7 +16,7 @@ async def initialize(context: InitializeContext): - await Bank.create(context, SINGLETON_BANK_ID) + await Bank.factory.create(context, SINGLETON_BANK_ID) async def main(): diff --git a/reboot/examples/bank-pydantic/backend/tests/full_bank_test.py b/reboot/examples/bank-pydantic/backend/tests/full_bank_test.py index 04e39db2..4fd3c483 100644 --- a/reboot/examples/bank-pydantic/backend/tests/full_bank_test.py +++ b/reboot/examples/bank-pydantic/backend/tests/full_bank_test.py @@ -150,7 +150,7 @@ async def test_transfer(self) -> None: ) ) context = self.rbt.create_external_context(name=f"test-{self.id()}") - bank, response = await Bank.create(context, BANK_ID) + bank, response = await Bank.factory.create(context, BANK_ID) # Assert that the constructor returns 'None' as described in # Pydantic schema. @@ -237,10 +237,10 @@ async def test_overdraft(self) -> None: ) ) context = self.rbt.create_external_context(name=f"test-{self.id()}") - await Bank.create(context, BANK_ID) + await Bank.factory.create(context, BANK_ID) ACCOUNT_ID = "test-overdraft-account" - account, _ = await Account.open(context, ACCOUNT_ID) + account, _ = await Account.factory.open(context, ACCOUNT_ID) try: await account.withdraw(context, amount=50.50) raise Exception("Expected `OverdraftError` to be thrown") @@ -260,11 +260,11 @@ async def test_tasks(self) -> None: ) ) context = self.rbt.create_external_context(name=f"test-{self.id()}") - await Bank.create(context, BANK_ID) + await Bank.factory.create(context, BANK_ID) ACCOUNT_ID = "test-overdraft-account" - account, _ = await Account.open(context, ACCOUNT_ID) + account, _ = await Account.factory.open(context, ACCOUNT_ID) task = await account.spawn().deposit(context, amount=10.0) diff --git a/reboot/examples/bank-zod/backend/src/bank.ts b/reboot/examples/bank-zod/backend/src/bank.ts index e87babb3..5eece5a5 100644 --- a/reboot/examples/bank-zod/backend/src/bank.ts +++ b/reboot/examples/bank-zod/backend/src/bank.ts @@ -51,7 +51,7 @@ export const BankServicer = Bank.servicer({ state: Bank.State, { customerId }: Bank.SignUpRequest ): Promise<[Bank.State]> => { - await Customer.signUp(context, customerId); + await Customer.factory.signUp(context, customerId); // Save the account ID to our _distributed_ map using a UUIDv7 // to get a "timestamp" based ordering. diff --git a/reboot/examples/bank-zod/backend/src/customer.ts b/reboot/examples/bank-zod/backend/src/customer.ts index 7c19bedf..8aa6b1e3 100644 --- a/reboot/examples/bank-zod/backend/src/customer.ts +++ b/reboot/examples/bank-zod/backend/src/customer.ts @@ -29,7 +29,7 @@ export const CustomerServicer = Customer.servicer({ const accountId = uuidv4(); state.accountIds.push(accountId); - const [account] = await Account.open(context, accountId, {}); + const [account] = await Account.factory.open(context, accountId, {}); await account.deposit(context, { amount: initialDeposit }); diff --git a/reboot/examples/bank-zod/backend/src/main.ts b/reboot/examples/bank-zod/backend/src/main.ts index 40d615db..88a97ce8 100644 --- a/reboot/examples/bank-zod/backend/src/main.ts +++ b/reboot/examples/bank-zod/backend/src/main.ts @@ -7,7 +7,7 @@ import { CustomerServicer } from "./customer.js"; const SINGLETON_BANK_ID = "reboot-bank"; const initialize = async (context) => { - await Bank.create(context, SINGLETON_BANK_ID); + await Bank.factory.create(context, SINGLETON_BANK_ID); }; new Application({ diff --git a/reboot/examples/bank-zod/backend/tests/test.ts b/reboot/examples/bank-zod/backend/tests/test.ts index fb55a836..76247e42 100644 --- a/reboot/examples/bank-zod/backend/tests/test.ts +++ b/reboot/examples/bank-zod/backend/tests/test.ts @@ -19,7 +19,7 @@ function reportErrorToUser(errorMessage: string): void { async function performErroringWithdrawal(context: any): Promise { const accountId = "account-nodejs"; - const [account] = await Account.open(context, accountId, {}); + const [account] = await Account.factory.open(context, accountId, {}); try { await account.withdraw(context, { amount: 65 }); @@ -66,7 +66,7 @@ test("Calling Bank.SignUp", async (t) => { await t.test("Sign Up", async (t) => { const context = rbt.createExternalContext("test"); - const [bank] = await Bank.create(context, "bank-nodejs"); + const [bank] = await Bank.factory.create(context, "bank-nodejs"); const response = await bank.signUp(context, { customerId: "test@reboot.dev", @@ -152,7 +152,7 @@ test("Transfer with Customer", async (t) => { await t.test("Sign Up", async (t) => { const context = rbt.createExternalContext("test"); - const [bank] = await Bank.create(context, "bank-nodejs"); + const [bank] = await Bank.factory.create(context, "bank-nodejs"); const CUSTOMER_ID_1 = "test@reboot.dev"; const CUSTOMER_ID_2 = "test2@reboot.dev"; diff --git a/reboot/examples/bank/backend/src/main.py b/reboot/examples/bank/backend/src/main.py index e5fca3ac..8b70111f 100644 --- a/reboot/examples/bank/backend/src/main.py +++ b/reboot/examples/bank/backend/src/main.py @@ -161,7 +161,7 @@ async def sign_up( account_id = request.account_id if mailgun_api_key := await self._mailgun_api_key(): - await mailgun.Message.send( + await mailgun.Message.factory.send( context, None, Options(bearer_token=mailgun_api_key), @@ -173,7 +173,7 @@ async def sign_up( text=self._text_email, ) - account, _ = await Account.open(context, account_id) + account, _ = await Account.factory.open(context, account_id) await account.deposit(context, amount=request.initial_deposit) @@ -213,7 +213,7 @@ async def _mailgun_api_key(self) -> Optional[str]: async def initialize(context: InitializeContext): - await Bank.create(context, SINGLETON_BANK_ID) + await Bank.factory.create(context, SINGLETON_BANK_ID) async def main(): diff --git a/reboot/examples/boutique/backend/src/checkout/servicer.py b/reboot/examples/boutique/backend/src/checkout/servicer.py index 65145c4d..e46d73f7 100644 --- a/reboot/examples/boutique/backend/src/checkout/servicer.py +++ b/reboot/examples/boutique/backend/src/checkout/servicer.py @@ -107,7 +107,7 @@ async def place_order( confirmation = template.render(order=order_result) if mailgun_api_key := await self._mailgun_api_key(): - await Message.send( + await Message.factory.send( context, Options(bearer_token=mailgun_api_key), recipient=request.email, diff --git a/reboot/examples/boutique/backend/src/main.py b/reboot/examples/boutique/backend/src/main.py index 68f4ad5f..4e54ea20 100644 --- a/reboot/examples/boutique/backend/src/main.py +++ b/reboot/examples/boutique/backend/src/main.py @@ -11,9 +11,11 @@ async def initialize(context): - await Checkout.create(context, CHECKOUT_ACTOR_ID) + await Checkout.factory.create(context, CHECKOUT_ACTOR_ID) - await ProductCatalog.load_products(context, PRODUCT_CATALOG_ACTOR_ID) + await ProductCatalog.factory.load_products( + context, PRODUCT_CATALOG_ACTOR_ID + ) async def main(): diff --git a/reboot/examples/chick-potle/backend/src/servicers/food.py b/reboot/examples/chick-potle/backend/src/servicers/food.py index 7b884eb7..c597f8fb 100644 --- a/reboot/examples/chick-potle/backend/src/servicers/food.py +++ b/reboot/examples/chick-potle/backend/src/servicers/food.py @@ -115,7 +115,7 @@ async def start_order( # authorizer only admits that user (or app-internal callers), so # `context.state_id` is the ordering user's ID — even for # app-internal calls, which carry no `context.auth`. - order, _ = await FoodOrder.create( + order, _ = await FoodOrder.factory.create( context, menu=MENU_ITEMS, user_id=context.state_id, diff --git a/reboot/examples/docubot/backend/src/main.ts b/reboot/examples/docubot/backend/src/main.ts index bfe6cb1f..5b53ec5d 100644 --- a/reboot/examples/docubot/backend/src/main.ts +++ b/reboot/examples/docubot/backend/src/main.ts @@ -4,7 +4,7 @@ import { DOCUBOT_ASSISTANT_ID } from "../../constants.js"; import docubot from "@reboot-dev/docubot"; const initialize = async (context) => { - await Assistant.create(context, DOCUBOT_ASSISTANT_ID, { + await Assistant.factory.create(context, DOCUBOT_ASSISTANT_ID, { name: DOCUBOT_ASSISTANT_ID, url: "https://docs.reboot.dev", }); diff --git a/reboot/examples/kcdc-2025/backend/src/main.py b/reboot/examples/kcdc-2025/backend/src/main.py index f011d1bd..884e255a 100644 --- a/reboot/examples/kcdc-2025/backend/src/main.py +++ b/reboot/examples/kcdc-2025/backend/src/main.py @@ -13,9 +13,9 @@ async def initialize(context): - await Channel.create(context, "channel") + await Channel.factory.create(context, "channel") - await Chatbot.create( + await Chatbot.factory.create( context, name="Fact Checker", channel_id="channel", diff --git a/reboot/examples/kcdc-2025/backend/src/servicers/channel.py b/reboot/examples/kcdc-2025/backend/src/servicers/channel.py index 0290d766..32aa3377 100644 --- a/reboot/examples/kcdc-2025/backend/src/servicers/channel.py +++ b/reboot/examples/kcdc-2025/backend/src/servicers/channel.py @@ -32,7 +32,7 @@ async def create( context: TransactionContext, request: ChannelCreateRequest, ) -> ChannelCreateResponse: - await Index.create( + await Index.factory.create( context, messages_id(context.state_id), order=100, diff --git a/reboot/examples/kcdc-2025/backend/src/servicers/chatbot.py b/reboot/examples/kcdc-2025/backend/src/servicers/chatbot.py index b656705b..161f0aaf 100644 --- a/reboot/examples/kcdc-2025/backend/src/servicers/chatbot.py +++ b/reboot/examples/kcdc-2025/backend/src/servicers/chatbot.py @@ -76,7 +76,7 @@ async def create( # Create our messages reactions index so folks can react to # our messages. - await Index.create( + await Index.factory.create( context, f'{request.name}-messages-reactions', order=100, diff --git a/reboot/examples/kcdc-2025/backend/src/servicers/user.py b/reboot/examples/kcdc-2025/backend/src/servicers/user.py index 93f9fa23..e8862dbc 100644 --- a/reboot/examples/kcdc-2025/backend/src/servicers/user.py +++ b/reboot/examples/kcdc-2025/backend/src/servicers/user.py @@ -62,7 +62,7 @@ async def create( if context.constructor: users = Users.ref(USERS_SINGLETON) await users.add(context, user=context.state_id) - await Index.create( + await Index.factory.create( context, self._messages_reactions.state_id, order=100, @@ -94,7 +94,7 @@ async def add_chatbot( request: AddChatbotRequest, ) -> AddChatbotResponse: - chatbot, _ = await Chatbot.create( + chatbot, _ = await Chatbot.factory.create( context, name=request.name, channel_id=request.channel_id, diff --git a/reboot/examples/monorepo/bank/backend/src/bank_servicer.py b/reboot/examples/monorepo/bank/backend/src/bank_servicer.py index b14ee6e8..cabaa5b1 100644 --- a/reboot/examples/monorepo/bank/backend/src/bank_servicer.py +++ b/reboot/examples/monorepo/bank/backend/src/bank_servicer.py @@ -31,7 +31,7 @@ async def sign_up( new_account_id = str(uuid.uuid4()) # Let's go create the account. - account, _ = await Account.open( + account, _ = await Account.factory.open( context, new_account_id, customer_name=request.customer_name, diff --git a/reboot/examples/monorepo/bank/backend/tests/account_servicer_test.py b/reboot/examples/monorepo/bank/backend/tests/account_servicer_test.py index ddb89acc..77343e44 100644 --- a/reboot/examples/monorepo/bank/backend/tests/account_servicer_test.py +++ b/reboot/examples/monorepo/bank/backend/tests/account_servicer_test.py @@ -28,7 +28,7 @@ async def test_basics(self) -> None: # Create the state machine by calling its constructor. The fact that the # state machine _has_ a constructor means that this step is required # before other methods can be called on it. - account, _ = await Account.open(context, customer_name="Alice") + account, _ = await Account.factory.open(context, customer_name="Alice") # We can now call methods on the state machine. It should have a balance # of 0. @@ -78,7 +78,7 @@ async def test_send_welcome_email(self, mock_send_email) -> None: # When we open an account, we expect the user to receive a welcome # email. - account, open_response = await Account.open( + account, open_response = await Account.factory.open( context, customer_name="Alice", ) diff --git a/reboot/examples/monorepo/hello-constructors/backend/src/main.py b/reboot/examples/monorepo/hello-constructors/backend/src/main.py index 28333944..da9c4d09 100644 --- a/reboot/examples/monorepo/hello-constructors/backend/src/main.py +++ b/reboot/examples/monorepo/hello-constructors/backend/src/main.py @@ -12,7 +12,7 @@ async def initialize(context: InitializeContext): # Explicitly create the state machine. - hello, _ = await Hello.create( + hello, _ = await Hello.factory.create( context, EXAMPLE_STATE_MACHINE_ID, initial_message="Welcome! This message was sent by a constructor.", diff --git a/reboot/examples/monorepo/hello-constructors/backend/tests/hello_servicer_test.py b/reboot/examples/monorepo/hello-constructors/backend/tests/hello_servicer_test.py index c9829660..0a9bb5be 100644 --- a/reboot/examples/monorepo/hello-constructors/backend/tests/hello_servicer_test.py +++ b/reboot/examples/monorepo/hello-constructors/backend/tests/hello_servicer_test.py @@ -22,7 +22,9 @@ async def test_hello_constructors(self) -> None: # Create the state machine by calling its constructor. The fact that the # state machine _has_ a constructor means that this step is required # before other methods can be called on it. - hello, _ = await Hello.create(context, initial_message="first message") + hello, _ = await Hello.factory.create( + context, initial_message="first message" + ) # Send another message. await hello.send(context, message="second message") diff --git a/reboot/examples/reboot-swag-store/backend/src/main.py b/reboot/examples/reboot-swag-store/backend/src/main.py index dad9770f..42915e12 100644 --- a/reboot/examples/reboot-swag-store/backend/src/main.py +++ b/reboot/examples/reboot-swag-store/backend/src/main.py @@ -27,7 +27,7 @@ async def initialize(context) -> None: """Ensure the coupon book exists (creates initial codes on first run).""" - await CouponBook.create(context, COUPON_BOOK_ID) + await CouponBook.factory.create(context, COUPON_BOOK_ID) async def main() -> None: diff --git a/reboot/examples/reboot-swag-store/backend/src/servicers/store.py b/reboot/examples/reboot-swag-store/backend/src/servicers/store.py index 9ba80c7d..6db10282 100644 --- a/reboot/examples/reboot-swag-store/backend/src/servicers/store.py +++ b/reboot/examples/reboot-swag-store/backend/src/servicers/store.py @@ -76,7 +76,7 @@ async def create_cart( this method), and is recorded on the cart so only this session can mutate it.""" owner_id = context.auth.user_id if context.auth else "" - cart, _ = await Cart.create(context, owner_id=owner_id) + cart, _ = await Cart.factory.create(context, owner_id=owner_id) return User.CreateCartResponse( cart_id=cart.state_id, ) @@ -272,7 +272,7 @@ async def checkout( variant_ids = [item.variant_id for item in self.state.items] quantities = [item.quantity for item in self.state.items] - order, _ = await Order.create( + order, _ = await Order.factory.create( context, order_id, Order.CreateRequest( diff --git a/reboot/examples/reboot-swag-store/backend/tests/store_servicer_test.py b/reboot/examples/reboot-swag-store/backend/tests/store_servicer_test.py index ff926464..0d4e5da3 100644 --- a/reboot/examples/reboot-swag-store/backend/tests/store_servicer_test.py +++ b/reboot/examples/reboot-swag-store/backend/tests/store_servicer_test.py @@ -65,7 +65,7 @@ async def fulfill( async def _initialize(context) -> None: - await CouponBook.create(context, COUPON_BOOK_ID) + await CouponBook.factory.create(context, COUPON_BOOK_ID) class TestStoreServicers(unittest.IsolatedAsyncioTestCase): @@ -179,7 +179,7 @@ async def test_different_user_cannot_touch_cart(self) -> None: don't probe the writers from the wrong user because Reboot's effect-validation can't safely retry a non-idempotent mutation that aborted.""" - cart, _ = await Cart.create( + cart, _ = await Cart.factory.create( self.context, owner_id=self.user_id, ) @@ -204,7 +204,9 @@ async def test_different_user_cannot_touch_cart(self) -> None: # ----- Cart.add_item / get_cart / remove_item --------------- async def test_add_item_and_get_cart(self) -> None: - cart, _ = await Cart.create(self.context, owner_id=self.user_id) + cart, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) await cart.add_item(self.context, quantity=2, **HOODIE) response = await cart.get_cart(self.context) self.assertEqual(len(response.items), 1) @@ -217,7 +219,9 @@ async def test_add_item_and_get_cart(self) -> None: async def test_add_same_variant_increments_quantity( self, ) -> None: - cart, _ = await Cart.create(self.context, owner_id=self.user_id) + cart, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) await cart.add_item(self.context, quantity=2, **HOODIE) await cart.add_item(self.context, quantity=1, **HOODIE) response = await cart.get_cart(self.context) @@ -227,7 +231,9 @@ async def test_add_same_variant_increments_quantity( async def test_add_different_variant_adds_a_line( self, ) -> None: - cart, _ = await Cart.create(self.context, owner_id=self.user_id) + cart, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) small = {**HOODIE, "variant_id": "hoodie-1-s", "size": "S"} await cart.add_item(self.context, quantity=1, **HOODIE) await cart.add_item(self.context, quantity=1, **small) @@ -237,7 +243,9 @@ async def test_add_different_variant_adds_a_line( self.assertEqual(sizes, ["L", "S"]) async def test_remove_item(self) -> None: - cart, _ = await Cart.create(self.context, owner_id=self.user_id) + cart, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) await cart.add_item(self.context, quantity=1, **HOODIE) await cart.remove_item(self.context, product_id="hoodie-1") response = await cart.get_cart(self.context) @@ -248,7 +256,9 @@ async def test_remove_item(self) -> None: async def test_checkout_on_empty_cart_raises_cart_empty( self, ) -> None: - cart, _ = await Cart.create(self.context, owner_id=self.user_id) + cart, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) with self.assertRaises(Cart.CheckoutAborted) as cm: await cart.checkout( self.context, @@ -260,7 +270,9 @@ async def test_checkout_on_empty_cart_raises_cart_empty( async def test_checkout_with_invalid_coupon_raises( self, ) -> None: - cart, _ = await Cart.create(self.context, owner_id=self.user_id) + cart, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) await cart.add_item(self.context, quantity=1, **HOODIE) with self.assertRaises(Cart.CheckoutAborted) as cm: await cart.checkout( @@ -274,7 +286,9 @@ async def test_checkout_with_invalid_coupon_raises( self.assertEqual(len(response.items), 1) async def test_checkout_happy_path(self) -> None: - cart, _ = await Cart.create(self.context, owner_id=self.user_id) + cart, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) await cart.add_item(self.context, quantity=2, **HOODIE) code = await self._mint_coupon() @@ -305,7 +319,9 @@ async def test_checkout_redeems_coupon_so_reuse_fails( ) -> None: code = await self._mint_coupon() - cart, _ = await Cart.create(self.context, owner_id=self.user_id) + cart, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) await cart.add_item(self.context, quantity=1, **HOODIE) await cart.checkout( self.context, @@ -314,7 +330,9 @@ async def test_checkout_redeems_coupon_so_reuse_fails( ) # Same code a second time should no longer be valid. - cart2, _ = await Cart.create(self.context, owner_id=self.user_id) + cart2, _ = await Cart.factory.create( + self.context, owner_id=self.user_id + ) await cart2.add_item(self.context, quantity=1, **HOODIE) with self.assertRaises(Cart.CheckoutAborted) as cm: await cart2.checkout( diff --git a/reboot/ping/ping.py b/reboot/ping/ping.py index 82b56745..2915ff02 100644 --- a/reboot/ping/ping.py +++ b/reboot/ping/ping.py @@ -166,7 +166,7 @@ async def create_counter( context: TransactionContext, request: CreateCounterRequest, ) -> CreateCounterResponse: - counter, _ = await Counter.create( + counter, _ = await Counter.factory.create( context, description=request.description, owner_id=context.state_id, diff --git a/reboot/plugin/skills/chat-app/SKILL.md b/reboot/plugin/skills/chat-app/SKILL.md index e30e9897..05c00a1e 100644 --- a/reboot/plugin/skills/chat-app/SKILL.md +++ b/reboot/plugin/skills/chat-app/SKILL.md @@ -149,7 +149,7 @@ exactly one of them — the step that needs it. `self.state_id`); `self.ref().schedule(...)`. - `python/references/rpc-calls.md` — kwargs, not Request wrappers. - `python/references/rpc-constructor-calls.md` — - `Service.create(context, id)` semantics. + `Service.factory.create(context, id)` semantics. - `python/references/servicer-workflow.md` — only when you declared a `Workflow`, and then top to bottom: the `@classmethod` / `WorkflowContext` declaration shape, the call-classification @@ -158,7 +158,7 @@ exactly one of them — the step that needs it. `until` / `until_changes`, and workflow exit semantics. - [`references/servicer-patterns.md`](references/servicer-patterns.md) — the chat-app servicer shapes: `UserServicer` calling - `.create(context)`, a Workflow Servicer with `MyType.ref()` + `.factory.create(context)`, a Workflow Servicer with `MyType.ref()` (no-arg) magic, inline writers via `.per_workflow("alias").write(context, fn)` / `.per_iteration("alias").write(...)` / `.always().write(...)`, @@ -400,7 +400,7 @@ Before writing code, analyze the user's request: 3. **User methods**: How does the AI create instances of application types? Each gets a `Transaction` on `User` that calls - `.create(context)`, then registers the new ID in the + `.factory.create(context)`, then registers the new ID in the appropriate container (Shape B or C above). 4. **State shape (per type)**: Fields, types — lists, nested objects, primitives. Each gets `Field(tag=N)`. **Nested `Model` @@ -508,7 +508,7 @@ that warn you are accreting concerns, and the split pattern, are in Full pydantic shape in [`references/api-method-types.md`](references/api-method-types.md); -the `UserServicer` + `.create(context)` pattern in +the `UserServicer` + `.factory.create(context)` pattern in [`references/servicer-patterns.md`](references/servicer-patterns.md). ### Tool Exposure Control diff --git a/reboot/plugin/skills/chat-app/references/gotchas.md b/reboot/plugin/skills/chat-app/references/gotchas.md index 288de10b..9d8eebaf 100644 --- a/reboot/plugin/skills/chat-app/references/gotchas.md +++ b/reboot/plugin/skills/chat-app/references/gotchas.md @@ -10,7 +10,7 @@ tags: gotchas, traps, errors, mcp, ui, factory, workflow, ref, schedule, optiona For the rest of the trip-list — `.rbtrc` line-based, no `__init__.py` in `api/`, pydantic Field zero-default rule, `self.ref().state_id` not `self.state_id`, kwargs not Request wrappers, generated import -paths, `Service.create(context, id)` semantics, register-all-Servicers +paths, `Service.factory.create(context, id)` semantics, register-all-Servicers — see `python/references/patterns-common-gotchas.md` and the per-topic references. diff --git a/reboot/plugin/skills/chat-app/references/servicer-patterns.md b/reboot/plugin/skills/chat-app/references/servicer-patterns.md index db7cc8d9..35315344 100644 --- a/reboot/plugin/skills/chat-app/references/servicer-patterns.md +++ b/reboot/plugin/skills/chat-app/references/servicer-patterns.md @@ -16,7 +16,10 @@ wrappers, raise typed `Aborted`) are in - One Servicer class per type — `UserServicer` plus one per application type. - The User Servicer's `create_` Transaction calls - `.create(context)` and returns the `state_id` in a response. + `.factory.create(context)` and returns the `state_id` in a + response. Constructors live under the `factory` namespace on the + state class (`.factory.create(...)`), keeping the top-level + state-class namespace free for framework methods like `ref()`. - Workflow Servicers use `MyType.ref()` (no args, picks up `state_id` from `WorkflowContext`) — see Gotcha #11 below; `cls.ref()` and `self.ref()` are both wrong. @@ -44,9 +47,10 @@ class UserServicer(User.Servicer): """Create a new Counter and return its ID.""" # Factory create: pass request fields as keyword args directly # — do NOT wrap in a Request object. - # No-args: Counter.create(context) - # With args: Counter.create(context, title="...", count=0) - counter, _ = await Counter.create(context) + # No-args: Counter.factory.create(context) + # With args: Counter.factory.create( + # context, title="...", count=0) + counter, _ = await Counter.factory.create(context) return User.CreateCounterResponse( counter_id=counter.state_id, ) @@ -188,7 +192,7 @@ class UserServicer(User.Servicer): context: TransactionContext, request: User.CreateGameRequest, ) -> User.CreateGameResponse: - game, _ = await Game.create(context, ...) + game, _ = await Game.factory.create(context, ...) # GOOD — schedule the workflow from the transaction. # Empty request: just pass `context`. await Game.ref(game.state_id).schedule().autoplay(context) diff --git a/reboot/plugin/skills/python/SKILL.md b/reboot/plugin/skills/python/SKILL.md index c1946136..7e641ddd 100644 --- a/reboot/plugin/skills/python/SKILL.md +++ b/reboot/plugin/skills/python/SKILL.md @@ -301,8 +301,9 @@ The `Agent` runs only inside a `WorkflowContext`, so also read the trap (`await ref.deposit(context, DepositRequest(amount=10))`) is a recurring miss; passes type-check and fails at runtime - `references/rpc-constructor-calls.md` — **always read** when the - agent invokes a constructor: use `.create(context, id, ...)` or - `.(context, id, ...)`, NEVER `.ref(id).(...)` + agent invokes a constructor: use `.factory.create(context, id, ...)` + or `.factory.(context, id, ...)`, NEVER + `.ref(id).(...)` (the trap that skips creation semantics). The factory-declaration side is `servicer-constructor.md`; the call-site side is here diff --git a/reboot/plugin/skills/python/references/_sections.md b/reboot/plugin/skills/python/references/_sections.md index cc4c8c94..934a4b31 100644 --- a/reboot/plugin/skills/python/references/_sections.md +++ b/reboot/plugin/skills/python/references/_sections.md @@ -47,7 +47,7 @@ This file defines the rule categories for Reboot Python best practices. Rules ar ## 9. RPC (rpc) **Impact:** MEDIUM -**Description:** Calling actors via `Service.ref(id)` and `await ref.method(context, ...)`. Constructor calls (`Service.create`), fan-out via `Service.forall(ids).method(context)`, and the kwargs-not-Request convention. +**Description:** Calling actors via `Service.ref(id)` and `await ref.method(context, ...)`. Constructor calls (`Service.factory.create`), fan-out via `Service.forall(ids).method(context)`, and the kwargs-not-Request convention. ## 10. Scheduling (scheduling) diff --git a/reboot/plugin/skills/python/references/api-pydantic.md b/reboot/plugin/skills/python/references/api-pydantic.md index a0a9ff17..18186193 100644 --- a/reboot/plugin/skills/python/references/api-pydantic.md +++ b/reboot/plugin/skills/python/references/api-pydantic.md @@ -132,8 +132,8 @@ Error while parsing option value for "method": Message type ```python # OK -open=Writer(... factory=True ...), # Account.Open(ctx, id, ...) -place=Transaction(... factory=True ...), # Order.Place(ctx, id, ...) +open=Writer(... factory=True ...), # Account.factory.open(ctx, id, ...) +place=Transaction(... factory=True ...), # Order.factory.place(ctx, id, ...) # REJECTED by `rbt generate` hello=Workflow(... factory=True ...), # codegen error diff --git a/reboot/plugin/skills/python/references/auth-external-api-calls.md b/reboot/plugin/skills/python/references/auth-external-api-calls.md index bda29346..081f7b49 100644 --- a/reboot/plugin/skills/python/references/auth-external-api-calls.md +++ b/reboot/plugin/skills/python/references/auth-external-api-calls.md @@ -174,7 +174,7 @@ class UserServicer(User.Servicer): request: User.ConnectAcmeRequest, ) -> User.ConnectAcmeResponse: user_id = self.ref().state_id - ciphertext, _ = await Ciphertext.encrypt( + ciphertext, _ = await Ciphertext.factory.encrypt( context, plaintext=request.api_key.encode(), associated_data=make_associated_data( @@ -316,7 +316,7 @@ await KeyManager.ref(_key_manager_id(GOOGLE)).shred(context, scope=user_id) (any other service): your own authorize + callback routes, callback registered `app_internal=True`, the OAuth `state` HMAC-signed and verified, `OAuthTokenManager.store` called with the app-internal `external_context(request)`. Path C - (the user provides an API key, not OAuth): `Ciphertext.encrypt`, + (the user provides an API key, not OAuth): `Ciphertext.factory.encrypt`, with the returned `state_id` — never the raw key — kept in state. A key the developer holds for the whole app is an application secret (`rbt cloud secret`), not actor state. diff --git a/reboot/plugin/skills/python/references/lifecycle-initialize-hook.md b/reboot/plugin/skills/python/references/lifecycle-initialize-hook.md index c8e2f3b0..b7bf6e3e 100644 --- a/reboot/plugin/skills/python/references/lifecycle-initialize-hook.md +++ b/reboot/plugin/skills/python/references/lifecycle-initialize-hook.md @@ -10,7 +10,7 @@ tags: initialize, InitializeContext, create, singleton, bootstrap > **Critical:** `initialize` runs on **every** application start, so > its calls get an **auto-generated idempotency key** (one per > `actor` + `method`) and run once. Constructors — -> `Service.create(context, id)` / factory methods — are a no-op on +> `Service.factory.create(context, id)` / factory methods — are a no-op on > existing actors. The catch: to call the **same method on the same > actor more than once** you **must** distinguish the calls with > `.idempotently("alias")` (or an explicit `key=`), or the second one @@ -23,7 +23,7 @@ runs against an `InitializeContext` and is the right place to create singletons or seed data that must exist before the first real request. The callback runs each time the application starts; Reboot's idempotent -`Service.create(context, id)` makes calling it on every boot safe. +`Service.factory.create(context, id)` makes calling it on every boot safe. **Incorrect (creating singletons inside a Servicer's `__init__`):** @@ -33,7 +33,7 @@ class BankServicer(Bank.Servicer): def __init__(self): # This won't run "at startup"; it runs the first time # someone references the Bank actor. - Bank.create(...) # also: no context here + Bank.factory.create(...) # also: no context here ``` **Correct (matches the [`reboot-bank-pydantic`](https://github.com/reboot-dev/reboot-bank-pydantic) example, `backend/src/main.py`):** @@ -47,7 +47,7 @@ SINGLETON_BANK_ID = 'SVB' async def initialize(context: InitializeContext): - await Bank.create(context, SINGLETON_BANK_ID) + await Bank.factory.create(context, SINGLETON_BANK_ID) async def main(): @@ -61,7 +61,7 @@ async def main(): If a `Type` does **not** declare a `factory=True` method, Reboot will implicitly create the actor on the first writer call. A simple chat -room can use this — no explicit `ChatRoom.create(...)` is needed when +room can use this — no explicit `ChatRoom.factory.create(...)` is needed when `send` is a `Writer`: ```python @@ -73,13 +73,14 @@ async def initialize(context: InitializeContext): When the API **does** declare a factory (`Writer(... factory=True ...)` or `Transaction(... factory=True ...)`), call it explicitly via -`Service.create(context, id)` or `Service.(context, id, ...)`. +`Service.factory.create(context, id)` or +`Service.factory.(context, id, ...)`. ## Calling the Same Method More Than Once — `.idempotently("alias")` `initialize` auto-generates an idempotency key per `(actor, method)`, so **one** call to a given method is fine bare — that's why -`Service.create(...)` followed by a single `ref.send(...)` works +`Service.factory.create(...)` followed by a single `ref.send(...)` works without any alias. But calling that **same** method on the **same** actor again in the same `initialize` raises: @@ -94,7 +95,7 @@ Give each call a **distinct** `.idempotently("alias")` (or explicit ```python async def initialize(context: InitializeContext): - hello, _ = await Hello.create( + hello, _ = await Hello.factory.create( context, "reboot-hello", initial_message="Welcome!", ) diff --git a/reboot/plugin/skills/python/references/patterns-common-gotchas.md b/reboot/plugin/skills/python/references/patterns-common-gotchas.md index 878258df..b4076cad 100644 --- a/reboot/plugin/skills/python/references/patterns-common-gotchas.md +++ b/reboot/plugin/skills/python/references/patterns-common-gotchas.md @@ -45,16 +45,16 @@ await account.deposit(context, DepositRequest(amount=10)) await account.deposit(context, amount=10) ``` -### 5. Constructor Calls Use `Service.create` / `Service.` +### 5. Constructor Calls Use `Service.factory.create` / `Service.factory.` -Don't call a constructor through `.ref(id).method(...)`. Use the factory -form so creation semantics apply: +Don't call a constructor through `.ref(id).method(...)`. Invoke it +through the `factory` namespace so creation semantics apply: ```python # Wrong: await Account.ref(id).open(context) # Right: -account, _ = await Account.open(context, id) +account, _ = await Account.factory.open(context, id) ``` ### 6. Servicer `authorizer()` Returns an Instance @@ -105,8 +105,8 @@ Workflow, Not a Transaction" in `servicer-transaction.md`. ### 9. `initialize` Runs on Every Restart -It's idempotent only if **you** make it so. Use `Service.create` and -`context.constructor` to gate set-once work. +It's idempotent only if **you** make it so. Use `Service.factory.create` +and `context.constructor` to gate set-once work. ### 10. Don't Hand-Edit `*_rbt.py` diff --git a/reboot/plugin/skills/python/references/patterns-idempotency.md b/reboot/plugin/skills/python/references/patterns-idempotency.md index 6ad74830..f6d6759a 100644 --- a/reboot/plugin/skills/python/references/patterns-idempotency.md +++ b/reboot/plugin/skills/python/references/patterns-idempotency.md @@ -8,12 +8,12 @@ tags: patterns, idempotency, initialize, constructor, restart ## Make Constructor and `initialize` Calls Idempotent > **Critical:** `initialize` runs on every restart, and Reboot may -> retry transactions internally. `Service.create(context, id)` is the +> retry transactions internally. `Service.factory.create(context, id)` is the > idempotent creation primitive — safe to call repeatedly. Inside a > reusable constructor, gate set-once fields on `context.constructor`. The `initialize` hook runs every time the application starts. Anything it -does must be safe to do repeatedly. Reboot's `Service.create(context, id)` +does must be safe to do repeatedly. Reboot's `Service.factory.create(context, id)` is the canonical idempotent creation primitive: calling it on an existing actor is a no-op. @@ -31,7 +31,7 @@ async def initialize(context: InitializeContext): ```python async def initialize(context: InitializeContext): # Create-once: idempotent on subsequent boots. - await Bank.create(context, SINGLETON_BANK_ID) + await Bank.factory.create(context, SINGLETON_BANK_ID) ``` ## Branch on `context.constructor` for Set-Once Fields diff --git a/reboot/plugin/skills/python/references/rpc-calls.md b/reboot/plugin/skills/python/references/rpc-calls.md index 16a080a9..e8cb7b81 100644 --- a/reboot/plugin/skills/python/references/rpc-calls.md +++ b/reboot/plugin/skills/python/references/rpc-calls.md @@ -55,7 +55,7 @@ Constructor calls return a `(ref, response)` tuple — the ref to the newly-constructed actor and the response from the method: ```python -account, _ = await Account.open(context, request.account_id) +account, _ = await Account.factory.open(context, request.account_id) await account.deposit(context, amount=request.initial_deposit) ``` diff --git a/reboot/plugin/skills/python/references/rpc-constructor-calls.md b/reboot/plugin/skills/python/references/rpc-constructor-calls.md index c5339882..3a24fc68 100644 --- a/reboot/plugin/skills/python/references/rpc-constructor-calls.md +++ b/reboot/plugin/skills/python/references/rpc-constructor-calls.md @@ -1,26 +1,29 @@ --- -title: Use `Service.create` and `Service.` for Constructor Calls +title: Use `Service.factory.create` and `Service.factory.` for Constructor Calls impact: MEDIUM impactDescription: Calling a constructor through `.ref(...).method(...)` skips creation semantics tags: rpc, constructor, create, factory --- -## Use `Service.create` and `Service.` for Constructor Calls +## Use `Service.factory.create` and `Service.factory.` for Constructor Calls > **Critical:** never invoke a constructor through `Service.ref(id).method(...)` -> — that skips creation semantics. Use `await Service.create(context, id)` -> for default constructors and `await Service.(context, id, ...)` -> for named ones. Both return a `(ref, response)` tuple. +> — that skips creation semantics. Use +> `await Service.factory.create(context, id)` for default constructors and +> `await Service.factory.(context, id, ...)` for named ones. +> Both return a `(ref, response)` tuple. A method declared with `factory=True` is the actor's creation path. -Invoke it via the generated factory call: +Invoke it through the `factory` namespace on the state type: -- `await Service.create(context, id)` — for the implicit/default - constructor (e.g., `Bank.create(context, SINGLETON_BANK_ID)`). -- `await Service.(context, id, **kwargs)` — for a named - constructor method (e.g., `Account.open(context, account_id)`). +- `await Service.factory.create(context, id)` — for the implicit/default + constructor (e.g., `Bank.factory.create(context, SINGLETON_BANK_ID)`). +- `await Service.factory.(context, id, **kwargs)` — for a named + constructor method (e.g., `Account.factory.open(context, account_id)`). -Both return a `(ref, response)` tuple. +Both return a `(ref, response)` tuple. Routing constructors through the +`factory` namespace keeps the top level of the state type free for +framework methods like `ref()`. **Incorrect (using `.ref(...).method(...)` for a constructor):** @@ -45,18 +48,18 @@ open=Writer( `main.py`: ```python -account, _ = await Account.open(context, account_id) +account, _ = await Account.factory.open(context, account_id) await account.deposit(context, amount=request.initial_deposit) ``` -## `Service.create(context, id)` Is the Idempotent Default +## `Service.factory.create(context, id)` Is the Idempotent Default When the `Type` has no explicit factory (no `factory=True` method), -use `Service.create` from the `initialize` hook: +use `Service.factory.create` from the `initialize` hook: ```python async def initialize(context: InitializeContext): - await Bank.create(context, SINGLETON_BANK_ID) + await Bank.factory.create(context, SINGLETON_BANK_ID) ``` This is safe to call on every application start; existing actors aren't @@ -68,7 +71,7 @@ The first element of the returned tuple is the ref. Prefer using it directly rather than re-constructing one with `Service.ref(...)`: ```python -account, _ = await Account.open(context, account_id) +account, _ = await Account.factory.open(context, account_id) # Use the returned ref: await account.deposit(context, amount=100) diff --git a/reboot/plugin/skills/python/references/servicer-constructor.md b/reboot/plugin/skills/python/references/servicer-constructor.md index 4dccbf48..2077f37c 100644 --- a/reboot/plugin/skills/python/references/servicer-constructor.md +++ b/reboot/plugin/skills/python/references/servicer-constructor.md @@ -7,10 +7,11 @@ tags: servicer, constructor, context.constructor, create, initialization ## Handle Constructor Methods -> **Critical:** invoke a constructor as `await Service.create(context, id)` -> (or `await Service.(context, id, **kwargs)`), **never** -> as `Service.ref(id).method(...)` — the latter skips creation -> semantics. Inside the implementation, branch on +> **Critical:** invoke a constructor as +> `await Service.factory.create(context, id)` (or +> `await Service.factory.(context, id, **kwargs)`), +> **never** as `Service.ref(id).method(...)` — the latter skips +> creation semantics. Inside the implementation, branch on > `context.constructor` for set-once initial state. A method declared with `factory=True` on its `Writer(...)` or @@ -18,7 +19,7 @@ A method declared with `factory=True` on its `Writer(...)` or The Servicer implementation is just an ordinary writer/transaction method — the _constructor-ness_ shows up in two places: -1. **Caller side**: use `await Service.create(context, id)` (not +1. **Caller side**: use `await Service.factory.create(context, id)` (not `Service.ref(id).method(...)`) to invoke it. 2. **Servicer side**: branch on `context.constructor` to set initial state only on the creation pass. @@ -74,10 +75,10 @@ second call. ```python async def initialize(context: InitializeContext): - await Bank.create(context, SINGLETON_BANK_ID) + await Bank.factory.create(context, SINGLETON_BANK_ID) ``` -`Service.create(context, id)` is **idempotent** when called from the +`Service.factory.create(context, id)` is **idempotent** when called from the `initialize` hook, so it's safe to invoke on every application start. ## Calling from a Transaction @@ -88,11 +89,11 @@ A transaction can create and operate on a new actor in one atomic step: async def sign_up( self, context: TransactionContext, request: Bank.SignUpRequest, ) -> None: - account, _ = await Account.open(context, request.account_id) + account, _ = await Account.factory.open(context, request.account_id) await account.deposit(context, amount=request.initial_deposit) ``` -`Account.open(context, id)` here is the constructor (the `open` method +`Account.factory.open(context, id)` here is the constructor (the `open` method declared `factory=True`) and returns the actor reference plus the response (or `None` when `response=None`). diff --git a/reboot/plugin/skills/python/references/servicer-transaction.md b/reboot/plugin/skills/python/references/servicer-transaction.md index 7b6a75d2..6d4d4323 100644 --- a/reboot/plugin/skills/python/references/servicer-transaction.md +++ b/reboot/plugin/skills/python/references/servicer-transaction.md @@ -97,7 +97,7 @@ async def sign_up( self, context: TransactionContext, request: SignUpRequest, ) -> SignUpResponse: if mailgun_api_key := await self._mailgun_api_key(): - await mailgun.Message.send( + await mailgun.Message.factory.send( context, None, Options(bearer_token=mailgun_api_key), recipient=request.account_id, sender='team@reboot.dev', @@ -107,16 +107,16 @@ async def sign_up( text=self._text_email, ) - account, _ = await Account.open(context, request.account_id) + account, _ = await Account.factory.open(context, request.account_id) await account.deposit(context, amount=request.initial_deposit) return SignUpResponse() ``` -`mailgun.Message.send` is a `Writer` on an in-system mailgun actor — it -does not hit the network itself; it **schedules a workflow** that makes -the actual HTTP send. So the transaction only ever issues in-system -RPCs, and the un-rollback-able external call lives safely in that -workflow. +`mailgun.Message.factory.send` is a `Writer` on an in-system mailgun +actor — it does not hit the network itself; it **schedules a workflow** +that makes the actual HTTP send. So the transaction only ever issues +in-system RPCs, and the un-rollback-able external call lives safely in +that workflow. When _you_ are the one making the external call — an LLM / model API call, a payment charge, an SMS — put it in a `Workflow` method and @@ -166,7 +166,7 @@ orchestration calls where the caller only needs success/failure - `rpc-forall.md` — `Service.forall(ids).method(context, ...)` for fan-out across many actors. - `servicer-constructor.md` — when a transaction also constructs an - actor (e.g. `Account.open(context, id)`). + actor (e.g. `Account.factory.open(context, id)`). - `api-errors.md` — typed errors that roll back the entire transaction. - `servicer-workflow.md` — when one-shot atomicity isn't enough and you need durable, long-running orchestration. diff --git a/reboot/plugin/skills/python/references/state-actor-decomposition.md b/reboot/plugin/skills/python/references/state-actor-decomposition.md index 2ca7ed02..c63c2bd4 100644 --- a/reboot/plugin/skills/python/references/state-actor-decomposition.md +++ b/reboot/plugin/skills/python/references/state-actor-decomposition.md @@ -111,9 +111,9 @@ class UserServicer(User.Servicer): ) -> None: if context.constructor: self.state.display_name = request.display_name - session, _ = await TelegramSession.create(context) + session, _ = await TelegramSession.factory.create(context) self.state.telegram_session_id = session.state_id - manager, _ = await MonitoringManager.create(context) + manager, _ = await MonitoringManager.factory.create(context) self.state.monitoring_manager_id = manager.state_id ``` diff --git a/reboot/plugin/skills/python/references/state-collections.md b/reboot/plugin/skills/python/references/state-collections.md index ebbe90cf..68fa812a 100644 --- a/reboot/plugin/skills/python/references/state-collections.md +++ b/reboot/plugin/skills/python/references/state-collections.md @@ -208,7 +208,7 @@ class UserServicer(User.Servicer): request: User.AddPersonRequest, ) -> User.AddPersonResponse: # `Person` is its own state Type with `factory=True` `create`. - person, _ = await Person.create( + person, _ = await Person.factory.create( context, name=request.name, birthday=request.birthday, diff --git a/reboot/plugin/skills/python/references/state-scalar-fields.md b/reboot/plugin/skills/python/references/state-scalar-fields.md index f8c8e266..8b0e8213 100644 --- a/reboot/plugin/skills/python/references/state-scalar-fields.md +++ b/reboot/plugin/skills/python/references/state-scalar-fields.md @@ -125,7 +125,7 @@ class IntegrationState(Model): ``` ```python -ciphertext, _ = await Ciphertext.encrypt( +ciphertext, _ = await Ciphertext.factory.encrypt( context, plaintext=raw_api_key.encode(), associated_data=make_associated_data(tenant_id=tenant_id, purpose="api-key"), diff --git a/reboot/plugin/skills/python/references/stdlib-ciphertext.md b/reboot/plugin/skills/python/references/stdlib-ciphertext.md index 10d37b84..0a15de06 100644 --- a/reboot/plugin/skills/python/references/stdlib-ciphertext.md +++ b/reboot/plugin/skills/python/references/stdlib-ciphertext.md @@ -61,13 +61,13 @@ async def main(): ### Methods -| Call | Type | Notes | -| ----------------------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `Ciphertext.encrypt(context, [id], *, plaintext, associated_data, scope, key_manager_id)` | transaction (constructor) | `key_manager_id` is **required** (pass `APP_SHARED_KEY_MANAGER_ID`); returns `(ref, EncryptResponse)`; omit `id` to auto-generate one and read it back as `ref.state_id` | -| `Ciphertext.ref(id).decrypt(context, *, associated_data)` | reader | `-> DecryptResponse(plaintext)`. Raises `DecryptAborted` | -| `Ciphertext.ref(id).rescope(context, *, scope)` | transaction | move a ciphertext to a different scope (same manager); only the wrapped DEK changes | -| `KeyManager.ref(APP_SHARED_KEY_MANAGER_ID).shred(context, *, scope)` | transaction | crypto-shred a scope — idempotent | -| `KeyManager.ref(APP_SHARED_KEY_MANAGER_ID).status(context)` | reader | `-> StatusResponse(active_version, rotating)`; poll to confirm a rotation finished (`active_version` reached and `rotating` is false) | +| Call | Type | Notes | +| ------------------------------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `Ciphertext.factory.encrypt(context, [id], *, plaintext, associated_data, scope, key_manager_id)` | transaction (constructor) | `key_manager_id` is **required** (pass `APP_SHARED_KEY_MANAGER_ID`); returns `(ref, EncryptResponse)`; omit `id` to auto-generate one and read it back as `ref.state_id` | +| `Ciphertext.ref(id).decrypt(context, *, associated_data)` | reader | `-> DecryptResponse(plaintext)`. Raises `DecryptAborted` | +| `Ciphertext.ref(id).rescope(context, *, scope)` | transaction | move a ciphertext to a different scope (same manager); only the wrapped DEK changes | +| `KeyManager.ref(APP_SHARED_KEY_MANAGER_ID).shred(context, *, scope)` | transaction | crypto-shred a scope — idempotent | +| `KeyManager.ref(APP_SHARED_KEY_MANAGER_ID).status(context)` | reader | `-> StatusResponse(active_version, rotating)`; poll to confirm a rotation finished (`active_version` reached and `rotating` is false) | Imports: @@ -84,7 +84,7 @@ from reboot.std.ciphertext.v1.ciphertext import ( ### Encrypt ```python -ciphertext, _ = await Ciphertext.encrypt( +ciphertext, _ = await Ciphertext.factory.encrypt( context, plaintext=b"123-45-6789", associated_data=make_associated_data(user_id="42", purpose="ssn"), diff --git a/reboot/plugin/skills/python/references/stdlib-ordered-map.md b/reboot/plugin/skills/python/references/stdlib-ordered-map.md index c6bbcc57..e2001878 100644 --- a/reboot/plugin/skills/python/references/stdlib-ordered-map.md +++ b/reboot/plugin/skills/python/references/stdlib-ordered-map.md @@ -88,7 +88,7 @@ async def create( self, context: TransactionContext, request: CreateRequest, ) -> CreateResponse: self.state.account_ids_map_id = str(uuid4()) - await OrderedMap.create( + await OrderedMap.factory.create( context, self.state.account_ids_map_id, ) return CreateResponse() diff --git a/reboot/plugin/skills/python/references/stdlib-presence.md b/reboot/plugin/skills/python/references/stdlib-presence.md index b946675b..7058dca7 100644 --- a/reboot/plugin/skills/python/references/stdlib-presence.md +++ b/reboot/plugin/skills/python/references/stdlib-presence.md @@ -71,7 +71,7 @@ async def main(): The intended dance, per the type's docs: -1. Client `Subscriber.create(context, subscriber_id)` — once. +1. Client `Subscriber.factory.create(context, subscriber_id)` — once. 2. Client opens a long-lived `Subscriber.ref(id).connect(context)` reader RPC; this stays open as long as the client is connected. 3. Client `Subscriber.ref(id).toggle(context)` to mark itself as live; diff --git a/reboot/plugin/skills/python/references/testing-harness.md b/reboot/plugin/skills/python/references/testing-harness.md index a447bd20..5e823176 100644 --- a/reboot/plugin/skills/python/references/testing-harness.md +++ b/reboot/plugin/skills/python/references/testing-harness.md @@ -104,7 +104,7 @@ Things to know: ```python async def _initialize(context) -> None: - await CouponBook.create(context, COUPON_BOOK_ID) + await CouponBook.factory.create(context, COUPON_BOOK_ID) await self.rbt.up( Application( diff --git a/reboot/plugin/skills/web-app/SKILL.md b/reboot/plugin/skills/web-app/SKILL.md index 8f84b2af..1c7db371 100644 --- a/reboot/plugin/skills/web-app/SKILL.md +++ b/reboot/plugin/skills/web-app/SKILL.md @@ -249,7 +249,7 @@ exactly one of them — the step that needs it. `self.state_id`); `self.ref().schedule(...)`. - `python/references/rpc-calls.md` — kwargs, not Request wrappers. - `python/references/rpc-constructor-calls.md` — - `Service.create(context, id)` semantics. + `Service.factory.create(context, id)` semantics. - `python/references/servicer-workflow.md` — only when you declared a `Workflow`, and then top to bottom: the `@classmethod` / `WorkflowContext` declaration shape, the call-classification diff --git a/reboot/std/oauth/v1/oauth.py b/reboot/std/oauth/v1/oauth.py index fdfc51d1..b5e9fde1 100644 --- a/reboot/std/oauth/v1/oauth.py +++ b/reboot/std/oauth/v1/oauth.py @@ -117,7 +117,7 @@ async def store( # merge first — we can't read the index here, since this same # transaction writes it (Reboot forbids reading and writing the # same state in one transaction). - ciphertext, _ = await Ciphertext.encrypt( + ciphertext, _ = await Ciphertext.factory.encrypt( context, plaintext=request.tokens.SerializeToString(), associated_data=_associated_data(service, request.user_id), diff --git a/tests/reboot/agents/pydantic_ai/agent_tests.py b/tests/reboot/agents/pydantic_ai/agent_tests.py index 1219f4c3..5e34859e 100644 --- a/tests/reboot/agents/pydantic_ai/agent_tests.py +++ b/tests/reboot/agents/pydantic_ai/agent_tests.py @@ -569,7 +569,9 @@ async def asyncSetUp(self) -> None: ) self.context = self.rbt.create_external_context(name=self.id()) - self.general, _ = await General.constructor_writer(self.context) + self.general, _ = await General.factory.constructor_writer( + self.context + ) async def asyncTearDown(self) -> None: await self.rbt.stop() diff --git a/tests/reboot/aio/internals/tasks_servicer_tests.py b/tests/reboot/aio/internals/tasks_servicer_tests.py index 2f51cb58..5747a7fa 100644 --- a/tests/reboot/aio/internals/tasks_servicer_tests.py +++ b/tests/reboot/aio/internals/tasks_servicer_tests.py @@ -624,7 +624,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) - general, _ = await General.ConstructorWriter( + general, _ = await General.factory.ConstructorWriter( context, "scheduled-loop-test" ) task = await general.spawn().Workflow(context) @@ -715,7 +715,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) - general, _ = await General.ConstructorWriter( + general, _ = await General.factory.ConstructorWriter( context, "test_iteration_count" ) task = await general.spawn().Workflow(context) diff --git a/tests/reboot/auth_bank_main.py b/tests/reboot/auth_bank_main.py index dde7b8eb..5018df76 100644 --- a/tests/reboot/auth_bank_main.py +++ b/tests/reboot/auth_bank_main.py @@ -20,7 +20,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank in our application.""" print("🏦🏦🏦 Creating Bank if it hasn't already been created.... 🏦🏦🏦") - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) print("💰💰💰 Bank is ready for business! 💰💰💰") diff --git a/tests/reboot/auth_tests.py b/tests/reboot/auth_tests.py index 7759a6f0..f3296930 100644 --- a/tests/reboot/auth_tests.py +++ b/tests/reboot/auth_tests.py @@ -160,7 +160,7 @@ async def asyncSetUp(self): bearer_token=VALID_JWT, ) - bank, _ = await Bank.create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.create(context, SINGLETON_BANK_ID) await bank.sign_up(context, account_id=ACCOUNT_NAME) async def asyncTearDown(self): @@ -325,7 +325,7 @@ async def asyncSetUp(self): bearer_token=VALID_JWT, ) - bank, _ = await Bank.create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.create(context, SINGLETON_BANK_ID) async def asyncTearDown(self): await self.rbt.stop() @@ -396,7 +396,7 @@ async def test_construct_auth(self): context = self.rbt.create_external_context(name=self.id()) # Test that a bearer token can be used via construct. - bank, _ = await Bank.create( + bank, _ = await Bank.factory.create( context, SINGLETON_BANK_ID, Options(bearer_token=VALID_JWT), diff --git a/tests/reboot/bank.py b/tests/reboot/bank.py index 89f91e30..fe26f03e 100644 --- a/tests/reboot/bank.py +++ b/tests/reboot/bank.py @@ -168,7 +168,7 @@ async def test_nested_transaction_that_aborts( state.balance += 10 # We abort below so this call should also not take effect. - await Account.open(context, f'{context.state_id}-nested') + await Account.factory.open(context, f'{context.state_id}-nested') raise Account.TestNestedTransactionThatAbortsAborted( bank_rbt.UserError() @@ -256,7 +256,7 @@ async def sign_up( # Since we may manually retry the following call, we must # provide idempotency, which we do via passing the string # alias 'open'. - await Account.idempotently('open').open( + await Account.factory.idempotently('open').open( context, request.account_id, Options(bearer_token=context.caller_bearer_token), @@ -268,7 +268,7 @@ async def sign_up( # For testing purposes, call the 'open' method again - so that it's always # called twice, and idempotency is demonstrated. - account, _ = await Account.idempotently('open').open( + account, _ = await Account.factory.idempotently('open').open( context, request.account_id, Options(bearer_token=context.caller_bearer_token), @@ -556,7 +556,7 @@ async def test_nested_transaction_that_aborts( else: raise RuntimeError('Expecting to abort!') - account, response = await Account.open( + account, response = await Account.factory.open( context, f'{request.account_id}-parent', initial_deposit=42, @@ -571,7 +571,7 @@ async def test_inherited_ownership_abort( ) -> Empty: # We (the root transaction) first join the account by opening # it. - account, _ = await Account.open( + account, _ = await Account.factory.open( context, request.account_id, initial_deposit=10, @@ -697,7 +697,7 @@ async def test_prepare_wait_for_nested_abort_rollback( ) -> Empty: # Open the remote account with a known balance so that the # nested transaction below shares (rather than constructs) it. - await Account.open( + await Account.factory.open( context, request.remote_account_id, initial_deposit=100, @@ -778,13 +778,13 @@ async def test_nested_transactions( request.type == bank_rbt.TestNestedTransactionsRequest.NESTED_TXN_SAME_STATE ): - await Account.open( + await Account.factory.open( context, 'jonathan-same-state', Options(bearer_token=context.caller_bearer_token), initial_deposit=2, ) - await Account.open( + await Account.factory.open( context, 'ben-same-state', Options(bearer_token=context.caller_bearer_token), @@ -804,13 +804,13 @@ async def test_nested_transactions( request.type == bank_rbt.TestNestedTransactionsRequest.NESTED_TXN_PARENT_WRITER ): - jonathan, _ = await Account.open( + jonathan, _ = await Account.factory.open( context, 'jonathan-parent-writer', Options(bearer_token=context.caller_bearer_token), initial_deposit=2, ) - await Account.open( + await Account.factory.open( context, 'ben-parent-writer', Options(bearer_token=context.caller_bearer_token), @@ -830,13 +830,13 @@ async def test_nested_transactions( request.type == bank_rbt.TestNestedTransactionsRequest. NESTED_TXN_SHARED_WRITE_ABORT ): - await Account.open( + await Account.factory.open( context, 'jonathan-shared-write-abort', Options(bearer_token=context.caller_bearer_token), initial_deposit=1, ) - await Account.open( + await Account.factory.open( context, 'ben-shared-write-abort', Options(bearer_token=context.caller_bearer_token), diff --git a/tests/reboot/bank_main.py b/tests/reboot/bank_main.py index 1d5cb32a..8cfc1c92 100644 --- a/tests/reboot/bank_main.py +++ b/tests/reboot/bank_main.py @@ -17,7 +17,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank in our application.""" print("🏦🏦🏦 Creating Bank if it hasn't already been created.... 🏦🏦🏦") - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) print("💰💰💰 Bank is ready for business! 💰💰💰") diff --git a/tests/reboot/benchmark.py b/tests/reboot/benchmark.py index 409b24c8..e0207944 100644 --- a/tests/reboot/benchmark.py +++ b/tests/reboot/benchmark.py @@ -137,7 +137,7 @@ async def benchmark() -> None: state_ids = [str(state_id) for state_id in range(4096)] await asyncio.gather( *( - General.ConstructorWriter(context, state_id) + General.factory.ConstructorWriter(context, state_id) for state_id in state_ids ) ) diff --git a/tests/reboot/cancellation_tests.py b/tests/reboot/cancellation_tests.py index eb990d7f..0ffe47cf 100644 --- a/tests/reboot/cancellation_tests.py +++ b/tests/reboot/cancellation_tests.py @@ -88,7 +88,7 @@ async def ClientStreamingReader( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.ConstructorWriter(context) + g, _ = await General.factory.ConstructorWriter(context) # Start task to Reader to test the unary case. reader_task = asyncio.create_task(g.Reader(context)) diff --git a/tests/reboot/context_tests.py b/tests/reboot/context_tests.py index c521129c..4f6fcd7d 100644 --- a/tests/reboot/context_tests.py +++ b/tests/reboot/context_tests.py @@ -45,7 +45,7 @@ async def test_context_not_constructible_in_actor(self) -> None: context = self.rbt.create_external_context(name=self.id()) - greeter, response = await Greeter.Create( + greeter, response = await Greeter.factory.Create( context, title='Dr', name='Jonathan', @@ -88,7 +88,7 @@ def fake_to_grpc_metadata(self): fake_to_grpc_metadata ): with self.assertRaises(Greeter.CreateAborted) as aborted: - await Greeter.Create( + await Greeter.factory.Create( context, title='Dr', name='Jonathan', diff --git a/tests/reboot/documentation/backend/src/servicers/counter.py b/tests/reboot/documentation/backend/src/servicers/counter.py index d6f7e135..72971460 100644 --- a/tests/reboot/documentation/backend/src/servicers/counter.py +++ b/tests/reboot/documentation/backend/src/servicers/counter.py @@ -42,7 +42,7 @@ async def create_counter( request: CreateCounterRequest, ) -> CreateCounterResponse: """Create a new Counter and return its ID.""" - counter, _ = await Counter.create( + counter, _ = await Counter.factory.create( context, description=request.description, owner_id=context.state_id, diff --git a/tests/reboot/documentation/task.py b/tests/reboot/documentation/task.py index e9ed2257..9fe154a1 100644 --- a/tests/reboot/documentation/task.py +++ b/tests/reboot/documentation/task.py @@ -114,7 +114,7 @@ async def value_is_stored(): async def initialize(context: InitializeContext): - await TestTask.create(context, "task") + await TestTask.factory.create(context, "task") # These tests are different from the other tests in this directory in that do not diff --git a/tests/reboot/documentation/task.ts b/tests/reboot/documentation/task.ts index 3232ce70..956c8ce2 100644 --- a/tests/reboot/documentation/task.ts +++ b/tests/reboot/documentation/task.ts @@ -193,7 +193,9 @@ test("task", async (t) => { await t.test("create", async (t) => { const context = rbt.createExternalContext("test"); - const [task] = await TestTask.idempotently().create(context, "task"); + const [task] = await TestTask.factory + .idempotently() + .create(context, "task"); const { task: { taskId }, diff --git a/tests/reboot/documentation/test_http.py b/tests/reboot/documentation/test_http.py index e8476fea..56d58a8b 100644 --- a/tests/reboot/documentation/test_http.py +++ b/tests/reboot/documentation/test_http.py @@ -22,7 +22,7 @@ async def hello_greeter( context: ExternalContext = InjectExternalContext, ): body = await request.json() - greeter, _ = await Greeter.create( + greeter, _ = await Greeter.factory.create( context, title=body['title'], name=body['name'], diff --git a/tests/reboot/documentation/test_http.ts b/tests/reboot/documentation/test_http.ts index b40b594c..ba8e5db8 100644 --- a/tests/reboot/documentation/test_http.ts +++ b/tests/reboot/documentation/test_http.ts @@ -57,7 +57,7 @@ test("Tests for Reboot HTTP documentation", async (t) => { name: string; adjective: string; }; - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title, name, adjective, diff --git a/tests/reboot/documentation/transactions.ts b/tests/reboot/documentation/transactions.ts index b934fbd3..534225c5 100644 --- a/tests/reboot/documentation/transactions.ts +++ b/tests/reboot/documentation/transactions.ts @@ -97,9 +97,9 @@ test("transactions", async (t) => { await t.test("transfer", async (t) => { const context = rbt.createExternalContext("test"); - const [bank] = await Bank.create(context, "bank"); - const [fromAccount] = await Account.open(context, "alice"); - const [toAccount] = await Account.open(context, "bob"); + const [bank] = await Bank.factory.create(context, "bank"); + const [fromAccount] = await Account.factory.open(context, "alice"); + const [toAccount] = await Account.factory.open(context, "bob"); await fromAccount.deposit(context, { amount: 100 }); diff --git a/tests/reboot/effect_validation_tests.py b/tests/reboot/effect_validation_tests.py index 85ea0057..06013c62 100644 --- a/tests/reboot/effect_validation_tests.py +++ b/tests/reboot/effect_validation_tests.py @@ -191,7 +191,7 @@ async def create( self, effect_validation: EffectValidation ) -> tuple[General.WeakReference, ExternalContext]: context = await self.up(effect_validation) - general, _ = await General.ConstructorWriter(context) + general, _ = await General.factory.ConstructorWriter(context) return general, context async def test_disabled(self) -> None: @@ -237,7 +237,7 @@ async def test_constructor_writer(self) -> None: async def test_constructor_transaction(self) -> None: context = await self.up(EffectValidation.ENABLED) - general, _ = await General.ConstructorTransaction(context) + general, _ = await General.factory.ConstructorTransaction(context) self.assert_effects( "constructor_transaction", "constructor_transaction" ) @@ -371,7 +371,7 @@ async def test_at_least_once_per_call_effect_validation_disabled( effect_validation=EffectValidation.ENABLED, ) context = self.rbt.create_external_context(name=self.id()) - general, _ = await General.ConstructorWriter(context) + general, _ = await General.factory.ConstructorWriter(context) await (await general.spawn().Workflow(context)) self.assertEqual(1, _DIRECT_CALLS) @@ -394,7 +394,7 @@ async def test_trusted_servicer_skips_reruns_for_app_developer( with mock.patch.dict(os.environ): os.environ.pop('RBT_VALIDATE_TRUSTED_EFFECTS', None) context = await self.up_trusted(EffectValidation.ENABLED) - await TrustedLibrary.ConstructorWriter(context) + await TrustedLibrary.factory.ConstructorWriter(context) self.assert_effects("ConstructorWriter") @@ -408,7 +408,7 @@ async def test_trusted_servicer_reruns_when_validation_requested( os.environ, {'RBT_VALIDATE_TRUSTED_EFFECTS': 'true'} ): context = await self.up_trusted(EffectValidation.ENABLED) - await TrustedLibrary.ConstructorWriter(context) + await TrustedLibrary.factory.ConstructorWriter(context) self.assert_effects("ConstructorWriter", "ConstructorWriter") diff --git a/tests/reboot/errors_tests.py b/tests/reboot/errors_tests.py index ac9a65fc..d47c9fd6 100644 --- a/tests/reboot/errors_tests.py +++ b/tests/reboot/errors_tests.py @@ -28,7 +28,7 @@ async def test_declared_error(self) -> None: context = self.rbt.create_external_context(name=self.id()) - account, _ = await Account.Open(context) + account, _ = await Account.factory.Open(context) await account.Deposit(context, amount=100) @@ -50,7 +50,7 @@ async def test_declared_errors_propagate(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan', initial_deposit=100) await bank.SignUp(context, account_id='morten') @@ -77,7 +77,7 @@ async def test_undeclared_error(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') @@ -99,7 +99,7 @@ async def test_undeclared_errors_propagate(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) with self.assertRaises(Bank.SignUpAborted) as aborted: await bank.SignUp( @@ -123,7 +123,7 @@ async def test_unavailable_errors_propagate(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') account = Account.ref('jonathan') @@ -198,7 +198,7 @@ async def test_external_context_mixing_error(self) -> None: name=self.id() + "2" ) - account, _ = await Account.Open(context1) + account, _ = await Account.factory.Open(context1) with self.assertRaises(MixedContextsError) as error: await account.Deposit(context2, amount=200) diff --git a/tests/reboot/external_context_tests.py b/tests/reboot/external_context_tests.py index dccc6e40..dec1d9f0 100644 --- a/tests/reboot/external_context_tests.py +++ b/tests/reboot/external_context_tests.py @@ -296,7 +296,7 @@ async def _test_keepalive_and_retry( url=proxied_url, name="test_keepalive_and_retry_unary_reader", ) - general, _ = await General.ConstructorWriter(context) + general, _ = await General.factory.ConstructorWriter(context) call_task: asyncio.Task[None] = asyncio.create_task( make_call(context, general) diff --git a/tests/reboot/idempotency_seeds_tests.py b/tests/reboot/idempotency_seeds_tests.py index cc59f379..7af18f85 100644 --- a/tests/reboot/idempotency_seeds_tests.py +++ b/tests/reboot/idempotency_seeds_tests.py @@ -187,12 +187,12 @@ def test_idempotently_with_alias_under_same_seed_returns_same_uuid( def test_idempotent_state_id_is_seed_scoped(self) -> None: # `generate_idempotent_state_id` derives a state ID from # `(seed, alias)`, used by constructors like - # `Counter.idempotently("create").create(context)` to pick a - # deterministic ID for the new state. It must fold in the + # `Counter.factory.idempotently("create").create(context)` to + # pick a deterministic ID for the new state. It must fold in the # active idempotency seeds for consistency with # `idempotently()`'s seed-aware idempotency key, otherwise the - # state ID collides across seed scopes while the idempotency - # key differs. + # state ID collides across seed scopes while the idempotency key + # differs. manager = IdempotencyManager(seed=self.SEED) with _merge_idempotency_seeds({"variant": "first"}): state_id_1 = manager.generate_idempotent_state_id( diff --git a/tests/reboot/idempotency_tests.py b/tests/reboot/idempotency_tests.py index e72e8292..bbacb5e3 100644 --- a/tests/reboot/idempotency_tests.py +++ b/tests/reboot/idempotency_tests.py @@ -29,7 +29,7 @@ async def test_exactly_one_idempotency_argument(self) -> None: context = self.rbt.create_external_context(name=self.id()) with self.assertRaises(ValueError) as exc: - await Account.idempotently( + await Account.factory.idempotently( key="key", alias="alias", # type: ignore[call-overload] ).Open(context, "one") @@ -53,7 +53,7 @@ async def _test_writers_are_idempotent( context = self.rbt.create_external_context(name=self.id()) - account, _ = await Account.Open(context) + account, _ = await Account.factory.Open(context) await account.Deposit(context, amount=1000) @@ -108,7 +108,7 @@ async def test_expiring_idempotency_key(self) -> None: context = self.rbt.create_external_context(name=self.id()) - account, _ = await Account.Open(context) + account, _ = await Account.factory.Open(context) await account.Deposit(context, amount=1000) @@ -146,7 +146,7 @@ async def _test_transactions_are_idempotent( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.idempotently(*args, **kwargs).SignUp( context, @@ -205,7 +205,7 @@ async def test_idempotency_request_violation(self) -> None: context = self.rbt.create_external_context(name=self.id()) - account, _ = await Account.idempotently( + account, _ = await Account.factory.idempotently( 'Open', ).Open(context, 'test-1234') @@ -236,7 +236,7 @@ async def test_idempotency_metadata_violation(self) -> None: context = self.rbt.create_external_context(name=self.id()) - account, _ = await Account.idempotently( + account, _ = await Account.factory.idempotently( 'Open', ).Open( context, @@ -247,7 +247,7 @@ async def test_idempotency_metadata_violation(self) -> None: # Using the same idempotency alias but for different metadata # should fail. with self.assertRaises(ValueError) as error: - await Account.idempotently('Open').Open( + await Account.factory.idempotently('Open').Open( context, 'test-1234', Options(metadata=(('x-reboot-some-key', '41'),)), @@ -267,12 +267,14 @@ async def test_idempotency_generate_violation(self) -> None: context = self.rbt.create_external_context(name=self.id()) - account, _ = await Account.idempotently().Open(context, 'test-1234') + account, _ = await Account.factory.idempotently().Open( + context, 'test-1234' + ) # Doing another call should fail, regardless of if it has # different arguments, metadata, etc. with self.assertRaises(ValueError) as error: - await Account.idempotently().Open( + await Account.factory.idempotently().Open( context, 'test-1234', Options(metadata=(('x-reboot-some-key', '41'),)), @@ -288,7 +290,7 @@ async def test_idempotency_generate_violation(self) -> None: async def test_idempotency_failed_mutation_violation(self) -> None: await self.rbt.up(Application(servicers=[AccountServicer])) context = self.rbt.create_external_context(name=self.id()) - account, _ = await Account.Open(context, "foo") + account, _ = await Account.factory.Open(context, "foo") # A failed mutation that we can't be sure is due to an error # that came from the backend will make this idempotency @@ -327,13 +329,13 @@ async def test_constructors_are_idempotent(self) -> None: # First call: construct the account idempotently. state_id = 'idempotent-constructor-test' - account1, _ = await Account.idempotently( + account1, _ = await Account.factory.idempotently( 'open account', ).Open(context, state_id) # Second call: exact same alias, context, and state ID. This # must succeed (not raise `StateAlreadyConstructed`). - account2, _ = await Account.idempotently( + account2, _ = await Account.factory.idempotently( 'open account', ).Open(context, state_id) @@ -344,7 +346,7 @@ async def test_constructors_are_idempotent(self) -> None: # Verify that calling the constructor *without* idempotency on # the same state ID does raise `StateAlreadyConstructed`. with self.assertRaises(Account.OpenAborted) as aborted: - await Account.Open(context, state_id) + await Account.factory.Open(context, state_id) self.assertEqual( type(aborted.exception.error), StateAlreadyConstructed @@ -364,7 +366,7 @@ async def test_non_constructor_transactions_are_idempotent( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # First call: sign up the account idempotently. await bank.idempotently('sign up jonathan').SignUp( @@ -394,7 +396,7 @@ async def create_or_assert(*, idempotency_seed: Optional[uuid.UUID]): name='create_or_assert', idempotency_seed=idempotency_seed, ) - account, _ = await Account.idempotently().Open( + account, _ = await Account.factory.idempotently().Open( context, ) nonlocal created_id diff --git a/tests/reboot/invalid_header_tests.py b/tests/reboot/invalid_header_tests.py index 8f291018..1f73bbfa 100644 --- a/tests/reboot/invalid_header_tests.py +++ b/tests/reboot/invalid_header_tests.py @@ -85,7 +85,7 @@ async def test_invalid_state_ref_type(self) -> None: context = ExternalContext(name='test', url='http://test') # Intentionally create a type error, as might happen when the user # doesn't use mypy. - await Greeter.Create( + await Greeter.factory.Create( context, 123 ) # type: ignore[arg-type, call-overload] self.assertEqual( @@ -113,7 +113,7 @@ async def test_invalid_state_ref_value_non_ascii(self) -> None: # Constructor. with self.assertRaises(InvalidStateRefError) as e: context = ExternalContext(name='test', url='http://test') - await Greeter.Create(context, '😾') + await Greeter.factory.Create(context, '😾') self.assertEqual( str(e.exception), "The 'state_id' option must be an ASCII string; the given value " @@ -137,7 +137,7 @@ async def test_invalid_state_ref_value_too_short(self) -> None: # Constructor. with self.assertRaises(InvalidStateRefError) as e: context = ExternalContext(name='test', url='http://test') - await Greeter.Create(context, '') + await Greeter.factory.Create(context, '') self.assertEqual( str(e.exception), "The 'state_id' option must be at least 1 character(s) long; the " @@ -161,7 +161,7 @@ async def test_invalid_state_ref_value_too_long(self) -> None: # Constructor. with self.assertRaises(InvalidStateRefError) as e: context = ExternalContext(name='test', url='http://test') - await Greeter.Create(context, 'x' * 129) + await Greeter.factory.Create(context, 'x' * 129) self.assertEqual( str(e.exception), "The 'state_id' option must be at most 128 characters long; the " @@ -192,7 +192,7 @@ async def test_invalid_state_ref_value_invalid_char(self) -> None: # Constructor. with self.assertRaises(InvalidStateRefError) as e: context = ExternalContext(name='test', url='http://test') - await Greeter.Create(context, 'hello \x00?') + await Greeter.factory.Create(context, 'hello \x00?') self.assertEqual( str(e.exception), "The 'state_id' option contained illegal characters: ['\\x00']. " @@ -205,7 +205,7 @@ async def test_invalid_bearer_token_type(self) -> None: header serialization, so that the user gets a friendlier stack trace. """ with self.assertRaises(TypeError) as e: - await Greeter.Create( + await Greeter.factory.Create( ExternalContext(name='test', url='http://test'), # Intentionally create a type error, as might happen when the user # doesn't use mypy. @@ -222,7 +222,7 @@ async def test_invalid_bearer_token_value(self) -> None: header serialization, so that the user gets a friendlier stack trace. """ with self.assertRaises(InvalidBearerTokenError) as e: - await Greeter.Create( + await Greeter.factory.Create( ExternalContext(name='test', url='http://test'), None, Options(bearer_token='😾'), @@ -234,7 +234,7 @@ async def test_invalid_bearer_token_value(self) -> None: ) with self.assertRaises(InvalidBearerTokenError) as e: - await Greeter.Create( + await Greeter.factory.Create( ExternalContext(name='test', url='http://test'), None, Options(bearer_token='test\n'), @@ -246,7 +246,7 @@ async def test_invalid_bearer_token_value(self) -> None: ) with self.assertRaises(InvalidBearerTokenError) as e: - await Greeter.Create( + await Greeter.factory.Create( ExternalContext(name='test', url='http://test'), None, Options(bearer_token='x' * 4097), @@ -264,7 +264,7 @@ async def test_invalid_idempotency_key_type(self) -> None: trace. """ with self.assertRaises(TypeError) as e: - await Greeter.idempotently( + await Greeter.factory.idempotently( # Intentionally create a type error, as might happen # when the user doesn't use mypy. key=1337, # type: ignore[call-overload] @@ -283,7 +283,7 @@ async def test_invalid_idempotency_key_value(self) -> None: header serialization, so that the user gets a friendlier stack trace. """ with self.assertRaises(InvalidIdempotencyKeyError) as e: - await Greeter.idempotently( + await Greeter.factory.idempotently( # Intentionally create a type error, as might happen # when the user doesn't use mypy. key='😾' # type: ignore[call-overload] @@ -300,7 +300,7 @@ async def test_invalid_idempotency_key_value(self) -> None: with self.assertRaises(InvalidIdempotencyKeyError) as e: # Intentionally create a type error, as might happen # when the user doesn't use mypy. - await Greeter.idempotently( + await Greeter.factory.idempotently( key='x' * 129, ).Create( # type: ignore[call-overload] ExternalContext(name='test', url='http://test'), diff --git a/tests/reboot/nodejs/app_internal_test/test.ts b/tests/reboot/nodejs/app_internal_test/test.ts index 3ec77e48..7db9933a 100644 --- a/tests/reboot/nodejs/app_internal_test/test.ts +++ b/tests/reboot/nodejs/app_internal_test/test.ts @@ -59,7 +59,7 @@ test("app internal", async (t) => { const context = rbt.createExternalContext("test", { appInternal: true }); - await Greeter.create(context, {}); + await Greeter.factory.create(context, {}); }); // Test that without a token verifier the authorizer and method both @@ -69,7 +69,7 @@ test("app internal", async (t) => { const context = rbt.createExternalContext("test", { appInternal: true }); - await Greeter.create(context, {}); + await Greeter.factory.create(context, {}); }); // Test that _with_ a token verifier the authorizer and method both @@ -84,6 +84,6 @@ test("app internal", async (t) => { const context = rbt.createExternalContext("test", { appInternal: true }); - await Greeter.create(context, {}); + await Greeter.factory.create(context, {}); }); }); diff --git a/tests/reboot/nodejs/auth_test/test.ts b/tests/reboot/nodejs/auth_test/test.ts index 356290f6..c3cce4e9 100644 --- a/tests/reboot/nodejs/auth_test/test.ts +++ b/tests/reboot/nodejs/auth_test/test.ts @@ -114,7 +114,7 @@ test("auth", async (t) => { bearerToken: options?.bearerToken, }); try { - await Greeter.create(context, options?.id); + await Greeter.factory.create(context, options?.id); assert(false, `Should not have successfully authed with ${options}`); } catch (e) { assert(e instanceof Greeter.CreateAborted, "not CreateAborted"); @@ -135,7 +135,7 @@ test("auth", async (t) => { const authedContext = rbt.createExternalContext("test", { bearerToken: TOKEN_FOR_TEST, }); - const [greeter] = await Greeter.create(authedContext); + const [greeter] = await Greeter.factory.create(authedContext); // Confirm that our authorizer does not allow access to any other method // by default, since we have not overridden other methods. @@ -157,7 +157,7 @@ test("auth", async (t) => { await t.test("via construct and lookup", async (t) => { // Test that an authenticated construct succeeds. const context = rbt.createExternalContext("test"); - const [greeter] = await Greeter.create( + const [greeter] = await Greeter.factory.create( context, { title: "Dr", diff --git a/tests/reboot/nodejs/greeter.ts b/tests/reboot/nodejs/greeter.ts index 10d98fcb..1428a530 100644 --- a/tests/reboot/nodejs/greeter.ts +++ b/tests/reboot/nodejs/greeter.ts @@ -218,7 +218,7 @@ export class GreeterServicer extends Greeter.Servicer { // iteration via `.perIteration()` by default. // // Create the other `Greeter` once per workflow. - const [other] = await Greeter.create(context, { + const [other] = await Greeter.factory.create(context, { title: "Dr", name: "Evil", adjective: "cunning", diff --git a/tests/reboot/nodejs/greeter_test/test.ts b/tests/reboot/nodejs/greeter_test/test.ts index 9ebc70fe..538d2cf6 100644 --- a/tests/reboot/nodejs/greeter_test/test.ts +++ b/tests/reboot/nodejs/greeter_test/test.ts @@ -37,7 +37,7 @@ test("constructors and readers", async (t) => { }); // Test creating with ID. - await Greeter.create(context, "other greeter", { + await Greeter.factory.create(context, "other greeter", { title: "Dr", name: "Jonathan", adjective: "Best", @@ -47,7 +47,7 @@ test("constructors and readers", async (t) => { // // Scoping here for snippet purposes. { - const [greeter, response] = await Greeter.create(context, { + const [greeter, response] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -55,19 +55,19 @@ test("constructors and readers", async (t) => { } // Test creating with generated ID idempotently. - await Greeter.idempotently().create(context, { + await Greeter.factory.idempotently().create(context, { title: "Mr", name: "John", adjective: "Dangerous", }); - await Greeter.idempotently("generated").create(context, { + await Greeter.factory.idempotently("generated").create(context, { title: "Mr", name: "John", adjective: "Dangerous", }); - await Greeter.idempotently("create").create( + await Greeter.factory.idempotently("create").create( context, "greeter", // Pass a whole object to test that we can take an object as a request. @@ -79,15 +79,13 @@ test("constructors and readers", async (t) => { ); // Call `idempotently()` with explicit alias to test "alias or options". - const [greeter] = await Greeter.idempotently({ alias: "create" }).create( - context, - "greeter", - { + const [greeter] = await Greeter.factory + .idempotently({ alias: "create" }) + .create(context, "greeter", { title: "Mr", name: "John", adjective: "Dangerous", - } - ); + }); // Pass a partial to test that we can take a partial as a request. let response = await greeter.greet(context, { name: "Jake" }); @@ -191,7 +189,7 @@ test("constructors and readers", async (t) => { idempotencySeed: uuid.v4(), }); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -233,7 +231,7 @@ test("constructors and readers", async (t) => { const context = rbt.createExternalContext("test"); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -262,7 +260,7 @@ test("constructors and readers", async (t) => { const context = rbt.createExternalContext("test"); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -280,13 +278,13 @@ test("constructors and readers", async (t) => { const context = rbt.createExternalContext("test"); // Creating some greeters. - await Greeter.create(context, "greeter-1", { + await Greeter.factory.create(context, "greeter-1", { title: "Mr", name: "Heinz", adjective: "Erhardt", }); - await Greeter.create(context, "greeter-2", { + await Greeter.factory.create(context, "greeter-2", { title: "Mrs", name: "Heidi", adjective: "Kabel", @@ -325,13 +323,13 @@ test("constructors and readers", async (t) => { const context = rbt.createExternalContext("test iterables"); - await Greeter.create(context, "greeter-iter-1", { + await Greeter.factory.create(context, "greeter-iter-1", { title: "Mr", name: "Heinz", adjective: "Erhardt", }); - await Greeter.create(context, "greeter-iter-2", { + await Greeter.factory.create(context, "greeter-iter-2", { title: "Mrs", name: "Heidi", adjective: "Kabel", diff --git a/tests/reboot/nodejs/reboot_down_test/test.ts b/tests/reboot/nodejs/reboot_down_test/test.ts index 66a5f96a..34b334fd 100644 --- a/tests/reboot/nodejs/reboot_down_test/test.ts +++ b/tests/reboot/nodejs/reboot_down_test/test.ts @@ -25,7 +25,7 @@ test("Reboot down test", async (t) => { idempotencySeed: uuid.v4(), }); - let [greeter, _] = await Greeter.create(context, { + let [greeter, _] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", diff --git a/tests/reboot/nodejs/reboot_test/test.ts b/tests/reboot/nodejs/reboot_test/test.ts index 3ebc35d9..825fbb43 100644 --- a/tests/reboot/nodejs/reboot_test/test.ts +++ b/tests/reboot/nodejs/reboot_test/test.ts @@ -52,7 +52,7 @@ test("Reboot", async (t) => { }); application.http.post("/hello_world", async (context, req, res) => { - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -116,7 +116,7 @@ test("Reboot", async (t) => { const context = rbt.createExternalContext("test"); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -165,7 +165,7 @@ test("Reboot", async (t) => { const context = rbt.createExternalContext("test"); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", diff --git a/tests/reboot/nodejs/reboot_web_test/test.ts b/tests/reboot/nodejs/reboot_web_test/test.ts index 1f31e050..31c3eb03 100644 --- a/tests/reboot/nodejs/reboot_web_test/test.ts +++ b/tests/reboot/nodejs/reboot_web_test/test.ts @@ -50,7 +50,7 @@ test("Reboot", async (t) => { url: rbt.url(), }); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -85,7 +85,7 @@ test("Reboot", async (t) => { bearerToken: TOKEN_FOR_TEST, }); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -124,7 +124,7 @@ test("Reboot", async (t) => { bearerToken: asyncBearerToken, }); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -160,7 +160,7 @@ test("Reboot", async (t) => { url: rbt.url(), }); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", @@ -215,7 +215,7 @@ test("Reboot", async (t) => { url: rbt.url(), }); - const [greeter] = await Greeter.create(context, "my-greeter", { + const [greeter] = await Greeter.factory.create(context, "my-greeter", { title: "Dr", name: "Jonathan", adjective: "Best", @@ -265,7 +265,7 @@ test("Reboot", async (t) => { url: rbt.url(), }); - const [greeter] = await Greeter.create(context, { + const [greeter] = await Greeter.factory.create(context, { title: "Dr", name: "Jonathan", adjective: "Best", diff --git a/tests/reboot/nodejs/tasks_test/test.ts b/tests/reboot/nodejs/tasks_test/test.ts index e4524ab1..696b7019 100644 --- a/tests/reboot/nodejs/tasks_test/test.ts +++ b/tests/reboot/nodejs/tasks_test/test.ts @@ -115,7 +115,7 @@ test("tasks", async (t) => { const context = rbt.createExternalContext("test"); - const [task, _] = await Task.constructorTransaction(context); + const [task, _] = await Task.factory.constructorTransaction(context); // Test that we schedule a writer task and run it immediately. await task.transaction(context); @@ -152,7 +152,7 @@ test("tasks", async (t) => { const context = rbt.createExternalContext("test"); - const [task, _] = await Task.constructorTransaction(context); + const [task, _] = await Task.factory.constructorTransaction(context); // Test that we schedule a transaction task and run it immediately. await task.transaction(context); @@ -189,7 +189,7 @@ test("tasks", async (t) => { const context = rbt.createExternalContext("test"); - const [task, _] = await Task.constructorTransaction(context); + const [task, _] = await Task.factory.constructorTransaction(context); // Test that we schedule a workflow task and run it immediately. await task.transaction(context); diff --git a/tests/reboot/nodejs/yarn_zod_test/backend/src/bank.ts b/tests/reboot/nodejs/yarn_zod_test/backend/src/bank.ts index 869b4688..097d7a30 100644 --- a/tests/reboot/nodejs/yarn_zod_test/backend/src/bank.ts +++ b/tests/reboot/nodejs/yarn_zod_test/backend/src/bank.ts @@ -64,7 +64,7 @@ export const BankServicer = Bank.servicer({ state: Bank.State, { accountId, initialDeposit }: Bank.SignUpRequest ): Promise<[Bank.State]> => { - const [account] = await Account.open(context, accountId, {}); + const [account] = await Account.factory.open(context, accountId, {}); await account.deposit(context, { amount: initialDeposit }); diff --git a/tests/reboot/nodejs/yarn_zod_test/backend/src/main.ts b/tests/reboot/nodejs/yarn_zod_test/backend/src/main.ts index f1790575..4f22272f 100644 --- a/tests/reboot/nodejs/yarn_zod_test/backend/src/main.ts +++ b/tests/reboot/nodejs/yarn_zod_test/backend/src/main.ts @@ -6,7 +6,7 @@ import { BankServicer } from "./bank.js"; const SINGLETON_BANK_ID = "reboot-bank"; const initialize = async (context) => { - await Bank.create(context, SINGLETON_BANK_ID); + await Bank.factory.create(context, SINGLETON_BANK_ID); }; new Application({ diff --git a/tests/reboot/nodejs/yarn_zod_test/backend/tests/test.ts b/tests/reboot/nodejs/yarn_zod_test/backend/tests/test.ts index aa09f198..7da4708a 100644 --- a/tests/reboot/nodejs/yarn_zod_test/backend/tests/test.ts +++ b/tests/reboot/nodejs/yarn_zod_test/backend/tests/test.ts @@ -32,7 +32,7 @@ test("Bank test", async (t) => { // Calling a constructor transaction method, which will call a // writer method from inside the transaction. - const [bank] = await Bank.create(context); + const [bank] = await Bank.factory.create(context); // Calling a common transaction method, which will call a writer // method from inside the transaction. diff --git a/tests/reboot/ping/ping_test.py b/tests/reboot/ping/ping_test.py index 3cdac78a..d93915b0 100644 --- a/tests/reboot/ping/ping_test.py +++ b/tests/reboot/ping/ping_test.py @@ -68,7 +68,7 @@ async def test_counter(self): app_internal=True, ) - counter, _ = await Counter.create( + counter, _ = await Counter.factory.create( context, description="test counter", owner_id="test-owner" ) diff --git a/tests/reboot/preload_tests.py b/tests/reboot/preload_tests.py index 67ffbf86..f6a7b3ec 100644 --- a/tests/reboot/preload_tests.py +++ b/tests/reboot/preload_tests.py @@ -27,7 +27,7 @@ async def test_preload_eliminates_load_actor_state_rpc(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.create(context, SINGLETON_BANK_ID) await bank.sign_up( context, @@ -73,7 +73,7 @@ async def test_preload_eliminates_recover_idempotent_mutations_rpc( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.create(context, SINGLETON_BANK_ID) await bank.sign_up( context, @@ -126,7 +126,7 @@ async def test_preload_failure_falls_back_to_own_rpcs(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.create(context, SINGLETON_BANK_ID) await bank.sign_up( context, @@ -176,7 +176,7 @@ async def test_preload_is_noop_when_state_is_cached(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.create(context, SINGLETON_BANK_ID) await bank.sign_up( context, @@ -219,7 +219,7 @@ async def test_preload_is_noop_when_idempotent_mutations_are_cached( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.create(context, SINGLETON_BANK_ID) await bank.sign_up( context, diff --git a/tests/reboot/protoc_gen_reboot_tests.py b/tests/reboot/protoc_gen_reboot_tests.py index 964c4a79..a2e5d82d 100644 --- a/tests/reboot/protoc_gen_reboot_tests.py +++ b/tests/reboot/protoc_gen_reboot_tests.py @@ -118,7 +118,8 @@ def test_forbid_http_annotations(self) -> None: # Reboot services don't support (custom) HTTP annotations. # # Modify the descriptor set to form the basis for the test. In this - # case, add an HTTP annotation to the `Greeter.Create()` method. + # case, add an HTTP annotation to the `Greeter.factory.Create()` + # method. file = self.descriptor_set.file[-1] self.assertEqual(file.name, 'tests/reboot/greeter.proto') diff --git a/tests/reboot/pydantic/auto_construct_user/servicer.py b/tests/reboot/pydantic/auto_construct_user/servicer.py index 860be676..f09830f0 100644 --- a/tests/reboot/pydantic/auto_construct_user/servicer.py +++ b/tests/reboot/pydantic/auto_construct_user/servicer.py @@ -23,7 +23,7 @@ async def create(self, context: TransactionContext) -> None: `Profile` for this user; a `Transaction` can call other state machines during construction.""" profile_id = f"profile-{context.state_id}" - await Profile.create(context, profile_id) + await Profile.factory.create(context, profile_id) self.state.profile_id = profile_id async def set_claims( diff --git a/tests/reboot/pydantic/auto_construct_user/test.py b/tests/reboot/pydantic/auto_construct_user/test.py index 40666fb3..a0cbac0c 100644 --- a/tests/reboot/pydantic/auto_construct_user/test.py +++ b/tests/reboot/pydantic/auto_construct_user/test.py @@ -167,8 +167,8 @@ async def test_authenticated_tolerates_preexisting_state(self) -> None: # already-constructed — and still deliver claims — rather # than aborting with `StateAlreadyConstructed`. user_id = "preexisting-user" - await User.idempotently("explicit-construction" - ).create(self.internal, user_id) + await User.factory.idempotently("explicit-construction" + ).create(self.internal, user_id) await UserServicer._authenticated( self.internal, diff --git a/tests/reboot/pydantic/discriminated_union/test.py b/tests/reboot/pydantic/discriminated_union/test.py index df37e7c0..9467a528 100644 --- a/tests/reboot/pydantic/discriminated_union/test.py +++ b/tests/reboot/pydantic/discriminated_union/test.py @@ -42,7 +42,7 @@ async def test_discriminated_union_variant_a(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await DiscriminatedUnionTest.initialize( + test, _ = await DiscriminatedUnionTest.factory.initialize( context, _TEST_STATE_ID, ) @@ -82,7 +82,7 @@ async def test_discriminated_union_variant_b(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await DiscriminatedUnionTest.initialize( + test, _ = await DiscriminatedUnionTest.factory.initialize( context, _TEST_STATE_ID, ) @@ -114,7 +114,7 @@ async def test_switch_between_variants(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await DiscriminatedUnionTest.initialize( + test, _ = await DiscriminatedUnionTest.factory.initialize( context, _TEST_STATE_ID, ) @@ -175,7 +175,7 @@ async def test_nested_discriminated_union_with_inner_x(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await NestedDiscriminatedUnionTest.initialize( + test, _ = await NestedDiscriminatedUnionTest.factory.initialize( context, _TEST_STATE_ID, ) @@ -215,7 +215,7 @@ async def test_nested_discriminated_union_with_inner_y(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await NestedDiscriminatedUnionTest.initialize( + test, _ = await NestedDiscriminatedUnionTest.factory.initialize( context, _TEST_STATE_ID, ) @@ -248,7 +248,7 @@ async def test_switch_between_nested_and_simple_variants(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await NestedDiscriminatedUnionTest.initialize( + test, _ = await NestedDiscriminatedUnionTest.factory.initialize( context, _TEST_STATE_ID, ) diff --git a/tests/reboot/pydantic/methods/servicer.py b/tests/reboot/pydantic/methods/servicer.py index ad092ce6..e56c2419 100644 --- a/tests/reboot/pydantic/methods/servicer.py +++ b/tests/reboot/pydantic/methods/servicer.py @@ -284,7 +284,7 @@ async def workflow( STR_VALUE = "initialized from workflow" STR_VALUE_WITH_STATE_ID = "initialized from workflow with state id" MY_STATE_ID = "my-state-id" - test_ref, _ = await Test.initialize_from_workflow( + test_ref, _ = await Test.factory.initialize_from_workflow( context, str_value=STR_VALUE, ) @@ -292,7 +292,7 @@ async def workflow( assert (test_ref_state.snapshot.current_str == STR_VALUE) assert test_ref.state_id != MY_STATE_ID - test_ref_with_state_id, _ = await Test.initialize_from_workflow( + test_ref_with_state_id, _ = await Test.factory.initialize_from_workflow( context, MY_STATE_ID, str_value=STR_VALUE_WITH_STATE_ID, diff --git a/tests/reboot/pydantic/methods/test.py b/tests/reboot/pydantic/methods/test.py index 84c0dfc2..fdb6f1ad 100644 --- a/tests/reboot/pydantic/methods/test.py +++ b/tests/reboot/pydantic/methods/test.py @@ -42,7 +42,7 @@ async def initialize(context: InitializeContext) -> None: STR_VALUE = "initialized from workflow" STR_VALUE_WITH_STATE_ID = "initialized from workflow with state id" - test_ref, _ = await Test.initialize_from_workflow( + test_ref, _ = await Test.factory.initialize_from_workflow( context, str_value=STR_VALUE, ) @@ -56,7 +56,7 @@ async def initialize(context: InitializeContext) -> None: MY_STATE_ID, ) - test_ref_with_state_id, _ = await Test.initialize_from_workflow( + test_ref_with_state_id, _ = await Test.factory.initialize_from_workflow( context, MY_STATE_ID, str_value=STR_VALUE_WITH_STATE_ID, @@ -83,7 +83,7 @@ async def initialize(context: InitializeContext) -> None: context = self.rbt.create_external_context(name=self.id()) - test, response = await Test.initialize( + test, response = await Test.factory.initialize( context, _TEST_STATE_ID, ) @@ -111,7 +111,7 @@ async def test_writer(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await Test.initialize( + test, _ = await Test.factory.initialize( context, _TEST_STATE_ID, ) @@ -186,7 +186,7 @@ async def test_reader(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await Test.initialize( + test, _ = await Test.factory.initialize( context, _TEST_STATE_ID, ) @@ -253,14 +253,14 @@ async def test_transaction(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await Test.initialize( + test, _ = await Test.factory.initialize( context, _TEST_STATE_ID, ) _SECOND_STATE_ID = f"{_TEST_STATE_ID}_other" - second_test, _ = await Test.initialize( + second_test, _ = await Test.factory.initialize( context, _SECOND_STATE_ID, ) @@ -341,7 +341,7 @@ async def test_workflow(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await Test.initialize( + test, _ = await Test.factory.initialize( context, _TEST_STATE_ID, ) @@ -374,7 +374,7 @@ async def test_transaction_ongoing_updates(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await Test.initialize( + test, _ = await Test.factory.initialize( context, _TEST_STATE_ID, ) @@ -396,7 +396,7 @@ async def test_raise_value_error(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await Test.initialize( + test, _ = await Test.factory.initialize( context, _TEST_STATE_ID, ) @@ -419,7 +419,7 @@ async def test_raise_declared_error(self) -> None: context = self.rbt.create_external_context(name=self.id()) - test, _ = await Test.idempotently('initialize').initialize( + test, _ = await Test.factory.idempotently('initialize').initialize( context, _TEST_STATE_ID, ) @@ -495,7 +495,7 @@ async def test_forall_with_iterables(self) -> None: "test-forall-3", ] for state_id in state_ids_list: - await Test.initialize(context, state_id) + await Test.factory.initialize(context, state_id) # Test `forall` with `dict.keys()`. state_ids_dict = {state_id: None for state_id in state_ids_list} diff --git a/tests/reboot/react/test_200_websockets/test_against_local_envoy.py b/tests/reboot/react/test_200_websockets/test_against_local_envoy.py index 530eb00d..31d6cd17 100644 --- a/tests/reboot/react/test_200_websockets/test_against_local_envoy.py +++ b/tests/reboot/react/test_200_websockets/test_against_local_envoy.py @@ -10,7 +10,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank for our test.""" - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) if __name__ == '__main__': diff --git a/tests/reboot/react/test_auth/test_against_local_envoy.py b/tests/reboot/react/test_auth/test_against_local_envoy.py index 35d29e79..ddf3f168 100644 --- a/tests/reboot/react/test_auth/test_against_local_envoy.py +++ b/tests/reboot/react/test_auth/test_against_local_envoy.py @@ -17,7 +17,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank for our test.""" - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) if __name__ == '__main__': diff --git a/tests/reboot/react/test_cache/greeter_cache.test.tsx b/tests/reboot/react/test_cache/greeter_cache.test.tsx index 7f2924c8..121f1c7a 100644 --- a/tests/reboot/react/test_cache/greeter_cache.test.tsx +++ b/tests/reboot/react/test_cache/greeter_cache.test.tsx @@ -35,7 +35,7 @@ describe("Disconnected mode - offline cache enabled", () => { it("creates Greeter and changes adjective", async () => { const context = rbt.createExternalContext("test-context-1"); - await Greeter.create(context, "greeter-test-id-1", { + await Greeter.factory.create(context, "greeter-test-id-1", { title: "Dr", name: "Jonathan", adjective: "Best", @@ -157,7 +157,7 @@ describe("Disconnected mode - offline cache disabled", () => { it("creates Greeter and changes adjectiv", async () => { const context = rbt.createExternalContext("test-context-1"); - await Greeter.create(context, "greeter-test-id-1", { + await Greeter.factory.create(context, "greeter-test-id-1", { title: "Dr", name: "Jonathan", adjective: "Best", diff --git a/tests/reboot/react/test_errors/test_against_local_envoy.py b/tests/reboot/react/test_errors/test_against_local_envoy.py index 3da691dc..c7057d42 100644 --- a/tests/reboot/react/test_errors/test_against_local_envoy.py +++ b/tests/reboot/react/test_errors/test_against_local_envoy.py @@ -10,7 +10,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank for our test.""" - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) if __name__ == '__main__': diff --git a/tests/reboot/react/test_http_fallback/test.py b/tests/reboot/react/test_http_fallback/test.py index 960f3a1d..5bc778b9 100644 --- a/tests/reboot/react/test_http_fallback/test.py +++ b/tests/reboot/react/test_http_fallback/test.py @@ -15,7 +15,7 @@ async def test(context: ExternalContext, uri: str): # Call the constructor for this actor so we have state to # receive when `Greet` is called. - await Greeter.idempotently(f"Create '{state_id}'").Create( + await Greeter.factory.idempotently(f"Create '{state_id}'").Create( context, state_id, title='Count', diff --git a/tests/reboot/react/test_idempotent_writer/test.py b/tests/reboot/react/test_idempotent_writer/test.py index 26b1086f..e9cf36a0 100644 --- a/tests/reboot/react/test_idempotent_writer/test.py +++ b/tests/reboot/react/test_idempotent_writer/test.py @@ -14,7 +14,7 @@ async def test(context: ExternalContext, uri: str): # Call the constructor for this actor so we have state to receive # when .Greet is called. - await Greeter.idempotently(f"Create '{state_id}'").Create( + await Greeter.factory.idempotently(f"Create '{state_id}'").Create( context, state_id, title='Count', diff --git a/tests/reboot/react/test_long_running_fetches/test.py b/tests/reboot/react/test_long_running_fetches/test.py index 81e0bc61..944f0694 100644 --- a/tests/reboot/react/test_long_running_fetches/test.py +++ b/tests/reboot/react/test_long_running_fetches/test.py @@ -24,7 +24,7 @@ async def test(context: ExternalContext, uri: str): # long running fetches. return - await Greeter.idempotently(f"Create '{STATE_ID}'").Create( + await Greeter.factory.idempotently(f"Create '{STATE_ID}'").Create( context, STATE_ID, title='Count', diff --git a/tests/reboot/react/test_mutations/test.py b/tests/reboot/react/test_mutations/test.py index 299d95d8..2b5336c7 100644 --- a/tests/reboot/react/test_mutations/test.py +++ b/tests/reboot/react/test_mutations/test.py @@ -14,7 +14,7 @@ async def test(context: ExternalContext, uri: str): # Call the constructor for this actor so we have state to receive # when .Greet is called. - await Greeter.idempotently(f"Create '{state_id}'").Create( + await Greeter.factory.idempotently(f"Create '{state_id}'").Create( context, state_id, title='Count', diff --git a/tests/reboot/react/test_reactive_reader_slow_consumer/test.py b/tests/reboot/react/test_reactive_reader_slow_consumer/test.py index 233b7dba..4abe5f16 100644 --- a/tests/reboot/react/test_reactive_reader_slow_consumer/test.py +++ b/tests/reboot/react/test_reactive_reader_slow_consumer/test.py @@ -21,7 +21,7 @@ async def test(context: ExternalContext, uri: str): """ state_id = 'greeter-slow-consumer-test' - await Greeter.idempotently(f"Create '{state_id}'").Create( + await Greeter.factory.idempotently(f"Create '{state_id}'").Create( context, state_id, title='Count', diff --git a/tests/reboot/react/test_reader/test_against_local_envoy.py b/tests/reboot/react/test_reader/test_against_local_envoy.py index 29a7570c..e597f09e 100644 --- a/tests/reboot/react/test_reader/test_against_local_envoy.py +++ b/tests/reboot/react/test_reader/test_against_local_envoy.py @@ -10,7 +10,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank for our test.""" - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) if __name__ == '__main__': diff --git a/tests/reboot/react/test_state_id_change/state_id_change.test.tsx b/tests/reboot/react/test_state_id_change/state_id_change.test.tsx index 37d4f3bf..c6a49a1e 100644 --- a/tests/reboot/react/test_state_id_change/state_id_change.test.tsx +++ b/tests/reboot/react/test_state_id_change/state_id_change.test.tsx @@ -50,13 +50,13 @@ describe("Reader state-ID change", () => { const context = rbt.createExternalContext("test-state-id-change"); // Create two independent Greeter state instances. - await Greeter.create(context, "greeter-alpha", { + await Greeter.factory.create(context, "greeter-alpha", { title: "Dr", name: "Alpha", adjective: "first", }); - await Greeter.create(context, "greeter-beta", { + await Greeter.factory.create(context, "greeter-beta", { title: "Mr", name: "Beta", adjective: "second", diff --git a/tests/reboot/react/test_suspense/test_against_local_envoy.py b/tests/reboot/react/test_suspense/test_against_local_envoy.py index fadac648..2f9b4d6e 100644 --- a/tests/reboot/react/test_suspense/test_against_local_envoy.py +++ b/tests/reboot/react/test_suspense/test_against_local_envoy.py @@ -10,7 +10,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank for our test.""" - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) if __name__ == '__main__': diff --git a/tests/reboot/react/test_undeclared_errors/test_against_local_envoy.py b/tests/reboot/react/test_undeclared_errors/test_against_local_envoy.py index a97b5efe..feffd0b7 100644 --- a/tests/reboot/react/test_undeclared_errors/test_against_local_envoy.py +++ b/tests/reboot/react/test_undeclared_errors/test_against_local_envoy.py @@ -10,7 +10,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank for our test.""" - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) if __name__ == '__main__': diff --git a/tests/reboot/react/test_websockets_connection/test_against_local_envoy.py b/tests/reboot/react/test_websockets_connection/test_against_local_envoy.py index 1f3bd9f4..dc3c3c81 100644 --- a/tests/reboot/react/test_websockets_connection/test_against_local_envoy.py +++ b/tests/reboot/react/test_websockets_connection/test_against_local_envoy.py @@ -10,7 +10,7 @@ async def initialize(context: InitializeContext): """Create the singleton bank for our test.""" - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) if __name__ == '__main__': diff --git a/tests/reboot/react/test_writer_abort_with_retrying_reactive_reader/test.py b/tests/reboot/react/test_writer_abort_with_retrying_reactive_reader/test.py index b45dd297..954cc184 100644 --- a/tests/reboot/react/test_writer_abort_with_retrying_reactive_reader/test.py +++ b/tests/reboot/react/test_writer_abort_with_retrying_reactive_reader/test.py @@ -35,7 +35,7 @@ async def test(context: ExternalContext, uri: str): state_id = 'actor-test-132' - test, _ = await Test.idempotently(f"Create '{state_id}'").Create( + test, _ = await Test.factory.idempotently(f"Create '{state_id}'").Create( context, state_id, ) diff --git a/tests/reboot/reactivity_test.py b/tests/reboot/reactivity_test.py index 488b1cf1..e2798cbc 100644 --- a/tests/reboot/reactivity_test.py +++ b/tests/reboot/reactivity_test.py @@ -56,7 +56,7 @@ async def test_reactive_get_all_state(self) -> None: """ await self.rbt.up(Application(servicers=[MyGreeterServicer])) context = self.rbt.create_external_context(name=f"test-{self.id()}") - greeter, _ = await Greeter.Create( + greeter, _ = await Greeter.factory.Create( context, "my-greeter", title="Mr.", diff --git a/tests/reboot/reboot_tests.py b/tests/reboot/reboot_tests.py index 5e41e9c5..c6580d90 100644 --- a/tests/reboot/reboot_tests.py +++ b/tests/reboot/reboot_tests.py @@ -436,7 +436,7 @@ async def test_deep_recursive_message(self) -> None: context = self.rbt.create_external_context(name=self.id()) - greeter, _ = await Greeter.Create( + greeter, _ = await Greeter.factory.Create( context, title='Dr', name='Jonathan', diff --git a/tests/reboot/server/local_envoy_test.py b/tests/reboot/server/local_envoy_test.py index 9e7a2621..995c9122 100644 --- a/tests/reboot/server/local_envoy_test.py +++ b/tests/reboot/server/local_envoy_test.py @@ -195,7 +195,7 @@ async def test_server_filter(self): name='test_server_filter', url=f"https://{endpoint}", ) - await General.ConstructorWriter(context, 'foo') + await General.factory.ConstructorWriter(context, 'foo') seen_ids = set() for i in range(30): response = await General.ref('foo').Reader(context) @@ -206,7 +206,9 @@ async def test_server_filter(self): # across all servers. seen_ids = set() for state_id in string.ascii_lowercase: - _, response = await General.ConstructorWriter(context, state_id) + _, response = await General.factory.ConstructorWriter( + context, state_id + ) server_id = response.content[SERVER_ID_HEADER] seen_ids.add((response.content["id"], server_id)) self.assertEqual( @@ -248,7 +250,9 @@ async def test_server_filter(self): # for such states must route to the same server both via gRPC # calls (which send tagged state refs) and via HTTP calls with # human-readable state refs. - _, response = await General.ConstructorWriter(context, "foo:bar/baz") + _, response = await General.factory.ConstructorWriter( + context, "foo:bar/baz" + ) id_server_pair = ( response.content["id"], response.content[SERVER_ID_HEADER], @@ -342,9 +346,11 @@ async def test_mangled_path_filter(self): for i in range(30): state_id = f"foo-{i}" - general, construct_response = await General.ConstructorWriter( - context, - state_id, + general, construct_response = ( + await General.factory.ConstructorWriter( + context, + state_id, + ) ) # If we make an HTTP request to the designated HTTP RPC endpoint using @@ -416,7 +422,7 @@ async def test_remove_json_trailers_filter(self): ) # Create a state to test with. - await General.ConstructorWriter(context, 'test_state') + await General.factory.ConstructorWriter(context, 'test_state') # Use h2 library to make a low-level HTTP/2 request # that can distinguish between headers and trailers. diff --git a/tests/reboot/std/ciphertext/v1/ciphertext_tests.py b/tests/reboot/std/ciphertext/v1/ciphertext_tests.py index e012fd02..7014ffe7 100644 --- a/tests/reboot/std/ciphertext/v1/ciphertext_tests.py +++ b/tests/reboot/std/ciphertext/v1/ciphertext_tests.py @@ -55,7 +55,7 @@ async def _encrypt( scope: str, key_manager_id: str, ) -> str: - ciphertext, _ = await Ciphertext.encrypt( + ciphertext, _ = await Ciphertext.factory.encrypt( self.context, plaintext=plaintext, associated_data=associated_data, diff --git a/tests/reboot/std/collections/sorted_map_tests.py b/tests/reboot/std/collections/sorted_map_tests.py index 613c89bd..1cb2bd68 100644 --- a/tests/reboot/std/collections/sorted_map_tests.py +++ b/tests/reboot/std/collections/sorted_map_tests.py @@ -518,7 +518,7 @@ async def test_transaction_basic(self) -> None: ) sorted_map, context = self.map() - consumer, _ = await General.ConstructorWriter(context) + consumer, _ = await General.factory.ConstructorWriter(context) expected_entries_before = {"2": b""} expected_entries_after = {"1": b"", "2": b"", "3": b""} @@ -584,7 +584,7 @@ async def test_transaction_abort(self) -> None: ) sorted_map, context = self.map() - consumer, _ = await General.ConstructorWriter(context) + consumer, _ = await General.factory.ConstructorWriter(context) expected_entries_before = {"2": b""} diff --git a/tests/reboot/tasks_tests.py b/tests/reboot/tasks_tests.py index d3c1f720..d7cac906 100644 --- a/tests/reboot/tasks_tests.py +++ b/tests/reboot/tasks_tests.py @@ -428,7 +428,7 @@ async def test_ref_schedule_in_transaction(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) response = await bank.SignUp(context, account_id='jonathan') @@ -580,7 +580,7 @@ async def test_alpha_servicer_read_write_in_workflow(self) -> None: context = self.rbt.create_external_context(name=self.id()) - greeter, _ = await Greeter.Create( + greeter, _ = await Greeter.factory.Create( context, title='Dr', name='Jonathan', @@ -666,7 +666,7 @@ async def callable() -> General.State: context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.ConstructorWriter(context) + g, _ = await General.factory.ConstructorWriter(context) task = await g.spawn().Workflow(context) @@ -750,7 +750,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.ConstructorWriter(context) + g, _ = await General.factory.ConstructorWriter(context) task = await g.spawn().Workflow(context) @@ -799,7 +799,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.ConstructorWriter(context) + g, _ = await General.factory.ConstructorWriter(context) # Spawn a workflow with an absolute time that includes the timezone. task = await g.spawn(when=datetime.now(tz=get_localzone()) @@ -886,7 +886,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.ConstructorWriter(context) + g, _ = await General.factory.ConstructorWriter(context) # Call Writer that will schedule a workflow with an absolute time that does not include the timezone. await g.Writer(context, content={'timezone_attached': ""}) @@ -981,7 +981,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.ConstructorTransaction(context, ID) + g, _ = await General.factory.ConstructorTransaction(context, ID) # Call Transaction that will schedule a workflow with an absolute time that does not include the timezone. await g.Transaction(context, content={'timezone_attached': ""}) @@ -1056,7 +1056,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.ConstructorWriter(context) + g, _ = await General.factory.ConstructorWriter(context) # Call Transaction that will schedule a workflow with a timedelta. await g.Transaction(context) @@ -1120,7 +1120,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.ConstructorTransaction(context, ID) + g, _ = await General.factory.ConstructorTransaction(context, ID) # Call Transaction that will schedule a workflow with a timedelta. await g.Transaction(context) @@ -1191,7 +1191,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.constructor_writer(context) + g, _ = await General.factory.constructor_writer(context) # Run the workflow. await g.workflow(context) @@ -1296,7 +1296,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.constructor_writer(context) + g, _ = await General.factory.constructor_writer(context) # Spawn the workflow. task = await g.spawn().workflow(context) @@ -1426,7 +1426,7 @@ async def workflow( context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.constructor_writer(context) + g, _ = await General.factory.constructor_writer(context) # Spawn the workflow. task = await g.spawn().workflow(context) @@ -1586,7 +1586,7 @@ async def write(state: General.State) -> str: context = self.rbt.create_external_context(name=self.id()) # Construct. - g, _ = await General.constructor_writer(context) + g, _ = await General.factory.constructor_writer(context) # Spawn the workflow. task = await g.spawn().workflow(context) @@ -1690,7 +1690,7 @@ async def async_on_method(*, retrying: bool) -> None: context = self.rbt.create_external_context(name=self.id()) - g, _ = await General.constructor_writer(context) + g, _ = await General.factory.constructor_writer(context) await g.workflow(context) @@ -1773,7 +1773,7 @@ def on_method(*, retrying: bool) -> None: context = self.rbt.create_external_context(name=self.id()) - g, _ = await General.constructor_writer(context) + g, _ = await General.factory.constructor_writer(context) await g.workflow(context) @@ -1856,7 +1856,7 @@ def on_iteration(*, iteration: int) -> None: context = self.rbt.create_external_context(name=self.id()) - g, _ = await General.constructor_writer(context) + g, _ = await General.factory.constructor_writer(context) await g.workflow(context) @@ -1923,7 +1923,7 @@ def on_method(*, retrying: bool) -> None: context = self.rbt.create_external_context(name=self.id()) - g, _ = await General.constructor_writer(context) + g, _ = await General.factory.constructor_writer(context) await g.workflow(context) diff --git a/tests/reboot/thirdparty/mailgun/tests.py b/tests/reboot/thirdparty/mailgun/tests.py index e51d85ad..0721cdea 100644 --- a/tests/reboot/thirdparty/mailgun/tests.py +++ b/tests/reboot/thirdparty/mailgun/tests.py @@ -36,7 +36,7 @@ async def test_emailer(self) -> None: bearer_token=MAILGUN_API_KEY, ) - _, send_response = await Message.Send( + _, send_response = await Message.factory.Send( context, recipient="team@reboot.dev", sender="hipsterstore@reboot.dev", @@ -54,7 +54,7 @@ async def test_emailer(self) -> None: self.assertEqual(1, len(MockMessageServicer.emails_sent)) MockMessageServicer.emails_sent.clear() - _, send_response = await Message.Send( + _, send_response = await Message.factory.Send( context, recipient="team@reboot.dev", sender="hipsterstore@reboot.dev", diff --git a/tests/reboot/transaction_tests.py b/tests/reboot/transaction_tests.py index bf2f1ae6..52548a20 100644 --- a/tests/reboot/transaction_tests.py +++ b/tests/reboot/transaction_tests.py @@ -110,7 +110,7 @@ async def test_transactions_basic(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp( context, @@ -156,7 +156,7 @@ async def test_transactions_after_down(self) -> None: context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp( context, @@ -223,7 +223,7 @@ async def mock_commit(state_manager, request, grpc_context): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') @@ -256,7 +256,7 @@ async def mock_prepare(state_manager, request, grpc_context): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) with self.assertRaises(Bank.SignUpAborted): await bank.SignUp(context, account_id='jonathan') @@ -299,7 +299,7 @@ async def mock_prepare(state_manager, request, grpc_context): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) with self.assertRaises(Bank.SignUpAborted): await bank.SignUp(context, account_id='jonathan') @@ -391,7 +391,7 @@ async def mock_abort(state_manager, request, grpc_context): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # Confirm that the relevant Bank and Account instances are running # in different servers. Note that this isn't necessarily @@ -486,7 +486,7 @@ async def mock_abort(state_manager, request, grpc_context): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # Confirm that the relevant Bank and Account instances are running # in different servers. Note that this isn't necessarily @@ -603,7 +603,7 @@ def mock_should_retry(unary_retried_call, error): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # Confirm that `Bank` and `Account` are on different # servers so we can restart just the participant. @@ -662,7 +662,7 @@ async def mock_transaction_participant_store( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') @@ -713,7 +713,7 @@ async def mock_transaction_participant_store( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') @@ -773,7 +773,7 @@ async def mock_commit(state_manager, request, grpc_context): ) context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # Confirm that the relevant Bank and Account instances are running # in different servers. Note that this isn't necessarily @@ -907,7 +907,7 @@ async def mock_commit(state_manager, request, grpc_context): ) context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp( context, account_id=alice_account_ref.id, initial_deposit=100 ) @@ -1054,7 +1054,7 @@ async def mock_commit(state_manager, request, grpc_context): ) context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # Bank and Account on different servers (the existing # recovery tests rely on this and we want the same @@ -1166,7 +1166,7 @@ async def mock_transaction_coordinator_prepared( ) context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # Confirm that `Bank` and `Account` are on different # servers so we exercise cross-server recovery. @@ -1263,7 +1263,7 @@ async def mock_transaction_participant_prepare( ) context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) bank_server_id, account_server_id = await self.rbt.unique_servers( bank._state_ref, @@ -1394,7 +1394,7 @@ def mock_transaction_await(*args, **kwargs): # Create the account using the transactional method `SignUp`. context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp( context, account_id=account_name, initial_deposit=10 @@ -1468,7 +1468,7 @@ async def mock_SignUp( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) with self.assertRaises(Bank.SignUpAborted) as aborted: await bank.SignUp(context, account_id='jonathan') @@ -1651,7 +1651,7 @@ def check_transactionally( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) bank_initialized = True @@ -1736,7 +1736,7 @@ def check_transactionally( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') @@ -1815,7 +1815,7 @@ def check_transactionally( context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) with self.assertRaises(Bank.SignUpAborted) as aborted: await bank.SignUp(context, account_id='jonathan') @@ -1835,7 +1835,7 @@ async def test_transaction_aborts_when_catching_undeclared_errors(self): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') @@ -1859,7 +1859,7 @@ async def test_nested_catch_undeclared_aborts_root(self): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') @@ -1889,7 +1889,7 @@ async def test_nested_read_only_doomed_subtree_aborts_root(self): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='catcher') await bank.SignUp(context, account_id='thrower') @@ -1915,7 +1915,7 @@ async def test_transaction_not_aborts_when_catching_declared_errors(self): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan') @@ -1981,7 +1981,7 @@ async def test_nested_transaction_aborts_even_if_parent_does_not(self): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='jonathan', initial_deposit=7) @@ -2025,7 +2025,7 @@ async def test_inherited_ownership_abort(self): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # Opens 'inherited' (balance 10), then via a nested transaction # that does NOT touch 'inherited' calls a deeper nested @@ -2093,7 +2093,7 @@ async def mock_acquire_exclusive(lock, *args, **kwargs): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp( context, account_id='retainacct', initial_deposit=10 @@ -2201,7 +2201,7 @@ async def mock_wait_ownership(transaction, condition, *args, **kwargs): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) root_task = asyncio.create_task( bank.TestPrepareWaitForNestedAbortRollback( @@ -2307,7 +2307,7 @@ async def test_constructor_after_abort_from_unconstructed(self): type(aborted.exception.error), errors_pb2.StateNotConstructed ) - await Bank.Create(context, SINGLETON_BANK_ID) + await Bank.factory.Create(context, SINGLETON_BANK_ID) async def test_transactional_constructor(self): """Tests that we can call a transactional constructor, and that aborting @@ -2346,7 +2346,9 @@ async def Reader( context = self.rbt.create_external_context(name=self.id()) # Successfully create, and confirm that we can see the state. - item1, _ = await General.ConstructorTransaction(context, "item1") + item1, _ = await General.factory.ConstructorTransaction( + context, "item1" + ) self.assertEqual( {"yep": "it ran"}, dict((await item1.Reader(context)).content) ) @@ -2355,7 +2357,7 @@ async def Reader( with self.assertRaises( General.ConstructorTransactionAborted ) as ct_aborted: - await General.ConstructorTransaction( + await General.factory.ConstructorTransaction( context, "item2", content={"abort": "True"}, @@ -2402,7 +2404,7 @@ async def Reader( ) context = self.rbt.create_external_context(name=self.id()) - item, _ = await General.ConstructorTransaction(context, "item") + item, _ = await General.factory.ConstructorTransaction(context, "item") # The actor must be constructed: reading it must succeed rather # than abort with `StateNotConstructed`. @@ -2418,7 +2420,7 @@ async def test_nested_transactions(self): context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # A nested transaction (`Bank.Transfer`) on the same `Bank` # state as the parent transaction, also modifying accounts @@ -2551,7 +2553,7 @@ async def Transaction( entries={"bar": b"bar"}, ) - general, _ = await General.ConstructorWriter(context) + general, _ = await General.factory.ConstructorWriter(context) # We first call `General.Transaction` for a nonexistent key, which # will cause its `SortedMap.Get` call to fail, and therefore cause the @@ -2597,7 +2599,7 @@ async def test_successful_transaction_no_trailing_metadata(self) -> None: # Create a bank and an account to test with. context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) await bank.SignUp(context, account_id='test-account') # Now use raw gRPC to call a transaction method, so we can check @@ -2643,7 +2645,7 @@ async def test_failing_transaction_no_trailing_metadata(self) -> None: # Create a bank to test with. context = self.rbt.create_external_context(name=self.id()) - bank, _ = await Bank.Create(context, SINGLETON_BANK_ID) + bank, _ = await Bank.factory.Create(context, SINGLETON_BANK_ID) # Now use raw gRPC to call a transaction method that will fail, # so we can check the trailing metadata. diff --git a/tests/reboot/zod/methods/test.ts b/tests/reboot/zod/methods/test.ts index 79d7a0d4..e3545253 100644 --- a/tests/reboot/zod/methods/test.ts +++ b/tests/reboot/zod/methods/test.ts @@ -17,7 +17,7 @@ test("Test Zod Service", async (t) => { const context = rbt.createExternalContext("test"); - const [test] = await Test.construct(context, {}); + const [test] = await Test.factory.construct(context, {}); await test.writer(context, { data: "initialize",