From 66e6e226ed410f00745b9c6b196d1b6078e93986 Mon Sep 17 00:00:00 2001 From: Tim Holm Date: Fri, 18 Nov 2022 12:35:31 +1100 Subject: [PATCH] build: Add local gRPC client generation. --- .github/workflows/test.yaml | 5 + .gitignore | 5 +- .pre-commit-config.yaml | 2 +- docs/nitric/api/documents.html | 2 +- docs/nitric/api/events.html | 2 +- docs/nitric/api/queues.html | 2 +- docs/nitric/api/secrets.html | 2 +- docs/nitric/api/storage.html | 2 +- docs/nitric/faas.html | 2 +- makefile | 17 + nitric/api/documents.py | 24 +- nitric/api/events.py | 13 +- nitric/api/queues.py | 27 +- nitric/api/secrets.py | 17 +- nitric/api/storage.py | 18 +- nitric/faas.py | 3 +- nitric/proto/__init__.py | 0 nitric/proto/nitric/document/__init__.py | 0 nitric/proto/nitric/document/v1/__init__.py | 363 ++++++ nitric/proto/nitric/error/__init__.py | 0 nitric/proto/nitric/error/v1/__init__.py | 37 + nitric/proto/nitric/event/__init__.py | 0 nitric/proto/nitric/event/v1/__init__.py | 167 +++ nitric/proto/nitric/faas/__init__.py | 0 nitric/proto/nitric/faas/v1/__init__.py | 312 +++++ nitric/proto/nitric/queue/__init__.py | 0 nitric/proto/nitric/queue/v1/__init__.py | 277 +++++ nitric/proto/nitric/resource/__init__.py | 0 nitric/proto/nitric/resource/v1/__init__.py | 257 ++++ nitric/proto/nitric/secret/__init__.py | 0 nitric/proto/nitric/secret/v1/__init__.py | 152 +++ nitric/proto/nitric/storage/__init__.py | 0 nitric/proto/nitric/storage/v1/__init__.py | 330 ++++++ nitric/proto/validate/__init__.py | 1170 +++++++++++++++++++ nitric/resources/apis.py | 2 +- nitric/resources/base.py | 2 +- nitric/resources/buckets.py | 8 +- nitric/resources/collections.py | 18 +- nitric/resources/queues.py | 8 +- nitric/resources/secrets.py | 15 +- nitric/resources/topics.py | 10 +- setup.py | 10 +- tests/api/test_documents.py | 59 +- tests/api/test_events.py | 37 +- tests/api/test_queues.py | 119 +- tests/api/test_secrets.py | 44 +- tests/api/test_storage.py | 18 +- tests/examples/test_documents_example.py | 30 +- tests/examples/test_events_example.py | 4 +- tests/examples/test_queues_example.py | 8 +- tests/examples/test_secrets_example.py | 10 +- tests/examples/test_storage_example.py | 6 +- tests/resources/test_buckets.py | 115 +- tests/resources/test_collections.py | 146 +-- tests/resources/test_queues.py | 86 +- tests/resources/test_secrets.py | 45 +- tests/resources/test_topics.py | 22 +- tests/test_faas.py | 26 +- tox.ini | 15 +- 59 files changed, 3606 insertions(+), 465 deletions(-) create mode 100644 nitric/proto/__init__.py create mode 100644 nitric/proto/nitric/document/__init__.py create mode 100644 nitric/proto/nitric/document/v1/__init__.py create mode 100644 nitric/proto/nitric/error/__init__.py create mode 100644 nitric/proto/nitric/error/v1/__init__.py create mode 100644 nitric/proto/nitric/event/__init__.py create mode 100644 nitric/proto/nitric/event/v1/__init__.py create mode 100644 nitric/proto/nitric/faas/__init__.py create mode 100644 nitric/proto/nitric/faas/v1/__init__.py create mode 100644 nitric/proto/nitric/queue/__init__.py create mode 100644 nitric/proto/nitric/queue/v1/__init__.py create mode 100644 nitric/proto/nitric/resource/__init__.py create mode 100644 nitric/proto/nitric/resource/v1/__init__.py create mode 100644 nitric/proto/nitric/secret/__init__.py create mode 100644 nitric/proto/nitric/secret/v1/__init__.py create mode 100644 nitric/proto/nitric/storage/__init__.py create mode 100644 nitric/proto/nitric/storage/v1/__init__.py create mode 100644 nitric/proto/validate/__init__.py diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6d8bcfb..21d9f97 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -24,6 +24,11 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install run: make install + - name: Check generated sources + run: | + make grpc-client + git add . + git diff --cached --quiet - name: Run Tox # Run tox using the version of Python in `PATH` run: tox -e py diff --git a/.gitignore b/.gitignore index 396799b..8a06b23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -# Protoc Output Files -nitric/proto/ - .idea/ # Byte-compiled / optimized / DLL files @@ -145,3 +142,5 @@ cython_debug/ .vscode/ + +contracts/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9ce07dc..79e03fe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: rev: stable hooks: - id: black - exclude: ^(examples)/ + exclude: ^(examples|nitric/proto)/ - repo: https://github.com/pycqa/flake8 rev: 3.7.9 hooks: diff --git a/docs/nitric/api/documents.html b/docs/nitric/api/documents.html index 671e10a..467ccf3 100644 --- a/docs/nitric/api/documents.html +++ b/docs/nitric/api/documents.html @@ -54,7 +54,7 @@

Module nitric.api.documents

from nitric.api.const import MAX_SUB_COLLECTION_DEPTH from nitric.api.exception import exception_from_grpc_error -from nitricapi.nitric.document.v1 import ( +from proto.nitric.document.v1 import ( DocumentServiceStub, Collection as CollectionMessage, Key as KeyMessage, diff --git a/docs/nitric/api/events.html b/docs/nitric/api/events.html index ea153c2..d14ac05 100644 --- a/docs/nitric/api/events.html +++ b/docs/nitric/api/events.html @@ -52,7 +52,7 @@

Module nitric.api.events

from nitric.api.exception import exception_from_grpc_error from nitric.utils import new_default_channel, _struct_from_dict -from nitricapi.nitric.event.v1 import EventServiceStub, NitricEvent, TopicServiceStub +from proto.nitric.event.v1 import EventServiceStub, NitricEvent, TopicServiceStub from dataclasses import dataclass, field diff --git a/docs/nitric/api/queues.html b/docs/nitric/api/queues.html index 5f0fd44..6bf18f4 100644 --- a/docs/nitric/api/queues.html +++ b/docs/nitric/api/queues.html @@ -52,7 +52,7 @@

Module nitric.api.queues

from nitric.api.exception import FailedPreconditionException, exception_from_grpc_error, InvalidArgumentException from nitric.utils import new_default_channel, _struct_from_dict, _dict_from_struct -from nitricapi.nitric.queue.v1 import QueueServiceStub, NitricTask, FailedTask as WireFailedTask +from proto.nitric.queue.v1 import QueueServiceStub, NitricTask, FailedTask as WireFailedTask from dataclasses import dataclass, field diff --git a/docs/nitric/api/secrets.html b/docs/nitric/api/secrets.html index 4efa7ac..fb0f5aa 100644 --- a/docs/nitric/api/secrets.html +++ b/docs/nitric/api/secrets.html @@ -52,7 +52,7 @@

Module nitric.api.secrets

from nitric.api.exception import exception_from_grpc_error from nitric.utils import new_default_channel -from nitricapi.nitric.secret.v1 import SecretServiceStub, Secret as SecretMessage, SecretVersion as VersionMessage +from proto.nitric.secret.v1 import SecretServiceStub, Secret as SecretMessage, SecretVersion as VersionMessage class Secrets(object): diff --git a/docs/nitric/api/storage.html b/docs/nitric/api/storage.html index 40ec8d1..8a0ec2d 100644 --- a/docs/nitric/api/storage.html +++ b/docs/nitric/api/storage.html @@ -50,7 +50,7 @@

Module nitric.api.storage

from nitric.api.exception import exception_from_grpc_error from nitric.utils import new_default_channel -from nitricapi.nitric.storage.v1 import StorageServiceStub +from proto.nitric.storage.v1 import StorageServiceStub class Storage(object): diff --git a/docs/nitric/faas.html b/docs/nitric/faas.html index 88b54c1..d236c18 100644 --- a/docs/nitric/faas.html +++ b/docs/nitric/faas.html @@ -36,7 +36,7 @@

Module nitric.faas

import betterproto from betterproto.grpc.util.async_channel import AsyncChannel from nitric.utils import new_default_channel -from nitricapi.nitric.faas.v1 import ( +from proto.nitric.faas.v1 import ( FaasServiceStub, InitRequest, ClientMessage, diff --git a/makefile b/makefile index 9165e6b..f99815d 100644 --- a/makefile +++ b/makefile @@ -16,6 +16,23 @@ clean: @rm -rf ./build @rm -rf ./dist +NITRIC_VERSION="v0.20.0-rc.2" + +download: + @curl -L https://github.com/nitrictech/nitric/releases/download/${NITRIC_VERSION}/contracts.tgz -o contracts.tgz + @tar xvzf contracts.tgz + @rm contracts.tgz + +OUTPUT="./nitric/proto" +CONTRACTS="./contracts" + +grpc-client: install download + @echo Generating Proto Sources + @echo $(OUTPUT) + @mkdir -p $(OUTPUT) + @python3 -m grpc_tools.protoc -I $(CONTRACTS) --python_betterproto_out=$(OUTPUT) ./contracts/proto/*/*/*.proto + + license: @echo Applying Apache 2 header to source files @licenseheaders -t tools/apache-2.tmpl -o "Nitric Technologies Pty Ltd" -y 2021 -n "Nitric Python 3 SDK" -u "https://github.com/nitrictech/python-sdk" -d nitric diff --git a/nitric/api/documents.py b/nitric/api/documents.py index eda0761..b20f04f 100644 --- a/nitric/api/documents.py +++ b/nitric/api/documents.py @@ -26,14 +26,18 @@ from nitric.api.const import MAX_SUB_COLLECTION_DEPTH from nitric.api.exception import exception_from_grpc_error -from nitricapi.nitric.document.v1 import ( +from nitric.proto.nitric.document.v1 import ( DocumentServiceStub, Collection as CollectionMessage, Key as KeyMessage, Expression as ExpressionMessage, ExpressionValue, - Document as DocumentMessage, DocumentSetRequest, DocumentGetRequest, DocumentDeleteRequest, - DocumentQueryStreamRequest, DocumentQueryRequest, + Document as DocumentMessage, + DocumentSetRequest, + DocumentGetRequest, + DocumentDeleteRequest, + DocumentQueryStreamRequest, + DocumentQueryRequest, ) from nitric.utils import new_default_channel, _dict_from_struct, _struct_from_dict @@ -75,9 +79,9 @@ def collection(self, name: str) -> CollectionRef: async def get(self) -> Document: """Retrieve the contents of this document, if it exists.""" try: - response = await self._documents._stub.get(document_get_request=DocumentGetRequest( - key=_doc_ref_to_wire(self) - )) + response = await self._documents._stub.get( + document_get_request=DocumentGetRequest(key=_doc_ref_to_wire(self)) + ) return _document_from_wire(documents=self._documents, message=response.document) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) @@ -101,9 +105,11 @@ async def set(self, content: dict): async def delete(self): """Delete this document, if it exists.""" try: - await self._documents._stub.delete(document_delete_request=DocumentDeleteRequest( - key=_doc_ref_to_wire(self), - )) + await self._documents._stub.delete( + document_delete_request=DocumentDeleteRequest( + key=_doc_ref_to_wire(self), + ) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) diff --git a/nitric/api/events.py b/nitric/api/events.py index 4bf2dd2..6993ca6 100644 --- a/nitric/api/events.py +++ b/nitric/api/events.py @@ -24,8 +24,13 @@ from nitric.api.exception import exception_from_grpc_error from nitric.utils import new_default_channel, _struct_from_dict -from nitricapi.nitric.event.v1 import EventServiceStub, NitricEvent, TopicServiceStub, EventPublishRequest, \ - TopicListRequest +from nitric.proto.nitric.event.v1 import ( + EventServiceStub, + NitricEvent, + TopicServiceStub, + EventPublishRequest, + TopicListRequest, +) from dataclasses import dataclass, field @@ -71,9 +76,7 @@ async def publish( try: response = await self._events._stub.publish( - event_publish_request=EventPublishRequest( - topic=self.name, event=_event_to_wire(event) - ) + event_publish_request=EventPublishRequest(topic=self.name, event=_event_to_wire(event)) ) return Event(**{**event.__dict__.copy(), **{"id": response.id}}) except GRPCError as grpc_err: diff --git a/nitric/api/queues.py b/nitric/api/queues.py index 3d83078..9ac808c 100644 --- a/nitric/api/queues.py +++ b/nitric/api/queues.py @@ -24,8 +24,15 @@ from nitric.api.exception import FailedPreconditionException, exception_from_grpc_error, InvalidArgumentException from nitric.utils import new_default_channel, _struct_from_dict, _dict_from_struct -from nitricapi.nitric.queue.v1 import QueueServiceStub, NitricTask, FailedTask as WireFailedTask, QueueCompleteRequest, \ - QueueSendRequest, QueueSendBatchRequest, QueueReceiveRequest +from nitric.proto.nitric.queue.v1 import ( + QueueServiceStub, + NitricTask, + FailedTask as WireFailedTask, + QueueCompleteRequest, + QueueSendRequest, + QueueSendBatchRequest, + QueueReceiveRequest, +) from dataclasses import dataclass, field @@ -60,7 +67,9 @@ async def complete(self): "Task is missing internal client or lease id, was it returned from " "queue.receive?" ) try: - await self._queueing._queue_stub.complete(queue_complete_request=QueueCompleteRequest(queue=self._queue.name, lease_id=self.lease_id)) + await self._queueing._queue_stub.complete( + queue_complete_request=QueueCompleteRequest(queue=self._queue.name, lease_id=self.lease_id) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) @@ -150,7 +159,9 @@ async def send( task = Task(**task) try: - await self._queueing._queue_stub.send(queue_send_request=QueueSendRequest(queue=self.name, task=_task_to_wire(task))) + await self._queueing._queue_stub.send( + queue_send_request=QueueSendRequest(queue=self.name, task=_task_to_wire(task)) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) @@ -168,7 +179,9 @@ async def _send_batch(self, tasks: List[Union[Task, dict]], raise_on_failure: bo wire_tasks = [_task_to_wire(Task(**task) if isinstance(task, dict) else task) for task in tasks] try: - response = await self._queueing._queue_stub.send_batch(queue_send_batch_request=QueueSendBatchRequest(queue=self.name, tasks=wire_tasks)) + response = await self._queueing._queue_stub.send_batch( + queue_send_batch_request=QueueSendBatchRequest(queue=self.name, tasks=wire_tasks) + ) return [_wire_to_failed_task(failed_task) for failed_task in response.failed_tasks] except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) @@ -191,7 +204,9 @@ async def receive(self, limit: int = None) -> List[Task]: limit = 1 try: - response = await self._queueing._queue_stub.receive(queue_receive_request=QueueReceiveRequest(queue=self.name, depth=limit)) + response = await self._queueing._queue_stub.receive( + queue_receive_request=QueueReceiveRequest(queue=self.name, depth=limit) + ) # Map the response protobuf response items to Python SDK Nitric Tasks return [_wire_to_received_task(task=task, queueing=self._queueing, queue=self) for task in response.tasks] except GRPCError as grpc_err: diff --git a/nitric/api/secrets.py b/nitric/api/secrets.py index 77f93cb..7c9a85c 100644 --- a/nitric/api/secrets.py +++ b/nitric/api/secrets.py @@ -24,8 +24,13 @@ from nitric.api.exception import exception_from_grpc_error from nitric.utils import new_default_channel -from nitricapi.nitric.secret.v1 import SecretServiceStub, Secret as SecretMessage, SecretVersion as VersionMessage, \ - SecretPutRequest, SecretAccessRequest +from nitric.proto.nitric.secret.v1 import ( + SecretServiceStub, + Secret as SecretMessage, + SecretVersion as VersionMessage, + SecretPutRequest, + SecretAccessRequest, +) class Secrets(object): @@ -73,7 +78,9 @@ async def put(self, value: Union[str, bytes]) -> SecretVersion: secret_message = _secret_to_wire(self) try: - response = await self._secrets._secrets_stub.put(secret_put_request=SecretPutRequest(secret=secret_message, value=value)) + response = await self._secrets._secrets_stub.put( + secret_put_request=SecretPutRequest(secret=secret_message, value=value) + ) return self.version(version=response.secret_version.version) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) @@ -112,7 +119,9 @@ async def access(self) -> SecretValue: """Return the value stored against this version of the secret.""" version_message = _secret_version_to_wire(self) try: - response = await self._secrets._secrets_stub.access(secret_access_request=SecretAccessRequest(secret_version=version_message)) + response = await self._secrets._secrets_stub.access( + secret_access_request=SecretAccessRequest(secret_version=version_message) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) diff --git a/nitric/api/storage.py b/nitric/api/storage.py index e6a44f2..7f08d14 100644 --- a/nitric/api/storage.py +++ b/nitric/api/storage.py @@ -17,13 +17,19 @@ # limitations under the License. # from dataclasses import dataclass -from typing import List from grpclib import GRPCError from nitric.api.exception import exception_from_grpc_error, InvalidArgumentException from nitric.utils import new_default_channel -from nitricapi.nitric.storage.v1 import StorageServiceStub, StoragePreSignUrlRequestOperation, StorageWriteRequest, \ - StorageReadRequest, StorageDeleteRequest, StoragePreSignUrlRequest, StorageListFilesRequest +from nitric.proto.nitric.storage.v1 import ( + StorageServiceStub, + StoragePreSignUrlRequestOperation, + StorageWriteRequest, + StorageReadRequest, + StorageDeleteRequest, + StoragePreSignUrlRequest, + StorageListFilesRequest, +) from enum import Enum @@ -61,8 +67,10 @@ def file(self, key: str): return File(_storage=self._storage, _bucket=self.name, key=key) async def files(self): + """Return a list of files in this bucket.""" resp = await self._storage._storage_stub.list_files( - storage_list_files_request=StorageListFilesRequest(bucket_name=self.name)) + storage_list_files_request=StorageListFilesRequest(bucket_name=self.name) + ) return [self.file(f.key) for f in resp.files] @@ -123,9 +131,11 @@ async def delete(self): raise exception_from_grpc_error(grpc_err) async def upload_url(self, expiry: int = 600): + """Get a temporary writable URL to this file.""" await self.sign_url(mode=FileMode.WRITE, expiry=expiry) async def download_url(self, expiry: int = 600): + """Get a temporary readable URL to this file.""" await self.sign_url(mode=FileMode.READ, expiry=expiry) async def sign_url(self, mode: FileMode = FileMode.READ, expiry: int = 3600): diff --git a/nitric/faas.py b/nitric/faas.py index f40c40e..6d1c34b 100644 --- a/nitric/faas.py +++ b/nitric/faas.py @@ -27,7 +27,7 @@ import betterproto from betterproto.grpc.util.async_channel import AsyncChannel from nitric.utils import new_default_channel -from nitricapi.nitric.faas.v1 import ( +from nitric.proto.nitric.faas.v1 import ( FaasServiceStub, InitRequest, ClientMessage, @@ -398,6 +398,7 @@ def __init__(self, security: dict[str, List[str]] = None): class FaasWorkerOptions: """Empty worker options for generic function handlers.""" + pass diff --git a/nitric/proto/__init__.py b/nitric/proto/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/document/__init__.py b/nitric/proto/nitric/document/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/document/v1/__init__.py b/nitric/proto/nitric/document/v1/__init__.py new file mode 100644 index 0000000..0321bc6 --- /dev/null +++ b/nitric/proto/nitric/document/v1/__init__.py @@ -0,0 +1,363 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: proto/document/v1/document.proto +# plugin: python-betterproto +from dataclasses import dataclass +from typing import ( + TYPE_CHECKING, + AsyncIterator, + Dict, + List, + Optional, +) + +import betterproto +import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf +import grpclib +from betterproto.grpc.grpclib_server import ServiceBase + + +if TYPE_CHECKING: + import grpclib.server + from betterproto.grpc.grpclib_client import MetadataLike + from grpclib.metadata import Deadline + + +@dataclass(eq=False, repr=False) +class Collection(betterproto.Message): + """Provides a Collection type for storing documents""" + + name: str = betterproto.string_field(1) + """The collection name""" + + parent: "Key" = betterproto.message_field(2) + """ + Optional parent key, required when the collection is a sub-collection of + another document + """ + + +@dataclass(eq=False, repr=False) +class Key(betterproto.Message): + """Provides a document identifying key type""" + + collection: "Collection" = betterproto.message_field(1) + """The item collection""" + + id: str = betterproto.string_field(2) + """The items unique id""" + + +@dataclass(eq=False, repr=False) +class Document(betterproto.Message): + """Provides a return document type""" + + content: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(1) + """The document content (JSON object)""" + + key: "Key" = betterproto.message_field(2) + """The document's unique key, including collection/sub-collections""" + + +@dataclass(eq=False, repr=False) +class ExpressionValue(betterproto.Message): + int_value: int = betterproto.int64_field(1, group="kind") + """Represents an integer value.""" + + double_value: float = betterproto.double_field(2, group="kind") + """Represents a double value.""" + + string_value: str = betterproto.string_field(3, group="kind") + """Represents a string value.""" + + bool_value: bool = betterproto.bool_field(4, group="kind") + """Represents a boolean value.""" + + +@dataclass(eq=False, repr=False) +class Expression(betterproto.Message): + """Provides a query expression type""" + + operand: str = betterproto.string_field(1) + """The query operand or attribute""" + + operator: str = betterproto.string_field(2) + """The query operator [ == | < | <= | > | >= | startsWith ]""" + + value: "ExpressionValue" = betterproto.message_field(3) + """The query expression value""" + + +@dataclass(eq=False, repr=False) +class DocumentGetRequest(betterproto.Message): + key: "Key" = betterproto.message_field(1) + """Key of the document to retrieve""" + + +@dataclass(eq=False, repr=False) +class DocumentGetResponse(betterproto.Message): + document: "Document" = betterproto.message_field(1) + """The retrieved value""" + + +@dataclass(eq=False, repr=False) +class DocumentSetRequest(betterproto.Message): + key: "Key" = betterproto.message_field(1) + """Key of the document to set""" + + content: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(3) + """The document content to store (JSON object)""" + + +@dataclass(eq=False, repr=False) +class DocumentSetResponse(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class DocumentDeleteRequest(betterproto.Message): + key: "Key" = betterproto.message_field(1) + """Key of the document to delete""" + + +@dataclass(eq=False, repr=False) +class DocumentDeleteResponse(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class DocumentQueryRequest(betterproto.Message): + collection: "Collection" = betterproto.message_field(1) + """The collection to query""" + + expressions: List["Expression"] = betterproto.message_field(3) + """Optional query expressions""" + + limit: int = betterproto.int32_field(4) + """Optional query fetch limit""" + + paging_token: Dict[str, str] = betterproto.map_field( + 5, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + """Optional query paging continuation token""" + + +@dataclass(eq=False, repr=False) +class DocumentQueryResponse(betterproto.Message): + documents: List["Document"] = betterproto.message_field(1) + """The retrieved values""" + + paging_token: Dict[str, str] = betterproto.map_field( + 2, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + """ + The query paging continuation token, when empty no further results are + available + """ + + +@dataclass(eq=False, repr=False) +class DocumentQueryStreamRequest(betterproto.Message): + collection: "Collection" = betterproto.message_field(1) + """The collection to query""" + + expressions: List["Expression"] = betterproto.message_field(3) + """Optional query expressions""" + + limit: int = betterproto.int32_field(4) + """Optional query fetch limit""" + + +@dataclass(eq=False, repr=False) +class DocumentQueryStreamResponse(betterproto.Message): + document: "Document" = betterproto.message_field(1) + """The stream document""" + + +class DocumentServiceStub(betterproto.ServiceStub): + async def get( + self, + document_get_request: "DocumentGetRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "DocumentGetResponse": + return await self._unary_unary( + "/nitric.document.v1.DocumentService/Get", + document_get_request, + DocumentGetResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def set( + self, + document_set_request: "DocumentSetRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "DocumentSetResponse": + return await self._unary_unary( + "/nitric.document.v1.DocumentService/Set", + document_set_request, + DocumentSetResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def delete( + self, + document_delete_request: "DocumentDeleteRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "DocumentDeleteResponse": + return await self._unary_unary( + "/nitric.document.v1.DocumentService/Delete", + document_delete_request, + DocumentDeleteResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def query( + self, + document_query_request: "DocumentQueryRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "DocumentQueryResponse": + return await self._unary_unary( + "/nitric.document.v1.DocumentService/Query", + document_query_request, + DocumentQueryResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def query_stream( + self, + document_query_stream_request: "DocumentQueryStreamRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> AsyncIterator["DocumentQueryStreamResponse"]: + async for response in self._unary_stream( + "/nitric.document.v1.DocumentService/QueryStream", + document_query_stream_request, + DocumentQueryStreamResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ): + yield response + + +class DocumentServiceBase(ServiceBase): + async def get( + self, document_get_request: "DocumentGetRequest" + ) -> "DocumentGetResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def set( + self, document_set_request: "DocumentSetRequest" + ) -> "DocumentSetResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def delete( + self, document_delete_request: "DocumentDeleteRequest" + ) -> "DocumentDeleteResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def query( + self, document_query_request: "DocumentQueryRequest" + ) -> "DocumentQueryResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def query_stream( + self, document_query_stream_request: "DocumentQueryStreamRequest" + ) -> AsyncIterator["DocumentQueryStreamResponse"]: + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def __rpc_get( + self, stream: "grpclib.server.Stream[DocumentGetRequest, DocumentGetResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.get(request) + await stream.send_message(response) + + async def __rpc_set( + self, stream: "grpclib.server.Stream[DocumentSetRequest, DocumentSetResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.set(request) + await stream.send_message(response) + + async def __rpc_delete( + self, + stream: "grpclib.server.Stream[DocumentDeleteRequest, DocumentDeleteResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.delete(request) + await stream.send_message(response) + + async def __rpc_query( + self, + stream: "grpclib.server.Stream[DocumentQueryRequest, DocumentQueryResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.query(request) + await stream.send_message(response) + + async def __rpc_query_stream( + self, + stream: "grpclib.server.Stream[DocumentQueryStreamRequest, DocumentQueryStreamResponse]", + ) -> None: + request = await stream.recv_message() + await self._call_rpc_handler_server_stream( + self.query_stream, + stream, + request, + ) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/nitric.document.v1.DocumentService/Get": grpclib.const.Handler( + self.__rpc_get, + grpclib.const.Cardinality.UNARY_UNARY, + DocumentGetRequest, + DocumentGetResponse, + ), + "/nitric.document.v1.DocumentService/Set": grpclib.const.Handler( + self.__rpc_set, + grpclib.const.Cardinality.UNARY_UNARY, + DocumentSetRequest, + DocumentSetResponse, + ), + "/nitric.document.v1.DocumentService/Delete": grpclib.const.Handler( + self.__rpc_delete, + grpclib.const.Cardinality.UNARY_UNARY, + DocumentDeleteRequest, + DocumentDeleteResponse, + ), + "/nitric.document.v1.DocumentService/Query": grpclib.const.Handler( + self.__rpc_query, + grpclib.const.Cardinality.UNARY_UNARY, + DocumentQueryRequest, + DocumentQueryResponse, + ), + "/nitric.document.v1.DocumentService/QueryStream": grpclib.const.Handler( + self.__rpc_query_stream, + grpclib.const.Cardinality.UNARY_STREAM, + DocumentQueryStreamRequest, + DocumentQueryStreamResponse, + ), + } diff --git a/nitric/proto/nitric/error/__init__.py b/nitric/proto/nitric/error/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/error/v1/__init__.py b/nitric/proto/nitric/error/v1/__init__.py new file mode 100644 index 0000000..09e6ec8 --- /dev/null +++ b/nitric/proto/nitric/error/v1/__init__.py @@ -0,0 +1,37 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: proto/error/v1/error.proto +# plugin: python-betterproto +from dataclasses import dataclass +from typing import Dict + +import betterproto + + +@dataclass(eq=False, repr=False) +class ErrorScope(betterproto.Message): + service: str = betterproto.string_field(1) + """The API service invoked, e.g. 'Service.Method'.""" + + plugin: str = betterproto.string_field(2) + """The plugin method invoked, e.g. 'PluginService.Method'.""" + + args: Dict[str, str] = betterproto.map_field( + 3, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + """ + The plugin method arguments, ensure only non-sensitive data is specified. + """ + + +@dataclass(eq=False, repr=False) +class ErrorDetails(betterproto.Message): + message: str = betterproto.string_field(1) + """ + The developer error message, explaining the error and ideally solution. + """ + + cause: str = betterproto.string_field(2) + """The error root cause.""" + + scope: "ErrorScope" = betterproto.message_field(3) + """The scope of the error.""" diff --git a/nitric/proto/nitric/event/__init__.py b/nitric/proto/nitric/event/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/event/v1/__init__.py b/nitric/proto/nitric/event/v1/__init__.py new file mode 100644 index 0000000..cd16894 --- /dev/null +++ b/nitric/proto/nitric/event/v1/__init__.py @@ -0,0 +1,167 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: proto/event/v1/event.proto +# plugin: python-betterproto +from dataclasses import dataclass +from typing import ( + TYPE_CHECKING, + Dict, + List, + Optional, +) + +import betterproto +import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf +import grpclib +from betterproto.grpc.grpclib_server import ServiceBase + + +if TYPE_CHECKING: + import grpclib.server + from betterproto.grpc.grpclib_client import MetadataLike + from grpclib.metadata import Deadline + + +@dataclass(eq=False, repr=False) +class EventPublishRequest(betterproto.Message): + """Request to publish an event to a topic""" + + topic: str = betterproto.string_field(1) + """The name of the topic to publish the event to""" + + event: "NitricEvent" = betterproto.message_field(2) + """The event to be published""" + + delay: int = betterproto.uint32_field(3) + """An optional delay specified in seconds (minimum 10 seconds)""" + + +@dataclass(eq=False, repr=False) +class EventPublishResponse(betterproto.Message): + """Result of publishing an event""" + + id: str = betterproto.string_field(1) + """ + The id of the published message When an id was not supplied one should be + automatically generated + """ + + +@dataclass(eq=False, repr=False) +class TopicListRequest(betterproto.Message): + """Request for the Topic List method""" + + pass + + +@dataclass(eq=False, repr=False) +class TopicListResponse(betterproto.Message): + """Topic List Response""" + + topics: List["NitricTopic"] = betterproto.message_field(1) + """The list of found topics""" + + +@dataclass(eq=False, repr=False) +class NitricTopic(betterproto.Message): + """Represents an event topic""" + + name: str = betterproto.string_field(1) + """The Nitric name for the topic""" + + +@dataclass(eq=False, repr=False) +class NitricEvent(betterproto.Message): + """Nitric Event Model""" + + id: str = betterproto.string_field(1) + """A Unique ID for the Nitric Event""" + + payload_type: str = betterproto.string_field(2) + """A content hint for the events payload""" + + payload: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(3) + """The payload of the event""" + + +class EventServiceStub(betterproto.ServiceStub): + async def publish( + self, + event_publish_request: "EventPublishRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "EventPublishResponse": + return await self._unary_unary( + "/nitric.event.v1.EventService/Publish", + event_publish_request, + EventPublishResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + +class TopicServiceStub(betterproto.ServiceStub): + async def list( + self, + topic_list_request: "TopicListRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "TopicListResponse": + return await self._unary_unary( + "/nitric.event.v1.TopicService/List", + topic_list_request, + TopicListResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + +class EventServiceBase(ServiceBase): + async def publish( + self, event_publish_request: "EventPublishRequest" + ) -> "EventPublishResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def __rpc_publish( + self, stream: "grpclib.server.Stream[EventPublishRequest, EventPublishResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.publish(request) + await stream.send_message(response) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/nitric.event.v1.EventService/Publish": grpclib.const.Handler( + self.__rpc_publish, + grpclib.const.Cardinality.UNARY_UNARY, + EventPublishRequest, + EventPublishResponse, + ), + } + + +class TopicServiceBase(ServiceBase): + async def list(self, topic_list_request: "TopicListRequest") -> "TopicListResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def __rpc_list( + self, stream: "grpclib.server.Stream[TopicListRequest, TopicListResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.list(request) + await stream.send_message(response) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/nitric.event.v1.TopicService/List": grpclib.const.Handler( + self.__rpc_list, + grpclib.const.Cardinality.UNARY_UNARY, + TopicListRequest, + TopicListResponse, + ), + } diff --git a/nitric/proto/nitric/faas/__init__.py b/nitric/proto/nitric/faas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/faas/v1/__init__.py b/nitric/proto/nitric/faas/v1/__init__.py new file mode 100644 index 0000000..fe43648 --- /dev/null +++ b/nitric/proto/nitric/faas/v1/__init__.py @@ -0,0 +1,312 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: proto/faas/v1/faas.proto +# plugin: python-betterproto +import warnings +from dataclasses import dataclass +from typing import ( + TYPE_CHECKING, + AsyncIterable, + AsyncIterator, + Dict, + Iterable, + List, + Optional, + Union, +) + +import betterproto +import grpclib +from betterproto.grpc.grpclib_server import ServiceBase + + +if TYPE_CHECKING: + import grpclib.server + from betterproto.grpc.grpclib_client import MetadataLike + from grpclib.metadata import Deadline + + +@dataclass(eq=False, repr=False) +class ClientMessage(betterproto.Message): + """Messages the client is able to send to the server""" + + id: str = betterproto.string_field(1) + """Client message ID, used to pair requests/responses""" + + init_request: "InitRequest" = betterproto.message_field(2, group="content") + """ + Client initialisation request A worker will not be eligible for triggers + until it has identified itself + """ + + trigger_response: "TriggerResponse" = betterproto.message_field(3, group="content") + """Client responsding with result of a trigger""" + + +@dataclass(eq=False, repr=False) +class ServerMessage(betterproto.Message): + """Messages the server is able to send to the client""" + + id: str = betterproto.string_field(1) + """Server message ID, used to pair requests/responses""" + + init_response: "InitResponse" = betterproto.message_field(2, group="content") + """ + Server responding with client configuration details to an InitRequest + """ + + trigger_request: "TriggerRequest" = betterproto.message_field(3, group="content") + """Server requesting client to process a trigger""" + + +@dataclass(eq=False, repr=False) +class ApiWorkerScopes(betterproto.Message): + scopes: List[str] = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class ApiWorkerOptions(betterproto.Message): + security: Dict[str, "ApiWorkerScopes"] = betterproto.map_field( + 1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE + ) + """Apply security definitions to this operation""" + + security_disabled: bool = betterproto.bool_field(2) + """ + explicitly disable security for this endpoint We need to do this as the + default value of a repeated field is always empty so there is no way of + knowing if security is explicitly disabled + """ + + +@dataclass(eq=False, repr=False) +class ApiWorker(betterproto.Message): + api: str = betterproto.string_field(1) + path: str = betterproto.string_field(2) + methods: List[str] = betterproto.string_field(3) + options: "ApiWorkerOptions" = betterproto.message_field(4) + + +@dataclass(eq=False, repr=False) +class SubscriptionWorker(betterproto.Message): + topic: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class ScheduleWorker(betterproto.Message): + key: str = betterproto.string_field(1) + rate: "ScheduleRate" = betterproto.message_field(10, group="cadence") + cron: "ScheduleCron" = betterproto.message_field(11, group="cadence") + + +@dataclass(eq=False, repr=False) +class ScheduleRate(betterproto.Message): + rate: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class ScheduleCron(betterproto.Message): + cron: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class InitRequest(betterproto.Message): + """ + InitRequest - Identifies a worker as ready to recieve triggers This message + will contain information on the type of triggers that a worker is capable + of handling + """ + + api: "ApiWorker" = betterproto.message_field(10, group="Worker") + subscription: "SubscriptionWorker" = betterproto.message_field(11, group="Worker") + schedule: "ScheduleWorker" = betterproto.message_field(12, group="Worker") + + +@dataclass(eq=False, repr=False) +class InitResponse(betterproto.Message): + """Placeholder message""" + + pass + + +@dataclass(eq=False, repr=False) +class TriggerRequest(betterproto.Message): + """The server has a trigger for the client to handle""" + + data: bytes = betterproto.bytes_field(1) + """The data in the trigger""" + + mime_type: str = betterproto.string_field(2) + """Should we supply a mime type for the data? Or rely on context?""" + + http: "HttpTriggerContext" = betterproto.message_field(3, group="context") + topic: "TopicTriggerContext" = betterproto.message_field(4, group="context") + + +@dataclass(eq=False, repr=False) +class HeaderValue(betterproto.Message): + value: List[str] = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class QueryValue(betterproto.Message): + value: List[str] = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class HttpTriggerContext(betterproto.Message): + method: str = betterproto.string_field(1) + """The request method""" + + path: str = betterproto.string_field(2) + """The path of the request""" + + headers_old: Dict[str, str] = betterproto.map_field( + 3, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + """ + The old request headers (preserving for backwards compatibility) TODO: + Remove in 1.0 + """ + + query_params_old: Dict[str, str] = betterproto.map_field( + 4, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + """ + The old query params (preserving for backwards compatibility) TODO: Remove + in 1.0 + """ + + headers: Dict[str, "HeaderValue"] = betterproto.map_field( + 5, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE + ) + """HTTP request headers""" + + query_params: Dict[str, "QueryValue"] = betterproto.map_field( + 6, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE + ) + """HTTP Query params""" + + path_params: Dict[str, str] = betterproto.map_field( + 7, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + """HTTP Path parameters""" + + def __post_init__(self) -> None: + super().__post_init__() + if self.is_set("headers_old"): + warnings.warn( + "HttpTriggerContext.headers_old is deprecated", DeprecationWarning + ) + if self.is_set("query_params_old"): + warnings.warn( + "HttpTriggerContext.query_params_old is deprecated", DeprecationWarning + ) + + +@dataclass(eq=False, repr=False) +class TopicTriggerContext(betterproto.Message): + topic: str = betterproto.string_field(1) + """The topic the message was published for""" + + +@dataclass(eq=False, repr=False) +class TriggerResponse(betterproto.Message): + """The worker has successfully processed a trigger""" + + data: bytes = betterproto.bytes_field(1) + """The data returned in the response""" + + http: "HttpResponseContext" = betterproto.message_field(10, group="context") + """response to a http request""" + + topic: "TopicResponseContext" = betterproto.message_field(11, group="context") + """response to a topic trigger""" + + +@dataclass(eq=False, repr=False) +class HttpResponseContext(betterproto.Message): + """ + Specific HttpResponse message Note this does not have to be handled by the + User at all but they will have the option of control If they choose... + """ + + headers_old: Dict[str, str] = betterproto.map_field( + 1, betterproto.TYPE_STRING, betterproto.TYPE_STRING + ) + """Old HTTP response headers (deprecated) TODO: Remove in 1.0""" + + status: int = betterproto.int32_field(2) + """The HTTP status of the request""" + + headers: Dict[str, "HeaderValue"] = betterproto.map_field( + 3, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE + ) + """HTTP response headers""" + + def __post_init__(self) -> None: + super().__post_init__() + if self.is_set("headers_old"): + warnings.warn( + "HttpResponseContext.headers_old is deprecated", DeprecationWarning + ) + + +@dataclass(eq=False, repr=False) +class TopicResponseContext(betterproto.Message): + """ + Specific event response message We do not accept responses for events only + whether or not they were successfully processed + """ + + success: bool = betterproto.bool_field(1) + """Success status of the handled event""" + + +class FaasServiceStub(betterproto.ServiceStub): + async def trigger_stream( + self, + client_message_iterator: Union[ + AsyncIterable["ClientMessage"], Iterable["ClientMessage"] + ], + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> AsyncIterator["ServerMessage"]: + async for response in self._stream_stream( + "/nitric.faas.v1.FaasService/TriggerStream", + client_message_iterator, + ClientMessage, + ServerMessage, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ): + yield response + + +class FaasServiceBase(ServiceBase): + async def trigger_stream( + self, client_message_iterator: AsyncIterator["ClientMessage"] + ) -> AsyncIterator["ServerMessage"]: + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def __rpc_trigger_stream( + self, stream: "grpclib.server.Stream[ClientMessage, ServerMessage]" + ) -> None: + request = stream.__aiter__() + await self._call_rpc_handler_server_stream( + self.trigger_stream, + stream, + request, + ) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/nitric.faas.v1.FaasService/TriggerStream": grpclib.const.Handler( + self.__rpc_trigger_stream, + grpclib.const.Cardinality.STREAM_STREAM, + ClientMessage, + ServerMessage, + ), + } diff --git a/nitric/proto/nitric/queue/__init__.py b/nitric/proto/nitric/queue/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/queue/v1/__init__.py b/nitric/proto/nitric/queue/v1/__init__.py new file mode 100644 index 0000000..3ceb3e3 --- /dev/null +++ b/nitric/proto/nitric/queue/v1/__init__.py @@ -0,0 +1,277 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: proto/queue/v1/queue.proto +# plugin: python-betterproto +from dataclasses import dataclass +from typing import ( + TYPE_CHECKING, + Dict, + List, + Optional, +) + +import betterproto +import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf +import grpclib +from betterproto.grpc.grpclib_server import ServiceBase + + +if TYPE_CHECKING: + import grpclib.server + from betterproto.grpc.grpclib_client import MetadataLike + from grpclib.metadata import Deadline + + +@dataclass(eq=False, repr=False) +class QueueSendRequest(betterproto.Message): + """Request to push a single event to a queue""" + + queue: str = betterproto.string_field(1) + """ + The Nitric name for the queue this will automatically be resolved to the + provider specific queue identifier. + """ + + task: "NitricTask" = betterproto.message_field(2) + """The task to push to the queue""" + + +@dataclass(eq=False, repr=False) +class QueueSendResponse(betterproto.Message): + """Result of pushing a single task to a queue""" + + pass + + +@dataclass(eq=False, repr=False) +class QueueSendBatchRequest(betterproto.Message): + queue: str = betterproto.string_field(1) + """ + The Nitric name for the queue this will automatically be resolved to the + provider specific queue identifier. + """ + + tasks: List["NitricTask"] = betterproto.message_field(2) + """Array of tasks to push to the queue""" + + +@dataclass(eq=False, repr=False) +class QueueSendBatchResponse(betterproto.Message): + """Response for sending a collection of tasks""" + + failed_tasks: List["FailedTask"] = betterproto.message_field(1) + """A list of tasks that failed to be queued""" + + +@dataclass(eq=False, repr=False) +class QueueReceiveRequest(betterproto.Message): + queue: str = betterproto.string_field(1) + """ + The nitric name for the queue this will automatically be resolved to the + provider specific queue identifier. + """ + + depth: int = betterproto.int32_field(2) + """ + The max number of items to pop off the queue, may be capped by provider + specific limitations + """ + + +@dataclass(eq=False, repr=False) +class QueueReceiveResponse(betterproto.Message): + tasks: List["NitricTask"] = betterproto.message_field(1) + """Array of tasks popped off the queue""" + + +@dataclass(eq=False, repr=False) +class QueueCompleteRequest(betterproto.Message): + queue: str = betterproto.string_field(1) + """ + The nitric name for the queue this will automatically be resolved to the + provider specific queue identifier. + """ + + lease_id: str = betterproto.string_field(2) + """Lease id of the task to be completed""" + + +@dataclass(eq=False, repr=False) +class QueueCompleteResponse(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class FailedTask(betterproto.Message): + task: "NitricTask" = betterproto.message_field(1) + """The task that failed to be pushed""" + + message: str = betterproto.string_field(2) + """A message describing the failure""" + + +@dataclass(eq=False, repr=False) +class NitricTask(betterproto.Message): + """A task to be sent or received from a queue.""" + + id: str = betterproto.string_field(1) + """A unique id for the task""" + + lease_id: str = betterproto.string_field(2) + """ + The lease id unique to the pop request, this must be used to complete, + extend the lease or release the task. + """ + + payload_type: str = betterproto.string_field(3) + """A content hint for the tasks payload""" + + payload: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(4) + """The payload of the task""" + + +class QueueServiceStub(betterproto.ServiceStub): + async def send( + self, + queue_send_request: "QueueSendRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "QueueSendResponse": + return await self._unary_unary( + "/nitric.queue.v1.QueueService/Send", + queue_send_request, + QueueSendResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def send_batch( + self, + queue_send_batch_request: "QueueSendBatchRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "QueueSendBatchResponse": + return await self._unary_unary( + "/nitric.queue.v1.QueueService/SendBatch", + queue_send_batch_request, + QueueSendBatchResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def receive( + self, + queue_receive_request: "QueueReceiveRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "QueueReceiveResponse": + return await self._unary_unary( + "/nitric.queue.v1.QueueService/Receive", + queue_receive_request, + QueueReceiveResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def complete( + self, + queue_complete_request: "QueueCompleteRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "QueueCompleteResponse": + return await self._unary_unary( + "/nitric.queue.v1.QueueService/Complete", + queue_complete_request, + QueueCompleteResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + +class QueueServiceBase(ServiceBase): + async def send(self, queue_send_request: "QueueSendRequest") -> "QueueSendResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def send_batch( + self, queue_send_batch_request: "QueueSendBatchRequest" + ) -> "QueueSendBatchResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def receive( + self, queue_receive_request: "QueueReceiveRequest" + ) -> "QueueReceiveResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def complete( + self, queue_complete_request: "QueueCompleteRequest" + ) -> "QueueCompleteResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def __rpc_send( + self, stream: "grpclib.server.Stream[QueueSendRequest, QueueSendResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.send(request) + await stream.send_message(response) + + async def __rpc_send_batch( + self, + stream: "grpclib.server.Stream[QueueSendBatchRequest, QueueSendBatchResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.send_batch(request) + await stream.send_message(response) + + async def __rpc_receive( + self, stream: "grpclib.server.Stream[QueueReceiveRequest, QueueReceiveResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.receive(request) + await stream.send_message(response) + + async def __rpc_complete( + self, + stream: "grpclib.server.Stream[QueueCompleteRequest, QueueCompleteResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.complete(request) + await stream.send_message(response) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/nitric.queue.v1.QueueService/Send": grpclib.const.Handler( + self.__rpc_send, + grpclib.const.Cardinality.UNARY_UNARY, + QueueSendRequest, + QueueSendResponse, + ), + "/nitric.queue.v1.QueueService/SendBatch": grpclib.const.Handler( + self.__rpc_send_batch, + grpclib.const.Cardinality.UNARY_UNARY, + QueueSendBatchRequest, + QueueSendBatchResponse, + ), + "/nitric.queue.v1.QueueService/Receive": grpclib.const.Handler( + self.__rpc_receive, + grpclib.const.Cardinality.UNARY_UNARY, + QueueReceiveRequest, + QueueReceiveResponse, + ), + "/nitric.queue.v1.QueueService/Complete": grpclib.const.Handler( + self.__rpc_complete, + grpclib.const.Cardinality.UNARY_UNARY, + QueueCompleteRequest, + QueueCompleteResponse, + ), + } diff --git a/nitric/proto/nitric/resource/__init__.py b/nitric/proto/nitric/resource/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/resource/v1/__init__.py b/nitric/proto/nitric/resource/v1/__init__.py new file mode 100644 index 0000000..8d62270 --- /dev/null +++ b/nitric/proto/nitric/resource/v1/__init__.py @@ -0,0 +1,257 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: proto/resource/v1/resource.proto +# plugin: python-betterproto +from dataclasses import dataclass +from typing import ( + TYPE_CHECKING, + Dict, + List, + Optional, +) + +import betterproto +import grpclib +from betterproto.grpc.grpclib_server import ServiceBase + + +if TYPE_CHECKING: + import grpclib.server + from betterproto.grpc.grpclib_client import MetadataLike + from grpclib.metadata import Deadline + + +class ResourceType(betterproto.Enum): + Api = 0 + Function = 1 + Bucket = 2 + Queue = 3 + Topic = 4 + Schedule = 5 + Subscription = 6 + Collection = 7 + Policy = 8 + Secret = 9 + + +class Action(betterproto.Enum): + BucketFileList = 0 + """Bucket Permissions: 0XX""" + + BucketFileGet = 1 + BucketFilePut = 2 + BucketFileDelete = 3 + TopicList = 200 + """Topic Permissions: 2XX""" + + TopicDetail = 201 + TopicEventPublish = 202 + QueueSend = 300 + """Queue Permissions: 3XX""" + + QueueReceive = 301 + QueueList = 302 + QueueDetail = 303 + CollectionDocumentRead = 400 + """Collection Permissions: 4XX""" + + CollectionDocumentWrite = 401 + CollectionDocumentDelete = 402 + CollectionQuery = 403 + CollectionList = 404 + SecretPut = 500 + """Secret Permissions: 5XX""" + + SecretAccess = 501 + + +@dataclass(eq=False, repr=False) +class PolicyResource(betterproto.Message): + principals: List["Resource"] = betterproto.message_field(1) + actions: List["Action"] = betterproto.enum_field(2) + resources: List["Resource"] = betterproto.message_field(3) + + +@dataclass(eq=False, repr=False) +class Resource(betterproto.Message): + type: "ResourceType" = betterproto.enum_field(1) + name: str = betterproto.string_field(2) + + +@dataclass(eq=False, repr=False) +class ResourceDeclareRequest(betterproto.Message): + resource: "Resource" = betterproto.message_field(1) + policy: "PolicyResource" = betterproto.message_field(10, group="config") + bucket: "BucketResource" = betterproto.message_field(11, group="config") + queue: "QueueResource" = betterproto.message_field(12, group="config") + topic: "TopicResource" = betterproto.message_field(13, group="config") + collection: "CollectionResource" = betterproto.message_field(14, group="config") + secret: "SecretResource" = betterproto.message_field(15, group="config") + api: "ApiResource" = betterproto.message_field(16, group="config") + + +@dataclass(eq=False, repr=False) +class BucketResource(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class QueueResource(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class TopicResource(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class CollectionResource(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class SecretResource(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class ApiSecurityDefinitionJwt(betterproto.Message): + """protect your API with JWT authentication""" + + issuer: str = betterproto.string_field(1) + audiences: List[str] = betterproto.string_field(2) + + +@dataclass(eq=False, repr=False) +class ApiSecurityDefinition(betterproto.Message): + jwt: "ApiSecurityDefinitionJwt" = betterproto.message_field(1, group="definition") + + +@dataclass(eq=False, repr=False) +class ApiScopes(betterproto.Message): + scopes: List[str] = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class ApiResource(betterproto.Message): + security_definitions: Dict[str, "ApiSecurityDefinition"] = betterproto.map_field( + 1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE + ) + """ + Security definitions for the api These may be used by registered routes and + operations on the API + """ + + security: Dict[str, "ApiScopes"] = betterproto.map_field( + 2, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE + ) + """root level security for this api""" + + +@dataclass(eq=False, repr=False) +class ResourceDeclareResponse(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class ApiResourceDetails(betterproto.Message): + url: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class ResourceDetailsRequest(betterproto.Message): + resource: "Resource" = betterproto.message_field(1) + + +@dataclass(eq=False, repr=False) +class ResourceDetailsResponse(betterproto.Message): + id: str = betterproto.string_field(1) + """The identifier of the resource""" + + provider: str = betterproto.string_field(2) + """The provider this resource is deployed with (e.g. aws)""" + + service: str = betterproto.string_field(3) + """The service this resource is deployed on (e.g. ApiGateway)""" + + api: "ApiResourceDetails" = betterproto.message_field(10, group="details") + + +class ResourceServiceStub(betterproto.ServiceStub): + async def declare( + self, + resource_declare_request: "ResourceDeclareRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "ResourceDeclareResponse": + return await self._unary_unary( + "/nitric.resource.v1.ResourceService/Declare", + resource_declare_request, + ResourceDeclareResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def details( + self, + resource_details_request: "ResourceDetailsRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "ResourceDetailsResponse": + return await self._unary_unary( + "/nitric.resource.v1.ResourceService/Details", + resource_details_request, + ResourceDetailsResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + +class ResourceServiceBase(ServiceBase): + async def declare( + self, resource_declare_request: "ResourceDeclareRequest" + ) -> "ResourceDeclareResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def details( + self, resource_details_request: "ResourceDetailsRequest" + ) -> "ResourceDetailsResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def __rpc_declare( + self, + stream: "grpclib.server.Stream[ResourceDeclareRequest, ResourceDeclareResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.declare(request) + await stream.send_message(response) + + async def __rpc_details( + self, + stream: "grpclib.server.Stream[ResourceDetailsRequest, ResourceDetailsResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.details(request) + await stream.send_message(response) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/nitric.resource.v1.ResourceService/Declare": grpclib.const.Handler( + self.__rpc_declare, + grpclib.const.Cardinality.UNARY_UNARY, + ResourceDeclareRequest, + ResourceDeclareResponse, + ), + "/nitric.resource.v1.ResourceService/Details": grpclib.const.Handler( + self.__rpc_details, + grpclib.const.Cardinality.UNARY_UNARY, + ResourceDetailsRequest, + ResourceDetailsResponse, + ), + } diff --git a/nitric/proto/nitric/secret/__init__.py b/nitric/proto/nitric/secret/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/secret/v1/__init__.py b/nitric/proto/nitric/secret/v1/__init__.py new file mode 100644 index 0000000..c369d3d --- /dev/null +++ b/nitric/proto/nitric/secret/v1/__init__.py @@ -0,0 +1,152 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: proto/secret/v1/secret.proto +# plugin: python-betterproto +from dataclasses import dataclass +from typing import ( + TYPE_CHECKING, + Dict, + Optional, +) + +import betterproto +import grpclib +from betterproto.grpc.grpclib_server import ServiceBase + + +if TYPE_CHECKING: + import grpclib.server + from betterproto.grpc.grpclib_client import MetadataLike + from grpclib.metadata import Deadline + + +@dataclass(eq=False, repr=False) +class SecretPutRequest(betterproto.Message): + """Request to put a secret to a Secret Store""" + + secret: "Secret" = betterproto.message_field(1) + """The Secret to put to the Secret store""" + + value: bytes = betterproto.bytes_field(2) + """The value to assign to that secret""" + + +@dataclass(eq=False, repr=False) +class SecretPutResponse(betterproto.Message): + """Result from putting the secret to a Secret Store""" + + secret_version: "SecretVersion" = betterproto.message_field(1) + """The id of the secret""" + + +@dataclass(eq=False, repr=False) +class SecretAccessRequest(betterproto.Message): + """Request to get a secret from a Secret Store""" + + secret_version: "SecretVersion" = betterproto.message_field(1) + """The id of the secret""" + + +@dataclass(eq=False, repr=False) +class SecretAccessResponse(betterproto.Message): + """The secret response""" + + secret_version: "SecretVersion" = betterproto.message_field(1) + """The version of the secret that was requested""" + + value: bytes = betterproto.bytes_field(2) + """The value of the secret""" + + +@dataclass(eq=False, repr=False) +class Secret(betterproto.Message): + """The secret container""" + + name: str = betterproto.string_field(1) + """The secret name""" + + +@dataclass(eq=False, repr=False) +class SecretVersion(betterproto.Message): + """A version of a secret""" + + secret: "Secret" = betterproto.message_field(1) + """Reference to the secret container""" + + version: str = betterproto.string_field(2) + """The secret version""" + + +class SecretServiceStub(betterproto.ServiceStub): + async def put( + self, + secret_put_request: "SecretPutRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "SecretPutResponse": + return await self._unary_unary( + "/nitric.secret.v1.SecretService/Put", + secret_put_request, + SecretPutResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def access( + self, + secret_access_request: "SecretAccessRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "SecretAccessResponse": + return await self._unary_unary( + "/nitric.secret.v1.SecretService/Access", + secret_access_request, + SecretAccessResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + +class SecretServiceBase(ServiceBase): + async def put(self, secret_put_request: "SecretPutRequest") -> "SecretPutResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def access( + self, secret_access_request: "SecretAccessRequest" + ) -> "SecretAccessResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def __rpc_put( + self, stream: "grpclib.server.Stream[SecretPutRequest, SecretPutResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.put(request) + await stream.send_message(response) + + async def __rpc_access( + self, stream: "grpclib.server.Stream[SecretAccessRequest, SecretAccessResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.access(request) + await stream.send_message(response) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/nitric.secret.v1.SecretService/Put": grpclib.const.Handler( + self.__rpc_put, + grpclib.const.Cardinality.UNARY_UNARY, + SecretPutRequest, + SecretPutResponse, + ), + "/nitric.secret.v1.SecretService/Access": grpclib.const.Handler( + self.__rpc_access, + grpclib.const.Cardinality.UNARY_UNARY, + SecretAccessRequest, + SecretAccessResponse, + ), + } diff --git a/nitric/proto/nitric/storage/__init__.py b/nitric/proto/nitric/storage/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nitric/proto/nitric/storage/v1/__init__.py b/nitric/proto/nitric/storage/v1/__init__.py new file mode 100644 index 0000000..6e6130e --- /dev/null +++ b/nitric/proto/nitric/storage/v1/__init__.py @@ -0,0 +1,330 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: proto/storage/v1/storage.proto +# plugin: python-betterproto +from dataclasses import dataclass +from typing import ( + TYPE_CHECKING, + Dict, + List, + Optional, +) + +import betterproto +import grpclib +from betterproto.grpc.grpclib_server import ServiceBase + + +if TYPE_CHECKING: + import grpclib.server + from betterproto.grpc.grpclib_client import MetadataLike + from grpclib.metadata import Deadline + + +class StoragePreSignUrlRequestOperation(betterproto.Enum): + """Operation""" + + READ = 0 + WRITE = 1 + + +@dataclass(eq=False, repr=False) +class StorageWriteRequest(betterproto.Message): + """Request to put (create/update) a storage item""" + + bucket_name: str = betterproto.string_field(1) + """ + Nitric name of the bucket to store in this will be automatically resolved + to the provider specific bucket identifier. + """ + + key: str = betterproto.string_field(2) + """Key to store the item under""" + + body: bytes = betterproto.bytes_field(3) + """bytes array to store""" + + +@dataclass(eq=False, repr=False) +class StorageWriteResponse(betterproto.Message): + """Result of putting a storage item""" + + pass + + +@dataclass(eq=False, repr=False) +class StorageReadRequest(betterproto.Message): + """Request to retrieve a storage item""" + + bucket_name: str = betterproto.string_field(1) + """ + Nitric name of the bucket to retrieve from this will be automatically + resolved to the provider specific bucket identifier. + """ + + key: str = betterproto.string_field(2) + """Key of item to retrieve""" + + +@dataclass(eq=False, repr=False) +class StorageReadResponse(betterproto.Message): + """Returned storage item""" + + body: bytes = betterproto.bytes_field(1) + """The body bytes of the retrieved storage item""" + + +@dataclass(eq=False, repr=False) +class StorageDeleteRequest(betterproto.Message): + """Request to delete a storage item""" + + bucket_name: str = betterproto.string_field(1) + """Name of the bucket to delete from""" + + key: str = betterproto.string_field(2) + """Key of item to delete""" + + +@dataclass(eq=False, repr=False) +class StorageDeleteResponse(betterproto.Message): + """Result of deleting a storage item""" + + pass + + +@dataclass(eq=False, repr=False) +class StoragePreSignUrlRequest(betterproto.Message): + """ + Request to generate a pre-signed URL for a file to perform a specific + operation, such as read or write. + """ + + bucket_name: str = betterproto.string_field(1) + """ + Nitric name of the bucket to retrieve from this will be automatically + resolved to the provider specific bucket identifier. + """ + + key: str = betterproto.string_field(2) + """ + Key of item to generate the signed URL for. The URL and the token it + contains will only be valid for operations on this resource specifically. + """ + + operation: "StoragePreSignUrlRequestOperation" = betterproto.enum_field(3) + expiry: int = betterproto.uint32_field(4) + """ + Expiry time in seconds for the token included in the signed URL. Time + starts from when the access token is generated, not when this request is + made. e.g. time.Now().Add(expiry * time.Second) on the server + """ + + +@dataclass(eq=False, repr=False) +class StoragePreSignUrlResponse(betterproto.Message): + url: str = betterproto.string_field(1) + """ + The pre-signed url, restricted to the operation, resource and expiry time + specified in the request. + """ + + +@dataclass(eq=False, repr=False) +class StorageListFilesRequest(betterproto.Message): + bucket_name: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class File(betterproto.Message): + key: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class StorageListFilesResponse(betterproto.Message): + files: List["File"] = betterproto.message_field(1) + """keys of the files in the bucket""" + + +class StorageServiceStub(betterproto.ServiceStub): + async def read( + self, + storage_read_request: "StorageReadRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "StorageReadResponse": + return await self._unary_unary( + "/nitric.storage.v1.StorageService/Read", + storage_read_request, + StorageReadResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def write( + self, + storage_write_request: "StorageWriteRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "StorageWriteResponse": + return await self._unary_unary( + "/nitric.storage.v1.StorageService/Write", + storage_write_request, + StorageWriteResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def delete( + self, + storage_delete_request: "StorageDeleteRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "StorageDeleteResponse": + return await self._unary_unary( + "/nitric.storage.v1.StorageService/Delete", + storage_delete_request, + StorageDeleteResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def pre_sign_url( + self, + storage_pre_sign_url_request: "StoragePreSignUrlRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "StoragePreSignUrlResponse": + return await self._unary_unary( + "/nitric.storage.v1.StorageService/PreSignUrl", + storage_pre_sign_url_request, + StoragePreSignUrlResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + async def list_files( + self, + storage_list_files_request: "StorageListFilesRequest", + *, + timeout: Optional[float] = None, + deadline: Optional["Deadline"] = None, + metadata: Optional["MetadataLike"] = None + ) -> "StorageListFilesResponse": + return await self._unary_unary( + "/nitric.storage.v1.StorageService/ListFiles", + storage_list_files_request, + StorageListFilesResponse, + timeout=timeout, + deadline=deadline, + metadata=metadata, + ) + + +class StorageServiceBase(ServiceBase): + async def read( + self, storage_read_request: "StorageReadRequest" + ) -> "StorageReadResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def write( + self, storage_write_request: "StorageWriteRequest" + ) -> "StorageWriteResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def delete( + self, storage_delete_request: "StorageDeleteRequest" + ) -> "StorageDeleteResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def pre_sign_url( + self, storage_pre_sign_url_request: "StoragePreSignUrlRequest" + ) -> "StoragePreSignUrlResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def list_files( + self, storage_list_files_request: "StorageListFilesRequest" + ) -> "StorageListFilesResponse": + raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED) + + async def __rpc_read( + self, stream: "grpclib.server.Stream[StorageReadRequest, StorageReadResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.read(request) + await stream.send_message(response) + + async def __rpc_write( + self, stream: "grpclib.server.Stream[StorageWriteRequest, StorageWriteResponse]" + ) -> None: + request = await stream.recv_message() + response = await self.write(request) + await stream.send_message(response) + + async def __rpc_delete( + self, + stream: "grpclib.server.Stream[StorageDeleteRequest, StorageDeleteResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.delete(request) + await stream.send_message(response) + + async def __rpc_pre_sign_url( + self, + stream: "grpclib.server.Stream[StoragePreSignUrlRequest, StoragePreSignUrlResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.pre_sign_url(request) + await stream.send_message(response) + + async def __rpc_list_files( + self, + stream: "grpclib.server.Stream[StorageListFilesRequest, StorageListFilesResponse]", + ) -> None: + request = await stream.recv_message() + response = await self.list_files(request) + await stream.send_message(response) + + def __mapping__(self) -> Dict[str, grpclib.const.Handler]: + return { + "/nitric.storage.v1.StorageService/Read": grpclib.const.Handler( + self.__rpc_read, + grpclib.const.Cardinality.UNARY_UNARY, + StorageReadRequest, + StorageReadResponse, + ), + "/nitric.storage.v1.StorageService/Write": grpclib.const.Handler( + self.__rpc_write, + grpclib.const.Cardinality.UNARY_UNARY, + StorageWriteRequest, + StorageWriteResponse, + ), + "/nitric.storage.v1.StorageService/Delete": grpclib.const.Handler( + self.__rpc_delete, + grpclib.const.Cardinality.UNARY_UNARY, + StorageDeleteRequest, + StorageDeleteResponse, + ), + "/nitric.storage.v1.StorageService/PreSignUrl": grpclib.const.Handler( + self.__rpc_pre_sign_url, + grpclib.const.Cardinality.UNARY_UNARY, + StoragePreSignUrlRequest, + StoragePreSignUrlResponse, + ), + "/nitric.storage.v1.StorageService/ListFiles": grpclib.const.Handler( + self.__rpc_list_files, + grpclib.const.Cardinality.UNARY_UNARY, + StorageListFilesRequest, + StorageListFilesResponse, + ), + } diff --git a/nitric/proto/validate/__init__.py b/nitric/proto/validate/__init__.py new file mode 100644 index 0000000..8b5dd42 --- /dev/null +++ b/nitric/proto/validate/__init__.py @@ -0,0 +1,1170 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# sources: validate/validate.proto +# plugin: python-betterproto +from dataclasses import dataclass +from datetime import ( + datetime, + timedelta, +) +from typing import List + +import betterproto + + +class KnownRegex(betterproto.Enum): + """WellKnownRegex contain some well-known patterns.""" + + UNKNOWN = 0 + HTTP_HEADER_NAME = 1 + """HTTP header name as defined by RFC 7230.""" + + HTTP_HEADER_VALUE = 2 + """HTTP header value as defined by RFC 7230.""" + + +@dataclass(eq=False, repr=False) +class FieldRules(betterproto.Message): + """ + FieldRules encapsulates the rules for each type of field. Depending on the + field, the correct set should be used to ensure proper validations. + """ + + message: "MessageRules" = betterproto.message_field(17) + float: "FloatRules" = betterproto.message_field(1, group="type") + """Scalar Field Types""" + + double: "DoubleRules" = betterproto.message_field(2, group="type") + int32: "Int32Rules" = betterproto.message_field(3, group="type") + int64: "Int64Rules" = betterproto.message_field(4, group="type") + uint32: "UInt32Rules" = betterproto.message_field(5, group="type") + uint64: "UInt64Rules" = betterproto.message_field(6, group="type") + sint32: "SInt32Rules" = betterproto.message_field(7, group="type") + sint64: "SInt64Rules" = betterproto.message_field(8, group="type") + fixed32: "Fixed32Rules" = betterproto.message_field(9, group="type") + fixed64: "Fixed64Rules" = betterproto.message_field(10, group="type") + sfixed32: "SFixed32Rules" = betterproto.message_field(11, group="type") + sfixed64: "SFixed64Rules" = betterproto.message_field(12, group="type") + bool: "BoolRules" = betterproto.message_field(13, group="type") + string: "StringRules" = betterproto.message_field(14, group="type") + bytes: "BytesRules" = betterproto.message_field(15, group="type") + enum: "EnumRules" = betterproto.message_field(16, group="type") + """Complex Field Types""" + + repeated: "RepeatedRules" = betterproto.message_field(18, group="type") + map: "MapRules" = betterproto.message_field(19, group="type") + any: "AnyRules" = betterproto.message_field(20, group="type") + """Well-Known Field Types""" + + duration: "DurationRules" = betterproto.message_field(21, group="type") + timestamp: "TimestampRules" = betterproto.message_field(22, group="type") + + +@dataclass(eq=False, repr=False) +class FloatRules(betterproto.Message): + """FloatRules describes the constraints applied to `float` values""" + + const: float = betterproto.float_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: float = betterproto.float_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: float = betterproto.float_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: float = betterproto.float_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: float = betterproto.float_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[float] = betterproto.float_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[float] = betterproto.float_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class DoubleRules(betterproto.Message): + """DoubleRules describes the constraints applied to `double` values""" + + const: float = betterproto.double_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: float = betterproto.double_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: float = betterproto.double_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: float = betterproto.double_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: float = betterproto.double_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[float] = betterproto.double_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[float] = betterproto.double_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class Int32Rules(betterproto.Message): + """Int32Rules describes the constraints applied to `int32` values""" + + const: int = betterproto.int32_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.int32_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.int32_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.int32_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.int32_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.int32_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.int32_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class Int64Rules(betterproto.Message): + """Int64Rules describes the constraints applied to `int64` values""" + + const: int = betterproto.int64_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.int64_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.int64_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.int64_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.int64_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.int64_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.int64_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class UInt32Rules(betterproto.Message): + """UInt32Rules describes the constraints applied to `uint32` values""" + + const: int = betterproto.uint32_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.uint32_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.uint32_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.uint32_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.uint32_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.uint32_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.uint32_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class UInt64Rules(betterproto.Message): + """UInt64Rules describes the constraints applied to `uint64` values""" + + const: int = betterproto.uint64_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.uint64_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.uint64_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.uint64_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.uint64_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.uint64_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.uint64_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class SInt32Rules(betterproto.Message): + """SInt32Rules describes the constraints applied to `sint32` values""" + + const: int = betterproto.sint32_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.sint32_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.sint32_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.sint32_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.sint32_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.sint32_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.sint32_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class SInt64Rules(betterproto.Message): + """SInt64Rules describes the constraints applied to `sint64` values""" + + const: int = betterproto.sint64_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.sint64_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.sint64_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.sint64_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.sint64_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.sint64_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.sint64_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class Fixed32Rules(betterproto.Message): + """Fixed32Rules describes the constraints applied to `fixed32` values""" + + const: int = betterproto.fixed32_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.fixed32_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.fixed32_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.fixed32_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.fixed32_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.fixed32_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.fixed32_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class Fixed64Rules(betterproto.Message): + """Fixed64Rules describes the constraints applied to `fixed64` values""" + + const: int = betterproto.fixed64_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.fixed64_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.fixed64_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.fixed64_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.fixed64_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.fixed64_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.fixed64_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class SFixed32Rules(betterproto.Message): + """SFixed32Rules describes the constraints applied to `sfixed32` values""" + + const: int = betterproto.sfixed32_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.sfixed32_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.sfixed32_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.sfixed32_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.sfixed32_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.sfixed32_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.sfixed32_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class SFixed64Rules(betterproto.Message): + """SFixed64Rules describes the constraints applied to `sfixed64` values""" + + const: int = betterproto.sfixed64_field(1) + """Const specifies that this field must be exactly the specified value""" + + lt: int = betterproto.sfixed64_field(2) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: int = betterproto.sfixed64_field(3) + """ + Lte specifies that this field must be less than or equal to the specified + value, inclusive + """ + + gt: int = betterproto.sfixed64_field(4) + """ + Gt specifies that this field must be greater than the specified value, + exclusive. If the value of Gt is larger than a specified Lt or Lte, the + range is reversed. + """ + + gte: int = betterproto.sfixed64_field(5) + """ + Gte specifies that this field must be greater than or equal to the + specified value, inclusive. If the value of Gte is larger than a specified + Lt or Lte, the range is reversed. + """ + + in_: List[int] = betterproto.sfixed64_field(6) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.sfixed64_field(7) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ignore_empty: bool = betterproto.bool_field(8) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class BoolRules(betterproto.Message): + """BoolRules describes the constraints applied to `bool` values""" + + const: bool = betterproto.bool_field(1) + """Const specifies that this field must be exactly the specified value""" + + +@dataclass(eq=False, repr=False) +class StringRules(betterproto.Message): + """StringRules describe the constraints applied to `string` values""" + + const: str = betterproto.string_field(1) + """Const specifies that this field must be exactly the specified value""" + + len: int = betterproto.uint64_field(19) + """ + Len specifies that this field must be the specified number of characters + (Unicode code points). Note that the number of characters may differ from + the number of bytes in the string. + """ + + min_len: int = betterproto.uint64_field(2) + """ + MinLen specifies that this field must be the specified number of characters + (Unicode code points) at a minimum. Note that the number of characters may + differ from the number of bytes in the string. + """ + + max_len: int = betterproto.uint64_field(3) + """ + MaxLen specifies that this field must be the specified number of characters + (Unicode code points) at a maximum. Note that the number of characters may + differ from the number of bytes in the string. + """ + + len_bytes: int = betterproto.uint64_field(20) + """ + LenBytes specifies that this field must be the specified number of bytes at + a minimum + """ + + min_bytes: int = betterproto.uint64_field(4) + """ + MinBytes specifies that this field must be the specified number of bytes at + a minimum + """ + + max_bytes: int = betterproto.uint64_field(5) + """ + MaxBytes specifies that this field must be the specified number of bytes at + a maximum + """ + + pattern: str = betterproto.string_field(6) + """ + Pattern specifes that this field must match against the specified regular + expression (RE2 syntax). The included expression should elide any + delimiters. + """ + + prefix: str = betterproto.string_field(7) + """ + Prefix specifies that this field must have the specified substring at the + beginning of the string. + """ + + suffix: str = betterproto.string_field(8) + """ + Suffix specifies that this field must have the specified substring at the + end of the string. + """ + + contains: str = betterproto.string_field(9) + """ + Contains specifies that this field must have the specified substring + anywhere in the string. + """ + + not_contains: str = betterproto.string_field(23) + """ + NotContains specifies that this field cannot have the specified substring + anywhere in the string. + """ + + in_: List[str] = betterproto.string_field(10) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[str] = betterproto.string_field(11) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + email: bool = betterproto.bool_field(12, group="well_known") + """ + Email specifies that the field must be a valid email address as defined by + RFC 5322 + """ + + hostname: bool = betterproto.bool_field(13, group="well_known") + """ + Hostname specifies that the field must be a valid hostname as defined by + RFC 1034. This constraint does not support internationalized domain names + (IDNs). + """ + + ip: bool = betterproto.bool_field(14, group="well_known") + """ + Ip specifies that the field must be a valid IP (v4 or v6) address. Valid + IPv6 addresses should not include surrounding square brackets. + """ + + ipv4: bool = betterproto.bool_field(15, group="well_known") + """Ipv4 specifies that the field must be a valid IPv4 address.""" + + ipv6: bool = betterproto.bool_field(16, group="well_known") + """ + Ipv6 specifies that the field must be a valid IPv6 address. Valid IPv6 + addresses should not include surrounding square brackets. + """ + + uri: bool = betterproto.bool_field(17, group="well_known") + """ + Uri specifies that the field must be a valid, absolute URI as defined by + RFC 3986 + """ + + uri_ref: bool = betterproto.bool_field(18, group="well_known") + """ + UriRef specifies that the field must be a valid URI as defined by RFC 3986 + and may be relative or absolute. + """ + + address: bool = betterproto.bool_field(21, group="well_known") + """ + Address specifies that the field must be either a valid hostname as defined + by RFC 1034 (which does not support internationalized domain names or + IDNs), or it can be a valid IP (v4 or v6). + """ + + uuid: bool = betterproto.bool_field(22, group="well_known") + """ + Uuid specifies that the field must be a valid UUID as defined by RFC 4122 + """ + + well_known_regex: "KnownRegex" = betterproto.enum_field(24, group="well_known") + """ + WellKnownRegex specifies a common well known pattern defined as a regex. + """ + + strict: bool = betterproto.bool_field(25) + """ + This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable + strict header validation. By default, this is true, and HTTP header + validations are RFC-compliant. Setting to false will enable a looser + validations that only disallows \r\n\0 characters, which can be used to + bypass header matching rules. + """ + + ignore_empty: bool = betterproto.bool_field(26) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class BytesRules(betterproto.Message): + """BytesRules describe the constraints applied to `bytes` values""" + + const: bytes = betterproto.bytes_field(1) + """Const specifies that this field must be exactly the specified value""" + + len: int = betterproto.uint64_field(13) + """Len specifies that this field must be the specified number of bytes""" + + min_len: int = betterproto.uint64_field(2) + """ + MinLen specifies that this field must be the specified number of bytes at a + minimum + """ + + max_len: int = betterproto.uint64_field(3) + """ + MaxLen specifies that this field must be the specified number of bytes at a + maximum + """ + + pattern: str = betterproto.string_field(4) + """ + Pattern specifes that this field must match against the specified regular + expression (RE2 syntax). The included expression should elide any + delimiters. + """ + + prefix: bytes = betterproto.bytes_field(5) + """ + Prefix specifies that this field must have the specified bytes at the + beginning of the string. + """ + + suffix: bytes = betterproto.bytes_field(6) + """ + Suffix specifies that this field must have the specified bytes at the end + of the string. + """ + + contains: bytes = betterproto.bytes_field(7) + """ + Contains specifies that this field must have the specified bytes anywhere + in the string. + """ + + in_: List[bytes] = betterproto.bytes_field(8) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[bytes] = betterproto.bytes_field(9) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + ip: bool = betterproto.bool_field(10, group="well_known") + """ + Ip specifies that the field must be a valid IP (v4 or v6) address in byte + format + """ + + ipv4: bool = betterproto.bool_field(11, group="well_known") + """ + Ipv4 specifies that the field must be a valid IPv4 address in byte format + """ + + ipv6: bool = betterproto.bool_field(12, group="well_known") + """ + Ipv6 specifies that the field must be a valid IPv6 address in byte format + """ + + ignore_empty: bool = betterproto.bool_field(14) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class EnumRules(betterproto.Message): + """EnumRules describe the constraints applied to enum values""" + + const: int = betterproto.int32_field(1) + """Const specifies that this field must be exactly the specified value""" + + defined_only: bool = betterproto.bool_field(2) + """ + DefinedOnly specifies that this field must be only one of the defined + values for this enum, failing on any undefined value. + """ + + in_: List[int] = betterproto.int32_field(3) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[int] = betterproto.int32_field(4) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + +@dataclass(eq=False, repr=False) +class MessageRules(betterproto.Message): + """ + MessageRules describe the constraints applied to embedded message values. + For message-type fields, validation is performed recursively. + """ + + skip: bool = betterproto.bool_field(1) + """ + Skip specifies that the validation rules of this field should not be + evaluated + """ + + required: bool = betterproto.bool_field(2) + """Required specifies that this field must be set""" + + +@dataclass(eq=False, repr=False) +class RepeatedRules(betterproto.Message): + """RepeatedRules describe the constraints applied to `repeated` values""" + + min_items: int = betterproto.uint64_field(1) + """ + MinItems specifies that this field must have the specified number of items + at a minimum + """ + + max_items: int = betterproto.uint64_field(2) + """ + MaxItems specifies that this field must have the specified number of items + at a maximum + """ + + unique: bool = betterproto.bool_field(3) + """ + Unique specifies that all elements in this field must be unique. This + contraint is only applicable to scalar and enum types (messages are not + supported). + """ + + items: "FieldRules" = betterproto.message_field(4) + """ + Items specifies the contraints to be applied to each item in the field. + Repeated message fields will still execute validation against each item + unless skip is specified here. + """ + + ignore_empty: bool = betterproto.bool_field(5) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class MapRules(betterproto.Message): + """MapRules describe the constraints applied to `map` values""" + + min_pairs: int = betterproto.uint64_field(1) + """ + MinPairs specifies that this field must have the specified number of KVs at + a minimum + """ + + max_pairs: int = betterproto.uint64_field(2) + """ + MaxPairs specifies that this field must have the specified number of KVs at + a maximum + """ + + no_sparse: bool = betterproto.bool_field(3) + """ + NoSparse specifies values in this field cannot be unset. This only applies + to map's with message value types. + """ + + keys: "FieldRules" = betterproto.message_field(4) + """ + Keys specifies the constraints to be applied to each key in the field. + """ + + values: "FieldRules" = betterproto.message_field(5) + """ + Values specifies the constraints to be applied to the value of each key in + the field. Message values will still have their validations evaluated + unless skip is specified here. + """ + + ignore_empty: bool = betterproto.bool_field(6) + """ + IgnoreEmpty specifies that the validation rules of this field should be + evaluated only if the field is not empty + """ + + +@dataclass(eq=False, repr=False) +class AnyRules(betterproto.Message): + """ + AnyRules describe constraints applied exclusively to the + `google.protobuf.Any` well-known type + """ + + required: bool = betterproto.bool_field(1) + """Required specifies that this field must be set""" + + in_: List[str] = betterproto.string_field(2) + """ + In specifies that this field's `type_url` must be equal to one of the + specified values. + """ + + not_in: List[str] = betterproto.string_field(3) + """ + NotIn specifies that this field's `type_url` must not be equal to any of + the specified values. + """ + + +@dataclass(eq=False, repr=False) +class DurationRules(betterproto.Message): + """ + DurationRules describe the constraints applied exclusively to the + `google.protobuf.Duration` well-known type + """ + + required: bool = betterproto.bool_field(1) + """Required specifies that this field must be set""" + + const: timedelta = betterproto.message_field(2) + """Const specifies that this field must be exactly the specified value""" + + lt: timedelta = betterproto.message_field(3) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: timedelta = betterproto.message_field(4) + """ + Lt specifies that this field must be less than the specified value, + inclusive + """ + + gt: timedelta = betterproto.message_field(5) + """ + Gt specifies that this field must be greater than the specified value, + exclusive + """ + + gte: timedelta = betterproto.message_field(6) + """ + Gte specifies that this field must be greater than the specified value, + inclusive + """ + + in_: List[timedelta] = betterproto.message_field(7) + """ + In specifies that this field must be equal to one of the specified values + """ + + not_in: List[timedelta] = betterproto.message_field(8) + """ + NotIn specifies that this field cannot be equal to one of the specified + values + """ + + +@dataclass(eq=False, repr=False) +class TimestampRules(betterproto.Message): + """ + TimestampRules describe the constraints applied exclusively to the + `google.protobuf.Timestamp` well-known type + """ + + required: bool = betterproto.bool_field(1) + """Required specifies that this field must be set""" + + const: datetime = betterproto.message_field(2) + """Const specifies that this field must be exactly the specified value""" + + lt: datetime = betterproto.message_field(3) + """ + Lt specifies that this field must be less than the specified value, + exclusive + """ + + lte: datetime = betterproto.message_field(4) + """ + Lte specifies that this field must be less than the specified value, + inclusive + """ + + gt: datetime = betterproto.message_field(5) + """ + Gt specifies that this field must be greater than the specified value, + exclusive + """ + + gte: datetime = betterproto.message_field(6) + """ + Gte specifies that this field must be greater than the specified value, + inclusive + """ + + lt_now: bool = betterproto.bool_field(7) + """ + LtNow specifies that this must be less than the current time. LtNow can + only be used with the Within rule. + """ + + gt_now: bool = betterproto.bool_field(8) + """ + GtNow specifies that this must be greater than the current time. GtNow can + only be used with the Within rule. + """ + + within: timedelta = betterproto.message_field(9) + """ + Within specifies that this field must be within this duration of the + current time. This constraint can be used alone or with the LtNow and GtNow + rules. + """ diff --git a/nitric/resources/apis.py b/nitric/resources/apis.py index be2a45a..73ea10f 100644 --- a/nitric/resources/apis.py +++ b/nitric/resources/apis.py @@ -21,7 +21,7 @@ from nitric.faas import ApiWorkerOptions, FunctionServer, HttpMiddleware, Middleware, MethodOptions, HttpMethod from nitric.application import Nitric from nitric.resources.base import BaseResource -from nitricapi.nitric.resource.v1 import ( +from nitric.proto.nitric.resource.v1 import ( Resource, ResourceType, ApiResource, diff --git a/nitric/resources/base.py b/nitric/resources/base.py index 6a01d80..96a6a1a 100644 --- a/nitric/resources/base.py +++ b/nitric/resources/base.py @@ -25,7 +25,7 @@ from typing import TypeVar, Type, Union, List from grpclib import GRPCError -from nitricapi.nitric.resource.v1 import ( +from nitric.proto.nitric.resource.v1 import ( Action, PolicyResource, Resource, diff --git a/nitric/resources/buckets.py b/nitric/resources/buckets.py index d6db1d7..702473c 100644 --- a/nitric/resources/buckets.py +++ b/nitric/resources/buckets.py @@ -25,10 +25,11 @@ from grpclib import GRPCError from nitric.application import Nitric -from nitricapi.nitric.resource.v1 import ( +from nitric.proto.nitric.resource.v1 import ( Resource, ResourceType, - Action, ResourceDeclareRequest, + Action, + ResourceDeclareRequest, ) from nitric.resources.base import SecureResource @@ -56,7 +57,8 @@ def __init__(self, name: str): async def _register(self): try: await self._resources_stub.declare( - resource_declare_request=ResourceDeclareRequest(resource=self._to_resource())) + resource_declare_request=ResourceDeclareRequest(resource=self._to_resource()) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) diff --git a/nitric/resources/collections.py b/nitric/resources/collections.py index 744cd75..9323eda 100644 --- a/nitric/resources/collections.py +++ b/nitric/resources/collections.py @@ -18,8 +18,6 @@ # from __future__ import annotations -import asyncio - from nitric.api.documents import CollectionRef, Documents from nitric.api.exception import exception_from_grpc_error from typing import List, Union @@ -27,10 +25,11 @@ from grpclib import GRPCError from nitric.application import Nitric -from nitricapi.nitric.resource.v1 import ( +from nitric.proto.nitric.resource.v1 import ( Resource, ResourceType, - Action, ResourceDeclareRequest, + Action, + ResourceDeclareRequest, ) from nitric.resources.base import SecureResource @@ -54,7 +53,9 @@ def __init__(self, name: str): async def _register(self): try: - await self._resources_stub.declare(resource_declare_request=ResourceDeclareRequest(resource=self._to_resource())) + await self._resources_stub.declare( + resource_declare_request=ResourceDeclareRequest(resource=self._to_resource()) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) @@ -63,8 +64,11 @@ def _to_resource(self) -> Resource: def _perms_to_actions(self, *args: Union[CollectionPermission, str]) -> List[Action]: permission_actions_map = { - CollectionPermission.reading: [Action.CollectionDocumentRead, Action.CollectionQuery, - Action.CollectionList], + CollectionPermission.reading: [ + Action.CollectionDocumentRead, + Action.CollectionQuery, + Action.CollectionList, + ], CollectionPermission.writing: [Action.CollectionDocumentWrite, Action.CollectionList], CollectionPermission.deleting: [Action.CollectionDocumentDelete, Action.CollectionList], } diff --git a/nitric/resources/queues.py b/nitric/resources/queues.py index 15f1b7b..36b49de 100644 --- a/nitric/resources/queues.py +++ b/nitric/resources/queues.py @@ -24,10 +24,11 @@ from grpclib import GRPCError from nitric.api.queues import QueueRef, Queues from nitric.application import Nitric -from nitricapi.nitric.resource.v1 import ( +from nitric.proto.nitric.resource.v1 import ( Resource, ResourceType, - Action, ResourceDeclareRequest, + Action, + ResourceDeclareRequest, ) from nitric.resources.base import SecureResource @@ -70,7 +71,8 @@ def _perms_to_actions(self, *args: Union[QueuePermission, str]) -> List[Action]: async def _register(self): try: await self._resources_stub.declare( - resource_declare_request=ResourceDeclareRequest(resource=self._to_resource())) + resource_declare_request=ResourceDeclareRequest(resource=self._to_resource()) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) diff --git a/nitric/resources/secrets.py b/nitric/resources/secrets.py index fb7c19e..ebba11c 100644 --- a/nitric/resources/secrets.py +++ b/nitric/resources/secrets.py @@ -18,8 +18,6 @@ # from __future__ import annotations -import asyncio - from nitric.api.exception import exception_from_grpc_error from typing import List, Union from enum import Enum @@ -27,10 +25,11 @@ from nitric.application import Nitric from nitric.api.secrets import Secrets, SecretContainerRef -from nitricapi.nitric.resource.v1 import ( +from nitric.proto.nitric.resource.v1 import ( Resource, ResourceType, - Action, ResourceDeclareRequest, + Action, + ResourceDeclareRequest, ) from nitric.resources.base import SecureResource @@ -43,8 +42,6 @@ class SecretPermission(Enum): putting = "putting" - - class Secret(SecureResource): """A secret resource, used for storing and retrieving secret versions and values.""" @@ -61,7 +58,9 @@ def _to_resource(self) -> Resource: async def _register(self): try: - await self._resources_stub.declare(resource_declare_request=ResourceDeclareRequest(resource=self._to_resource())) + await self._resources_stub.declare( + resource_declare_request=ResourceDeclareRequest(resource=self._to_resource()) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) @@ -80,11 +79,11 @@ def _perms_to_actions(self, *args: Union[SecretPermission, str]) -> List[Action] def allow(self, *args: Union[SecretPermission, str]) -> SecretContainerRef: """Request the specified permissions to this resource.""" - self._register_policy(*args) return Secrets().secret(self.name) + # def secret(name: str) -> Secret: """ diff --git a/nitric/resources/topics.py b/nitric/resources/topics.py index 5e3e793..ed8a4c9 100644 --- a/nitric/resources/topics.py +++ b/nitric/resources/topics.py @@ -25,10 +25,11 @@ from grpclib import GRPCError from nitric.application import Nitric from nitric.faas import EventMiddleware, FunctionServer, SubscriptionWorkerOptions -from nitricapi.nitric.resource.v1 import ( +from nitric.proto.nitric.resource.v1 import ( Resource, ResourceType, - Action, ResourceDeclareRequest, + Action, + ResourceDeclareRequest, ) from nitric.resources.base import SecureResource @@ -55,7 +56,8 @@ def __init__(self, name: str): async def _register(self): try: await self._resources_stub.declare( - resource_declare_request=ResourceDeclareRequest(resource=self._to_resource())) + resource_declare_request=ResourceDeclareRequest(resource=self._to_resource()) + ) except GRPCError as grpc_err: raise exception_from_grpc_error(grpc_err) @@ -74,14 +76,12 @@ def _perms_to_actions(self, *args: Union[TopicPermission, str]) -> List[Action]: def allow(self, *args: Union[TopicPermission, str]) -> TopicRef: """Request the specified permissions to this resource.""" - self._register_policy(*args) return Events().topic(self.name) def subscribe(self, func: EventMiddleware): """Create and return a subscription decorator for this topic.""" - self.server = FunctionServer(SubscriptionWorkerOptions(topic=self.name)) self.server.event(func) Nitric._register_worker(self.server) diff --git a/setup.py b/setup.py index 02a9b3c..b32d73d 100644 --- a/setup.py +++ b/setup.py @@ -42,8 +42,9 @@ def get_current_version_tag(): ], setup_requires=["wheel"], install_requires=[ - "nitric-api==0.18.0", - "protobuf==3.19.4", + # "nitric-api==0.18.0", + "protobuf==3.19.5", + "betterproto==2.0.0b5", "asyncio", ], extras_require={ @@ -63,6 +64,11 @@ def get_current_version_tag(): "pip-licenses==3.3.1", "licenseheaders==0.8.8", "pdoc3==0.9.2", + "markupsafe==2.0.1", + "betterproto[compiler]==2.0.0b5", + # "grpcio==1.33.2", + "grpcio-tools==1.44.0", + "twine==3.2.0", ] }, python_requires=">=3.7", diff --git a/tests/api/test_documents.py b/tests/api/test_documents.py index cc63353..edea3b6 100644 --- a/tests/api/test_documents.py +++ b/tests/api/test_documents.py @@ -34,7 +34,7 @@ QueryResultsPage, ) from nitric.api.exception import UnknownException -from nitricapi.nitric.document.v1 import ( +from nitric.proto.nitric.document.v1 import ( Key, Collection, DocumentGetResponse, @@ -42,10 +42,14 @@ DocumentQueryResponse, Expression, ExpressionValue, - DocumentQueryStreamResponse, DocumentSetRequest, DocumentGetRequest, DocumentDeleteRequest, DocumentQueryRequest, + DocumentQueryStreamResponse, + DocumentSetRequest, + DocumentGetRequest, + DocumentDeleteRequest, + DocumentQueryRequest, DocumentQueryStreamRequest, ) -from nitricapi.nitric.event.v1 import TopicListResponse, NitricTopic +from nitric.proto.nitric.event.v1 import TopicListResponse, NitricTopic from nitric.utils import _struct_from_dict @@ -57,7 +61,7 @@ class DocumentsClientTest(IsolatedAsyncioTestCase): async def test_set_document(self): mock_set = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.set", mock_set): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.set", mock_set): await Documents().collection("a").doc("b").set({"a": 1}) mock_set.assert_called_once_with( @@ -77,7 +81,7 @@ async def test_set_document(self): async def test_set_subcollection_document(self): mock_set = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.set", mock_set): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.set", mock_set): await Documents().collection("a").doc("b").collection("c").doc("d").set({"a": 1}) mock_set.assert_called_once_with( @@ -113,7 +117,7 @@ async def test_get_document(self): ), ) - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.get", mock_get): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.get", mock_get): response = await Documents().collection("a").doc("b").get() mock_get.assert_called_once_with( @@ -146,7 +150,7 @@ async def test_get_subcollection_document(self): ), ) - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.get", mock_get): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.get", mock_get): response: SdkDocument = await Documents().collection("a").doc("b").collection("c").doc("d").get() mock_get.assert_called_once_with( @@ -172,7 +176,7 @@ async def test_get_subcollection_document(self): async def test_delete_document(self): mock_delete = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.delete", mock_delete): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.delete", mock_delete): await Documents().collection("a").doc("b").delete() mock_delete.assert_called_once_with( @@ -187,7 +191,7 @@ async def test_delete_document(self): async def test_delete_subcollection_document(self): mock_delete = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.delete", mock_delete): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.delete", mock_delete): await Documents().collection("a").doc("b").collection("c").doc("d").delete() mock_delete.assert_called_once_with( @@ -244,7 +248,7 @@ async def test_collection_query_fetch(self): paging_token={"b": "c"}, ) - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_query): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_query): results = ( await Documents() .collection("a") @@ -287,7 +291,7 @@ async def test_subcollection_query_fetch(self): paging_token={"b": "c"}, ) - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_query): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_query): results = ( await Documents() .collection("a") @@ -340,22 +344,23 @@ async def mock_stream(self, **kwargs): document=Document(content=Struct(fields={"a": Value(number_value=i)})) ) - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query_stream", mock_stream): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query_stream", mock_stream): results = [] async for result in Documents().collection("a").query().where("name", "startsWith", "test").stream(): results.append(result) self.assertEqual(3, stream_calls) - self.assertEqual({ - 'document_query_stream_request': DocumentQueryStreamRequest( - collection=Collection(name="a"), - expressions=[ - Expression(operand="name", operator="startsWith", value=ExpressionValue(string_value="test")) - ], - limit=0 - ), - }, - call_args, + self.assertEqual( + { + "document_query_stream_request": DocumentQueryStreamRequest( + collection=Collection(name="a"), + expressions=[ + Expression(operand="name", operator="startsWith", value=ExpressionValue(string_value="test")) + ], + limit=0, + ), + }, + call_args, ) self.assertEqual([{"a": i} for i in range(3)], [doc.content for doc in results]) @@ -365,7 +370,7 @@ async def test_set_document_error(self): mock_set = AsyncMock() mock_set.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.set", mock_set): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.set", mock_set): with pytest.raises(UnknownException) as e: await Documents().collection("a").doc("b").set({"a": 1}) @@ -373,7 +378,7 @@ async def test_get_document_error(self): mock_get = AsyncMock() mock_get.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.get", mock_get): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.get", mock_get): with pytest.raises(UnknownException) as e: await Documents().collection("a").doc("b").get() @@ -381,7 +386,7 @@ async def test_delete_document_error(self): mock_delete = AsyncMock() mock_delete.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.delete", mock_delete): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.delete", mock_delete): with pytest.raises(UnknownException) as e: await Documents().collection("a").doc("b").delete() @@ -389,7 +394,7 @@ async def test_query_fetch_error(self): mock_fetch = AsyncMock() mock_fetch.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_fetch): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_fetch): with pytest.raises(UnknownException) as e: await Documents().collection("a").query().fetch() @@ -408,7 +413,7 @@ async def mock_stream(self, **kwargs): document=Document(content=Struct(fields={"a": Value(number_value=i)})) ) - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query_stream", mock_stream): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query_stream", mock_stream): with pytest.raises(UnknownException) as e: async for result in Documents().collection("a").query().stream(): assert False diff --git a/tests/api/test_events.py b/tests/api/test_events.py index 603c88c..e8881ac 100644 --- a/tests/api/test_events.py +++ b/tests/api/test_events.py @@ -25,7 +25,7 @@ from nitric.api import Events, Event from nitric.api.exception import UnknownException -from nitricapi.nitric.event.v1 import TopicListResponse, NitricTopic, EventPublishRequest, NitricEvent +from nitric.proto.nitric.event.v1 import TopicListResponse, NitricTopic, EventPublishRequest, NitricEvent from nitric.utils import _struct_from_dict @@ -42,7 +42,7 @@ async def test_publish(self): payload = {"content": "of event"} - with patch("nitricapi.nitric.event.v1.EventServiceStub.publish", mock_publish): + with patch("nitric.proto.nitric.event.v1.EventServiceStub.publish", mock_publish): topic = Events().topic("test-topic") event = await topic.publish(Event(payload=payload)) @@ -53,12 +53,7 @@ async def test_publish(self): # mock_publish.assert_called_once() mock_publish.assert_called_once_with( event_publish_request=EventPublishRequest( - topic="test-topic", - event=NitricEvent( - id=None, - payload_type=None, - payload=_struct_from_dict(payload) - ) + topic="test-topic", event=NitricEvent(id=None, payload_type=None, payload=_struct_from_dict(payload)) ) ) @@ -70,18 +65,13 @@ async def test_publish_dict(self): payload = {"content": "of event"} - with patch("nitricapi.nitric.event.v1.EventServiceStub.publish", mock_publish): + with patch("nitric.proto.nitric.event.v1.EventServiceStub.publish", mock_publish): topic = Events().topic("test-topic") await topic.publish(Event(id="123", payload=payload)) mock_publish.assert_called_once_with( event_publish_request=EventPublishRequest( - topic="test-topic", - event=NitricEvent( - id="123", - payload=_struct_from_dict(payload), - payload_type=None - ) + topic="test-topic", event=NitricEvent(id="123", payload=_struct_from_dict(payload), payload_type=None) ) ) @@ -93,7 +83,7 @@ async def test_publish_invalid_type(self): payload = {"content": "of event"} - with patch("nitricapi.nitric.event.v1.EventServiceStub.publish", mock_publish): + with patch("nitric.proto.nitric.event.v1.EventServiceStub.publish", mock_publish): topic = Events().topic("test-topic") with pytest.raises(Exception): await topic.publish((1, 2, 3)) @@ -106,19 +96,14 @@ async def test_publish_none(self): payload = {"content": "of event"} - with patch("nitricapi.nitric.event.v1.EventServiceStub.publish", mock_publish): + with patch("nitric.proto.nitric.event.v1.EventServiceStub.publish", mock_publish): topic = Events().topic("test-topic") await topic.publish() # Check expected values were passed to Stub mock_publish.assert_called_once_with( event_publish_request=EventPublishRequest( - topic="test-topic", - event=NitricEvent( - id=None, - payload=Struct(), - payload_type=None - ) + topic="test-topic", event=NitricEvent(id=None, payload=Struct(), payload_type=None) ) ) @@ -134,7 +119,7 @@ async def test_get_topics(self): payload = {"content": "of event"} - with patch("nitricapi.nitric.event.v1.TopicServiceStub.list", mock_list_topics): + with patch("nitric.proto.nitric.event.v1.TopicServiceStub.list", mock_list_topics): topics = await Events().topics() # Check expected values were passed to Stub @@ -147,7 +132,7 @@ async def test_publish_error(self): mock_publish = AsyncMock() mock_publish.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.event.v1.EventServiceStub.publish", mock_publish): + with patch("nitric.proto.nitric.event.v1.EventServiceStub.publish", mock_publish): with pytest.raises(UnknownException) as e: await Events().topic("test-topic").publish(Event(payload={})) @@ -155,6 +140,6 @@ async def test_get_topics_error(self): mock_get_topics = AsyncMock() mock_get_topics.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.event.v1.TopicServiceStub.list", mock_get_topics): + with patch("nitric.proto.nitric.event.v1.TopicServiceStub.list", mock_get_topics): with pytest.raises(UnknownException) as e: await Events().topics() diff --git a/tests/api/test_queues.py b/tests/api/test_queues.py index bcf2ac9..8793047 100644 --- a/tests/api/test_queues.py +++ b/tests/api/test_queues.py @@ -26,12 +26,16 @@ from nitric.api import Queues, Task from nitric.api.exception import UnknownException from nitric.api.queues import ReceivedTask -from nitricapi.nitric.queue.v1 import ( +from nitric.proto.nitric.queue.v1 import ( QueueReceiveResponse, NitricTask, QueueCompleteResponse, QueueSendBatchResponse, - FailedTask, QueueSendRequest, QueueSendBatchRequest, QueueReceiveRequest, QueueCompleteRequest, + FailedTask, + QueueSendRequest, + QueueSendBatchRequest, + QueueReceiveRequest, + QueueCompleteRequest, ) from nitric.utils import _struct_from_dict @@ -48,19 +52,16 @@ async def test_send(self): payload = {"content": "of task"} - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send", mock_send): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send", mock_send): queue = Queues().queue("test-queue") await queue.send(Task(payload=payload)) # Check expected values were passed to Stub - mock_send.assert_called_once_with(queue_send_request=QueueSendRequest( - queue="test-queue", - task=NitricTask( - id=None, - payload_type=None, - payload=_struct_from_dict(payload) + mock_send.assert_called_once_with( + queue_send_request=QueueSendRequest( + queue="test-queue", task=NitricTask(id=None, payload_type=None, payload=_struct_from_dict(payload)) ) - )) + ) async def test_send_with_failed(self): payload = {"content": "of task"} @@ -78,22 +79,19 @@ async def test_send_with_failed(self): ] ) - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send_batch", mock_send): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send_batch", mock_send): queue = Queues().queue("test-queue") failed = await queue.send([Task(payload=payload) for i in range(2)]) - mock_send.assert_called_once_with(queue_send_batch_request=QueueSendBatchRequest( - queue="test-queue", - tasks=[NitricTask( - id=None, - payload_type=None, - payload=_struct_from_dict(payload) - ), NitricTask( - id=None, - payload_type=None, - payload=_struct_from_dict(payload) - )] - )) + mock_send.assert_called_once_with( + queue_send_batch_request=QueueSendBatchRequest( + queue="test-queue", + tasks=[ + NitricTask(id=None, payload_type=None, payload=_struct_from_dict(payload)), + NitricTask(id=None, payload_type=None, payload=_struct_from_dict(payload)), + ], + ) + ) # Check that the failed task is returned with its details self.assertEqual(1, len(failed)) @@ -107,19 +105,16 @@ async def test_send_dict(self): payload = {"content": "of task"} - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send", mock_send): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send", mock_send): queue = Queues().queue("test-queue") await queue.send({"id": "123", "payload": payload}) # Check expected values were passed to Stub - mock_send.assert_called_once_with(queue_send_request=QueueSendRequest( - queue="test-queue", - task=NitricTask( - id="123", - payload_type=None, - payload=_struct_from_dict(payload) + mock_send.assert_called_once_with( + queue_send_request=QueueSendRequest( + queue="test-queue", task=NitricTask(id="123", payload_type=None, payload=_struct_from_dict(payload)) ) - )) + ) async def test_send_invalid_type(self): mock_send = AsyncMock() @@ -128,7 +123,7 @@ async def test_send_invalid_type(self): payload = {"content": "of task"} - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send", mock_send): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send", mock_send): queue = Queues().queue("test-queue") with pytest.raises(AttributeError): await queue.send((1, 2, 3)) @@ -140,20 +135,16 @@ async def test_send_none(self): payload = {"content": "of task"} - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send", mock_send): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send", mock_send): queue = Queues().queue("test-queue") await queue.send() # Check expected values were passed to Stub - mock_send.assert_called_once_with(queue_send_request=QueueSendRequest( - queue="test-queue", - task=NitricTask( - id=None, - payload_type=None, - payload=Struct() + mock_send.assert_called_once_with( + queue_send_request=QueueSendRequest( + queue="test-queue", task=NitricTask(id=None, payload_type=None, payload=Struct()) ) - )) - + ) async def test_send_empty_list(self): with pytest.raises(Exception) as e_info: @@ -173,16 +164,13 @@ async def test_receive(self): ] ) - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.receive", mock_receive): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.receive", mock_receive): queueing = Queues() queue = queueing.queue("test-queue") (task,) = await queue.receive() # Check expected values were passed to Stub - mock_receive.assert_called_once_with(queue_receive_request=QueueReceiveRequest( - queue="test-queue", - depth=1 - )) + mock_receive.assert_called_once_with(queue_receive_request=QueueReceiveRequest(queue="test-queue", depth=1)) self.assertEqual("test-task", task.id) self.assertEqual("test-lease", task.lease_id) @@ -204,15 +192,11 @@ async def test_receive_custom_limit(self): ] ) - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.receive", mock_receive): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.receive", mock_receive): await Queues().queue("test-queue").receive(limit=3) # explicitly set a limit # Check expected values were passed to Stub - mock_receive.assert_called_once_with(queue_receive_request=QueueReceiveRequest( - queue="test-queue", - depth=3 - )) - + mock_receive.assert_called_once_with(queue_receive_request=QueueReceiveRequest(queue="test-queue", depth=3)) async def test_receive_below_minimum_limit(self): mock_receive = AsyncMock() @@ -227,26 +211,20 @@ async def test_receive_below_minimum_limit(self): ] ) - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.receive", mock_receive): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.receive", mock_receive): await Queues().queue("test-queue").receive(limit=0) # explicitly set a limit - mock_receive.assert_called_once_with(queue_receive_request=QueueReceiveRequest( - queue="test-queue", - depth=1 - )) + mock_receive.assert_called_once_with(queue_receive_request=QueueReceiveRequest(queue="test-queue", depth=1)) async def test_receive_task_without_payload(self): mock_receive = AsyncMock() mock_receive.return_value = QueueReceiveResponse(tasks=[NitricTask(id="test-task", lease_id="test-lease")]) - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.receive", mock_receive): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.receive", mock_receive): (task,) = await Queues().queue("test-queue").receive(limit=0) # explicitly set a limit # Verify that an empty dict is returned for payload and no payload type. - mock_receive.assert_called_once_with(queue_receive_request=QueueReceiveRequest( - queue="test-queue", - depth=1 - )) + mock_receive.assert_called_once_with(queue_receive_request=QueueReceiveRequest(queue="test-queue", depth=1)) self.assertEqual("", task.payload_type) self.assertEqual({}, task.payload) @@ -258,13 +236,12 @@ async def test_complete(self): queueing = Queues() task = ReceivedTask(lease_id="test-lease", _queueing=queueing, _queue=queueing.queue("test-queue")) - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.complete", mock_complete): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.complete", mock_complete): await task.complete() - mock_complete.assert_called_once_with(queue_complete_request=QueueCompleteRequest( - queue="test-queue", - lease_id="test-lease" - )) + mock_complete.assert_called_once_with( + queue_complete_request=QueueCompleteRequest(queue="test-queue", lease_id="test-lease") + ) async def test_complete_task_without_client(self): queueing = Queues() @@ -279,7 +256,7 @@ async def test_send_error(self): mock_send = AsyncMock() mock_send.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send", mock_send): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send", mock_send): with pytest.raises(UnknownException) as e: await Queues().queue("test-queue").send(Task(payload={"content": "of task"})) @@ -287,7 +264,7 @@ async def test_send_batch_error(self): mock_send = AsyncMock() mock_send.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send_batch", mock_send): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send_batch", mock_send): with pytest.raises(UnknownException) as e: await Queues().queue("test-queue").send([Task(payload={"content": "of task"}) for i in range(2)]) @@ -295,7 +272,7 @@ async def test_receive_error(self): mock_receive = AsyncMock() mock_receive.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.receive", mock_receive): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.receive", mock_receive): with pytest.raises(UnknownException) as e: await Queues().queue("test-queue").receive() @@ -306,6 +283,6 @@ async def test_complete_error(self): queueing = Queues() task = ReceivedTask(lease_id="test-lease", _queueing=queueing, _queue=queueing.queue("test-queue")) - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.complete", mock_complete): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.complete", mock_complete): with pytest.raises(UnknownException) as e: await task.complete() diff --git a/tests/api/test_secrets.py b/tests/api/test_secrets.py index d85b081..83d079e 100644 --- a/tests/api/test_secrets.py +++ b/tests/api/test_secrets.py @@ -25,8 +25,14 @@ from nitric.api import Secrets from nitric.api.exception import UnknownException from nitric.api.secrets import SecretValue -from nitricapi.nitric.secret.v1 import SecretPutResponse, SecretVersion, Secret, SecretAccessResponse, SecretPutRequest, \ - SecretAccessRequest +from nitric.proto.nitric.secret.v1 import ( + SecretPutResponse, + SecretVersion, + Secret, + SecretAccessResponse, + SecretPutRequest, + SecretAccessRequest, +) class Object(object): @@ -41,15 +47,14 @@ async def test_put(self): ) mock_put.return_value = mock_response - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.put", mock_put): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.put", mock_put): secret = Secrets().secret("test-secret") result = await secret.put(b"a test secret value") # Check expected values were passed to Stub - mock_put.assert_called_once_with(secret_put_request=SecretPutRequest( - secret=Secret(name="test-secret"), - value=b"a test secret value" - )) + mock_put.assert_called_once_with( + secret_put_request=SecretPutRequest(secret=Secret(name="test-secret"), value=b"a test secret value") + ) # Check the returned value assert result.id == "test-version" @@ -62,15 +67,14 @@ async def test_put_string(self): ) mock_put.return_value = mock_response - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.put", mock_put): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.put", mock_put): secret = Secrets().secret("test-secret") await secret.put("a test secret value") # string, not bytes # Check expected values were passed to Stub - mock_put.assert_called_once_with(secret_put_request=SecretPutRequest( - secret=Secret(name="test-secret"), - value=b"a test secret value" - )) + mock_put.assert_called_once_with( + secret_put_request=SecretPutRequest(secret=Secret(name="test-secret"), value=b"a test secret value") + ) async def test_latest(self): version = Secrets().secret("test-secret").latest() @@ -86,18 +90,16 @@ async def test_access(self): ) mock_access.return_value = mock_response - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.access", mock_access): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.access", mock_access): version = Secrets().secret("test-secret").latest() result = await version.access() # Check expected values were passed to Stub - mock_access.assert_called_once_with(secret_access_request=SecretAccessRequest( - secret_version=SecretVersion( - secret=Secret(name="test-secret"), - version="latest" - + mock_access.assert_called_once_with( + secret_access_request=SecretAccessRequest( + secret_version=SecretVersion(secret=Secret(name="test-secret"), version="latest") ) - )) + ) # Check the returned value assert result.version.id == "response-version" @@ -119,7 +121,7 @@ async def test_put_error(self): mock_put = AsyncMock() mock_put.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.put", mock_put): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.put", mock_put): with pytest.raises(UnknownException) as e: secret = Secrets().secret("test-secret") await secret.put(b"a test secret value") @@ -128,6 +130,6 @@ async def test_access_error(self): mock_access = AsyncMock() mock_access.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.access", mock_access): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.access", mock_access): with pytest.raises(UnknownException) as e: await Secrets().secret("test-secret").latest().access() diff --git a/tests/api/test_storage.py b/tests/api/test_storage.py index 22e8ffc..6aabfc6 100644 --- a/tests/api/test_storage.py +++ b/tests/api/test_storage.py @@ -21,7 +21,7 @@ import pytest from grpclib import GRPCError, Status -from nitricapi.nitric.storage.v1 import ( +from nitric.proto.nitric.storage.v1 import ( StorageWriteRequest, StorageReadRequest, StorageDeleteRequest, @@ -46,7 +46,7 @@ async def test_write(self): contents = b"some text as bytes" - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.write", mock_write): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.write", mock_write): bucket = Storage().bucket("test-bucket") file = bucket.file("test-file") await file.write(contents) @@ -64,7 +64,7 @@ async def test_read(self): mock_response.body = contents mock_read.return_value = mock_response - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.read", mock_read): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.read", mock_read): bucket = Storage().bucket("test-bucket") file = bucket.file("test-file") response = await file.read() @@ -83,7 +83,7 @@ async def test_delete(self): mock_delete = AsyncMock() mock_delete.return_value = Object() - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.delete", mock_delete): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.delete", mock_delete): bucket = Storage().bucket("test-bucket") file = bucket.file("test-file") await file.delete() @@ -100,7 +100,7 @@ async def test_sign_url(self): mock_pre_sign_url = AsyncMock() mock_pre_sign_url.return_value = StoragePreSignUrlResponse(url="www.example.com") - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.pre_sign_url", mock_pre_sign_url): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.pre_sign_url", mock_pre_sign_url): bucket = Storage().bucket("test-bucket") file = bucket.file("test-file") url = await file.sign_url() @@ -122,7 +122,7 @@ async def test_write_error(self): mock_write = AsyncMock() mock_write.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.write", mock_write): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.write", mock_write): with pytest.raises(UnknownException) as e: await Storage().bucket("test-bucket").file("test-file").write(b"some text as bytes") @@ -130,7 +130,7 @@ async def test_read_error(self): mock_read = AsyncMock() mock_read.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.read", mock_read): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.read", mock_read): with pytest.raises(UnknownException) as e: await Storage().bucket("test-bucket").file("test-file").read() @@ -138,7 +138,7 @@ async def test_delete_error(self): mock_delete = AsyncMock() mock_delete.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.delete", mock_delete): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.delete", mock_delete): with pytest.raises(UnknownException) as e: await Storage().bucket("test-bucket").file("test-file").delete() @@ -146,6 +146,6 @@ async def test_sign_url_error(self): mock_pre_sign_url = AsyncMock() mock_pre_sign_url.side_effect = GRPCError(Status.UNKNOWN, "test error") - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.pre_sign_url", mock_pre_sign_url): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.pre_sign_url", mock_pre_sign_url): with pytest.raises(UnknownException) as e: await Storage().bucket("test-bucket").file("test-file").sign_url() diff --git a/tests/examples/test_documents_example.py b/tests/examples/test_documents_example.py index 3cae8a7..39e9e34 100644 --- a/tests/examples/test_documents_example.py +++ b/tests/examples/test_documents_example.py @@ -17,8 +17,14 @@ # limitations under the License. # from examples.documents.sub_col_query import documents_sub_col_query -from nitricapi.nitric.document.v1 import Collection, DocumentGetResponse, DocumentQueryStreamResponse, Document, Key, \ - DocumentGetRequest +from nitric.proto.nitric.document.v1 import ( + Collection, + DocumentGetResponse, + DocumentQueryStreamResponse, + Document, + Key, + DocumentGetRequest, +) from examples.documents.set import documents_set from examples.documents.get import documents_get from examples.documents.delete import documents_delete @@ -40,7 +46,7 @@ class DocumentsExamplesTest(IsolatedAsyncioTestCase): async def test_set_document(self): mock_set = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.set", mock_set): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.set", mock_set): await documents_set() mock_set.assert_called_once() @@ -58,7 +64,7 @@ async def test_get_document(self): ), ) - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.get", mock_get): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.get", mock_get): await documents_get() mock_get.assert_called_once_with( @@ -73,7 +79,7 @@ async def test_get_document(self): async def test_delete_document(self): mock_delete = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.delete", mock_delete): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.delete", mock_delete): await documents_delete() mock_delete.assert_called_once() @@ -81,7 +87,7 @@ async def test_delete_document(self): async def test_query_document(self): mock_query = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_query): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_query): await documents_query() mock_query.assert_called_once() @@ -89,7 +95,7 @@ async def test_query_document(self): async def test_paged_results_document(self): mock_query = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_query): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_query): await documents_paged_results() mock_query.assert_called() @@ -97,7 +103,7 @@ async def test_paged_results_document(self): async def test_query_filter_document(self): mock_query = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_query): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_query): await documents_query_filter() mock_query.assert_called_once() @@ -105,7 +111,7 @@ async def test_query_filter_document(self): async def test_query_limits_document(self): mock_query = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_query): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_query): await documents_query_limits() mock_query.assert_called_once() @@ -113,7 +119,7 @@ async def test_query_limits_document(self): async def test_sub_doc_query_document(self): mock_query = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_query): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_query): await documents_sub_doc_query() mock_query.assert_called_once() @@ -121,7 +127,7 @@ async def test_sub_doc_query_document(self): async def test_sub_col_query_document(self): mock_query = AsyncMock() - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query", mock_query): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query", mock_query): await documents_sub_col_query() mock_query.assert_called_once() @@ -140,7 +146,7 @@ async def mock_stream(self, **kwargs): document=Document(content=Struct(fields={"a": Value(number_value=i)})) ) - with patch("nitricapi.nitric.document.v1.DocumentServiceStub.query_stream", mock_stream): + with patch("nitric.proto.nitric.document.v1.DocumentServiceStub.query_stream", mock_stream): await documents_streamed() self.assertEqual(3, stream_calls) diff --git a/tests/examples/test_events_example.py b/tests/examples/test_events_example.py index 622f71c..f8103fd 100644 --- a/tests/examples/test_events_example.py +++ b/tests/examples/test_events_example.py @@ -27,7 +27,7 @@ class EventsExamplesTest(IsolatedAsyncioTestCase): async def test_publish_topic(self): mock_publish = AsyncMock() - with patch("nitricapi.nitric.event.v1.EventServiceStub.publish", mock_publish): + with patch("nitric.proto.nitric.event.v1.EventServiceStub.publish", mock_publish): await events_publish() mock_publish.assert_called_once() @@ -35,7 +35,7 @@ async def test_publish_topic(self): async def test_event_id_publish(self): mock_publish = AsyncMock() - with patch("nitricapi.nitric.event.v1.EventServiceStub.publish", mock_publish): + with patch("nitric.proto.nitric.event.v1.EventServiceStub.publish", mock_publish): await events_event_ids() mock_publish.assert_called_once() diff --git a/tests/examples/test_queues_example.py b/tests/examples/test_queues_example.py index 5a2dd26..ee4f7f6 100644 --- a/tests/examples/test_queues_example.py +++ b/tests/examples/test_queues_example.py @@ -18,7 +18,7 @@ # from typing import List -from nitricapi.nitric.queue.v1 import NitricTask, QueueSendBatchResponse, QueueSendResponse, FailedTask +from nitric.proto.nitric.queue.v1 import NitricTask, QueueSendBatchResponse, QueueSendResponse, FailedTask from examples.queues.failed import queues_failed from examples.queues.receive import queues_receive @@ -32,7 +32,7 @@ class QueuesExamplesTest(IsolatedAsyncioTestCase): async def test_receive_queue(self): mock_receive = AsyncMock() - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.receive", mock_receive): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.receive", mock_receive): await queues_receive() mock_receive.assert_called_once() @@ -40,7 +40,7 @@ async def test_receive_queue(self): async def test_send_queue(self): mock_send = AsyncMock() - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send", mock_send): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send", mock_send): await queues_send() mock_send.assert_called_once() @@ -58,7 +58,7 @@ async def test_failed_queue(self): ] ) - with patch("nitricapi.nitric.queue.v1.QueueServiceStub.send_batch", mock_failed): + with patch("nitric.proto.nitric.queue.v1.QueueServiceStub.send_batch", mock_failed): await queues_failed() mock_failed.assert_called_once() diff --git a/tests/examples/test_secrets_example.py b/tests/examples/test_secrets_example.py index c3603b3..5c9a455 100644 --- a/tests/examples/test_secrets_example.py +++ b/tests/examples/test_secrets_example.py @@ -16,7 +16,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -from nitricapi.nitric.secret.v1 import Secret, SecretVersion, SecretAccessResponse, SecretPutResponse +from nitric.proto.nitric.secret.v1 import Secret, SecretVersion, SecretAccessResponse, SecretPutResponse from examples.secrets.access import secret_access from examples.secrets.put import secret_put from examples.secrets.latest import secret_latest @@ -34,7 +34,7 @@ async def test_latest_secret(self): ) mock_latest.return_value = mock_response - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.access", mock_latest): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.access", mock_latest): await secret_latest() mock_latest.assert_called_once() @@ -53,8 +53,8 @@ async def test_put_secret(self): ) mock_access.return_value = mock_response - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.put", mock_put): - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.access", mock_access): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.put", mock_put): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.access", mock_access): await secret_put() mock_put.assert_called_once() @@ -67,7 +67,7 @@ async def test_access_secret(self): value=b"super secret value", ) mock_access.return_value = mock_response - with patch("nitricapi.nitric.secret.v1.SecretServiceStub.access", mock_access): + with patch("nitric.proto.nitric.secret.v1.SecretServiceStub.access", mock_access): await secret_access() mock_access.assert_called_once() diff --git a/tests/examples/test_storage_example.py b/tests/examples/test_storage_example.py index 328f77f..f6742ed 100644 --- a/tests/examples/test_storage_example.py +++ b/tests/examples/test_storage_example.py @@ -28,7 +28,7 @@ class StorageExamplesTest(IsolatedAsyncioTestCase): async def test_read_storage(self): mock_read = AsyncMock() - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.read", mock_read): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.read", mock_read): await storage_read() mock_read.assert_called_once() @@ -36,7 +36,7 @@ async def test_read_storage(self): async def test_write_storage(self): mock_write = AsyncMock() - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.write", mock_write): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.write", mock_write): await storage_write() mock_write.assert_called_once() @@ -44,7 +44,7 @@ async def test_write_storage(self): async def test_delete_storage(self): mock_delete = AsyncMock() - with patch("nitricapi.nitric.storage.v1.StorageServiceStub.delete", mock_delete): + with patch("nitric.proto.nitric.storage.v1.StorageServiceStub.delete", mock_delete): await storage_delete() mock_delete.assert_called_once() diff --git a/tests/resources/test_buckets.py b/tests/resources/test_buckets.py index b1bd59a..7943377 100644 --- a/tests/resources/test_buckets.py +++ b/tests/resources/test_buckets.py @@ -19,11 +19,11 @@ from unittest import IsolatedAsyncioTestCase from unittest.mock import patch, AsyncMock -from nitricapi.nitric.storage.v1 import StorageWriteRequest +from nitric.proto.nitric.storage.v1 import StorageWriteRequest from nitric.resources import bucket -from nitricapi.nitric.resource.v1 import Action, ResourceDeclareRequest, Resource, ResourceType, PolicyResource +from nitric.proto.nitric.resource.v1 import Action, ResourceDeclareRequest, Resource, ResourceType, PolicyResource class Object(object): @@ -36,98 +36,107 @@ def test_create_allow_writing(self): mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): bucket("test-bucket").allow("writing") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[Action.BucketFilePut], - resources=[Resource(type=ResourceType.Bucket, name="test-bucket")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[Action.BucketFilePut], + resources=[Resource(type=ResourceType.Bucket, name="test-bucket")], + ), ) - )) + ) def test_create_allow_reading(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): bucket("test-bucket").allow("reading") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[Action.BucketFileGet, Action.BucketFileList], - resources=[Resource(type=ResourceType.Bucket, name="test-bucket")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[Action.BucketFileGet, Action.BucketFileList], + resources=[Resource(type=ResourceType.Bucket, name="test-bucket")], + ), ) - )) + ) def test_create_allow_deleting(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): bucket("test-bucket").allow("deleting") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[Action.BucketFileDelete], - resources=[Resource(type=ResourceType.Bucket, name="test-bucket")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[Action.BucketFileDelete], + resources=[Resource(type=ResourceType.Bucket, name="test-bucket")], + ), ) - )) + ) def test_create_allow_all(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): bucket("test-bucket").allow("deleting", "reading", "writing") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.BucketFileDelete, - Action.BucketFileGet, - Action.BucketFileList, - Action.BucketFilePut - ], - resources=[Resource(type=ResourceType.Bucket, name="test-bucket")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.BucketFileDelete, + Action.BucketFileGet, + Action.BucketFileList, + Action.BucketFilePut, + ], + resources=[Resource(type=ResourceType.Bucket, name="test-bucket")], + ), ) - )) + ) def test_create_allow_all_reversed_policy(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): bucket("test-bucket").allow("writing", "reading", "deleting") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.BucketFilePut, - Action.BucketFileGet, - Action.BucketFileList, - Action.BucketFileDelete, - ], - resources=[Resource(type=ResourceType.Bucket, name="test-bucket")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.BucketFilePut, + Action.BucketFileGet, + Action.BucketFileList, + Action.BucketFileDelete, + ], + resources=[Resource(type=ResourceType.Bucket, name="test-bucket")], + ), ) - )) - + ) diff --git a/tests/resources/test_collections.py b/tests/resources/test_collections.py index 3b89a57..1f8cf79 100644 --- a/tests/resources/test_collections.py +++ b/tests/resources/test_collections.py @@ -21,12 +21,12 @@ from nitric.resources import collection -from nitricapi.nitric.resource.v1 import Action, ResourceType, PolicyResource, ResourceDeclareRequest, Resource +from nitric.proto.nitric.resource.v1 import Action, ResourceType, PolicyResource, ResourceDeclareRequest, Resource from betterproto.lib.google.protobuf import Struct, Value -from nitricapi.nitric.document.v1 import Key, Collection as DocumentCollection, DocumentGetResponse, Document +from nitric.proto.nitric.document.v1 import Key, Collection as DocumentCollection, DocumentGetResponse, Document class Object(object): @@ -39,113 +39,123 @@ def test_create_allow_writing(self): mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): collection("test-collection").allow("writing") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.CollectionDocumentWrite, - Action.CollectionList, - ], - resources=[Resource(type=ResourceType.Collection, name="test-collection")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.CollectionDocumentWrite, + Action.CollectionList, + ], + resources=[Resource(type=ResourceType.Collection, name="test-collection")], + ), ) - )) + ) def test_create_allow_reading(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): collection("test-collection").allow("reading") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.CollectionDocumentRead, - Action.CollectionQuery, - Action.CollectionList, - ], - resources=[Resource(type=ResourceType.Collection, name="test-collection")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.CollectionDocumentRead, + Action.CollectionQuery, + Action.CollectionList, + ], + resources=[Resource(type=ResourceType.Collection, name="test-collection")], + ), ) - )) + ) def test_create_allow_deleting(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): collection("test-collection").allow("deleting") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.CollectionDocumentDelete, - Action.CollectionList, - ], - resources=[Resource(type=ResourceType.Collection, name="test-collection")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.CollectionDocumentDelete, + Action.CollectionList, + ], + resources=[Resource(type=ResourceType.Collection, name="test-collection")], + ), ) - )) + ) def test_create_allow_all(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): collection("test-collection").allow("deleting", "reading", "writing") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.CollectionDocumentDelete, - Action.CollectionList, - Action.CollectionDocumentRead, - Action.CollectionQuery, - Action.CollectionList, - Action.CollectionDocumentWrite, - Action.CollectionList, - ], - resources=[Resource(type=ResourceType.Collection, name="test-collection")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.CollectionDocumentDelete, + Action.CollectionList, + Action.CollectionDocumentRead, + Action.CollectionQuery, + Action.CollectionList, + Action.CollectionDocumentWrite, + Action.CollectionList, + ], + resources=[Resource(type=ResourceType.Collection, name="test-collection")], + ), ) - )) + ) def test_create_allow_all_reversed_policy(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): collection("test-collection").allow("writing", "reading", "deleting") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.CollectionDocumentWrite, - Action.CollectionList, - Action.CollectionDocumentRead, - Action.CollectionQuery, - Action.CollectionList, - Action.CollectionDocumentDelete, - Action.CollectionList, - ], - resources=[Resource(type=ResourceType.Collection, name="test-collection")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.CollectionDocumentWrite, + Action.CollectionList, + Action.CollectionDocumentRead, + Action.CollectionQuery, + Action.CollectionList, + Action.CollectionDocumentDelete, + Action.CollectionList, + ], + resources=[Resource(type=ResourceType.Collection, name="test-collection")], + ), ) - )) + ) diff --git a/tests/resources/test_queues.py b/tests/resources/test_queues.py index 46ad0b5..f18e945 100644 --- a/tests/resources/test_queues.py +++ b/tests/resources/test_queues.py @@ -20,7 +20,7 @@ from unittest.mock import patch, AsyncMock from nitric.resources import queue -from nitricapi.nitric.resource.v1 import Action, ResourceDeclareRequest, Resource, ResourceType, PolicyResource +from nitric.proto.nitric.resource.v1 import Action, ResourceDeclareRequest, Resource, ResourceType, PolicyResource from nitric.utils import _struct_from_dict @@ -34,66 +34,72 @@ def test_create_allow_sending(self): mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): queue("test-queue").allow("sending") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.QueueSend, - Action.QueueList, - Action.QueueDetail, - ], - resources=[Resource(type=ResourceType.Queue, name="test-queue")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.QueueSend, + Action.QueueList, + Action.QueueDetail, + ], + resources=[Resource(type=ResourceType.Queue, name="test-queue")], + ), ) - )) + ) def test_create_allow_receiving(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): queue("test-queue").allow("receiving") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.QueueReceive, - Action.QueueList, - Action.QueueDetail, - ], - resources=[Resource(type=ResourceType.Queue, name="test-queue")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.QueueReceive, + Action.QueueList, + Action.QueueDetail, + ], + resources=[Resource(type=ResourceType.Queue, name="test-queue")], + ), ) - )) + ) def test_create_allow_all(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): queue("test-queue").allow("sending", "receiving") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.QueueSend, - Action.QueueList, - Action.QueueDetail, - Action.QueueReceive, - Action.QueueList, - Action.QueueDetail, - ], - resources=[Resource(type=ResourceType.Queue, name="test-queue")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[ + Action.QueueSend, + Action.QueueList, + Action.QueueDetail, + Action.QueueReceive, + Action.QueueList, + Action.QueueDetail, + ], + resources=[Resource(type=ResourceType.Queue, name="test-queue")], + ), ) - )) + ) diff --git a/tests/resources/test_secrets.py b/tests/resources/test_secrets.py index b43e602..8fe235f 100644 --- a/tests/resources/test_secrets.py +++ b/tests/resources/test_secrets.py @@ -20,8 +20,8 @@ from unittest.mock import patch, AsyncMock from nitric.resources import secret -from nitricapi.nitric.resource.v1 import Action, ResourceDeclareRequest, Resource, ResourceType, PolicyResource -from nitricapi.nitric.secret.v1 import SecretPutResponse, SecretVersion, Secret +from nitric.proto.nitric.resource.v1 import Action, ResourceDeclareRequest, Resource, ResourceType, PolicyResource +from nitric.proto.nitric.secret.v1 import SecretPutResponse, SecretVersion, Secret class Object(object): @@ -34,38 +34,37 @@ def test_allow_put(self): mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): secret("test-secret").allow("putting") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.SecretPut - ], - resources=[Resource(type=ResourceType.Secret, name="test-secret")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[Action.SecretPut], + resources=[Resource(type=ResourceType.Secret, name="test-secret")], + ), ) - )) - + ) def test_allow_access(self): mock_declare = AsyncMock() mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): secret("test-secret").allow("accessing") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.SecretAccess - ], - resources=[Resource(type=ResourceType.Secret, name="test-secret")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[Action.SecretAccess], + resources=[Resource(type=ResourceType.Secret, name="test-secret")], + ), ) - )) + ) diff --git a/tests/resources/test_topics.py b/tests/resources/test_topics.py index c8e490f..7602a5e 100644 --- a/tests/resources/test_topics.py +++ b/tests/resources/test_topics.py @@ -19,7 +19,7 @@ from unittest import IsolatedAsyncioTestCase from unittest.mock import patch, AsyncMock, Mock -from nitricapi.nitric.resource.v1 import Action, ResourceDeclareRequest, Resource, ResourceType, PolicyResource +from nitric.proto.nitric.resource.v1 import Action, ResourceDeclareRequest, Resource, ResourceType, PolicyResource from nitric.resources import topic @@ -41,17 +41,17 @@ def test_create_allow_publishing(self): mock_response = Object() mock_declare.return_value = mock_response - with patch("nitricapi.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): + with patch("nitric.proto.nitric.resource.v1.ResourceServiceStub.declare", mock_declare): topic("test-topic").allow("publishing") # Check expected values were passed to Stub - mock_declare.assert_called_with(resource_declare_request=ResourceDeclareRequest( - resource=Resource(type=ResourceType.Policy), - policy=PolicyResource( - principals=[Resource(type=ResourceType.Function)], - actions=[ - Action.TopicEventPublish - ], - resources=[Resource(type=ResourceType.Topic, name="test-topic")] + mock_declare.assert_called_with( + resource_declare_request=ResourceDeclareRequest( + resource=Resource(type=ResourceType.Policy), + policy=PolicyResource( + principals=[Resource(type=ResourceType.Function)], + actions=[Action.TopicEventPublish], + resources=[Resource(type=ResourceType.Topic, name="test-topic")], + ), ) - )) + ) diff --git a/tests/test_faas.py b/tests/test_faas.py index 693314e..1aa9195 100644 --- a/tests/test_faas.py +++ b/tests/test_faas.py @@ -23,7 +23,7 @@ from nitric.faas import start, FunctionServer, HttpContext, compose_middleware, HttpResponse, FaasWorkerOptions -from nitricapi.nitric.faas.v1 import ( +from nitric.proto.nitric.faas.v1 import ( ServerMessage, InitResponse, ClientMessage, @@ -133,7 +133,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).http(mock_handler)._run() @@ -174,7 +174,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).http(mock_http_handler).event(mock_event_handler)._run() @@ -209,7 +209,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).http(mock_http_handler).event(mock_event_handler)._run() @@ -244,7 +244,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).http(mock_http_handler).event(mock_event_handler)._run() @@ -279,7 +279,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).http(mock_http_handler).event(mock_event_handler)._run() @@ -314,7 +314,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).http(mock_http_handler).event(mock_event_handler)._run() @@ -343,7 +343,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).event(mock_handler)._run() @@ -382,7 +382,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).http(mock_handler)._run() @@ -423,7 +423,7 @@ async def mock_stream(self, request_iterator): yield message with patch("nitric.faas.AsyncChannel", mock_async_channel_init), patch( - "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + "nitric.proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream ), patch("nitric.faas.new_default_channel", mock_grpc_channel): await FunctionServer(opts=FaasWorkerOptions()).http(mock_handler)._run() @@ -463,7 +463,7 @@ async def mock_stream(self, request_iterator): # yield message # # with patch("nitric.faas.faas.AsyncChannel", mock_async_channel_init), patch( - # "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + # "proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream # ), patch("nitric.faas.faas.new_default_channel", mock_grpc_channel): # await faas._register_function_handler(mock_handler) # @@ -504,7 +504,7 @@ async def mock_stream(self, request_iterator): # yield message # # with patch("nitric.faas.faas.AsyncChannel", mock_async_channel_init), patch( - # "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + # "proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream # ), patch("nitric.faas.faas.new_default_channel", mock_grpc_channel): # await faas._register_function_handler(mock_handler) # @@ -553,7 +553,7 @@ async def mock_stream(self, request_iterator): # yield message # # with patch("nitric.faas.faas.AsyncChannel", mock_async_channel_init), patch( - # "nitricapi.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream + # "proto.nitric.faas.v1.FaasServiceStub.trigger_stream", mock_stream # ), patch("nitric.faas.faas.new_default_channel", mock_grpc_channel): # # An exception shouldn't be thrown, even though the serialization fails # await faas._register_function_handler(mock_handler) diff --git a/tox.ini b/tox.ini index ebf4289..3a0d9a2 100644 --- a/tox.ini +++ b/tox.ini @@ -22,16 +22,15 @@ commands = pydocstyle nitric pip-licenses --allow-only="MIT License;BSD License;Zope Public License;Python Software Foundation License;Apache License 2.0;Apache Software License;MIT License, Mozilla Public License 2.0 (MPL 2.0);MIT;BSD License, Apache Software License;3-Clause BSD License;Historical Permission Notice and Disclaimer (HPND);Mozilla Public License 2.0 (MPL 2.0);Apache Software License, BSD License;BSD;Python Software Foundation License, MIT License;Public Domain;Public Domain, Python Software Foundation License, BSD License, GNU General Public License (GPL);GNU Library or Lesser General Public License (LGPL);LGPL;Apache Software License, MIT License" --ignore-packages nitric nitric-api asyncio - [flake8] exclude = - venv, - tests, - build, - dist, - .git, - .tox, - nitric/proto, + venv + tests + build + dist + .git + .tox + nitric/proto examples ignore = F821, W503 max-line-length = 120