diff --git a/bank/backend/src/account_servicer.py b/bank/backend/src/account_servicer.py index 04f4a08..e851784 100644 --- a/bank/backend/src/account_servicer.py +++ b/bank/backend/src/account_servicer.py @@ -13,6 +13,7 @@ WithdrawResponse, ) from bank.v1.errors_pb2 import OverdraftError +from reboot.aio.auth.authorizers import allow from reboot.aio.contexts import ReaderContext, WriterContext logging.basicConfig(level=logging.INFO) @@ -20,6 +21,9 @@ class AccountServicer(Account.Servicer): + def authorizer(self): + return allow() + async def Open( self, context: WriterContext, diff --git a/bank/backend/src/bank_servicer.py b/bank/backend/src/bank_servicer.py index b73b634..9863570 100644 --- a/bank/backend/src/bank_servicer.py +++ b/bank/backend/src/bank_servicer.py @@ -8,6 +8,7 @@ TransferRequest, TransferResponse, ) +from reboot.aio.auth.authorizers import allow from reboot.aio.contexts import TransactionContext logging.basicConfig(level=logging.INFO) @@ -15,6 +16,9 @@ class BankServicer(Bank.Servicer): + def authorizer(self): + return allow() + async def SignUp( self, context: TransactionContext, diff --git a/bank/backend/tests/account_servicer_test.py b/bank/backend/tests/account_servicer_test.py index 2bbbc1b..457c026 100644 --- a/bank/backend/tests/account_servicer_test.py +++ b/bank/backend/tests/account_servicer_test.py @@ -2,6 +2,7 @@ from account_servicer import AccountServicer from bank.v1.account_rbt import Account, BalanceResponse from bank.v1.errors_pb2 import OverdraftError +from reboot.aio.applications import Application from reboot.aio.tests import Reboot from unittest import mock @@ -23,7 +24,7 @@ async def asyncTearDown(self) -> None: async def test_basics(self) -> None: context = self.rbt.create_external_context(name=f"test-{self.id()}") - await self.rbt.up(servicers=[AccountServicer]) + await self.rbt.up(Application(servicers=[AccountServicer])) # Create the state machine by calling its constructor. The fact that the # state machine _has_ a constructor means that this step is required @@ -72,7 +73,7 @@ async def withdraw(): @mock.patch("account_servicer.send_email") async def test_send_welcome_email(self, mock_send_email) -> None: await self.rbt.up( - servicers=[AccountServicer], + Application(servicers=[AccountServicer]), # Normally, `rbt.up()` runs the servicers in a separate process, to # ensure that accidental use of blocking functions (an easy mistake # to make) don't cause the test to lock up. However, in this test diff --git a/bank/backend/tests/bank_servicer_test.py b/bank/backend/tests/bank_servicer_test.py index 82d5273..09f0882 100644 --- a/bank/backend/tests/bank_servicer_test.py +++ b/bank/backend/tests/bank_servicer_test.py @@ -4,6 +4,7 @@ from bank.v1.bank_rbt import Bank, SignUpResponse from bank.v1.errors_pb2 import OverdraftError from bank_servicer import BankServicer +from reboot.aio.applications import Application from reboot.aio.tests import Reboot @@ -17,7 +18,9 @@ async def asyncTearDown(self) -> None: await self.rbt.stop() async def test_signup(self) -> None: - await self.rbt.up(servicers=[BankServicer, AccountServicer]) + await self.rbt.up( + Application(servicers=[BankServicer, AccountServicer]) + ) context = self.rbt.create_external_context(name=f"test-{self.id()}") bank = Bank.ref("my-bank") @@ -34,7 +37,9 @@ async def test_signup(self) -> None: self.assertEqual(response.balance, 0) async def test_transfer(self): - await self.rbt.up(servicers=[BankServicer, AccountServicer]) + await self.rbt.up( + Application(servicers=[BankServicer, AccountServicer]) + ) context = self.rbt.create_external_context(name=f"test-{self.id()}") bank = Bank.ref("my-bank") diff --git a/hello-constructors/backend/src/hello_servicer.py b/hello-constructors/backend/src/hello_servicer.py index 098b1e4..2f3f4d2 100644 --- a/hello-constructors/backend/src/hello_servicer.py +++ b/hello-constructors/backend/src/hello_servicer.py @@ -7,11 +7,15 @@ SendRequest, SendResponse, ) +from reboot.aio.auth.authorizers import allow from reboot.aio.contexts import ReaderContext, WriterContext class HelloServicer(Hello.Servicer): + def authorizer(self): + return allow() + async def Create( self, context: WriterContext, diff --git a/hello-constructors/backend/tests/hello_servicer_test.py b/hello-constructors/backend/tests/hello_servicer_test.py index 47d7de7..0c7635a 100644 --- a/hello-constructors/backend/tests/hello_servicer_test.py +++ b/hello-constructors/backend/tests/hello_servicer_test.py @@ -1,6 +1,7 @@ import unittest from hello_constructors.v1.hello_rbt import Hello from hello_servicer import HelloServicer +from reboot.aio.applications import Application from reboot.aio.tests import Reboot @@ -14,7 +15,7 @@ async def asyncTearDown(self) -> None: await self.rbt.stop() async def test_hello_constructors(self) -> None: - await self.rbt.up(servicers=[HelloServicer]) + await self.rbt.up(Application(servicers=[HelloServicer])) context = self.rbt.create_external_context(name=f"test-{self.id()}") diff --git a/hello-legacy-grpc/backend/src/deprecated_greeter_servicer.py b/hello-legacy-grpc/backend/src/deprecated_greeter_servicer.py index 7e6213e..c5087f7 100644 --- a/hello-legacy-grpc/backend/src/deprecated_greeter_servicer.py +++ b/hello-legacy-grpc/backend/src/deprecated_greeter_servicer.py @@ -2,10 +2,14 @@ import random from google.protobuf.empty_pb2 import Empty from hello_legacy_grpc.v1 import greeter_pb2, greeter_pb2_grpc +from reboot.aio.auth.authorizers import allow class DeprecatedGreeterServicer(greeter_pb2_grpc.DeprecatedGreeterServicer): + def authorizer(self): + return allow() + async def Greet( self, request: greeter_pb2.GreetRequest, diff --git a/hello-legacy-grpc/backend/src/proxy_greeter_servicer.py b/hello-legacy-grpc/backend/src/proxy_greeter_servicer.py index ecef902..3af9dec 100644 --- a/hello-legacy-grpc/backend/src/proxy_greeter_servicer.py +++ b/hello-legacy-grpc/backend/src/proxy_greeter_servicer.py @@ -15,7 +15,9 @@ async def Greet( # new Reboot service. This proxy servicer will forward traffic to # either the RebootGreeter or the DeprecatedGreeter with a 50/50 # ratio. - context = legacy_context.external_context(name=self.Greet.__name__) + context = legacy_context.external_context( + name="Call into `RebootGreeter`" + ) if random.random() < 0.5: # Route to RebootGreeter. reboot_greeter = RebootGreeter.ref("my-greeter") diff --git a/hello-legacy-grpc/backend/src/reboot_greeter_servicer.py b/hello-legacy-grpc/backend/src/reboot_greeter_servicer.py index c45adc3..9b1c7ac 100644 --- a/hello-legacy-grpc/backend/src/reboot_greeter_servicer.py +++ b/hello-legacy-grpc/backend/src/reboot_greeter_servicer.py @@ -7,6 +7,7 @@ GreetResponse, RebootGreeter, ) +from reboot.aio.auth.authorizers import allow from reboot.aio.contexts import ( Context, ReaderContext, @@ -20,6 +21,9 @@ class RebootGreeterServicer(RebootGreeter.Servicer): + def authorizer(self): + return allow() + async def _get_deprecated_salutation(self, context: Context) -> str: """Fetch a salutation from the deprecated Greeter service written in legacy gRPC.""" diff --git a/hello-legacy-grpc/backend/tests/greeter_servicer_test.py b/hello-legacy-grpc/backend/tests/greeter_servicer_test.py index b2f785d..60618f6 100644 --- a/hello-legacy-grpc/backend/tests/greeter_servicer_test.py +++ b/hello-legacy-grpc/backend/tests/greeter_servicer_test.py @@ -4,6 +4,7 @@ from hello_legacy_grpc.v1 import greeter_pb2, greeter_pb2_grpc from hello_legacy_grpc.v1.greeter_rbt import RebootGreeter from proxy_greeter_servicer import ProxyGreeterServicer +from reboot.aio.applications import Application from reboot.aio.tests import Reboot from reboot_greeter_servicer import RebootGreeterServicer @@ -19,8 +20,10 @@ async def asyncTearDown(self) -> None: async def test_reboot_greeter(self) -> None: await self.rbt.up( - servicers=[RebootGreeterServicer], - legacy_grpc_servicers=[DeprecatedGreeterServicer], + Application( + servicers=[RebootGreeterServicer], + legacy_grpc_servicers=[DeprecatedGreeterServicer], + ), ) context = self.rbt.create_external_context(name=f"test-{self.id()}") @@ -46,7 +49,9 @@ async def test_reboot_greeter(self) -> None: ) async def test_deprecated_greeter(self) -> None: - await self.rbt.up(legacy_grpc_servicers=[DeprecatedGreeterServicer]) + await self.rbt.up( + Application(legacy_grpc_servicers=[DeprecatedGreeterServicer]) + ) context = self.rbt.create_external_context(name=f"test-{self.id()}") @@ -66,10 +71,13 @@ async def test_deprecated_greeter(self) -> None: ) async def test_proxy_greeter(self) -> None: await self.rbt.up( - servicers=[RebootGreeterServicer], - legacy_grpc_servicers=[ - DeprecatedGreeterServicer, ProxyGreeterServicer - ], + Application( + servicers=[RebootGreeterServicer], + legacy_grpc_servicers=[ + DeprecatedGreeterServicer, + ProxyGreeterServicer, + ], + ), local_envoy=True, ) diff --git a/hello-tasks/backend/src/hello_servicer.py b/hello-tasks/backend/src/hello_servicer.py index 68b716e..3d8a02d 100644 --- a/hello-tasks/backend/src/hello_servicer.py +++ b/hello-tasks/backend/src/hello_servicer.py @@ -12,6 +12,7 @@ WarningRequest, WarningResponse, ) +from reboot.aio.auth.authorizers import allow from reboot.aio.contexts import ReaderContext, WriterContext SECS_UNTIL_WARNING = 7 @@ -20,6 +21,9 @@ class HelloServicer(Hello.Servicer): + def authorizer(self): + return allow() + async def Messages( self, context: ReaderContext, diff --git a/hello-tasks/backend/tests/hello_servicer_test.py b/hello-tasks/backend/tests/hello_servicer_test.py index 57d719e..8d467df 100644 --- a/hello-tasks/backend/tests/hello_servicer_test.py +++ b/hello-tasks/backend/tests/hello_servicer_test.py @@ -2,6 +2,7 @@ import unittest from hello_servicer import HelloServicer from hello_tasks.v1.hello_rbt import Hello +from reboot.aio.applications import Application from reboot.aio.tests import Reboot @@ -20,7 +21,7 @@ async def test_hello_tasks(self) -> None: hello_servicer.SECS_UNTIL_WARNING = 0 hello_servicer.ADDITIONAL_SECS_UNTIL_ERASE = 0 await self.rbt.up( - servicers=[HelloServicer], + Application(servicers=[HelloServicer]), # Normally, `rbt.up()` runs the servicers in a separate process, to # ensure that accidental use of blocking functions (an easy mistake # to make) doesn't cause the test to lock up. However, in this test diff --git a/pyproject.toml b/pyproject.toml index 285bd65..a769682 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] requires-python = ">= 3.10" dependencies = [ - "reboot==0.24.0", + "reboot==0.25.1", ] [tool.rye] @@ -9,7 +9,7 @@ dev-dependencies = [ "mypy==1.2.0", "pytest>=7.4.2", "types-protobuf>=4.24.0.20240129", - "reboot==0.24.0", + "reboot==0.25.1", ] # This project only uses `rye` to provide `python` and its dependencies, so diff --git a/requirements-dev.lock b/requirements-dev.lock index 62d7838..84a9d3b 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -16,6 +16,10 @@ aiohttp==3.10.5 # via reboot aiosignal==1.3.1 # via aiohttp +annotated-types==0.7.0 + # via pydantic +anyio==4.9.0 + # via starlette async-timeout==4.0.3 # via aiohttp attrs==24.2.0 @@ -25,6 +29,8 @@ certifi==2024.8.30 cffi==1.17.1 # via cryptography # via reboot +click==8.1.8 + # via uvicorn colorama==0.4.6 # via reboot cryptography==44.0.0 @@ -34,7 +40,10 @@ deprecated==1.2.15 # via opentelemetry-exporter-otlp-proto-grpc # via opentelemetry-semantic-conventions exceptiongroup==1.2.2 + # via anyio # via pytest +fastapi==0.115.12 + # via reboot frozenlist==1.4.1 # via aiohttp # via aiosignal @@ -60,7 +69,10 @@ grpcio-status==1.64.3 # via reboot grpcio-tools==1.64.3 # via reboot +h11==0.14.0 + # via uvicorn idna==3.10 + # via anyio # via yarl importlib-metadata==8.5.0 # via opentelemetry-api @@ -129,6 +141,10 @@ psutil==6.0.0 # via reboot pycparser==2.22 # via cffi +pydantic==2.9.2 + # via fastapi +pydantic-core==2.23.4 + # via pydantic pyjwt==2.8.0 # via reboot pyprctl==0.1.3 @@ -139,14 +155,18 @@ python-dateutil==2.9.0.post0 pyyaml==6.0.2 # via kubernetes-asyncio # via reboot -reboot==0.24.0 +reboot==0.25.1 setuptools==75.1.0 # via grpcio-tools six==1.16.0 # via kubernetes-asyncio # via python-dateutil +sniffio==1.3.1 + # via anyio sortedcontainers==2.4.0 # via reboot +starlette==0.46.2 + # via fastapi tabulate==0.9.0 # via reboot tomli==2.0.1 @@ -155,10 +175,15 @@ tomli==2.0.1 types-protobuf==5.28.0.20240924 # via mypy-protobuf typing-extensions==4.9.0 + # via anyio + # via fastapi # via multidict # via mypy # via opentelemetry-sdk + # via pydantic + # via pydantic-core # via reboot + # via uvicorn tzlocal==5.3 # via reboot urllib3==1.26.15 @@ -166,6 +191,8 @@ urllib3==1.26.15 # via reboot uuid7==0.1.0 # via reboot +uvicorn==0.34.0 + # via reboot watchdog==6.0.0 # via reboot websockets==13.1 diff --git a/requirements.lock b/requirements.lock index 57aade3..d87b2d1 100644 --- a/requirements.lock +++ b/requirements.lock @@ -16,6 +16,10 @@ aiohttp==3.10.5 # via reboot aiosignal==1.3.1 # via aiohttp +annotated-types==0.7.0 + # via pydantic +anyio==4.9.0 + # via starlette async-timeout==4.0.3 # via aiohttp attrs==24.2.0 @@ -25,6 +29,8 @@ certifi==2024.8.30 cffi==1.17.1 # via cryptography # via reboot +click==8.1.8 + # via uvicorn colorama==0.4.6 # via reboot cryptography==44.0.0 @@ -33,6 +39,10 @@ deprecated==1.2.15 # via opentelemetry-api # via opentelemetry-exporter-otlp-proto-grpc # via opentelemetry-semantic-conventions +exceptiongroup==1.2.2 + # via anyio +fastapi==0.115.12 + # via reboot frozenlist==1.4.1 # via aiohttp # via aiosignal @@ -58,7 +68,10 @@ grpcio-status==1.64.3 # via reboot grpcio-tools==1.64.3 # via reboot +h11==0.14.0 + # via uvicorn idna==3.10 + # via anyio # via yarl importlib-metadata==8.5.0 # via opentelemetry-api @@ -119,6 +132,10 @@ psutil==6.0.0 # via reboot pycparser==2.22 # via cffi +pydantic==2.9.2 + # via fastapi +pydantic-core==2.23.4 + # via pydantic pyjwt==2.8.0 # via reboot pyprctl==0.1.3 @@ -128,22 +145,31 @@ python-dateutil==2.9.0.post0 pyyaml==6.0.2 # via kubernetes-asyncio # via reboot -reboot==0.24.0 +reboot==0.25.1 setuptools==75.1.0 # via grpcio-tools six==1.16.0 # via kubernetes-asyncio # via python-dateutil +sniffio==1.3.1 + # via anyio sortedcontainers==2.4.0 # via reboot +starlette==0.46.2 + # via fastapi tabulate==0.9.0 # via reboot types-protobuf==5.28.0.20240924 # via mypy-protobuf typing-extensions==4.9.0 + # via anyio + # via fastapi # via multidict # via opentelemetry-sdk + # via pydantic + # via pydantic-core # via reboot + # via uvicorn tzlocal==5.3 # via reboot urllib3==1.26.15 @@ -151,6 +177,8 @@ urllib3==1.26.15 # via reboot uuid7==0.1.0 # via reboot +uvicorn==0.34.0 + # via reboot watchdog==6.0.0 # via reboot websockets==13.1