Skip to content

Commit a5d1355

Browse files
committed
Add the typed client to the test harness
1 parent 8272635 commit a5d1355

File tree

10 files changed

+70
-17
lines changed

10 files changed

+70
-17
lines changed

examples/client.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919

2020
async def main():
21-
2221
async with restate.create_client("http://localhost:8080") as client:
2322
await client.object_call(increment, key="a", arg=5)
2423

examples/example.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
# pylint: disable=C0116
1313
# pylint: disable=W0613
1414

15+
16+
#
17+
# uv run examples/example.py
18+
#
19+
1520
import logging
1621
import restate
1722

examples/harness.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#
2+
# Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH
3+
#
4+
# This file is part of the Restate SDK for Python,
5+
# which is released under the MIT license.
6+
#
7+
# You can find a copy of the license in file LICENSE in the root
8+
# directory of this repository or package, or at
9+
# https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
10+
#
11+
import restate
12+
13+
from virtual_object import increment, count, counter
14+
15+
#
16+
# uv run examples/harness.py
17+
#
18+
19+
20+
async def main():
21+
app = restate.app([counter])
22+
async with restate.create_test_harness(app) as harness:
23+
await harness.client.object_call(increment, key="a", arg=5)
24+
await harness.client.object_call(increment, key="a", arg=5)
25+
26+
current_count = await harness.client.object_call(count, key="a", arg=None)
27+
28+
print(f"Current count for 'a': {current_count}")
29+
30+
send = await harness.client.object_send(increment, key="b", arg=-10, idempotency_key="op1")
31+
32+
print(f"Sent increment to 'b', invocation ID: {send.invocation_id}")
33+
34+
35+
if __name__ == "__main__":
36+
import asyncio
37+
38+
asyncio.run(main())

examples/requirements.txt

Lines changed: 0 additions & 4 deletions
This file was deleted.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ test = ["pytest", "hypercorn"]
2525
lint = ["mypy>=1.11.2", "pyright>=1.1.390", "ruff>=0.6.9"]
2626
harness = ["testcontainers", "hypercorn", "httpx"]
2727
serde = ["dacite", "pydantic"]
28-
client = ["httpx"]
28+
client = ["httpx[http2]"]
2929

3030
[build-system]
3131
requires = ["maturin>=1.6,<2.0"]

python/restate/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
Restate SDK for Python
1313
"""
1414

15-
from contextlib import contextmanager, asynccontextmanager
15+
from contextlib import asynccontextmanager
1616
import typing
1717

1818
from restate.server_types import RestateAppT
@@ -51,14 +51,14 @@
5151
# we don't have the appropriate dependencies installed
5252

5353
# pylint: disable=unused-argument, redefined-outer-name
54-
@contextmanager
54+
@asynccontextmanager
5555
def create_test_harness(
5656
app: RestateAppT,
5757
follow_logs: bool = False,
5858
restate_image: str = "restatedev/restate:latest",
5959
always_replay: bool = False,
6060
disable_retries: bool = False,
61-
) -> typing.Generator[TestHarnessEnvironment, None, None]:
61+
) -> typing.AsyncGenerator[TestHarnessEnvironment, None]:
6262
"""a dummy harness constructor to raise ImportError. Install restate-sdk[harness] to use this feature"""
6363
raise ImportError("Install restate-sdk[harness] to use this feature")
6464

python/restate/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,5 +312,5 @@ async def create_client(ingress: str, headers: typing.Optional[dict] = None) ->
312312
"""
313313
Create a new Restate client.
314314
"""
315-
async with httpx.AsyncClient(base_url=ingress, headers=headers) as http_client:
315+
async with httpx.AsyncClient(base_url=ingress, headers=headers, http2=True) as http_client:
316316
yield Client(http_client, headers)

python/restate/harness.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@
1717
import typing
1818
from urllib.error import URLError
1919
import socket
20-
from contextlib import contextmanager
20+
from contextlib import contextmanager, asynccontextmanager
2121
from warnings import deprecated
2222

2323
from hypercorn.config import Config
2424
from hypercorn.asyncio import serve
25+
from restate.client import create_client
2526
from restate.server_types import RestateAppT
2627
from restate.types import TestHarnessEnvironment
2728
from testcontainers.core.container import DockerContainer # type: ignore
2829
from testcontainers.core.waiting_utils import wait_container_is_ready # type: ignore
30+
2931
import httpx
3032

3133

@@ -332,14 +334,14 @@ def test_harness(
332334
return RestateTestHarness(app, config)
333335

334336

335-
@contextmanager
336-
def create_test_harness(
337+
@asynccontextmanager
338+
async def create_test_harness(
337339
app: RestateAppT,
338340
follow_logs: bool = False,
339341
restate_image: str = "restatedev/restate:latest",
340342
always_replay: bool = False,
341343
disable_retries: bool = False,
342-
) -> typing.Generator[TestHarnessEnvironment, None, None]:
344+
) -> typing.AsyncGenerator[TestHarnessEnvironment, None]:
343345
"""
344346
Creates a test harness for running Restate services together with restate-server.
345347
@@ -378,4 +380,7 @@ def create_test_harness(
378380
msg = f"unable to register the services at {bind_address} - {res.status_code} {res.text}"
379381
raise AssertionError(msg)
380382

381-
yield TestHarnessEnvironment(ingress_url=runtime.ingress_url(), admin_api_url=runtime.admin_url())
383+
async with create_client(runtime.ingress_url()) as client:
384+
yield TestHarnessEnvironment(
385+
ingress_url=runtime.ingress_url(), admin_api_url=runtime.admin_url(), client=client
386+
)

python/restate/types.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
from dataclasses import dataclass
1919

20+
from restate.client import RestateClient
21+
2022

2123
@dataclass
2224
class TestHarnessEnvironment:
@@ -27,3 +29,6 @@ class TestHarnessEnvironment:
2729

2830
admin_api_url: str
2931
"""The URL of the Restate admin API endpoint used in the test"""
32+
33+
client: RestateClient
34+
"""The Restate client connected to the ingress URL"""

uv.lock

Lines changed: 7 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)